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, | |
) | |