from __future__ import annotations import logging from fastapi import FastAPI, Request from fastapi.middleware.cors import CORSMiddleware from fastapi.responses import JSONResponse from slowapi.errors import RateLimitExceeded from app.config import settings from app.rate_limit import ip_limiter, key_limiter from app.routers import health, suggestion logging.basicConfig( level=logging.INFO, format="%(asctime)s %(levelname)s %(name)s: %(message)s", ) logger = logging.getLogger(__name__) app = FastAPI( title="Meeting AI Assistant", version=settings.app_version, ) # Shared limiters — both attached so SlowAPIMiddleware can find them. app.state.limiter = ip_limiter app.state.key_limiter = key_limiter @app.exception_handler(RateLimitExceeded) async def _rate_limit_handler(request: Request, exc: RateLimitExceeded) -> JSONResponse: retry_after = getattr(exc, "retry_after", None) headers = {"Retry-After": str(int(retry_after))} if retry_after else {} return JSONResponse( status_code=429, content={"detail": "Rate limit exceeded", "limit": str(exc.detail)}, headers=headers, ) app.add_middleware( CORSMiddleware, allow_origins=settings.cors_origins_list, allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) app.include_router(health.router) app.include_router(suggestion.router)