Spaces:
Sleeping
Sleeping
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 --- | |
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 --- | |
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" | |
) | |
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) |