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)