medinsight / app.py
Muhammadidrees's picture
Update app.py
127d575 verified
from fastapi import FastAPI
from pydantic import BaseModel, Field
from dotenv import load_dotenv
import google.generativeai as genai
import os
import re
import gradio as gr
from typing import Dict, Any, Union, List
# ---------------- Initialize ----------------
app = FastAPI(title="LLM Model API + Gradio UI", version="4.0")
GEMINI_API_KEY='AIzaSyC0XU6yLCILZFUVhKoIcqoy2k5qwQmnDsc'
if not GEMINI_API_KEY:
raise ValueError("❌ GEMINI_API_KEY not found. Please set it in your .env file.")
genai.configure(api_key=GEMINI_API_KEY)
MODEL_ID = "gemini-2.5-flash"
# ---------------- Schema ----------------
class BiomarkerRequest(BaseModel):
albumin: float = Field(default=3.2)
creatinine: float = Field(default=1.4)
glucose: float = Field(default=145)
crp: float = Field(default=12.0)
mcv: float = Field(default=88)
rdw: float = Field(default=15.5)
alp: float = Field(default=120)
wbc: float = Field(default=11.8)
lymphocytes: float = Field(default=20)
hb: float = Field(default=13.0)
pv: float = Field(default=2.1)
age: int = Field(default=52)
gender: str = Field(default="female")
height: float = Field(default=165)
weight: float = Field(default=70)
# ---------------- Utility ----------------
def clean_json(data: Union[Dict, List, str]) -> Union[Dict, List, str]:
if isinstance(data, str):
text = re.sub(r"-{3,}", "", data)
text = re.sub(r"\s+", " ", text)
text = text.strip(" -\n\t\r")
return text
elif isinstance(data, list):
return [clean_json(i) for i in data if i and clean_json(i)]
elif isinstance(data, dict):
return {k.strip(): clean_json(v) for k, v in data.items()}
return data
# ---------------- Core Gemini Logic ----------------
def generate_report(data: BiomarkerRequest) -> str:
"""Main logic β€” uses Gemini to generate markdown medical report"""
prompt = """
You are an advanced **Medical Insight Generation AI** trained to analyze **biomarkers and lab results**.
⚠️ IMPORTANT β€” OUTPUT FORMAT INSTRUCTIONS:
Return your report in this strict markdown structure.
------------------------------
### Executive Summary
**Top 3 Health Priorities:**
1. ...
2. ...
3. ...
**Key Strengths:**
- ...
- ...
------------------------------
### System-Specific Analysis
**Cardiovascular System**
Status: Normal. Explanation: ...
**Liver Function**
Status: Elevated ALP. Explanation: ...
------------------------------
### Personalized Action Plan
### Nutrition:** ...
### **Lifestyle:** ...
### **Testing:** ...
### **Medical Consultation:** ...
------------------------------
### Interaction Alerts
- ...
- ...
------------------------------
### Normal Ranges
- Albumin: 3.5–5.0 g/dL
- Creatinine: 0.7–1.3 mg/dL
- Glucose: 70–100 mg/dL
- CRP: 0–10 mg/L
- MCV: 80–100 fL
- RDW: 11.5–14.5 %
- ALP: 44–147 U/L
- WBC: 4.0–10.0 Γ—10^3/ΞΌL
- Lymphocytes: 20–40 %
- Hemoglobin: 13–17 g/dL
- PV: 2500–3000 mL
------------------------------
### Tabular Mapping
| Biomarker | Value | Status | Insight | Reference Range |
| Albumin | X | Normal | ... | 3.5–5.0 g/dL |
| Creatinine | X | High | ... | 0.7–1.3 mg/dL |
| Glucose | X | ... | ... | 70–100 mg/dL |
------------------------------
"""
user_message = f"""
Patient Info:
- Age: {data.age}
- Gender: {data.gender}
- Height: {data.height} cm
- Weight: {data.weight} kg
Biomarkers:
- Albumin: {data.albumin} g/dL
- Creatinine: {data.creatinine} mg/dL
- Glucose: {data.glucose} mg/dL
- CRP: {data.crp} mg/L
- MCV: {data.mcv} fL
- RDW: {data.rdw} %
- ALP: {data.alp} U/L
- WBC: {data.wbc} Γ—10^3/ΞΌL
- Lymphocytes: {data.lymphocytes} %
- Hemoglobin: {data.hb} g/dL
- Plasma Volume (PV): {data.pv} L
"""
model = genai.GenerativeModel(MODEL_ID)
response = model.generate_content(f"{prompt}\n\n{user_message}")
if not response or not getattr(response, "text", None):
return "⚠️ Gemini returned an empty response."
return response.text.strip()
# ---------------- Gradio Function ----------------
def gradio_interface(albumin, creatinine, glucose, crp, mcv, rdw, alp, wbc,
lymphocytes, hb, pv, age, gender, height, weight):
req = BiomarkerRequest(
albumin=albumin, creatinine=creatinine, glucose=glucose, crp=crp,
mcv=mcv, rdw=rdw, alp=alp, wbc=wbc, lymphocytes=lymphocytes,
hb=hb, pv=pv, age=int(age), gender=gender, height=height, weight=weight
)
return generate_report(req)
# ---------------- Gradio UI (Vertical Layout) ----------------
with gr.Blocks(theme="soft", title="LLM Biomarker Analyzer") as iface:
gr.Markdown("## 🧬 LLM Biomarker Analyzer")
gr.Markdown("Enter your biomarker and demographic data below to generate a **Gemini-powered medical insight report**:")
with gr.Column():
with gr.Row():
age = gr.Number(label="Age (years)", value=52)
gender = gr.Radio(["male", "female"], label="Gender", value="female")
with gr.Row():
height = gr.Number(label="Height (cm)", value=165)
weight = gr.Number(label="Weight (kg)", value=70)
gr.Markdown("### πŸ”¬ Biomarker Values")
grid_inputs = [
gr.Number(label="Albumin (g/dL)", value=3.2),
gr.Number(label="Creatinine (mg/dL)", value=1.4),
gr.Number(label="Glucose (mg/dL)", value=145),
gr.Number(label="CRP (mg/L)", value=12.0),
gr.Number(label="MCV (fL)", value=88),
gr.Number(label="RDW (%)", value=15.5),
gr.Number(label="ALP (U/L)", value=120),
gr.Number(label="WBC (Γ—10Β³/ΞΌL)", value=11.8),
gr.Number(label="Lymphocytes (%)", value=20),
gr.Number(label="Hemoglobin (g/dL)", value=13.0),
gr.Number(label="Plasma Volume (mL)", value=2100)
]
submit_btn = gr.Button("🧠 Generate Medical Report", variant="primary")
output_md = gr.Markdown(label="AI-Generated Medical Report")
submit_btn.click(
fn=gradio_interface,
inputs=grid_inputs + [age, gender, height, weight],
outputs=output_md
)
# ---------------- Launch ----------------
if __name__ == "__main__":
iface.launch(server_name="0.0.0.0", server_port=7860)