"""FastAPI app: CORS, rate limit, router. No fallback on auth.""" import logging from contextlib import asynccontextmanager from fastapi import FastAPI from fastapi.middleware.cors import CORSMiddleware from slowapi import _rate_limit_exceeded_handler from slowapi.errors import RateLimitExceeded from app.api.routes import documents from app.auth import require_api_key from app.storage.metadata import init_db logging.basicConfig( level=logging.INFO, format="%(asctime)s [%(levelname)s] %(name)s: %(message)s", ) logger = logging.getLogger(__name__) @asynccontextmanager async def lifespan(app: FastAPI): """Init DB on startup.""" init_db() logger.info("Storage initialized") yield logger.info("Shutdown") app = FastAPI( title="Local Office API", description="API for third-party apps to upload and edit Office documents", lifespan=lifespan, ) app.add_middleware( CORSMiddleware, allow_origins=["*"], allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) from app.limiter import limiter app.state.limiter = limiter app.add_exception_handler(RateLimitExceeded, _rate_limit_exceeded_handler) app.include_router( documents.router, prefix="/documents", tags=["documents"], dependencies=[], # auth done per-route to allow public docs later if needed )