aneesqumar commited on
Commit
318cabe
·
verified ·
1 Parent(s): 8a5a7e4

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +261 -0
app.py ADDED
@@ -0,0 +1,261 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+
218
+ doc.build(elements)
219
+ return file_path
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")
231
+ age = gr.Number(label="Age")
232
+ gender = gr.Radio(["Male", "Female"], label="Gender")
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()