Muhammadidrees commited on
Commit
f3e951a
·
verified ·
1 Parent(s): c08ace3

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +370 -140
app.py CHANGED
@@ -1,156 +1,386 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  import torch
2
- from transformers import AutoTokenizer, AutoModelForCausalLM, pipeline
3
  import gradio as gr
4
- import os
5
-
6
- # ----------------------------
7
- # Model Config
8
- # ----------------------------
9
- MODEL_ID = "Muhammadidrees/my-biomed" # or "BioMistral/BioMistral-7B"
10
 
11
- tokenizer = AutoTokenizer.from_pretrained(MODEL_ID)
 
 
 
12
 
13
- model = AutoModelForCausalLM.from_pretrained(
14
- MODEL_ID,
15
- device_map="auto", # Ensures GPU usage on HF (L4)
16
- torch_dtype=torch.float16 # FP16 for speed + memory efficiency
 
 
 
 
17
  )
18
 
19
- pipe = pipeline(
20
- "text-generation",
21
- model=model,
22
- tokenizer=tokenizer
23
- )
24
 
25
- # ----------------------------
26
- # Helper: split report into panels
27
- # ----------------------------
28
- def split_report(text: str):
29
- markers = ["5. Tabular", "📊 Tabular", "## 5"]
30
- idx = None
31
- for m in markers:
32
- pos = text.find(m)
33
- if pos != -1:
34
- idx = pos if idx is None or pos < idx else idx
35
- if idx is None:
36
- return text.strip(), ""
37
- return text[:idx].strip(), text[idx:].strip()
38
-
39
- # ----------------------------
40
- # Main Analysis Function
41
- # ----------------------------
42
- def analyze(albumin, creatinine, glucose, crp, mcv, rdw, alp,
43
- wbc, lymph, age, gender, height, weight):
44
 
45
- # Compute BMI
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
46
  try:
