Pankaj70's picture
Deploy AHCGR legal inference app
d8423e6 verified
Raw
History Blame Contribute Delete
2.76 kB
"""
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")
@asynccontextmanager
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