Spaces:
Sleeping
Sleeping
| from fastapi import FastAPI, Request, HTTPException | |
| from fastapi.middleware.cors import CORSMiddleware | |
| from fastapi.staticfiles import StaticFiles | |
| from fastapi.responses import FileResponse, JSONResponse | |
| from dotenv import load_dotenv | |
| from pathlib import Path | |
| import os | |
| import requests | |
| import subprocess | |
| import time | |
| from app.auth import get_room_name | |
| load_dotenv() | |
| app = FastAPI() | |
| app.add_middleware( | |
| CORSMiddleware, | |
| allow_origins=["*"], | |
| allow_credentials=True, | |
| allow_methods=["*"], | |
| allow_headers=["*"], | |
| ) | |
| # Mount the static directory | |
| app.mount("/static", StaticFiles(directory="frontend/out", html=True), name="static") | |
| def _create_room(): | |
| api_path = os.getenv("DAILY_API_PATH") or "https://api.daily.co/v1" | |
| expiry_time = os.getenv("BOT_MAX_DURATION", 300) | |
| daily_api_key = os.getenv("DAILY_API_KEY", None) | |
| try: | |
| res = requests.post( | |
| f"{api_path}/rooms", | |
| headers={"Authorization": f"Bearer {daily_api_key}"}, | |
| json={ | |
| "properties": { | |
| "exp": time.time() + int(expiry_time), | |
| "eject_at_room_exp": True, | |
| "enable_prejoin_ui": False, | |
| "start_audio_off": True, | |
| "permissions": { | |
| "canSend": ["video"] | |
| } | |
| } | |
| } | |
| ) | |
| if res.status_code != 200: | |
| return JSONResponse({ | |
| "error": "Unable to create room", | |
| "status_code": res.status_code, | |
| "text": res.text | |
| }, 500) | |
| data = res.json() | |
| print(data) | |
| return JSONResponse({"room_url": data["url"], "privacy": data["privacy"]}) | |
| except Exception: | |
| return JSONResponse({"error": Exception}) | |
| def _start_bot(bot_path, room_url, args=None): | |
| daily_room_name = get_room_name(room_url) | |
| daily_api_path = os.getenv("DAILY_API_PATH") | |
| daily_api_key = os.getenv("DAILY_API_KEY") | |
| #@TODO error handling here | |
| if args: | |
| extra_args = " ".join([f'-{x[0]} "{x[1]}"' for x in args]) | |
| else: | |
| extra_args = "" | |
| proc = subprocess.Popen( | |
| [ | |
| f"python3 {bot_path} -u {room_url} -k {daily_api_key} {extra_args}" | |
| ], | |
| shell=True, | |
| bufsize=1, | |
| ) | |
| # Don't return until the bot has joined the room, but wait for at most 2 seconds. | |
| attempts = 0 | |
| while attempts < 20: | |
| time.sleep(0.1) | |
| attempts += 1 | |
| res = requests.get( | |
| f"{daily_api_path}/rooms/{daily_room_name}/get-session-data", | |
| headers={"Authorization": f"Bearer {daily_api_key}"}, | |
| ) | |
| if res.status_code == 200: | |
| break | |
| print(f"Took {attempts} attempts to join room {daily_room_name}") | |
| return JSONResponse({"started": True}) | |
| async def start(request: Request): | |
| data = await request.json() | |
| return _start_bot("./app/bot.py", data['room_url']) | |
| async def create(): | |
| return _create_room() | |
| async def catch_all(path_name: str): | |
| if path_name == "": | |
| return FileResponse("frontend/out/index.html") | |
| file_path = Path("frontend/out") / path_name | |
| if file_path.is_file(): | |
| return file_path | |
| html_file_path = file_path.with_suffix(".html") | |
| if html_file_path.is_file(): | |
| return FileResponse(html_file_path) | |
| raise HTTPException(status_code=450, detail="Incorrect API call") | |
| # Run the application using Uvicorn | |
| if __name__ == "__main__": | |
| import uvicorn | |
| uvicorn.run( | |
| "server:app", | |
| host="0.0.0.0", | |
| port=int(os.getenv('FAST_API_PORT', 8000)), | |
| reload=os.getenv('FAST_API_RELOAD', 'false').lower() == 'true', | |
| #ssl_certfile=args.ssl_certfile, | |
| #ssl_keyfile=args.ssl_keyfile, | |
| ) | |