From e9f041e170d24ed79ef772131a4cedfd271532e7 Mon Sep 17 00:00:00 2001 From: Filipi Fuchter Date: Fri, 6 Jun 2025 17:09:01 -0300 Subject: [PATCH] Removing the old websocket-server example --- examples/websocket-server/Dockerfile | 15 -- examples/websocket-server/README.md | 28 --- examples/websocket-server/bot.py | 153 --------------- examples/websocket-server/env.example | 8 - examples/websocket-server/frames.proto | 44 ----- examples/websocket-server/index.html | 211 --------------------- examples/websocket-server/requirements.txt | 2 - 7 files changed, 461 deletions(-) delete mode 100644 examples/websocket-server/Dockerfile delete mode 100644 examples/websocket-server/README.md delete mode 100644 examples/websocket-server/bot.py delete mode 100644 examples/websocket-server/env.example delete mode 100644 examples/websocket-server/frames.proto delete mode 100644 examples/websocket-server/index.html delete mode 100644 examples/websocket-server/requirements.txt diff --git a/examples/websocket-server/Dockerfile b/examples/websocket-server/Dockerfile deleted file mode 100644 index 0610ab7f8..000000000 --- a/examples/websocket-server/Dockerfile +++ /dev/null @@ -1,15 +0,0 @@ -FROM python:3.10-bullseye - -RUN mkdir /app - -COPY *.py /app/ -COPY requirements.txt /app/ -COPY .env /app/ - -WORKDIR /app - -RUN pip3 install -r requirements.txt - -EXPOSE 7860 - -CMD ["python3", "bot.py"] diff --git a/examples/websocket-server/README.md b/examples/websocket-server/README.md deleted file mode 100644 index a8f2f1aac..000000000 --- a/examples/websocket-server/README.md +++ /dev/null @@ -1,28 +0,0 @@ -# Websocket Server - -This is an example that shows how to use `WebsocketServerTransport` to communicate with a web client. - -## Get started - -```python -python3 -m venv venv -source venv/bin/activate -pip install -r requirements.txt -cp env.example .env # and add your credentials -``` - -## Run the bot - -```bash -python bot.py -``` - -## Run the HTTP server - -This will host the static web client: - -```bash -python -m http.server -``` - -Then, visit `http://localhost:8000` in your browser to start a session. diff --git a/examples/websocket-server/bot.py b/examples/websocket-server/bot.py deleted file mode 100644 index 816d7540b..000000000 --- a/examples/websocket-server/bot.py +++ /dev/null @@ -1,153 +0,0 @@ -# -# Copyright (c) 2024–2025, Daily -# -# SPDX-License-Identifier: BSD 2-Clause License -# - -import asyncio -import os -import sys - -from dotenv import load_dotenv -from loguru import logger - -from pipecat.audio.vad.silero import SileroVADAnalyzer -from pipecat.frames.frames import BotInterruptionFrame, EndFrame -from pipecat.pipeline.pipeline import Pipeline -from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask -from pipecat.processors.aggregators.openai_llm_context import OpenAILLMContext -from pipecat.serializers.protobuf import ProtobufFrameSerializer -from pipecat.services.cartesia.tts import CartesiaTTSService -from pipecat.services.deepgram.stt import DeepgramSTTService -from pipecat.services.openai.llm import OpenAILLMService -from pipecat.transports.network.websocket_server import ( - WebsocketServerParams, - WebsocketServerTransport, -) - -load_dotenv(override=True) - -logger.remove(0) -logger.add(sys.stderr, level="DEBUG") - - -class SessionTimeoutHandler: - """Handles actions to be performed when a session times out. - Inputs: - - task: Pipeline task (used to queue frames). - - tts: TTS service (used to generate speech output). - """ - - def __init__(self, task, tts): - self.task = task - self.tts = tts - self.background_tasks = set() - - async def handle_timeout(self, client_address): - """Handles the timeout event for a session.""" - try: - logger.info(f"Connection timeout for {client_address}") - - # Queue a BotInterruptionFrame to notify the user - await self.task.queue_frames([BotInterruptionFrame()]) - - # Send the TTS message to inform the user about the timeout - await self.tts.say( - "I'm sorry, we are ending the call now. Please feel free to reach out again if you need assistance." - ) - - # Start the process to gracefully end the call in the background - end_call_task = asyncio.create_task(self._end_call()) - self.background_tasks.add(end_call_task) - end_call_task.add_done_callback(self.background_tasks.discard) - except Exception as e: - logger.error(f"Error during session timeout handling: {e}") - - async def _end_call(self): - """Completes the session termination process after the TTS message.""" - try: - # Wait for a duration to ensure TTS has completed - await asyncio.sleep(15) - - # Queue both BotInterruptionFrame and EndFrame to conclude the session - await self.task.queue_frames([BotInterruptionFrame(), EndFrame()]) - - logger.info("TTS completed and EndFrame pushed successfully.") - except Exception as e: - logger.error(f"Error during call termination: {e}") - - -async def main(): - transport = WebsocketServerTransport( - params=WebsocketServerParams( - serializer=ProtobufFrameSerializer(), - audio_in_enabled=True, - audio_out_enabled=True, - add_wav_header=True, - vad_analyzer=SileroVADAnalyzer(), - session_timeout=60 * 3, # 3 minutes - ) - ) - - llm = OpenAILLMService(api_key=os.getenv("OPENAI_API_KEY")) - - stt = DeepgramSTTService(api_key=os.getenv("DEEPGRAM_API_KEY")) - - tts = CartesiaTTSService( - api_key=os.getenv("CARTESIA_API_KEY"), - voice_id="71a7ad14-091c-4e8e-a314-022ece01c121", # British Reading Lady - ) - - messages = [ - { - "role": "system", - "content": "You are a helpful LLM in a WebRTC call. Your goal is to demonstrate your capabilities in a succinct way. Your output will be converted to audio so don't include special characters in your answers. Respond to what the user said in a creative and helpful way.", - }, - ] - - context = OpenAILLMContext(messages) - context_aggregator = llm.create_context_aggregator(context) - - pipeline = Pipeline( - [ - transport.input(), # Websocket input from client - stt, # Speech-To-Text - context_aggregator.user(), - llm, # LLM - tts, # Text-To-Speech - transport.output(), # Websocket output to client - context_aggregator.assistant(), - ] - ) - - task = PipelineTask( - pipeline, - params=PipelineParams( - audio_in_sample_rate=16000, - audio_out_sample_rate=16000, - allow_interruptions=True, - ), - ) - - @transport.event_handler("on_client_connected") - async def on_client_connected(transport, client): - # Kick off the conversation. - messages.append({"role": "system", "content": "Please introduce yourself to the user."}) - await task.queue_frames([context_aggregator.user().get_context_frame()]) - - @transport.event_handler("on_session_timeout") - async def on_session_timeout(transport, client): - logger.info(f"Entering in timeout for {client.remote_address}") - - timeout_handler = SessionTimeoutHandler(task, tts) - - await timeout_handler.handle_timeout(client) - - runner = PipelineRunner() - - await runner.run(task) - - -if __name__ == "__main__": - asyncio.run(main()) diff --git a/examples/websocket-server/env.example b/examples/websocket-server/env.example deleted file mode 100644 index c3359ada2..000000000 --- a/examples/websocket-server/env.example +++ /dev/null @@ -1,8 +0,0 @@ -# OpenAI API Key -OPENAI_API_KEY=your_openai_api_key_here - -# Deepgram API Key -DEEPGRAM_API_KEY=your_deepgram_api_key_here - -# Cartesia API Key -CARTESIA_API_KEY=your_cartesia_api_key_here diff --git a/examples/websocket-server/frames.proto b/examples/websocket-server/frames.proto deleted file mode 100644 index 98dc014db..000000000 --- a/examples/websocket-server/frames.proto +++ /dev/null @@ -1,44 +0,0 @@ -// -// Copyright (c) 2024–2025, Daily -// -// SPDX-License-Identifier: BSD 2-Clause License -// - -// Generate frames_pb2.py with: -// -// python -m grpc_tools.protoc --proto_path=./ --python_out=./protobufs frames.proto - -syntax = "proto3"; - -package pipecat; - -message TextFrame { - uint64 id = 1; - string name = 2; - string text = 3; -} - -message AudioRawFrame { - uint64 id = 1; - string name = 2; - bytes audio = 3; - uint32 sample_rate = 4; - uint32 num_channels = 5; - optional uint64 pts = 6; -} - -message TranscriptionFrame { - uint64 id = 1; - string name = 2; - string text = 3; - string user_id = 4; - string timestamp = 5; -} - -message Frame { - oneof frame { - TextFrame text = 1; - AudioRawFrame audio = 2; - TranscriptionFrame transcription = 3; - } -} diff --git a/examples/websocket-server/index.html b/examples/websocket-server/index.html deleted file mode 100644 index 6f0bd1ada..000000000 --- a/examples/websocket-server/index.html +++ /dev/null @@ -1,211 +0,0 @@ - - - - - - - - Pipecat WebSocket Client Example - - - -

Pipecat WebSocket Client Example

-

Loading, wait...

- - - - - - diff --git a/examples/websocket-server/requirements.txt b/examples/websocket-server/requirements.txt deleted file mode 100644 index ed2130a79..000000000 --- a/examples/websocket-server/requirements.txt +++ /dev/null @@ -1,2 +0,0 @@ -python-dotenv -pipecat-ai[cartesia,openai,silero,websocket,deepgram]