Spaces:
Running
RagBot API
REST API for Medical Biomarker Analysis
Exposes the RagBot multi-agent RAG system as a FastAPI REST service for web integration.
π― Overview
This API wraps the RagBot clinical analysis system, providing:
- Natural language input - Extract biomarkers from conversational text
- Structured JSON input - Direct biomarker analysis
- Full detailed responses - All agent outputs, citations, recommendations
- Example endpoint - Pre-run diabetes case for testing
π Table of Contents
π Quick Start
Prerequisites
- Python 3.11+ installed
- Free API key from one of:
- Groq β Recommended (fast, free)
- Google Gemini β Alternative
- RagBot dependencies installed (see root README)
Option 1: Run Locally (Development)
# From RagBot root directory
cd api
# Install dependencies
pip install -r ../requirements.txt
pip install -r requirements.txt
# Ensure .env is configured in project root with your API keys
# GROQ_API_KEY=gsk_...
# LLM_PROVIDER=groq
# Run server
python -m uvicorn app.main:app --reload --port 8000
Option 2: Run with Docker
# From api directory
docker-compose up --build
Server will start on http://localhost:8000
π‘ Endpoints
1. Health Check
GET /api/v1/health
Response:
{
"status": "healthy",
"timestamp": "2026-02-23T10:30:00Z",
"llm_status": "connected",
"vector_store_loaded": true,
"available_models": ["llama-3.3-70b-versatile (Groq)"],
"uptime_seconds": 3600.0,
"version": "1.0.0"
}
2. List Biomarkers
GET /api/v1/biomarkers
Returns: All 24 supported biomarkers with reference ranges, units, and clinical significance.
3. Natural Language Analysis
POST /api/v1/analyze/natural
Content-Type: application/json
Request:
{
"message": "My glucose is 185, HbA1c is 8.2 and cholesterol is 210",
"patient_context": {
"age": 52,
"gender": "male",
"bmi": 31.2
}
}
Response: Full detailed analysis (see Response Structure)
4. Structured Analysis
POST /api/v1/analyze/structured
Content-Type: application/json
Request:
{
"biomarkers": {
"Glucose": 185.0,
"HbA1c": 8.2,
"Cholesterol": 210.0,
"Triglycerides": 210.0,
"HDL": 38.0
},
"patient_context": {
"age": 52,
"gender": "male",
"bmi": 31.2
}
}
Response: Same as natural language analysis
5. Example Case
GET /api/v1/example
Returns: Pre-run diabetes case (52-year-old male with elevated glucose/HbA1c)
π Request/Response Examples
Response Structure
{
"status": "success",
"request_id": "req_abc123xyz",
"timestamp": "2025-11-23T10:30:00.000Z",
"extracted_biomarkers": {
"Glucose": 185.0,
"HbA1c": 8.2
},
"input_biomarkers": {
"Glucose": 185.0,
"HbA1c": 8.2
},
"patient_context": {
"age": 52,
"gender": "male",
"bmi": 31.2
},
"prediction": {
"disease": "Diabetes",
"confidence": 0.87,
"probabilities": {
"Diabetes": 0.87,
"Heart Disease": 0.08,
"Anemia": 0.03,
"Thalassemia": 0.01,
"Thrombocytopenia": 0.01
}
},
"analysis": {
"biomarker_flags": [
{
"name": "Glucose",
"value": 185.0,
"unit": "mg/dL",
"status": "CRITICAL_HIGH",
"reference_range": "70-100 mg/dL",
"warning": "Hyperglycemia"
}
],
"safety_alerts": [
{
"severity": "CRITICAL",
"biomarker": "Glucose",
"message": "Glucose is 185.0 mg/dL, above critical threshold",
"action": "SEEK IMMEDIATE MEDICAL ATTENTION"
}
],
"key_drivers": [
{
"biomarker": "Glucose",
"value": 185.0,
"explanation": "Glucose at 185.0 mg/dL is CRITICAL_HIGH...",
"evidence": "Retrieved from medical literature..."
}
],
"disease_explanation": {
"pathophysiology": "Detailed disease mechanism...",
"citations": ["Source 1", "Source 2"],
"retrieved_chunks": [...]
},
"recommendations": {
"immediate_actions": [
"Consult healthcare provider immediately..."
],
"lifestyle_changes": [
"Follow a balanced, nutrient-rich diet..."
],
"monitoring": [
"Monitor glucose levels daily..."
]
},
"confidence_assessment": {
"prediction_reliability": "MODERATE",
"evidence_strength": "STRONG",
"limitations": ["Limited biomarkers provided"],
"reasoning": "High confidence based on glucose and HbA1c..."
}
},
"agent_outputs": [
{
"agent_name": "Biomarker Analyzer",
"findings": {...},
"metadata": {...}
}
],
"workflow_metadata": {
"sop_version": "Baseline",
"processing_timestamp": "2025-11-23T10:30:00Z",
"agents_executed": 5,
"workflow_success": true
},
"conversational_summary": "Hi there! π\n\nBased on your biomarkers...",
"processing_time_ms": 3542.0,
"sop_version": "Baseline"
}
cURL Examples
Health Check:
curl http://localhost:8000/api/v1/health
Natural Language Analysis:
curl -X POST http://localhost:8000/api/v1/analyze/natural \
-H "Content-Type: application/json" \
-d '{
"message": "My glucose is 185 and HbA1c is 8.2",
"patient_context": {
"age": 52,
"gender": "male"
}
}'
Structured Analysis:
curl -X POST http://localhost:8000/api/v1/analyze/structured \
-H "Content-Type: application/json" \
-d '{
"biomarkers": {
"Glucose": 185.0,
"HbA1c": 8.2
},
"patient_context": {
"age": 52,
"gender": "male"
}
}'
Get Example:
curl http://localhost:8000/api/v1/example
π³ Deployment
Docker Deployment
Build and run:
cd api docker-compose up --buildCheck health:
curl http://localhost:8000/api/v1/healthView logs:
docker-compose logs -f ragbot-apiStop:
docker-compose down
Production Deployment
For production:
Update
.env:CORS_ORIGINS=https://your-frontend-domain.com API_RELOAD=false LOG_LEVEL=WARNINGUse production WSGI server:
gunicorn app.main:app -w 4 -k uvicorn.workers.UvicornWorkerAdd reverse proxy (nginx):
location /api { proxy_pass http://localhost:8000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; }
π» Development
Project Structure
api/
βββ app/
β βββ __init__.py
β βββ main.py # FastAPI application
β βββ models/
β β βββ __init__.py
β β βββ schemas.py # Pydantic models
β βββ routes/
β β βββ __init__.py
β β βββ analyze.py # Analysis endpoints
β β βββ biomarkers.py # Biomarkers list
β β βββ health.py # Health check
β βββ services/
β βββ __init__.py
β βββ extraction.py # Natural language extraction
β βββ ragbot.py # Workflow wrapper
βββ requirements.txt
βββ Dockerfile
βββ docker-compose.yml
βββ .env.example
βββ README.md
Running Tests
# Test health endpoint
curl http://localhost:8000/api/v1/health
# Test example case
curl http://localhost:8000/api/v1/example
# Test natural language
curl -X POST http://localhost:8000/api/v1/analyze/natural \
-H "Content-Type: application/json" \
-d '{"message": "glucose 140, HbA1c 7.5"}'
Hot Reload
For development with auto-reload:
uvicorn app.main:app --reload --port 8000
π§ Troubleshooting
Issue: "API key not found"
Symptom: Health check shows llm_status: "disconnected"
Solutions:
- Ensure
.envin project root has your API key:GROQ_API_KEY=gsk_... LLM_PROVIDER=groq - Get a free key at https://console.groq.com/keys
- Restart the API server after editing
.env
Issue: "Vector store not loaded"
Symptom: Health check shows vector_store_loaded: false
Solutions:
- Run vector store setup from RagBot root:
python scripts/setup_embeddings.py - Check
data/vector_stores/medical_knowledge.faissexists - Restart API server
Issue: "No biomarkers found"
Symptom: Natural language endpoint returns error
Solutions:
- Be explicit: "My glucose is 140" (not "blood sugar is high")
- Include numbers: "glucose 140" works better than "elevated glucose"
- Use structured endpoint if you have exact values
Issue: Docker container can't reach LLM API
Symptom: Container health check fails
Solutions:
Ensure your API keys are passed as environment variables in docker-compose.yml:
environment:
- GROQ_API_KEY=${GROQ_API_KEY}
- LLM_PROVIDER=groq
For local Ollama (optional):
Windows/Mac (Docker Desktop):
environment:
- OLLAMA_BASE_URL=http://host.docker.internal:11434
Linux:
network_mode: "host"
π Integration Examples
JavaScript/TypeScript
// Analyze biomarkers from natural language
async function analyzeBiomarkers(userInput: string) {
const response = await fetch('http://localhost:8000/api/v1/analyze/natural', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
message: userInput,
patient_context: {
age: 52,
gender: "male"
}
})
});
const result = await response.json();
return result;
}
// Display results
const analysis = await analyzeBiomarkers("My glucose is 185 and HbA1c is 8.2");
console.log(`Prediction: ${analysis.prediction.disease}`);
console.log(`Confidence: ${(analysis.prediction.confidence * 100).toFixed(0)}%`);
console.log(`\n${analysis.conversational_summary}`);
Python
import requests
# Structured analysis
response = requests.post(
'http://localhost:8000/api/v1/analyze/structured',
json={
'biomarkers': {
'Glucose': 185.0,
'HbA1c': 8.2
},
'patient_context': {
'age': 52,
'gender': 'male'
}
}
)
result = response.json()
print(f"Disease: {result['prediction']['disease']}")
print(f"Confidence: {result['prediction']['confidence']:.1%}")
π API Documentation
Once the server is running, visit:
- Swagger UI: http://localhost:8000/docs
- ReDoc: http://localhost:8000/redoc
- OpenAPI Schema: http://localhost:8000/openapi.json
π€ Support
For issues or questions:
- Check Troubleshooting section
- Review API documentation at
/docs - Check RagBot main README
π Performance Notes
- Initial startup: 10-30 seconds (loads vector store)
- Analysis time: 15-25 seconds per request (6 agents + RAG retrieval)
- Concurrent requests: Supported (FastAPI async)
- Memory usage: ~2-4GB (vector store + embeddings model)
π Security Notes
For MVP/Development:
- CORS allows all origins (
*) - No authentication required
- Runs on localhost
For Production:
- Restrict CORS to specific origins
- Add API key authentication
- Use HTTPS
- Implement rate limiting
- Add request validation
Built with β€οΈ on top of RagBot Multi-Agent RAG System