aneesqumar commited on
Commit
c1a609f
·
verified ·
1 Parent(s): 413f892

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +176 -129
app.py CHANGED
@@ -1,217 +1,244 @@
1
  import gradio as gr
2
  import joblib
3
  import pandas as pd
 
4
  import os
5
  from groq import Groq
6
 
7
- from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle
8
- from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
9
  from reportlab.lib import colors
10
  from reportlab.lib.units import inch
 
11
 
12
  # ===============================
13
- # Load ML Model
14
  # ===============================
15
- model = joblib.load("typhoidguard_model_reduced.pkl")
16
 
17
- # ===============================
18
  # Groq Client
19
- # ===============================
20
  client = Groq(api_key=os.environ.get("GROQ_API_KEY"))
21
 
22
- # ===============================
23
- # GLOBAL CACHE (avoid double LLM call)
24
- # ===============================
25
- LLM_CACHE = {
26
- "english": "",
27
- "urdu": ""
28
- }
29
-
30
- # ===============================
31
- # FORMAT LLM TEXT TO HTML
32
- # ===============================
33
- def format_llm_text(text):
34
- lines = text.split("\n")
35
- html = ""
36
-
37
- for line in lines:
38
- line = line.strip()
39
-
40
- if line.lower().startswith("1.") or line.lower().startswith("2.") or line.lower().startswith("3.") \
41
- or line.lower().startswith("4.") or line.lower().startswith("5."):
42
- html += f"<h3 style='color:#003366'>{line}</h3>"
43
-
44
- elif line.startswith("*"):
45
- html += f"<li>{line[1:].strip()}</li>"
46
-
47
- elif line:
48
- html += f"<p>{line}</p>"
49
-
50
- return f"<ul>{html}</ul>"
51
 
52
 
53
  # ===============================
54
- # LLM REPORT (English + Urdu)
55
  # ===============================
56
  def generate_llm_report(patient_info, prob_pct, risk_label, recommendation, factors):
57
 
58
  prompt = f"""
59
- You are a medical AI assistant helping doctors in rural Pakistan.
60
 
61
  Patient Details:
62
  {patient_info}
63
 
64
- Risk of Treatment Failure: {prob_pct}%
65
  Risk Category: {risk_label}
66
 
67
- Risk Factors:
68
  {", ".join(factors) if factors else "None"}
69
 
70
  Agent Recommendation:
71
  {recommendation}
72
 
73
- TASK:
74
- 1. Write a detailed medical report with headings:
75
- - Clinical Interpretation
76
- - Possible Complications
77
- - Immediate Precautions
78
- - Preventive Measures
79
- - Follow-up Recommendations
80
-
81
- 2. Then write a SHORT summary in URDU for healthcare staff.
82
 
83
- Rules:
84
- - Use bullet points
85
- - No markdown (** or ###)
86
- - Simple clinical language
87
  """
88
 
89
  response = client.chat.completions.create(
90
  model="llama-3.3-70b-versatile",
91
  messages=[{"role": "user", "content": prompt}],
92
- temperature=0.3,
93
  )
94
 
95
- full_text = response.choices[0].message.content
96
-
97
- # Split English & Urdu
98
- if "اردو" in full_text:
99
- eng, urdu = full_text.split("اردو", 1)
100
- urdu = "اردو" + urdu
101
- else:
102
- eng, urdu = full_text, ""
103
-
104
- return eng.strip(), urdu.strip()
105
 
106
 
107
  # ===============================
108
- # BASIC ANALYSIS (NO LLM)
109
  # ===============================
110
- def analyze_patient(name, age, gender, platelets, hb, duration, calcium, potassium):
 
 
 
 
111
 
112
  data = pd.DataFrame([{
113
- "Platelet Count": platelets,
114
  "Age": age,
 
115
  "Hemoglobin (g/dL)": hb,
116
  "Treatment Duration": duration,
117
- "Calcium (mg/dL)": calcium,
118
- "Potassium (mmol/L)": potassium,
119
- "Gender": gender
 
120
  }])
121
 
122
- X = model.named_steps["preprocessor"].transform(data)
123
- prob = model.named_steps["classifier"].predict_proba(X)[0][1]
124
 
 
125
  low_platelets = platelets < 150000
126
  low_hb = hb < 10
127
-
128
- prob_pct = 90.0 if (low_platelets or low_hb) else round(prob * 100, 2)
129
 