47
- bmi = round(float(weight) / ((float(height) / 100) ** 2), 2)
48
- except Exception:
49
- bmi = "N/A"
50
-
51
- # ----------------------------
52
- # Strict System Prompt
53
- # ----------------------------
54
- system_prompt = (
55
- "You are a professional AI Medical Assistant.\n"
56
- "You must ONLY analyze: 9 Levine biomarkers + Age + Height + Weight.\n"
57
- "Forbidden: Any extra labs (cholesterol, vitamin D, hormones, etc.).\n"
58
- "If information is not derivable, state clearly: 'Not available from current biomarkers.'\n\n"
59
-
60
- "Biomarkers allowed:\n"
61
- "- Albumin\n- Creatinine\n- Glucose\n- C-reactive protein (CRP)\n"
62
- "- Mean Cell Volume (MCV)\n- Red Cell Distribution Width (RDW)\n"
63
- "- Alkaline Phosphatase (ALP)\n- White Blood Cell count (WBC)\n"
64
- "- Lymphocyte percentage\n\n"
65
-
66
- "Output format:\n"
67
- "1. Executive Summary\n"
68
- "2. System-Specific Analysis\n"
69
- "3. Personalized Action Plan\n"
70
- "4. Interaction Alerts\n"
71
- "5. Tabular Mapping (Markdown table with Biomarker | Value | Range | Status | Insight)\n"
72
- "6. Enhanced AI Insights & Longitudinal Risk\n\n"
73
-
74
- "Style: Professional, concise, structured, client-friendly. "
75
- "No hallucinations. No extra biomarkers. No absolute longevity claims.\n"
76
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
77
 
78
- patient_input = (
79
- f"Patient Profile:\n- Age: {age}\n- Gender: {gender}\n"
80
- f"- Height: {height} cm\n- Weight: {weight} kg\n- BMI: {bmi}\n\n"
81
- "Lab Values:\n"
82
- f"- Albumin: {albumin}\n- Creatinine: {creatinine}\n"
83
- f"- Glucose: {glucose}\n- CRP: {crp}\n"
84
- f"- MCV: {mcv}\n- RDW: {rdw}\n"
85
- f"- ALP: {alp}\n- WBC: {wbc}\n- Lymphocytes: {lymph}\n"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
86
  )
87
 
88
- prompt = system_prompt + "\n" + patient_input
 
89
 
90
- # ----------------------------
91
- # Generate
92
- # ----------------------------
93
- try:
94
- gen = pipe(
95
- prompt,
96
- max_new_tokens=1200,
97
- temperature=0.25,
98
- top_p=0.9,
99
- return_full_text=False
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
100
  )
101
- generated = gen[0]["generated_text"].strip()
102
- except Exception as e:
103
- return f"❌ Error: {str(e)}", ""
104
-
105
- if not generated:
106
- return "⚠️ No valid response. Please try again.", ""
107
-
108
- left_md, right_md = split_report(generated)
109
- return left_md, right_md
110
-
111
- # ----------------------------
112
- # Gradio UI
113
- # ----------------------------
114
- with gr.Blocks(theme=gr.themes.Soft()) as demo:
115
- gr.Markdown("# 🏥 AI Medical Biomarker Dashboard")
116
-
117
- with gr.Row():
118
- with gr.Column():
119
- gr.Markdown("### Demographics")
120
- age = gr.Number(label="Age", value=45)
121
- gender = gr.Dropdown(["Male", "Female"], label="Gender", value="Male")
122
- height = gr.Number(label="Height (cm)", value=174)
123
- weight = gr.Number(label="Weight (kg)", value=75)
124
-
125
- gr.Markdown("### Blood Panel")
126
- wbc = gr.Number(label="WBC (K/uL)", value=6.5)
127
- lymph = gr.Number(label="Lymphocytes (%)", value=30)
128
- mcv = gr.Number(label="MCV (fL)", value=88)
129
- rdw = gr.Number(label="RDW (%)", value=13)
130
-
131
- with gr.Column():
132
- gr.Markdown("### Chemistry Panel")
133
- albumin = gr.Number(label="Albumin (g/dL)", value=4.2)
134
- creatinine = gr.Number(label="Creatinine (mg/dL)", value=0.9)
135
- glucose = gr.Number(label="Glucose (mg/dL)", value=92)
136
- crp = gr.Number(label="CRP (mg/L)", value=1.0)
137
- alp = gr.Number(label="ALP (U/L)", value=70)
138
-
139
- analyze_btn = gr.Button("🔬 Generate Report", variant="primary")
140
-
141
- with gr.Row():
142
- with gr.Column():
143
- gr.Markdown("### 📝 Summary & Action Plan")
144
- left_output = gr.Markdown()
145
- with gr.Column():
146
- gr.Markdown("### 📊 Tabular & AI Insights")
147
- right_output = gr.Markdown()
148
-
149
- analyze_btn.click(
150
- fn=analyze,
151
- inputs=[albumin, creatinine, glucose, crp, mcv, rdw, alp, wbc, lymph, age, gender, height, weight],
152
- outputs=[left_output, right_output]
153
- )
154
 
155
  if __name__ == "__main__":
156
- demo.launch(server_name="0.0.0.0", server_port=int(os.environ.get("PORT", 7860)), show_error=True)
 
1
+ """
2
+ app.py
3
+ Gradio app that loads Muhammadidrees/bioLLM (Hugging Face) and
4
+ performs prompt-feeding based biomarker report generation.
5
+
6
+ Inputs:
7
+ - Nine Levine biomarkers (numeric)
8
+ - Age, weight (kg), height (cm), sex
9
+
10
+ Outputs:
11
+ - Text sections: Executive summary, System analysis, Personalized action plan, Further recommendations
12
+ - Table: biomarker | value | unit | status | short interpretation
13
+
14
+ Notes:
15
+ - Not a clinical decision tool. Validate outputs externally.
16
+ - If CUDA is available, the script will use GPU (device=0).
17
+ """
18
+
19
+ import os
20
+ import math
21
+ import pandas as pd
22
  import torch
23
+ from transformers import AutoTokenizer, AutoModelForCausalLM, pipeline, set_seed
24
  import gradio as gr
25
+ from typing import Dict, Tuple
 
 
 
 
 
26
 
27
+ # ========== Config ==========
28
+ HF_MODEL = "Muhammadidrees/bioLLM" # user-specified
29
+ SEED = 42
30
+ set_seed(SEED)
31
 
32
+ # Generation hyperparameters (tune as needed)
33
+ GEN_KWARGS = dict(
34
+ max_new_tokens=512,
35
+ do_sample=True,
36
+ temperature=0.7,
37
+ top_p=0.92,
38
+ num_return_sequences=1,
39
+ eos_token_id=None,
40
  )
41
 
42
+ # ========== Utility functions ==========
 
 
 
 
43
 
44
+ def bmi_from_weight_height(kg: float, cm: float) -> float:
45
+ if kg <= 0 or cm <= 0:
46
+ return None
47
+ m = cm / 100.0
48
+ return kg / (m * m)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
49
 
50
+ def device_selection():
51
+ if torch.cuda.is_available():
52
+ return 0 # pipeline expects device index (0)
53
+ return -1 # CPU
54
+
55
+ def load_model_and_tokenizer(model_name: str):
56
+ """
57
+ Load tokenizer and model for causal LM. Adjust device map as needed.
58
+ """
59
+ print(f"Loading tokenizer and model: {model_name} ...")
60
+ tokenizer = AutoTokenizer.from_pretrained(model_name, use_fast=True)
61
+ # Avoid loading to CPU twice; huggingface will map to available device
62
+ model = AutoModelForCausalLM.from_pretrained(model_name, torch_dtype=torch.float16 if torch.cuda.is_available() else None, low_cpu_mem_usage=True)
63
+ # Create pipeline
64
+ pipe = pipeline("text-generation", model=model, tokenizer=tokenizer, device=device_selection())
65
+ return pipe, tokenizer
66
+
67
+ # ========== Domain knowledge: Levine 9 biomarkers ==========
68
+ # Units below are conventional / commonly used — allow user to input any units but document expects these.
69
+ LEVINED_BIOMARKERS = [
70
+ ("Fasting Glucose", "mg/dL"),
71
+ ("C-reactive protein (CRP)", "mg/L"),
72
+ ("Albumin", "g/dL"),
73
+ ("Alkaline phosphatase", "U/L"),
74
+ ("Creatinine", "mg/dL"),
75
+ ("Red Cell Distribution Width (RDW)", "%"),
76
+ ("Lymphocyte %", "%"),
77
+ ("White Blood Cell count (WBC)", "10^3/µL"),
78
+ ("Mean Corpuscular Volume (MCV)", "fL"),
79
+ ]
80
+
81
+ # Example reference ranges (simple defaults). You can adjust to local lab ranges.
82
+ # These ranges are coarse and illustrative. Use local clinical ranges in production.
83
+ REFERENCE_RANGES = {
84
+ "Fasting Glucose": (70, 99), # mg/dL normal fasting
85
+ "C-reactive protein (CRP)": (0.0, 3.0), # mg/L low-normal; >10 often indicates acute inflammation
86
+ "Albumin": (3.5, 5.0), # g/dL
87
+ "Alkaline phosphatase": (44, 147), # U/L
88
+ "Creatinine": (0.6, 1.3), # mg/dL (adult average; sex/age dependent)
89
+ "Red Cell Distribution Width (RDW)": (11.5, 14.5), # %
90
+ "Lymphocyte %": (20.0, 50.0), # %
91
+ "White Blood Cell count (WBC)": (4.0, 11.0), # 10^3/µL
92
+ "Mean Corpuscular Volume (MCV)": (80, 100), # fL
93
+ }
94
+
95
+ def value_to_status(name: str, val: float) -> str:
96
+ """
97
+ Convert a numeric biomarker value to a simple 'Low/Normal/High' status.
98
+ Uses REFERENCE_RANGES map; if not found returns 'Unknown'.
99
+ """
100
+ if val is None:
101
+ return "Missing"
102
+ rng = REFERENCE_RANGES.get(name)
103
+ if not rng:
104
+ return "Unknown"
105
+ low, high = rng
106
  try:
107
+ v = float(val)
108
+ except:
109
+ return "Invalid"
110
+ if v < low:
111
+ return "Low"
112
+ elif v > high:
113
+ return "High"
114
+ else:
115
+ return "Normal"
116
+
117
+ def short_interpretation(name: str, val: float, status: str) -> str:
118
+ """
119
+ Very short, literature-style interpretation used for the table.
120
+ These are template-like; you can expand or replace with another knowledge base.
121
+ """
122
+ if status == "Missing":
123
+ return "No value provided."
124
+ if status == "Invalid":
125
+ return "Invalid input."
126
+ if status == "Unknown":
127
+ return "No reference range available."
128
+ if name == "Albumin":
129
+ if status == "Low":
130
+ return "Hypoalbuminemia malnutrition, liver disease, or inflammation possible."
131
+ else:
132
+ return "Within expected range."
133
+ if name.startswith("C-reactive"):
134
+ if status == "High":
135
+ return "Elevated suggests systemic inflammation or acute infection."
136
+ else:
137
+ return "Within expected range."
138
+ if name == "Fasting Glucose":
139
+ if status == "High":
140
+ return "Hyperglycemia — impaired glucose control; consider further metabolic workup."
141
+ else:
142
+ return "Within expected fasting range."
143
+ if name == "Creatinine":
144
+ if status == "High":
145
+ return "Possible renal dysfunction or reduced GFR (age/sex dependent)."
146
+ else:
147
+ return "Within expected range."
148
+ if name == "Alkaline phosphatase":
149
+ if status == "High":
150
+ return "May suggest cholestasis or bone turnover; correlate clinically."
151
+ else:
152
+ return "Within expected range."
153
+ if name == "Red Cell Distribution Width (RDW)":
154
+ if status == "High":
155
+ return "Anisocytosis — possible nutritional deficiency or marrow response."
156
+ else:
157
+ return "Within expected range."
158
+ if name == "Lymphocyte %":
159
+ if status == "Low":
160
+ return "Relative lymphopenia — may reflect infection or immunosuppression."
161
+ else:
162
+ return "Within expected range."
163
+ if name == "White Blood Cell count (WBC)":
164
+ if status == "High":
165
+ return "Leukocytosis — often infection or inflammation."
166
+ elif status == "Low":
167
+ return "Leukopenia — consider bone marrow suppression or viral infection."
168
+ else:
169
+ return "Within expected range."
170
+ if name == "Mean Corpuscular Volume (MCV)":
171
+ if status == "High":
172
+ return "Macrocytosis — check B12/folate, liver disease, alcohol use."
173
+ elif status == "Low":
174
+ return "Microcytosis — consider iron deficiency."
175
+ else:
176
+ return "Within expected range."
177
+ # fallback
178
+ return "Interpretation not available."
179
+
180
+ # ========== Prompt construction ==========
181
+ PROMPT_TEMPLATE = """
182
+ You are a biomedical-language assistant. You will be given patient demographics and a list of biomarkers with values and status (Low/Normal/High).
183
+ Produce an output that contains the following labeled sections:
184
+
185
+ 1) Executive Summary:
186
+ - 2-4 sentence high-level synthesis of the patient's biomarker pattern and clinical implication.
187
+
188
+ 2) System-specific analysis:
189
+ - Bullet-style analysis per organ/system (e.g., metabolic, hepatic, renal, hematologic, immune), referencing biomarkers when relevant.
190
+
191
+ 3) Personalized action plan:
192
+ - Practical, prioritized next steps suitable for a clinician or informed researcher (diagnostic tests, immediate actions, lifestyle suggestions).
193
+ - Keep recommendations conservative and evidence-minded. Mention when specialty referral is reasonable.
194
+
195
+ 4) Further recommendations:
196
+ - Additional tests, monitoring frequency, non-pharmacological measures, and resources for patient education.
197
 
198
+ 5) Tabular biomarker interpretation:
199
+ - Provide a Markdown table with columns: Biomarker | Value | Unit | Status | Short interpretation.
200
+ - Include only biomarkers provided.
201
+
202
+ Important:
203
+ - Keep your language cautious and non-prescriptive (e.g., "consider", "suggest", "may indicate").
204
+ - Add a single-line concluding clinical disclaimer: "This report is for research/educational use only and not a substitute for clinical judgment."
205
+
206
+ Patient demographics:
207
+ - Age: {age}
208
+ - Sex: {sex}
209
+ - Weight: {weight_kg} kg
210
+ - Height: {height_cm} cm
211
+ - BMI: {bmi:.1f}
212
+
213
+ Biomarkers:
214
+ {biomarker_lines}
215
+
216
+ Now produce the requested sections.
217
+ """
218
+
219
+ def build_biomarker_lines(biomarker_inputs: Dict[str, Tuple[float,str]]) -> str:
220
+ """
221
+ biomarker_inputs: dict mapping biomarker name -> (value, unit)
222
+ returns a text block with lines: - Name: value unit (Status)
223
+ """
224
+ lines = []
225
+ for name, (val, unit) in biomarker_inputs.items():
226
+ status = value_to_status(name, val)
227
+ val_str = "" if val is None else str(val)
228
+ lines.append(f"- {name}: {val_str} {unit} ({status})")
229
+ return "\n".join(lines)
230
+
231
+ # ========== Load pipeline ==========
232
+ print("Initializing model pipeline...\n(If this stalls, make sure the model is available and you have network access.)")
233
+ pipe, tokenizer = load_model_and_tokenizer(HF_MODEL)
234
+ print("Model loaded.")
235
+
236
+ # ========== Inference function ==========
237
+ def generate_report(
238
+ fasting_glucose,
239
+ crp,
240
+ albumin,
241
+ alk_phos,
242
+ creatinine,
243
+ rdw,
244
+ lymph_pct,
245
+ wbc,
246
+ mcv,
247
+ age,
248
+ weight_kg,
249
+ height_cm,
250
+ sex
251
+ ):
252
+ # Build biomarker dict (names must match LEVINE list keys)
253
+ biom_inputs = {
254
+ "Fasting Glucose": (fasting_glucose, "mg/dL"),
255
+ "C-reactive protein (CRP)": (crp, "mg/L"),
256
+ "Albumin": (albumin, "g/dL"),
257
+ "Alkaline phosphatase": (alk_phos, "U/L"),
258
+ "Creatinine": (creatinine, "mg/dL"),
259
+ "Red Cell Distribution Width (RDW)": (rdw, "%"),
260
+ "Lymphocyte %": (lymph_pct, "%"),
261
+ "White Blood Cell count (WBC)": (wbc, "10^3/µL"),
262
+ "Mean Corpuscular Volume (MCV)": (mcv, "fL"),
263
+ }
264
+
265
+ # Compute BMI
266
+ bmi = bmi_from_weight_height(weight_kg, height_cm) or 0.0
267
+
268
+ # Construct biomarker lines for prompt
269
+ biomarker_lines = build_biomarker_lines(biom_inputs)
270
+ prompt = PROMPT_TEMPLATE.format(
271
+ age=int(age) if age is not None else "Unknown",
272
+ sex=sex,
273
+ weight_kg=weight_kg,
274
+ height_cm=height_cm,
275
+ bmi=bmi,
276
+ biomarker_lines=biomarker_lines
277
  )
278
 
279
+ # Debug: you may print prompt during development
280
+ # print("Prompt sent to model:\n", prompt)
281
 
282
+ # Call model
283
+ gen = pipe(prompt, **GEN_KWARGS)[0]["generated_text"]
284
+
285
+ # Post-process: separate sections if model includes them; otherwise present whole text.
286
+ # We'll attempt to split by the numeric section headings used in prompt (1), 2), etc.
287
+ sections = {"full_text": gen}
288
+ for label in ["Executive Summary:", "System-specific analysis:", "Personalized action plan:", "Further recommendations:", "Tabular biomarker interpretation:"]:
289
+ if label in gen:
290
+ # naive split: find start
291
+ start = gen.find(label)
292
+ # find next label start index
293
+ sections[label] = gen[start: gen.find("\n\n", start) + 2] # short snippet fallback
294
+
295
+ # Build table as DataFrame for nicer display in Gradio
296
+ rows = []
297
+ for name, (val, unit) in biom_inputs.items():
298
+ status = value_to_status(name, val)
299
+ interp = short_interpretation(name, val, status)
300
+ rows.append({
301
+ "Biomarker": name,
302
+ "Value": "" if val is None else val,
303
+ "Unit": unit,
304
+ "Status": status,
305
+ "Short interpretation": interp
306
+ })
307
+ df = pd.DataFrame(rows)
308
+
309
+ # Return model raw text and dataframe
310
+ return gen, df
311
+
312
+ # ========== Gradio UI ==========
313
+ def launch_app():
314
+ demo_inputs = {
315
+ "fasting_glucose": 92,
316
+ "crp": 5.2,
317
+ "albumin": 3.2,
318
+ "alk_phos": 85,
319
+ "creatinine": 1.0,
320
+ "rdw": 13.1,
321
+ "lymph_pct": 30,
322
+ "wbc": 7.2,
323
+ "mcv": 90,
324
+ "age": 58,
325
+ "weight_kg": 78,
326
+ "height_cm": 172,
327
+ "sex": "Male",
328
+ }
329
+
330
+ with gr.Blocks(title="bioLLM — Biomarker Report (Levine 9-panel)") as demo:
331
+ # gr.Markdown("## bioLLM biomarker report generator\n**Not for clinical use.** ` and prompt-feeding to produce literature-style explanations.")
332
+ with gr.Row():
333
+ with gr.Column(scale=1):
334
+ fasting_glucose = gr.Number(label="Fasting Glucose (mg/dL)", value=demo_inputs["fasting_glucose"])
335
+ crp = gr.Number(label="C-reactive protein (CRP) (mg/L)", value=demo_inputs["crp"])
336
+ albumin = gr.Number(label="Albumin (g/dL)", value=demo_inputs["albumin"])
337
+ alk_phos = gr.Number(label="Alkaline phosphatase (U/L)", value=demo_inputs["alk_phos"])
338
+ creatinine = gr.Number(label="Creatinine (mg/dL)", value=demo_inputs["creatinine"])
339
+ with gr.Column(scale=1):
340
+ rdw = gr.Number(label="Red Cell Distribution Width (RDW) (%)", value=demo_inputs["rdw"])
341
+ lymph_pct = gr.Number(label="Lymphocyte %", value=demo_inputs["lymph_pct"])
342
+ wbc = gr.Number(label="White Blood Cell count (10^3/µL)", value=demo_inputs["wbc"])
343
+ mcv = gr.Number(label="Mean Corpuscular Volume (MCV) (fL)", value=demo_inputs["mcv"])
344
+ sex = gr.Dropdown(choices=["Male", "Female", "Other"], value=demo_inputs["sex"], label="Sex")
345
+ with gr.Row():
346
+ age = gr.Number(label="Age (years)", value=demo_inputs["age"])
347
+ weight_kg = gr.Number(label="Weight (kg)", value=demo_inputs["weight_kg"])
348
+ height_cm = gr.Number(label="Height (cm)", value=demo_inputs["height_cm"])
349
+ with gr.Row():
350
+ submit = gr.Button("Generate report")
351
+ clear = gr.Button("Reset")
352
+ with gr.Row():
353
+ output_text = gr.Markdown(label="Model report (text)")
354
+ with gr.Row():
355
+ output_table = gr.Dataframe(headers=["Biomarker", "Value", "Unit", "Status", "Short interpretation"], label="Tabular interpretation (derived)")
356
+
357
+ def on_submit(
358
+ fasting_glucose, crp, albumin, alk_phos, creatinine,
359
+ rdw, lymph_pct, wbc, mcv, age, weight_kg, height_cm, sex
360
+ ):
361
+ text, df = generate_report(
362
+ fasting_glucose, crp, albumin, alk_phos, creatinine,
363
+ rdw, lymph_pct, wbc, mcv, age, weight_kg, height_cm, sex
364
+ )
365
+ # Return text as markdown and dataframe as table
366
+ return text, df
367
+
368
+ submit.click(
369
+ on_submit,
370
+ inputs=[fasting_glucose, crp, albumin, alk_phos, creatinine, rdw, lymph_pct, wbc, mcv, age, weight_kg, height_cm, sex],
371
+ outputs=[output_text, output_table]
372
  )
373
+ clear.click(lambda: (gr.update(value=demo_inputs["fasting_glucose"]), gr.update(value=demo_inputs["crp"]),
374
+ gr.update(value=demo_inputs["albumin"]), gr.update(value=demo_inputs["alk_phos"]),
375
+ gr.update(value=demo_inputs["creatinine"]), gr.update(value=demo_inputs["rdw"]),
376
+ gr.update(value=demo_inputs["lymph_pct"]), gr.update(value=demo_inputs["wbc"]),
377
+ gr.update(value=demo_inputs["mcv"]), gr.update(value=demo_inputs["age"]),
378
+ gr.update(value=demo_inputs["weight_kg"]), gr.update(value=demo_inputs["height_cm"]),
379
+ gr.update(value=demo_inputs["sex"])),
380
+ inputs=[], outputs=[]
381
+ )
382
+
383
+ demo.launch(server_name="0.0.0.0", share=False)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
384
 
385
  if __name__ == "__main__":
386
+ launch_app()