CoolFace
Apppublic

Vizz17/context-aware-rag

sourceHugging Faceupdated 4mo agoView on Hugging Face
0likes
main.py110 linesDownload Raw Back to app
1"""FastAPI application entrypoint."""2 3from __future__ import annotations4 5import logging6from contextlib import asynccontextmanager7from pathlib import Path8 9logging.basicConfig(10    level=logging.INFO,11    format="%(asctime)s  %(levelname)-8s  %(name)s — %(message)s",12    datefmt="%H:%M:%S",13)14 15from fastapi import FastAPI16from fastapi.middleware.cors import CORSMiddleware17from fastapi.responses import FileResponse, Response18from fastapi.staticfiles import StaticFiles19 20from app.api import chat, health, upload, auth21from app.core.config import settings22 23FRONTEND_DIR = Path(__file__).resolve().parent.parent / "frontend"24 25 26import asyncio27 28async def periodic_guest_cleanup():29    while True:30        try:31            await asyncio.sleep(3600)  # Clean up every hour32            from app.services.auth import cleanup_old_guest_sessions33            cleanup_old_guest_sessions()34        except asyncio.CancelledError:35            break36        except Exception as e:37            logging.getLogger("app.main").error(f"Periodic guest cleanup failed: {e}")38 39@asynccontextmanager40async def lifespan(app: FastAPI):41    """Startup / shutdown lifecycle hook."""42    # ── Startup ──43    settings.ensure_dirs()44    45    # Initialize SQLite User DB and clean up old sessions46    from app.services.auth import init_db, cleanup_old_guest_sessions47    init_db()48    try:49        cleanup_old_guest_sessions()50    except Exception as e:51        logging.getLogger("app.main").error(f"Failed to clean up old guest sessions on start: {e}")52 53    # Eagerly initialize vector store to avoid cold start lag on first search54    from app.services.vector_store import get_vector_store55    get_vector_store()56    57    # Eagerly load cross-encoder reranker model to avoid cold start lag on first request58    if settings.enable_reranker:59        from app.services.reranker import _get_cross_encoder60        _get_cross_encoder()61        62    cleanup_task = asyncio.create_task(periodic_guest_cleanup())63    64    yield65    # ── Shutdown ──66    cleanup_task.cancel()67    try:68        await cleanup_task69    except asyncio.CancelledError:70        pass71 72 73app = FastAPI(74    title="Context-Aware RAG Engine",75    description="Semantic search & QA over PDF collections with source-grounded answers.",76    version="0.1.0",77    lifespan=lifespan,78)79 80# ── CORS ────────────────────────────────────────────────────81app.add_middleware(82    CORSMiddleware,83    allow_origins=settings.cors_origins,84    allow_credentials=True,85    allow_methods=["*"],86    allow_headers=["*"],87)88 89# ── Routes ──────────────────────────────────────────────────90app.include_router(health.router, tags=["Health"])91app.include_router(auth.router, prefix="/api", tags=["Auth"])92app.include_router(upload.router, prefix="/api", tags=["Documents"])93app.include_router(chat.router, prefix="/api", tags=["Chat"])94 95 96# ── Frontend ────────────────────────────────────────────────97@app.get("/", include_in_schema=False)98async def serve_root():99    """Serve the main chat page."""100    return FileResponse(FRONTEND_DIR / "index.html")101 102 103@app.get("/favicon.ico", include_in_schema=False)104async def favicon():105    """Return an empty response for browser favicon requests."""106    return Response(status_code=204)107 108 109app.mount("/static", StaticFiles(directory=str(FRONTEND_DIR)), name="static")110