import gradio as gr import joblib import pandas as pd import os from groq import Groq from reportlab.platypus import ( SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle, Image ) from reportlab.lib.styles import ParagraphStyle, getSampleStyleSheet from reportlab.lib import colors from reportlab.lib.units import inch # =============================== # LOAD MODEL # =============================== model = joblib.load("typhoidguard_model_reduced2.pkl") client = Groq(api_key=os.environ.get("GROQ_API_KEY")) last_llm_report = "" last_basic_data = {} LOGO_PATH = "logo1.png" # 🔹 Place your logo file in HF repo # =============================== # LLM FUNCTION # =============================== def generate_llm_report(patient_info, prob_pct, risk_label, recommendation, factors): prompt = f""" You are a responsible medical AI assistant helping rural healthcare units in Pakistan. Patient Details: {patient_info} Predicted Risk: {prob_pct}% Risk Category: {risk_label} Clinical Risk Factors: {", ".join(factors) if factors else "None"} Agent Recommendation: {recommendation} Generate structured sections: Clinical Interpretation Possible Complications Immediate Precautions Preventative Measures Follow-up Recommendations Keep headings clear. End with this line: "Remember, this advice is generated based on the provided information and should not replace the judgment of a qualified doctor. It is essential to consult a qualified doctor for personalized advice and treatment reminder to consult qualified doctor." """ response = client.chat.completions.create( model="llama-3.3-70b-versatile", messages=[{"role": "user", "content": prompt}], temperature=0.4, ) return response.choices[0].message.content # =============================== # BASIC PREDICTION # =============================== def predict_basic(name, age, gender, platelets, hb, duration, blood_bacteria, severity, medication): global last_basic_data, last_llm_report last_llm_report = "" data = pd.DataFrame([{ "Age": age, "Platelet Count": platelets, "Hemoglobin (g/dL)": hb, "Treatment Duration": duration, "Gender": gender, "Blood Culture Bacteria": blood_bacteria, "Symptoms Severity": severity, "Current Medication": medication }]) prob = model.predict_proba(data)[0][1] prob_pct = round(prob * 100, 2) low_platelets = platelets < 150000 low_hb = hb < 10 if low_platelets or low_hb: prob_pct = 90.0 risk_label = "HIGH RISK" color = "#b00020" recommendation = "Immediate referral to secondary care facility recommended." elif prob >= 0.65: risk_label = "HIGH RISK" color = "#b00020" recommendation = "Urgent clinical evaluation required." elif prob >= 0.35: risk_label = "MODERATE RISK" color = "#f57c00" recommendation = "Close monitoring advised." else: risk_label = "LOW RISK" color = "#2e7d32" recommendation = "Continue standard treatment protocol." factors = [] if low_platelets: factors.append("Low Platelet Count") if low_hb: factors.append("Low Hemoglobin") last_basic_data = { "name": name, "age": age, "gender": gender, "platelets": platelets, "hb": hb, "duration": duration, "bacteria": blood_bacteria, "severity": severity, "medication": medication, "prob_pct": prob_pct, "risk_label": risk_label, "recommendation": recommendation, "factors": factors, "color": color } urdu = f"""
اردو خلاصہ:
علاج ناکامی کا خطرہ {prob_pct}% ہے۔ درجہ: {risk_label}۔
ڈاکٹر سے مشورہ ضرور کریں۔
""" return f"""

Patient: {name}

Risk of Treatment Failure: {prob_pct}% - {risk_label}

Clinical Risk Factors:

Agent Recommendation:

{recommendation}

{urdu}
""" # =============================== # DETAILED BUTTON # =============================== def generate_detailed(*inputs): global last_basic_data, last_llm_report basic_html = predict_basic(*inputs) d = last_basic_data patient_info = f""" Age: {d['age']} Gender: {d['gender']} Platelets: {d['platelets']} Hemoglobin: {d['hb']} Duration: {d['duration']} Bacteria: {d['bacteria']} Severity: {d['severity']} Medication: {d['medication']} """ last_llm_report = generate_llm_report( patient_info, d["prob_pct"], d["risk_label"], d["recommendation"], d["factors"] ) lines = last_llm_report.split("\n") formatted_parts = [] disclaimer_html = "" for line in lines: line = line.strip() if not line: continue # Detect disclaimer line if "consult a qualified doctor" in line.lower(): disclaimer_html = f"""
Disclaimer:
{line}
""" continue # Detect headings starting with ## if line.startswith("##"): clean_heading = line.replace("##", "").strip() formatted_parts.append( f"
{clean_heading}:
" ) else: formatted_parts.append(f"{line}
") formatted = "".join(formatted_parts) return basic_html + f"""

