VoiceStack / server.py
klentyboopathi's picture
updated
35a55c1
#
# Copyright (c) 2025, Daily
#
# SPDX-License-Identifier: BSD 2-Clause License
#
import asyncio
import os
import sys
from contextlib import asynccontextmanager
from typing import Any, Dict
import uvicorn
from dotenv import load_dotenv
from fastapi import FastAPI, Request, WebSocket
from fastapi.middleware.cors import CORSMiddleware
# from bot.bot_fast_api import run_bot
from bot.bot_websocket_server import run_bot_websocket_server
# Load environment variables
load_dotenv(override=True)
@asynccontextmanager
async def lifespan(app: FastAPI):
"""Handles FastAPI startup and shutdown."""
yield # Run app
# Initialize FastAPI app with lifespan manager
app = FastAPI(lifespan=lifespan)
# Configure CORS to allow requests from any origin
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
@app.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket):
await websocket.accept()
print("WebSocket connection accepted")
try:
await run_bot_websocket_server(websocket)
except Exception as e:
print(f"Exception in run_bot: {e}")
@app.get("/")
async def read_root():
"""Root endpoint that provides basic information about the API."""
return {
"message": "VoiceStack API is running",
"status": "online",
"endpoints": {"websocket": "/ws", "connect": "/connect"},
}
@app.post("/connect")
async def bot_connect(request: Request) -> Dict[Any, Any]:
# return {"ws_url": "ws://localhost:7860/ws"}
# Get the host from the request headers for dynamic URL generation
host = request.headers.get("host", "localhost:7860")
protocol = "wss" if request.url.scheme == "https" else "wss"
return {"ws_url": f"{protocol}://{host}/ws"}
async def main():
config = uvicorn.Config(app, host="0.0.0.0", port=7860)
server = uvicorn.Server(config)
await server.serve()
if __name__ == "__main__":
import signal
async def serve():
config = uvicorn.Config(app, host="0.0.0.0", port=7860)
server = uvicorn.Server(config)
await server.serve()
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
try:
loop.run_until_complete(serve())
except KeyboardInterrupt:
print("Received exit signal (Ctrl+C), shutting down...")
finally:
loop.run_until_complete(loop.shutdown_asyncgens())
loop.close()