130
  if low_platelets or low_hb:
131
- status = "🔴 HIGH RISK"
 
132
  color = "#d62828"
133
  recommendation = "Immediate referral to secondary care facility recommended."
 
 
 
 
134
  elif prob >= 0.35:
135
- status = "🟡 MODERATE RISK"
136
  color = "#f4a261"
137
- recommendation = "Close monitoring advised."
138
  else:
139
- status = "🟢 LOW RISK"
140
  color = "#2a9d8f"
141
- recommendation = "Continue standard treatment."
142
 
143
  factors = []
144
- if low_platelets: factors.append("Low Platelet Count")
145
- if low_hb: factors.append("Low Hemoglobin")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
146
 
147
- html = f"""
148
- <div style="padding:15px;font-family:Arial">
149
- <h2 style="color:{color}">Patient: {name}</h2>
150
  <h3>Risk of Treatment Failure: {prob_pct}%</h3>
151
- <h3>Status: {status}</h3>
152
- <h4>Agent Recommendation</h4>
 
 
 
 
 
 
153
  <p><b>{recommendation}</b></p>
 
 
154
  </div>
155
  """
156
 
157
- return html, prob_pct, status, recommendation, factors
 
 
158
 
159
 
160
  # ===============================
161
  # DETAILED REPORT BUTTON
162
  # ===============================
163
- def detailed_report(name, age, gender, platelets, hb, duration, calcium, potassium):
 
164
 
