Skip to main content

Python library that provides a websocket endpoint 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

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,
        tools=[],  # Optionally pass tool functions
        state={},  # Optionally pass a mutable state object, to be passed to tool functions
    )

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.0.tar.gz (29.9 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.0.tar.gz.

File metadata

File hashes

Hashes for realtime_websocket_conversation-0.1.0.tar.gz
Algorithm Hash digest
SHA256 8b509d079270a374cfbc30ed49de7b868008ded3fcde239a16c64302cd4a45d6
MD5 d0cd1c0813bdeb75c37c2949f852d2ee
BLAKE2b-256 07838ff77d3bf602fd0dae12e1673c73bc3afeab2c24a218f71d809e5bdc4a0b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for realtime_websocket_conversation-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 8ebc1d01a9af5b3d4ca5f47f6419534c40f5c7fd6cdb12c43863d138452021c1
MD5 9c6a06403d6e172227e8ea8f66b620d8
BLAKE2b-256 2773fb2f528ff47a3c48b21f4dd598020a0179d7fd042f639847866424554a84

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