import os import random import string import logging from fastapi import FastAPI, HTTPException, Query from fastapi.responses import HTMLResponse from fastapi.staticfiles import StaticFiles from dotenv import load_dotenv from lib import livekit load_dotenv() logging.basicConfig(level=logging.INFO) LIVEKIT_URL = os.getenv("LIVEKIT_URL") if not LIVEKIT_URL: raise EnvironmentError("LIVEKIT_URL must be set") app = FastAPI() def random_string(length: int) -> str: return "".join(random.choices(string.ascii_letters + string.digits, k=length)) # API Routes @app.get("/api/connection-details") async def connection_details( roomName: str = Query(..., alias="roomName"), participantName: str = Query(..., alias="participantName"), metadata: str = Query(""), ): try: random_postfix = random_string(4) identity = f"{participantName}__{random_postfix}" token = livekit.create_access_token(identity, participantName, metadata, roomName) return { "serverUrl": LIVEKIT_URL, "roomName": roomName, "participantToken": token, "participantName": participantName, } except Exception as e: logging.error(f"Error creating token: {e}") raise HTTPException(status_code=500, detail=str(e)) @app.get("/rooms/{room_name}", response_class=HTMLResponse) async def create_room(room_name: str): try: await livekit.create_room_if_not_exists(room_name) # Return HTML that loads the LiveKit component for this room html_content = f""" LiveKit Meet - {room_name}
""" return html_content except Exception as e: logging.error(f"Error creating room: {e}") raise HTTPException(status_code=500, detail=str(e)) # Serve the static files from the 'public' directory, with html=True to handle SPA routing app.mount("/", StaticFiles(directory="../public", html=True), name="static")