Spaces:
Sleeping
Sleeping
| """ | |
| FastAPI application factory with lifespan management. | |
| The lifespan context manager handles: | |
| - Startup: initialize Qdrant, embedding, LLM, reranker services | |
| - Shutdown: close connections gracefully | |
| Services are stored in app.state and injected into route handlers. | |
| This avoids global state and makes the app testable. | |
| """ | |
| from __future__ import annotations | |
| from contextlib import asynccontextmanager | |
| from typing import AsyncGenerator | |
| import structlog | |
| from fastapi import FastAPI | |
| from fastapi.middleware.cors import CORSMiddleware | |
| from ahcgr import __app_name__, __version__ | |
| from ahcgr.api.middleware import RequestLoggingMiddleware | |
| from ahcgr.api.routes import router | |
| from ahcgr.pipeline.p1b_entity import EntityIndex | |
| from ahcgr.services.embedding import EmbeddingService | |
| from ahcgr.services.llm import LLMService | |
| from ahcgr.services.qdrant_client import QdrantService | |
| from ahcgr.services.reranker import RerankerService | |
| from ahcgr.utils.logging import setup_logging | |
| logger = structlog.get_logger("ahcgr.api.server") | |
| async def lifespan(app: FastAPI) -> AsyncGenerator[None, None]: | |
| """ | |
| Application lifespan: initialize shared services, then close them cleanly. | |
| """ | |
| setup_logging() | |
| logger.info("startup_begin", app=__app_name__, version=__version__) | |
| qdrant = QdrantService() | |
| embedding = EmbeddingService() | |
| llm = LLMService() | |
| reranker = RerankerService() | |
| entity_index = EntityIndex() | |
| entity_index.build_from_qdrant(qdrant) | |
| app.state.qdrant = qdrant | |
| app.state.embedding = embedding | |
| app.state.llm = llm | |
| app.state.reranker = reranker | |
| app.state.entity_index = entity_index | |
| health = qdrant.health_check() | |
| logger.info("qdrant_health", **health) | |
| logger.info( | |
| "startup_complete", | |
| services=["qdrant", "embedding", "llm", "reranker", "entity_index"], | |
| entity_acts=entity_index.act_count, | |
| ) | |
| yield | |
| logger.info("shutdown_begin") | |
| qdrant.close() | |
| logger.info("shutdown_complete") | |
| def create_app() -> FastAPI: | |
| """ | |
| Build the FastAPI application. | |
| """ | |
| app = FastAPI( | |
| title=__app_name__, | |
| version=__version__, | |
| description=( | |
| "AHCGR - Adaptive Hierarchical Confidence-Guided Retrieval. " | |
| "A 7-phase Indian legal inference engine with hybrid search, " | |
| "RAPTOR tree traversal, and multi-gate quality evaluation." | |
| ), | |
| lifespan=lifespan, | |
| ) | |
| app.add_middleware( | |
| CORSMiddleware, | |
| allow_origins=["*"], | |
| allow_credentials=True, | |
| allow_methods=["*"], | |
| allow_headers=["*"], | |
| ) | |
| app.add_middleware(RequestLoggingMiddleware) | |
| app.include_router(router, prefix="/api/v1") | |
| return app | |