| import os |
| import asyncio |
| from contextlib import asynccontextmanager |
|
|
| from fastapi import FastAPI |
| from fastapi.middleware.cors import CORSMiddleware |
| from loguru import logger |
|
|
| from app.core.config import get_settings |
| from app.db.database import init_db |
| from app.api.routes.auth import router as auth_router |
| from app.api.routes.conversations import router as conv_router |
| from app.api.routes.query import router as query_router |
| from app.api.routes.documents import router as docs_router |
| from app.api.routes.audio import router as audio_router |
| from app.api.routes.health_admin import health_router, admin_router |
|
|
| settings = get_settings() |
| os.makedirs("./data/users", exist_ok=True) |
|
|
|
|
| from app.services.speech_service import get_speech_service, get_tts_service |
|
|
| @asynccontextmanager |
| async def lifespan(app: FastAPI): |
| logger.info(f"Starting {settings.app_name} v{settings.app_version}") |
| await init_db() |
| logger.info("Main database initialised") |
| |
| |
| try: |
| logger.info("Preloading Speech-to-Text (STT) model...") |
| await asyncio.to_thread(get_speech_service) |
| logger.info("STT model preloaded successfully") |
| |
| logger.info("Preloading Text-to-Speech (TTS) model...") |
| await asyncio.to_thread(get_tts_service().preload, settings.tts_voice) |
| logger.info("TTS model preloaded successfully") |
| except Exception as e: |
| logger.error(f"Failed to preload speech models during startup: {e}") |
| |
| |
| try: |
| from app.services.qdrant_service import get_qdrant_service |
| qdrant = get_qdrant_service() |
| await qdrant.ensure_collection() |
| logger.info("Qdrant collection and payload indexes ensured on startup") |
| except Exception as e: |
| logger.error(f"Failed to initialize Qdrant collection on startup: {e}") |
| |
| yield |
| logger.info("Shutting down") |
|
|
|
|
| app = FastAPI( |
| title=settings.app_name, |
| version=settings.app_version, |
| description="Medical Knowledge RAG API β Groq Β· Llama 4 Scout Β· Qdrant Β· BioBERT Β· Cross-Encoder", |
| lifespan=lifespan, |
| ) |
|
|
| app.add_middleware( |
| CORSMiddleware, |
| allow_origins=settings.allowed_origins_list, |
| allow_credentials=True, |
| allow_methods=["*"], |
| allow_headers=["*"], |
| ) |
|
|
| |
| PREFIX = "/api/v1" |
| app.include_router(health_router, prefix=PREFIX) |
| app.include_router(auth_router, prefix=PREFIX) |
| app.include_router(conv_router, prefix=PREFIX) |
| app.include_router(query_router, prefix=PREFIX) |
| app.include_router(docs_router, prefix=PREFIX) |
| app.include_router(audio_router, prefix=PREFIX) |
| app.include_router(admin_router, prefix=PREFIX) |
|
|
|
|
| @app.get("/") |
| async def root(): |
| return {"name": settings.app_name, "version": settings.app_version, "docs": "/docs"} |
|
|