Skip to main content

Python library that provides a websocket endpoint handler for FastAPI to stream between Twilio and OpenAI realtime.

Project description

realtime-websocket-conversation

A Python package for building real-time, streaming websocket conversations between Twilio and OpenAI using FastAPI. This library provides a websocket handler that streams audio between a Twilio client and an OpenAI model, enabling interactive voice assistants and conversational AI applications.

The goal of this package is really to reduce the boilerplate code needed to set up a real-time conversation with OpenAI's models.

Features

  • Real-time audio streaming between Twilio and OpenAI
  • FastAPI websocket integration
  • Supports OpenAI function calling with simple @tool decorator (modified & borrowed from OpenAI's Agent SDK)
    • In your tool function signatures, you can use state and connection parameters to access mutable state and the OpenAI websocket connection (in case you need to update session settings). If you don't need these, use **kwargs in your function signature, as the decorator will pass them anyway.
  • Handles interruptions and audio truncation for natural conversations
  • Optional callback functions for user and assistant message transcription events

Installation

You can install the package using uv:

uv add realtime-websocket-conversation

or with pip:

pip install realtime-websocket-conversation

Usage Example

FastAPI Integration

from fastapi import FastAPI, Request, WebSocket
from fastapi.responses import HTMLResponse
from openai import AsyncOpenAI
from realtime_websocket_conversation import handle_websocket_conversation, tool
from twilio.twiml.voice_response import Connect, VoiceResponse

app = FastAPI()
openai_client = AsyncOpenAI()

@app.get("/incoming-call", response_class=HTMLResponse)
async def incoming_call(request: Request):
    response = VoiceResponse()
    response.say("Connecting your call...")
    host = (
        request.headers.get("X-Forwarded-Host")
        or request.headers.get("Host")
        or request.url.hostname
    )
    connect = Connect()
    connect.stream(url=f"wss://{host}/media-stream")
    response.append(connect)
    return HTMLResponse(content=str(response), media_type="application/xml")

@app.websocket("/media-stream")
async def media_stream(websocket: WebSocket):
    await handle_websocket_conversation(
        websocket=websocket,
        openai_client=openai_client,
        model="gpt-4o-realtime-preview",
        voice="alloy",
        system_message="You are a helpful chat assistant.",
        temperature=0.8,
        turn_detection=None,  # Optional turn detection config, defaults to {"type": "server_vad"}, fed directly to session settings
        tools=[],  # Optionally pass tool functions
        state={},  # Optionally pass a mutable state object, to be passed to tool functions
        on_user_message=None,  # Optional callback when user message transcription completes
        on_assistant_message=None,  # Optional callback when assistant message transcription completes
    )

Point your Twilio webhook to the /incoming-call endpoint, and the websocket connection will be established when a call is received.

Registering a Tool Function

from realtime_websocket_conversation import tool

@tool
def get_time(state=None, connection=None):
    from datetime import datetime
    return {"time": datetime.now().isoformat()}

Add your tool functions to the tools list when calling handle_websocket_conversation, i.e. [get_time].

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

realtime_websocket_conversation-0.1.2.tar.gz (83.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

File details

Details for the file realtime_websocket_conversation-0.1.2.tar.gz.

File metadata

File hashes

Hashes for realtime_websocket_conversation-0.1.2.tar.gz
Algorithm Hash digest
SHA256 40365810e1b132a2d32bd4b59ad8e5f75c83a4488b00d075a302e8f539616ed5
MD5 8d8feb1716c1f4e949d82127ca9c9ddb
BLAKE2b-256 d18a40dc7ebb2edeadadcffd05ba4594c915d4360fa19784803cb211873c91b6

See more details on using hashes here.

File details

Details for the file realtime_websocket_conversation-0.1.2-py3-none-any.whl.

File metadata

File hashes

Hashes for realtime_websocket_conversation-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 de93f7c95f54433c35e9b69293c3040acc89c225dd11c83a6aa5e7c7b3c74311
MD5 ccc20bf5dc0b220838515f8b8442d751
BLAKE2b-256 1a47728669118eaf5e0245ba8cb15a10f5681db4e59830a9d41fceb57117f50b

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page