vedaMD / src /api /main.py
sniro23's picture
Initial commit without binary files
19aaa42
import sys
import os
from contextlib import asynccontextmanager
from fastapi import FastAPI, HTTPException
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import JSONResponse
from pydantic import BaseModel
import uvicorn
import logging
from typing import Optional, List, Dict
# Configure logging
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)
# Add the project root to the Python path
sys.path.append(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))))
from src.groq_medical_rag import GroqMedicalRAG, MedicalResponse
# --- Globals ---
rag_system = None
# --- Lifespan Management ---
@asynccontextmanager
async def lifespan(app: FastAPI):
global rag_system
logger.info("🚀 Initializing RAG system...")
try:
rag_system = GroqMedicalRAG()
logger.info("✅ RAG system initialized successfully.")
except Exception as e:
logger.error(f"❌ CRITICAL: Failed to initialize RAG system: {str(e)}")
logger.info("✅ API server is running, but RAG functionality will be disabled.")
rag_system = None
yield
logger.info("👋 Shutting down...")
# --- FastAPI App ---
app = FastAPI(title="Clinical Assistant API", lifespan=lifespan)
# --- CORS Middleware ---
app.add_middleware(
CORSMiddleware,
allow_origins=["*"], # Allows all origins
allow_credentials=True,
allow_methods=["*"], # Allows all methods
allow_headers=["*"], # Allows all headers
)
# --- Pydantic Models ---
class QueryRequest(BaseModel):
query: str
history: Optional[List[Dict[str, str]]] = None
class QueryResponse(BaseModel):
response: str
class HealthResponse(BaseModel):
status: str
rag_system_status: str
version: str = "1.0.0"
# --- API Endpoints ---
@app.get("/health", response_model=HealthResponse)
async def health_check():
"""Check the health status of the API and its components."""
return HealthResponse(
status="healthy",
rag_system_status="initialized" if rag_system else "offline"
)
@app.post("/query", response_model=QueryResponse)
async def process_query(query_request: QueryRequest):
"""Processes a clinical query and returns an evidence-based answer."""
logger.info(f"Received query: {query_request.query[:50]}...")
if not rag_system:
logger.warning("Query received but RAG system is offline")
return JSONResponse(
status_code=503,
content={
"response": "Sorry, the clinical assistant is currently offline due to a connection issue. Please try again later."
}
)
try:
query_text = query_request.query
history = query_request.history
medical_response = rag_system.query(query=query_text, history=history)
logger.info("Query processed successfully")
return QueryResponse(response=medical_response.answer)
except Exception as e:
logger.error(f"Error processing query: {str(e)}")
return JSONResponse(
status_code=500,
content={
"response": "An error occurred while processing your query. Please try again.",
"error": str(e)
}
)
# --- Main ---
if __name__ == "__main__":
uvicorn.run("main:app", host="0.0.0.0", port=8000, reload=True)