165
- html, prob_pct, status, rec, factors = analyze_patient(
166
- name, age, gender, platelets, hb, duration, calcium, potassium
167
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
168
 
169
  patient_info = f"""
170
- Age: {age}, Gender: {gender}
171
- Platelets: {platelets}, Hb: {hb}
172
- Duration: {duration} days
173
- Calcium: {calcium}, Potassium: {potassium}
 
 
 
 
174
  """
175
 
176
- eng, urdu = generate_llm_report(patient_info, prob_pct, status, rec, factors)
 
 
177
 
178
- LLM_CACHE["english"] = eng
179
- LLM_CACHE["urdu"] = urdu
180
 
181
- formatted_eng = format_llm_text(eng)
182
 
183
- return html + f"""
184
  <hr>
185
- <h2 style="color:#003366">🧠 Detailed AI Report</h2>
186
- {formatted_eng}
187
- <h3 style="color:#006400">اردو خلاصہ</h3>
188
- <p>{urdu}</p>
189
  """
190
 
191
 
192
  # ===============================
193
- # PDF GENERATION (USES CACHE)
194
  # ===============================
195
- def generate_pdf(name, age, gender, platelets, hb, duration, calcium, potassium):
 
 
 
196
 
197
  file_path = f"{name}_Typhoid_Report.pdf"
198
  doc = SimpleDocTemplate(file_path)
199
- styles = getSampleStyleSheet()
200
  elements = []
 
201
 
202
  elements.append(Paragraph("<b>TyphoidGuard AI Clinical Report</b>", styles["Title"]))
203
  elements.append(Spacer(1, 0.3 * inch))
204
 
205
- elements.append(Paragraph("<b>Detailed AI Clinical Report</b>", styles["Heading2"]))
206
- elements.append(Paragraph(LLM_CACHE["english"].replace("\n", "<br/>"), styles["Normal"]))
207
- elements.append(Spacer(1, 0.2 * inch))
208
 
209
- elements.append(Paragraph("<b>اردو خلاصہ</b>", styles["Heading2"]))
210
- elements.append(Paragraph(LLM_CACHE["urdu"], styles["Normal"]))
 
 
 
 
211
 
212
- elements.append(Spacer(1, 0.3 * inch))
213
  elements.append(Paragraph(
214
- "<i>Disclaimer: This report is AI-generated. Consult a qualified doctor.</i>",
215
  styles["Normal"]
216
  ))
217
 
@@ -220,11 +247,12 @@ def generate_pdf(name, age, gender, platelets, hb, duration, calcium, potassium)
220
 
221
 
222
  # ===============================
223
- # UI
224
  # ===============================
225
  with gr.Blocks(theme=gr.themes.Soft()) as demo:
226
 
227
  gr.Markdown("# 🏥 TyphoidGuard AI")
 
228
 
229
  with gr.Row():
230
  name = gr.Textbox(label="Patient Name")
@@ -233,29 +261,48 @@ with gr.Blocks(theme=gr.themes.Soft()) as demo:
233
 
234
  with gr.Row():
235
  platelets = gr.Number(label="Platelet Count")
236
- hb = gr.Number(label="Hemoglobin")
237
- duration = gr.Number(label="Treatment Duration")
238
 
239
  with gr.Row():
240
- calcium = gr.Number(label="Calcium")
241
- potassium = gr.Number(label="Potassium")
 
 
 
 
 
 
 
 
 
 
242
 
243
  output = gr.HTML()
244
 
245
- btn1 = gr.Button("🔍 Analyze Patient")
246
- btn2 = gr.Button("🧠 Detailed Report and Recommendations")
247
  pdf_btn = gr.Button("📄 Generate PDF Report")
248
 
249
- btn1.click(analyze_patient,
250
- inputs=[name, age, gender, platelets, hb, duration, calcium, potassium],
251
- outputs=[output, gr.State(), gr.State(), gr.State(), gr.State()])
 
 
 
252
 
253
- btn2.click(detailed_report,
254
- inputs=[name, age, gender, platelets, hb, duration, calcium, potassium],
255
- outputs=output)
 
 
 
256
 
257
- pdf_btn.click(generate_pdf,
258
- inputs=[name, age, gender, platelets, hb, duration, calcium, potassium],
259
- outputs=gr.File())
 
 
 
260
 
261
  demo.launch()
 
1
  import gradio as gr
2
  import joblib
3
  import pandas as pd
4
+ import numpy as np
5
  import os
6
  from groq import Groq
7
 
8
+ from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Table
9
+ from reportlab.lib.styles import ParagraphStyle, getSampleStyleSheet
10
  from reportlab.lib import colors
11
  from reportlab.lib.units import inch
12
+ from reportlab.platypus import TableStyle
13
 
14
  # ===============================
15
+ # Load Model
16
  # ===============================
17
+ model = joblib.load("typhoidguard_model_reduced2.pkl")
18
 
 
19
  # Groq Client
 
20
  client = Groq(api_key=os.environ.get("GROQ_API_KEY"))
21
 
22
+ # Cache LLM result (avoid double call)
23
+ last_llm_report = ""
24
+ last_basic_output = ""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
25
 
26
 
27
  # ===============================
28
+ # LLM FUNCTION
29
  # ===============================
30
  def generate_llm_report(patient_info, prob_pct, risk_label, recommendation, factors):
31
 
32
  prompt = f"""
33
+ You are a responsible medical AI assistant helping rural healthcare units in Pakistan.
34
 
35
  Patient Details:
36
  {patient_info}
37
 
38
+ Predicted Risk of Treatment Failure: {prob_pct}%
39
  Risk Category: {risk_label}
40
 
41
+ Clinical Risk Factors:
42
  {", ".join(factors) if factors else "None"}
43
 
44
  Agent Recommendation:
45
  {recommendation}
46
 
47
+ Generate a structured detailed report including:
48
+ 1. Clinical Interpretation
49
+ 2. Possible Complications
50
+ 3. Immediate Precautions
51
+ 4. Preventative Measures
52
+ 5. Follow-up Recommendations
 
 
 
53
 
54
+ Use professional formatting.
55
+ End with reminder that final decision must be taken by qualified doctor.
 
 
56
  """
57
 
58
  response = client.chat.completions.create(
59
  model="llama-3.3-70b-versatile",
60
  messages=[{"role": "user", "content": prompt}],
61
+ temperature=0.4,
62
  )
63
 
64
+ return response.choices[0].message.content
 
 
 
 
 
 
 
 
 
65
 
66
 
67
  # ===============================
68
+ # PREDICT FUNCTION (UPDATED FEATURES)
69
  # ===============================
70
+ def predict_basic(name, age, gender, platelets, hb, duration,
71
+ blood_bacteria, severity, medication):
72
+
73
+ global last_llm_report, last_basic_output
74
+ last_llm_report = "" # reset
75
 
76
  data = pd.DataFrame([{
 
77
  "Age": age,
78
+ "Platelet Count": platelets,
79
  "Hemoglobin (g/dL)": hb,
80
  "Treatment Duration": duration,
81
+ "Gender": gender,
82
+ "Blood Culture Bacteria": blood_bacteria,
83
+ "Symptoms Severity": severity,
84
+ "Current Medication": medication
85
  }])
86
 
87
+ prob = model.predict_proba(data)[0][1]
88
+ prob_pct = round(prob * 100, 2)
89
 
90
+ # Agentic Override Logic
91
  low_platelets = platelets < 150000
92
  low_hb = hb < 10
93
+ prolonged_treatment = duration > 7
 
94
 
95
  if low_platelets or low_hb:
96
+ prob_pct = 90.0
97
+ risk_label = "🔴 HIGH RISK"
98
  color = "#d62828"
99
  recommendation = "Immediate referral to secondary care facility recommended."
100
+ elif prob >= 0.65:
101
+ risk_label = "🔴 HIGH RISK"
102
+ color = "#d62828"
103
+ recommendation = "Urgent clinical evaluation required."
104
  elif prob >= 0.35:
105
+ risk_label = "🟡 MODERATE RISK"
106
  color = "#f4a261"
107
+ recommendation = "Close monitoring advised. Repeat tests in 48 hours."
108
  else:
109
+ risk_label = "🟢 LOW RISK"
110
  color = "#2a9d8f"
111
+ recommendation = "Continue standard treatment protocol."
112
 
113
  factors = []
114
+ if low_platelets:
115
+ factors.append("Low Platelet Count")
116
+ if low_hb:
117
+ factors.append("Low Hemoglobin")
118
+ if prolonged_treatment:
119
+ factors.append("Prolonged Treatment Duration")
120
+ if severity == "High":
121
+ factors.append("High Symptom Severity")
122
+
123
+ urdu_summary = f"""
124
+ <div style='background:#eef7ff;padding:10px;border-radius:8px;'>
125
+ <b>اردو خلاصہ:</b><br>
126
+ مریض میں علاج ناکامی کا خطرہ <b>{prob_pct}%</b> ہے۔ موجودہ کیفیت: <b>{risk_label}</b>۔<br>
127
+ براہ کرم ڈاکٹر سے مشورہ ضرور کریں۔
128
+ </div>
129
+ """
130
 
131
+ basic_output = f"""
132
+ <div style="font-family:Arial; padding:15px;">
133
+ <h2 style="color:{color};">Patient: {name}</h2>
134
  <h3>Risk of Treatment Failure: {prob_pct}%</h3>
135
+ <h3>Status: {risk_label}</h3>
136
+
137
+ <h4>Clinical Risk Factors:</h4>
138
+ <ul>
139
+ {''.join([f"<li>{f}</li>" for f in factors]) if factors else "<li>None</li>"}
140
+ </ul>
141
+
142
+ <h4>Agent Recommendation:</h4>
143
  <p><b>{recommendation}</b></p>
144
+
145
+ {urdu_summary}
146
  </div>
147
  """
148
 
149
+ last_basic_output = basic_output
150
+
151
+ return basic_output
152
 
153
 
154
  # ===============================
155
  # DETAILED REPORT BUTTON
156
  # ===============================
157
+ def generate_detailed(name, age, gender, platelets, hb, duration,
158
+ blood_bacteria, severity, medication):
159
 
160
+ global last_llm_report, last_basic_output
161
+
162
+ basic_html = predict_basic(name, age, gender, platelets, hb,
163
+ duration, blood_bacteria, severity, medication)
164
+
165
+ data = pd.DataFrame([{
166
+ "Age": age,
167
+ "Platelet Count": platelets,
168
+ "Hemoglobin (g/dL)": hb,
169
+ "Treatment Duration": duration,
170
+ "Gender": gender,
171
+ "Blood Culture Bacteria": blood_bacteria,
172
+ "Symptoms Severity": severity,
173
+ "Current Medication": medication
174
+ }])
175
+
176
+ prob = model.predict_proba(data)[0][1]
177
+ prob_pct = round(prob * 100, 2)
178
+
179
+ factors = []
180
+ if platelets < 150000:
181
+ factors.append("Low Platelet Count")
182
+ if hb < 10:
183
+ factors.append("Low Hemoglobin")
184
 
185
  patient_info = f"""
186
+ Age: {age}
187
+ Gender: {gender}
188
+ Platelets: {platelets}
189
+ Hemoglobin: {hb}
190
+ Treatment Duration: {duration}
191
+ Blood Bacteria: {blood_bacteria}
192
+ Severity: {severity}
193
+ Medication: {medication}
194
  """
195
 
196
+ llm_report = generate_llm_report(
197
+ patient_info, prob_pct, "See Above", "See Above", factors
198
+ )
199
 
200
+ last_llm_report = llm_report
 
201
 
202
+ formatted_llm = llm_report.replace("\n", "<br>")
203
 
204
+ return basic_html + f"""
205
  <hr>
206
+ <h3 style="color:#003366;">🧠 Detailed AI Report & Recommendations</h3>
207
+ <div style="background:#f8f9fa;padding:15px;border-radius:10px;line-height:1.6;">
208
+ {formatted_llm}
209
+ </div>
210
  """
211
 
212
 
213
  # ===============================
214
+ # PDF GENERATION
215
  # ===============================
216
+ def generate_pdf(name, age, gender, platelets, hb, duration,
217
+ blood_bacteria, severity, medication):
218
+
219
+ global last_llm_report, last_basic_output
220
 
221
  file_path = f"{name}_Typhoid_Report.pdf"
222
  doc = SimpleDocTemplate(file_path)
 
223
  elements = []
224
+ styles = getSampleStyleSheet()
225
 
226
  elements.append(Paragraph("<b>TyphoidGuard AI Clinical Report</b>", styles["Title"]))
227
  elements.append(Spacer(1, 0.3 * inch))
228
 
229
+ # Basic Output
230
+ elements.append(Paragraph(last_basic_output.replace("<br>", "<br/>"), styles["Normal"]))
231
+ elements.append(Spacer(1, 0.3 * inch))
232
 
233
+ # Detailed LLM Output (if exists)
234
+ if last_llm_report:
235
+ elements.append(Paragraph("<b>Detailed AI Report</b>", styles["Heading2"]))
236
+ elements.append(Spacer(1, 0.2 * inch))
237
+ elements.append(Paragraph(last_llm_report.replace("\n", "<br/>"), styles["Normal"]))
238
+ elements.append(Spacer(1, 0.3 * inch))
239
 
 
240
  elements.append(Paragraph(
241
+ "<i>Disclaimer: This report is AI-generated. Please consult a qualified doctor before making clinical decisions.</i>",
242
  styles["Normal"]
243
  ))
244
 
 
247
 
248
 
249
  # ===============================
250
+ # INTERFACE
251
  # ===============================
252
  with gr.Blocks(theme=gr.themes.Soft()) as demo:
253
 
254
  gr.Markdown("# 🏥 TyphoidGuard AI")
255
+ gr.Markdown("### HEC Generative AI Training Hackathon – Pakistan")
256
 
257
  with gr.Row():
258
  name = gr.Textbox(label="Patient Name")
 
261
 
262
  with gr.Row():
263
  platelets = gr.Number(label="Platelet Count")
264
+ hb = gr.Number(label="Hemoglobin (g/dL)")
265
+ duration = gr.Number(label="Treatment Duration (Days)")
266
 
267
  with gr.Row():
268
+ blood_bacteria = gr.Dropdown(
269
+ ["Escherichia coli", "Salmonella typhi", "Unknown", "Staphylococcus"],
270
+ label="Blood Culture Bacteria"
271
+ )
272
+ severity = gr.Dropdown(
273
+ ["Low", "Moderate", "High", "Unknown"],
274
+ label="Symptoms Severity"
275
+ )
276
+ medication = gr.Dropdown(
277
+ ["Amoxicillin", "Ceftriaxone", "Azithromycin"],
278
+ label="Current Medication"
279
+ )
280
 
281
  output = gr.HTML()
282
 
283
+ predict_btn = gr.Button("🔍 Basic Risk Assessment")
284
+ detailed_btn = gr.Button("🧠 Detailed Report and Recommendations")
285
  pdf_btn = gr.Button("📄 Generate PDF Report")
286
 
287
+ predict_btn.click(
288
+ predict_basic,
289
+ inputs=[name, age, gender, platelets, hb, duration,
290
+ blood_bacteria, severity, medication],
291
+ outputs=output
292
+ )
293
 
294
+ detailed_btn.click(
295
+ generate_detailed,
296
+ inputs=[name, age, gender, platelets, hb, duration,
297
+ blood_bacteria, severity, medication],
298
+ outputs=output
299
+ )
300
 
301
+ pdf_btn.click(
302
+ generate_pdf,
303
+ inputs=[name, age, gender, platelets, hb, duration,
304
+ blood_bacteria, severity, medication],
305
+ outputs=gr.File()
306
+ )
307
 
308
  demo.launch()