Detailed AI Report & Recommendations

{formatted} {disclaimer_html}
""" # =============================== # PDF GENERATION # =============================== def generate_pdf(*inputs): global last_basic_data, last_llm_report d = last_basic_data file_path = f"{d['name']}_Typhoid_Report.pdf" doc = SimpleDocTemplate(file_path) elements = [] styles = getSampleStyleSheet() # ---- Custom Styles ---- heading_style = ParagraphStyle( name="CustomHeading", parent=styles["Heading2"], fontSize=14, spaceAfter=6, textColor=colors.black ) bullet_style = ParagraphStyle( name="BulletStyle", parent=styles["Normal"], leftIndent=15, bulletIndent=5, spaceAfter=4 ) disclaimer_heading_style = ParagraphStyle( name="DisclaimerHeading", parent=styles["Heading2"], textColor=colors.red, fontSize=13, spaceBefore=15 ) disclaimer_text_style = ParagraphStyle( name="DisclaimerText", parent=styles["Normal"], fontSize=10, textColor=colors.grey ) # ---- LOGO ---- if os.path.exists(LOGO_PATH): elements.append(Image(LOGO_PATH, width=1.6*inch, height=1.2*inch)) elements.append(Spacer(1,0.2*inch)) elements.append(Paragraph("TyphoidGuard AI Clinical Report", styles["Title"])) elements.append(Spacer(1, 0.3 * inch)) # ---- RISK BADGE (Improved Height & Padding) ---- risk_color = colors.HexColor(d["color"]) badge_style = ParagraphStyle( name="Badge", parent=styles["Normal"], backColor=risk_color, textColor=colors.white, fontSize=13, leading=18, leftIndent=10, rightIndent=10, spaceBefore=10, spaceAfter=15 ) elements.append(Paragraph( f"Risk: {d['prob_pct']}% - {d['risk_label']}", badge_style )) elements.append(Spacer(1,0.3*inch)) # ---- PATIENT TABLE ---- table_data = [ ["Patient Name", d["name"]], ["Age", d["age"]], ["Gender", d["gender"]], ["Platelet Count", d["platelets"]], ["Hemoglobin", d["hb"]], ["Treatment Duration", d["duration"]], ["Bacteria", d["bacteria"]], ["Severity", d["severity"]], ["Medication", d["medication"]], ] table = Table(table_data, colWidths=[2.5*inch, 3*inch]) table.setStyle(TableStyle([ ('GRID',(0,0),(-1,-1),1,colors.grey), ('FONTNAME',(0,0),(-1,-1),'Helvetica') ])) elements.append(table) elements.append(Spacer(1,0.4*inch)) # ---- AGENT RECOMMENDATION ---- elements.append(Paragraph("Agent Recommendation", heading_style)) elements.append(Paragraph(d["recommendation"], styles["Normal"])) elements.append(Spacer(1,0.4*inch)) # ---- DETAILED AI REPORT ---- if last_llm_report: elements.append(Paragraph("Detailed AI Report", heading_style)) elements.append(Spacer(1,0.2*inch)) lines = last_llm_report.split("\n") for line in lines: line = line.strip() if not line: continue if "qualified doctor" in line.lower(): continue if line.startswith("##"): clean_heading = line.replace("##", "").strip() elements.append(Spacer(1,0.2*inch)) elements.append( Paragraph(f"{clean_heading}:", heading_style) ) else: elements.append(Paragraph(line, styles["Normal"])) elements.append(Spacer(1,0.5*inch)) # ---- DISCLAIMER ---- elements.append(Paragraph("Disclaimer", disclaimer_heading_style)) elements.append(Spacer(1,0.1*inch)) elements.append(Paragraph( "Remember to consult a qualified doctor for personalized advice and treatment. " "They will be able to provide guidance tailored to the patient's specific needs and circumstances.", disclaimer_text_style )) elements.append(Spacer(1,0.5*inch)) # ---- TEAM ---- elements.append(Paragraph("Team Chinar AI (AJK)", styles["Normal"])) elements.append(Paragraph( "Anees Qumar Abbasi (Team Lead) | Sharafat Hussain | Salma Asghar | " "Kaleem Hussain | Munazza Zahra | Kokub Khhurishid", styles["Normal"] )) doc.build(elements) # ✅ SUCCESS POPUP MESSAGE (Added Feature) gr.Info("Report Generated Successfully! Please download it below.") return file_path # =============================== # INTERFACE # =============================== # =============================== # PREMIUM MEDICAL INTERFACE (UPDATED) # =============================== with gr.Blocks( theme=gr.themes.Soft(), css=""" body { background: linear-gradient(135deg, #e3f2fd, #f4f9ff); } .center-header { text-align: center; } #header-center { text-align: center; } .instruction-text { text-align: center; font-size: 16px; color: #37474f; margin-bottom: 20px; } .gr-button { border-radius: 10px !important; font-weight: 600 !important; padding: 10px 18px !important; font-size: 15px !important; } .gr-textbox, .gr-number, .gr-dropdown { border-radius: 8px !important; } .footer-team { background: #ffffff; padding: 15px; border-radius: 10px; margin-top: 20px; text-align: center; font-size: 14px; box-shadow: 0 2px 8px rgba(0,0,0,0.05); } """ ) as demo: # ---- LOGO (Guaranteed to Display in HF) ---- # ---- LOGO (Centered) ---- '''gr.Markdown('
') gr.Image(LOGO_PATH, width=300, show_label=False, container=False) gr.Markdown('
') # ---- CENTERED HEADER ---- gr.Markdown("""

🏥 TyphoidGuard AI

HEC Generative AI Hackathon – Pakistan

Team Chinar AI (AJK)

""")''' # ---- CENTERED LOGO + HEADER ---- with gr.Row(): with gr.Column(scale=1, elem_id="header-center"): gr.Image(LOGO_PATH, width=300, show_label=False) gr.Markdown("""

🏥 TyphoidGuard AI

HEC Generative AI Hackathon – Pakistan

Team Chinar AI (AJK)

""") # ---- INSTRUCTION TEXT ---- gr.Markdown("""
Please enter the patient clinical values below to assess the risk of typhoid treatment failure and receive AI-based recommendations.
""") # ---- INPUT FIELDS ---- with gr.Row(): name = gr.Textbox(label="Patient Name") age = gr.Number(label="Age") gender = gr.Radio(["Male", "Female"], label="Gender") with gr.Row(): platelets = gr.Number(label="Platelet Count") hb = gr.Number(label="Hemoglobin (g/dL)") duration = gr.Number(label="Treatment Duration (Days)") with gr.Row(): blood_bacteria = gr.Dropdown( ["Escherichia coli","Salmonella typhi","Unknown","Staphylococcus"], label="Blood Culture Bacteria" ) severity = gr.Dropdown( ["Low","Moderate","High","Unknown"], label="Symptoms Severity" ) medication = gr.Dropdown( ["Amoxicillin","Ceftriaxone","Azithromycin"], label="Current Medication" ) # ---- BUTTONS ---- with gr.Row(): predict_btn = gr.Button("Basic Risk Assessment") detailed_btn = gr.Button("Detailed Report & Recommendations") pdf_btn = gr.Button("Generate PDF Report") output = gr.HTML() predict_btn.click(predict_basic, inputs=[name,age,gender,platelets,hb,duration, blood_bacteria,severity,medication], outputs=output) detailed_btn.click(generate_detailed, inputs=[name,age,gender,platelets,hb,duration, blood_bacteria,severity,medication], outputs=output) pdf_btn.click(generate_pdf, inputs=[name,age,gender,platelets,hb,duration, blood_bacteria,severity,medication], outputs=gr.File()) # ---- TEAM FOOTER ---- gr.Markdown(""" """) demo.launch()