import logging from contextlib import asynccontextmanager import uvicorn from fastapi import FastAPI from fastapi.middleware.cors import CORSMiddleware from config import settings from qdrant_client_wrapper import qdrant_wrapper from minio_client_wrapper import minio_wrapper logging.basicConfig( level=logging.INFO, format="%(asctime)s [%(name)s] %(levelname)s: %(message)s", ) logger = logging.getLogger("rag-service") @asynccontextmanager async def lifespan(app: FastAPI): """Startup: initialise Qdrant collections and MinIO bucket.""" logger.info("RAG-Service starting up ...") try: await qdrant_wrapper.init_collections() logger.info("Qdrant collections ready") except Exception as exc: logger.error("Qdrant init failed (will retry on first request): %s", exc) try: await minio_wrapper.init_bucket() logger.info("MinIO bucket ready") except Exception as exc: logger.error("MinIO init failed (will retry on first request): %s", exc) yield logger.info("RAG-Service shutting down ...") app = FastAPI( title="BreakPilot RAG Service", description="Wraps Qdrant vector search and MinIO document storage for the BreakPilot platform.", version="1.0.0", lifespan=lifespan, ) # ---- CORS ----------------------------------------------------------------- app.add_middleware( CORSMiddleware, allow_origins=["*"], allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) # ---- Routers -------------------------------------------------------------- from api import router as api_router # noqa: E402 app.include_router(api_router) # ---- Health --------------------------------------------------------------- @app.get("/health") async def health(): """Basic liveness probe.""" qdrant_ok = False minio_ok = False try: qdrant_wrapper.client.get_collections() qdrant_ok = True except Exception: pass try: minio_wrapper.client.bucket_exists(settings.MINIO_BUCKET) minio_ok = True except Exception: pass status = "healthy" if (qdrant_ok and minio_ok) else "degraded" return { "status": status, "service": "rag-service", "version": "1.0.0", "dependencies": { "qdrant": "ok" if qdrant_ok else "unavailable", "minio": "ok" if minio_ok else "unavailable", }, } # ---- Main ----------------------------------------------------------------- if __name__ == "__main__": uvicorn.run( "main:app", host="0.0.0.0", port=settings.PORT, reload=False, log_level="info", )