from contextlib import asynccontextmanager import logging from fastapi import FastAPI from fastapi.middleware.cors import CORSMiddleware from sqlalchemy import text from sqlalchemy.exc import OperationalError from app.config import settings from app.database import Base, engine from app.mongo import close_mongo, connect_mongo from app.routers import auth, collab, documents, health from app.services.document_service import ensure_indexes logger = logging.getLogger(__name__) @asynccontextmanager async def lifespan(_: FastAPI): try: Base.metadata.create_all(bind=engine) logger.info("Database connected and tables ready") except OperationalError: logger.warning("Database unavailable — check DATABASE_URL in .env") try: await connect_mongo() from app.mongo import get_mongo_db await ensure_indexes(get_mongo_db()) logger.info("MongoDB connected and indexes ready") except Exception: logger.warning("MongoDB unavailable — will connect when available") yield await close_mongo() app = FastAPI(title=settings.app_name, debug=settings.debug, lifespan=lifespan) app.add_middleware( CORSMiddleware, allow_origins=settings.cors_origin_list, allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) app.include_router(health.router, prefix="/api/v1") app.include_router(auth.router, prefix="/api/v1") app.include_router(documents.router, prefix="/api/v1") app.include_router(collab.router, prefix="/api/v1") @app.get("/") def root() -> dict[str, str]: return {"message": "Silos API", "docs": "/docs"}