Spaces:
Running
Running
| import logging | |
| from contextlib import asynccontextmanager | |
| from fastapi import FastAPI | |
| from fastapi.middleware.cors import CORSMiddleware | |
| from app.config import settings | |
| from app.api import chat, ingestion, health | |
| logging.basicConfig( | |
| level=logging.INFO, | |
| format="%(asctime)s | %(levelname)-8s | %(name)s | %(message)s", | |
| ) | |
| logger = logging.getLogger(__name__) | |
| async def lifespan(_app: FastAPI): | |
| # Eagerly load the embedding model and vector store so the first visitor | |
| # doesn't pay the model-load latency. | |
| from app.services.embedding_service import get_embedding_service | |
| from app.services.vector_store import get_vector_store | |
| from app.services.llm_service import get_llm_service | |
| get_embedding_service() | |
| chunks = get_vector_store().count() | |
| get_llm_service() | |
| if chunks == 0: | |
| logger.warning("Vector store is EMPTY — run scripts/ingest.py to build the index") | |
| logger.info("Warmup complete — %d chunks indexed", chunks) | |
| yield | |
| app = FastAPI( | |
| title="Negoptim AI Backend", | |
| description="RAG-powered chatbot backend for Users Love IT (ULiT)", | |
| version="1.0.0", | |
| lifespan=lifespan, | |
| ) | |
| app.add_middleware( | |
| CORSMiddleware, | |
| allow_origins=settings.cors_origin_list, | |
| allow_credentials=True, | |
| allow_methods=["*"], | |
| allow_headers=["*"], | |
| ) | |
| app.include_router(health.router, prefix="/api", tags=["health"]) | |
| app.include_router(chat.router, prefix="/api", tags=["chat"]) | |
| app.include_router(ingestion.router, prefix="/api", tags=["ingestion"]) | |
| async def root(): | |
| return {"service": "Negoptim AI", "docs": "/docs"} | |