import hmac from fastapi import FastAPI, Request from fastapi.middleware.cors import CORSMiddleware from fastapi.responses import JSONResponse from slowapi import Limiter, _rate_limit_exceeded_handler from slowapi.errors import RateLimitExceeded from slowapi.util import get_remote_address from app.config import settings from app.routers import avm, avm_industrial, avm_v2, moderation, neighborhood, nlp limiter = Limiter(key_func=get_remote_address, default_limits=[settings.rate_limit]) app = FastAPI( title=settings.app_name, version="0.1.0", docs_url="/docs", redoc_url="/redoc", ) app.state.limiter = limiter app.add_exception_handler(RateLimitExceeded, _rate_limit_exceeded_handler) if not settings.cors_origin_list: raise RuntimeError("AI_CORS_ORIGINS must be set (comma-separated list of allowed origins)") app.add_middleware( CORSMiddleware, allow_origins=settings.cors_origin_list, allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) @app.middleware("http") async def enforce_api_key(request: Request, call_next): if request.url.path in {"/health", "/health/live"}: return await call_next(request) if not settings.api_key: return await call_next(request) api_key = request.headers.get("X-API-Key") if not api_key or not hmac.compare_digest(api_key, settings.api_key): return JSONResponse( status_code=401, content={"detail": "Invalid or missing API key"}, ) return await call_next(request) app.include_router(avm.router) app.include_router(avm_v2.router) app.include_router(avm_industrial.router) app.include_router(moderation.router) app.include_router(neighborhood.router) app.include_router(nlp.router) @app.get("/health") def health() -> dict: return {"status": "ok", "service": settings.app_name} @app.get("/health/live") def live() -> dict: return {"status": "ok", "service": settings.app_name}