"""FastAPI application for the Aseesa AI Ingestion Agent.""" import asyncio import logging from contextlib import asynccontextmanager from fastapi import FastAPI from fastapi.responses import RedirectResponse from app.api.deps import cleanup_expired_sessions from app.api.routes import ingest, mapping, template from app.api.routes.ui import router as ui_router from app.config import settings CLEANUP_INTERVAL_SECONDS = 3600 # run cleanup every hour async def _session_cleanup_loop(): """Background task that periodically cleans up expired sessions.""" while True: await asyncio.sleep(CLEANUP_INTERVAL_SECONDS) try: cleanup_expired_sessions() except Exception as exc: logging.getLogger(__name__).warning("Session cleanup error: %s", exc) @asynccontextmanager async def lifespan(app: FastAPI): """Startup/shutdown lifecycle.""" logging.basicConfig(level=logging.INFO, format="%(asctime)s %(name)s %(levelname)s %(message)s") settings.ensure_dirs() logging.getLogger(__name__).info("Ingestion AI Agent started") cleanup_task = asyncio.create_task(_session_cleanup_loop()) yield cleanup_task.cancel() logging.getLogger(__name__).info("Ingestion AI Agent shutting down") app = FastAPI( title="Aseesa AI Ingestion Agent", description="AI-powered pharma data ingestion — maps SAS metadata to internal templates", version="0.1.0", lifespan=lifespan, ) # API routes app.include_router(ingest.router, prefix="/api/v1") app.include_router(mapping.router, prefix="/api/v1") app.include_router(template.router, prefix="/api/v1") # UI routes app.include_router(ui_router) @app.get("/") async def root(): return RedirectResponse(url="/ui/") @app.get("/health") async def health_check(): return {"status": "ok"}