import sqlite3 from pathlib import Path from fastapi import FastAPI from fastapi.staticfiles import StaticFiles from app.shared.config import Settings, get_settings from app.shared.database import get_db, init_schema from app.api.routes import utterances, speakers, rooms, search, rag def create_app(settings: Settings) -> FastAPI: init_schema(settings) app = FastAPI(title="LinkedStorm") def db_factory() -> sqlite3.Connection: return get_db(settings) app.include_router(utterances.make_router(settings, db_factory)) app.include_router(speakers.make_router(settings, db_factory)) app.include_router(rooms.make_router(settings, db_factory)) app.include_router(search.make_router(settings, db_factory)) app.include_router(rag.make_router(settings, db_factory)) @app.get("/health") async def health(): return {"status": "ok"} # Mount static files last so they don't shadow API routes. # Only mount if the directory exists AND contains at least one file, # otherwise StaticFiles raises an error on empty directories. static_dir = Path(__file__).parent / "static" if static_dir.exists() and any(static_dir.iterdir()): app.mount("/", StaticFiles(directory=str(static_dir), html=True), name="static") return app _app_instance = None def app_factory(): global _app_instance if _app_instance is None: _app_instance = create_app(get_settings()) return _app_instance