"""RehearsalHub FastAPI application entry point.""" from contextlib import asynccontextmanager import os from fastapi import FastAPI from fastapi.middleware.cors import CORSMiddleware from fastapi.staticfiles import StaticFiles from rehearsalhub.config import get_settings from rehearsalhub.routers import ( annotations_router, auth_router, bands_router, internal_router, members_router, sessions_router, songs_router, versions_router, ws_router, ) @asynccontextmanager async def lifespan(app: FastAPI): yield # Clean up DB connections on shutdown from rehearsalhub.db.engine import get_engine engine = get_engine() await engine.dispose() def create_app() -> FastAPI: settings = get_settings() app = FastAPI( title="RehearsalHub API", version="0.1.0", docs_url="/api/docs", redoc_url="/api/redoc", openapi_url="/api/openapi.json", lifespan=lifespan, ) app.add_middleware( CORSMiddleware, allow_origins=[f"https://{settings.domain}", "http://localhost:3000"], allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) prefix = "/api/v1" app.include_router(auth_router, prefix=prefix) app.include_router(bands_router, prefix=prefix) app.include_router(sessions_router, prefix=prefix) app.include_router(songs_router, prefix=prefix) app.include_router(versions_router, prefix=prefix) app.include_router(annotations_router, prefix=prefix) app.include_router(members_router, prefix=prefix) app.include_router(internal_router, prefix=prefix) app.include_router(ws_router) # WebSocket routes don't use /api/v1 prefix @app.get("/api/health") async def health(): return {"status": "ok"} # Mount static files for avatar uploads upload_dir = "uploads/avatars" os.makedirs(upload_dir, exist_ok=True) app.mount("/api/static/avatars", StaticFiles(directory=upload_dir), name="avatars") return app app = create_app()