Files
Benjamin Boenisch ad111d5e69 Initial commit: breakpilot-core - Shared Infrastructure
Docker Compose with 24+ services:
- PostgreSQL (PostGIS), Valkey, MinIO, Qdrant
- Vault (PKI/TLS), Nginx (Reverse Proxy)
- Backend Core API, Consent Service, Billing Service
- RAG Service, Embedding Service
- Gitea, Woodpecker CI/CD
- Night Scheduler, Health Aggregator
- Jitsi (Web/XMPP/JVB/Jicofo), Mailpit

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 23:47:13 +01:00

102 lines
2.6 KiB
Python

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",
)