Spaces:
Runtime error
Runtime error
| """FastAPI application entrypoint.""" | |
| from fastapi import FastAPI | |
| from fastapi.middleware.cors import CORSMiddleware | |
| from fastapi.staticfiles import StaticFiles | |
| from app.core.config import settings | |
| from app.core.lifecycle import lifespan | |
| from app.core.paths import images_dir, extracted_dir, assets_dir, research_images_dir | |
| from app.core.security import SecurityHeadersMiddleware, RateLimitMiddleware | |
| from app.api.v1.router import api_router | |
| from app.api.errors import register_exception_handlers | |
| app = FastAPI( | |
| title=settings.app_name, | |
| version="0.1.0", | |
| lifespan=lifespan, | |
| ) | |
| # Middleware order matters: the LAST add_middleware call is the outermost | |
| # layer. Security headers and rate limiting are added first (inner), CORS | |
| # last (outer) so even 429 rejections carry CORS headers and the browser can | |
| # read them instead of failing opaquely. | |
| app.add_middleware(SecurityHeadersMiddleware) | |
| app.add_middleware(RateLimitMiddleware, limit_per_minute=settings.rate_limit_per_minute) | |
| app.add_middleware( | |
| CORSMiddleware, | |
| allow_origins=settings.cors_origin_list, | |
| allow_credentials=True, | |
| allow_methods=["*"], | |
| allow_headers=["*"], | |
| ) | |
| app.include_router(api_router, prefix="/api/v1") | |
| register_exception_handlers(app) | |
| # Serve extracted images as static files | |
| app.mount("/static/images", StaticFiles(directory=str(images_dir()), check_dir=False), name="images") | |
| app.mount("/static/extracted", StaticFiles(directory=str(extracted_dir()), check_dir=False), name="extracted") | |
| app.mount("/static/assets", StaticFiles(directory=str(assets_dir()), check_dir=False), name="assets") | |
| # Permanent research images (Option B) — scoped per conversation. | |
| # These are the durable, local-first assets created by the ResearchAgent. | |
| app.mount( | |
| "/static/images/research", | |
| StaticFiles(directory=str(research_images_dir()), check_dir=False), | |
| name="research-images", | |
| ) | |
| # SPA frontend mount decision moved to lifespan (core/lifecycle.py) so it runs | |
| # after filesystem/volume state is stable (important for Docker + multi-worker). | |
| # The old module-level block is intentionally removed. | |