Spaces:
Sleeping
Sleeping
| 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 | |
| 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) | |