McQbis/document-intelligence-rag
0
1from __future__ import annotations2 3import os4from contextlib import asynccontextmanager5 6from dotenv import load_dotenv7from fastapi import FastAPI8from fastapi.middleware.cors import CORSMiddleware9from fastapi.staticfiles import StaticFiles10from fastapi.responses import FileResponse11 12# Loads .env into os.environ if present (local dev only — on HF Spaces /13# Cloud Run, GROQ_API_KEY etc. come from real platform secrets, and14# load_dotenv() is a harmless no-op there since there's no .env file).15load_dotenv()16 17from rag.retrieval.embeddings import EmbeddingModel18from rag.generation import AnswerGenerator19from api.session import SessionManager20from api.routes import router, set_manager, set_generator21 22 23@asynccontextmanager24async def lifespan(app: FastAPI):25 """Load shared application resources during startup."""26 model_name = os.getenv("EMBEDDING_MODEL", "BAAI/bge-base-en-v1.5")27 reranker_name = os.getenv("RERANKER_MODEL", "BAAI/bge-reranker-base")28 29 print(f"[startup] Loading embedding model : {model_name}")30 emb = EmbeddingModel(model_name=model_name)31 32 print(f"[startup] Reranker : {reranker_name}")33 manager = SessionManager(emb, reranker_name)34 set_manager(manager)35 36 # LLM generation (LangChain + Groq) is optional: the app still works in37 # retrieval-only mode if GROQ_API_KEY isn't set.38 generator = AnswerGenerator()39 print(f"[startup] LLM generation (Groq) : {'enabled' if generator.is_configured else 'disabled (no GROQ_API_KEY)'}")40 set_generator(generator)41 42 print("[startup] Ready.")43 yield44 45 46app = FastAPI(title="Document Intelligence RAG", version="1.0.0", lifespan=lifespan)47 48app.add_middleware(49 CORSMiddleware,50 allow_origins=["*"],51 allow_methods=["*"],52 allow_headers=["*"],53 allow_credentials=True,54)55 56app.include_router(router, prefix="/api")57 58app.mount("/static", StaticFiles(directory="static"), name="static")59 60@app.get("/")61def root():62 return FileResponse("static/index.html")