Abdo_chatbot / app.py
khaledsayed1's picture
Update app.py
a58d539 verified
raw
history blame
16.3 kB
import pandas as pd
import gradio as gr
from transformers import AutoTokenizer, AutoModelForSequenceClassification
from sentence_transformers import SentenceTransformer, util
from difflib import get_close_matches
import requests
import io
import torch
# GitHub Excel file URL
GITHUB_EXCEL_URL = "https://raw.githubusercontent.com/3Zzamt0o/HospitalData/main/Hospital%20Data%20(1).xlsx"
def load_hospital_data():
try:
# Fetch Excel file from GitHub
response = requests.get(GITHUB_EXCEL_URL)
response.raise_for_status() # Raise an exception for bad status codes
# Read Excel file from the response content
excel_data = io.BytesIO(response.content)
df = pd.read_excel(excel_data)
print("Successfully loaded data from GitHub")
return df
except Exception as e:
print(f"Error loading data from GitHub: {e}")
# Fallback to default data if GitHub fetch fails
return pd.DataFrame({
'العيادات': ['عيادة الأسنان', 'عيادة الباطنة', 'عيادة العظام', 'عيادة الأطفال'],
'الدكتور': ['د. أحمد محمد', 'د. محمد علي', 'د. علي حسن', 'د. سارة أحمد'],
'الأيام': ['السبت والاثنين', 'الأحد والثلاثاء', 'الاثنين والأربعاء', 'الثلاثاء والخميس'],
'سعر الكشف': ['100 جنيه', '150 جنيه', '120 جنيه', '130 جنيه']
})
# Load the hospital data
print("Loading hospital data...")
df = load_hospital_data()
# Q&A data for lab tests and equipment
data = {
"السؤال": [
"ما هي مواعيد معمل التحاليل ؟", "ما هي المده المستغرقه لعمل التحاليل ؟",
"ما هي انواع التحاليل الموجوده و المتوفره ؟", "هل يوجد تحليل صوره دم ؟",
"ماهي تحاليل صوره الدم ؟", "ما هي تحاليل السكر ؟", "ما هي تحاليل وظائف الكبد ؟",
"ما هي تحاليل وظائف الكلي ؟", "ما هي تحاليل البول و البراز ؟",
"ما هي تحاليل الدهون ؟", "ما هي تحاليل الألتهابات و الروماتيزم ؟",
"ما هي تحاليل الفيروسات ؟", "ما هي تحاليل الغده الدرقيه ؟",
"هل يوجد حشو اسنان ؟", "هل يوجد جهاز سونار ؟", "هل يوجد اجهزه تنفس اصطناعي ؟",
"هل يوجد قياس نظر ؟", "ما هي الاجهزه المتاحه في عياده الرمد ؟",
"هل يوجد قياس ضغط ؟", "هل يوجد سونار ؟", "هل يوجد رسم قلب ؟"
],
"الجواب": [
"طول ايام الاسبوع من 9 صباحا الي 9 مسائا", "من 24 ساعه الي 48 ساعه",
"تحاليل صوره الدم، تحاليل سكر، تحاليل وظائف الكبد، تحاليل وظائف الكلي",
"نعم يوجد جميع انواع التحاليل بالمستشفي", "CBC، Hb%(Heamoglobin)، Blood Group، Rh",
"Rbs سكر عشوائي، سكر صائم FBS، PPbs سكر فاطر", "ALT(GPT)، AST(GOT)، Billirubin",
"Ceatinin الكرياتنين، Urea اليوريا، Urine البول، Uric acid اليوريك اسد",
"Urine البول، Stool البراز، جرثومه المعده في البراز", "Cholesterol كوليسترول، Triglyceride الدهون الثلاثيه",
"CRP، ASOT", "HCV Ab، GBS Ag، HIC Ab", "Tsh، T3، t4",
"نعم يوجد حشو أسنان", "نعم يوجد جهاز سونار", "نعم يوجد أجهزة تنفس إصطناعي",
"نعم يوجد قياس نظر", "جهاز قاع العين، جهاز قياس النظر، جهاز الكشف من الحساسية والالتهابات",
"نعم يوجد قياس ضغط", "نعم يوجد سونار", "نعم يوجد رسم قلب"
]
}
qa_data = pd.DataFrame(data)
# Medical knowledge base
medical_kb = {
"الجفاف": "في حالة الشعور بالجفاف: 1- شرب الكثير من السوائل 2- تناول الأطعمة الغنية بالماء 3- تجنب التعرض المباشر للشمس 4- استشارة الطبيب إذا استمرت الأعراض",
"الصداع": "لعلاج الصداع: 1- الراحة في مكان هادئ 2- شرب الماء بكثرة 3- تناول مسكن خفيف 4- تجنب الضوء القوي والضوضاء",
"التعب": "للتغلب على التعب: 1- الحصول على قسط كافٍ من النوم 2- تناول غذاء صحي متوازن 3- ممارسة تمارين خفيفة 4- تجنب الإجهاد",
"الحمى": "عند الإصابة بالحمى: 1- الراحة التامة 2- شرب السوائل بكثرة 3- خفض درجة الحرارة بالكمادات 4- استشارة الطبيب إذا تجاوزت 39 درجة",
"السعال": "لتخفيف السعال: 1- شرب الماء الدافئ مع العسل 2- استخدام مرطب الهواء 3- تجنب المثيرات 4- الراحة وتناول الأدوية المناسبة",
"ألم المعدة": "لعلاج ألم المعدة: 1- تجنب الأطعمة الدهنية والحارة 2- تناول وجبات خفيفة 3- شرب مشروبات دافئة كاليانسون 4- استشارة الطبيب إذا استمر الألم",
"الإسهال": "لعلاج الإسهال: 1- شرب محلول معالجة الجفاف 2- تجنب الأطعمة الدسمة 3- تناول وجبات خفيفة وسهلة الهضم 4- مراجعة الطبيب إذا استمر لأكثر من يومين",
"الإمساك": "لعلاج الإمساك: 1- تناول الألياف مثل الخضروات والفواكه 2- شرب الماء بكثرة 3- ممارسة النشاط البدني 4- استخدام ملينات طبيعية إذا لزم الأمر",
"الزكام": "لعلاج الزكام: 1- الراحة 2- شرب السوائل الساخنة 3- استخدام بخاخات الأنف 4- تجنب البرد والتيارات الهوائية",
"ألم الظهر": "لتخفيف ألم الظهر: 1- تجنب الجلوس لفترات طويلة 2- ممارسة تمارين التمدد 3- استخدام كمادات دافئة 4- مراجعة الطبيب في حال استمرار الألم"
}
# Initialize models and embeddings
print("Loading Arabic model and tokenizer...")
try:
model_id = "aubmindlab/bert-base-arabertv2"
tokenizer = AutoTokenizer.from_pretrained(model_id)
model = AutoModelForSequenceClassification.from_pretrained(model_id)
print("Arabic model loaded successfully")
except Exception as e:
print(f"Warning: Could not load Arabic model: {e}")
tokenizer = None
model = None
print("Loading sentence transformer...")
try:
embedder = SentenceTransformer("sentence-transformers/all-MiniLM-L6-v2")
print("Sentence transformer loaded successfully")
except Exception as e:
print(f"Error loading sentence transformer: {e}")
embedder = None
# Prepare passages from hospital data
passages = []
for _, row in df.iterrows():
if pd.isna(row['الدكتور']) and pd.isna(row['العيادات']):
continue
text = f"العيادة: {row['العيادات']}، الدكتور: {row['الدكتور']}، الأيام: {row['الأيام']}، السعر: {row['سعر الكشف']}"
passages.append(text)
# Create embeddings for passages
if embedder:
try:
corpus_embeddings = embedder.encode(passages, convert_to_tensor=True)
print("Corpus embeddings created successfully")
except Exception as e:
print(f"Error creating embeddings: {e}")
corpus_embeddings = None
else:
corpus_embeddings = None
def check_lab_or_radiology(question):
keywords = ['أشعة', 'تحاليل', 'رنين', 'سونار', 'تحليل', 'مختبر', 'معمل']
if any(word in question for word in keywords):
try:
matches = get_close_matches(question, qa_data['السؤال'].tolist(), n=1, cutoff=0.5)
if matches:
matched_q = matches[0]
answer = qa_data[qa_data['السؤال'] == matched_q]['الجواب'].values[0]
return answer
except Exception as e:
print(f"Error in lab/radiology check: {e}")
return None
def answer_question_from_excel(user_question, k=3):
# First check if it's a medical symptom question
for symptom, advice in medical_kb.items():
if symptom in user_question or any(word in user_question for word in ["اشعر", "اعاني", "الم", "وجع", "مريض"]):
return f"🩺 **الرد:** {advice}\n\n⚠️ **ملاحظة هامة:** هذه النصائح عامة، يرجى استشارة الطبيب للتشخيص الدقيق."
# Then check in qa_data for lab tests and equipment
qa_answer = check_lab_or_radiology(user_question)
if qa_answer:
return f"💡 **الرد:** {qa_answer}"
# Define clinic keywords with variations
clinic_mapping = {
"عيادة الباطنة": ["باطنة", "الباطنة", "باطنه"],
"عيادة الجلدية": ["جلد", "جلدية", "الجلدية"],
"عيادة المسالك": ["مسالك", "المسالك", "مسالك بولية"],
"عيادة النساء": ["نسا", "نساء", "توليد", "ولادة"],
"عيادة الأنف والأذن": ["انف", "اذن", "حنجرة", "الأنف", "الأذن"],
"عيادة الرمد": ["رمد", "الرمد", "عيون", "العيون"],
"عيادة الأسنان": ["اسنان", "الاسنان", "الأسنان", "سنان"],
"الحضانة": ["حضان", "حضانة", "الحضانة", "حضانات"],
"المعمل": ["معمل", "المعمل", "تحاليل", "مختبر"],
"عيادة الأطفال": ["اطفال", "الاطفال", "الأطفال"],
"عيادة الجهاز الهضمي": ["هضم", "هضمي", "الجهاز الهضمي"],
"عيادة التخاطب": ["تخاطب", "التخاطب", "نطق"]
}
# Check for specific clinic mentions
target_clinic = None
for clinic, keywords in clinic_mapping.items():
if any(keyword in user_question for keyword in keywords):
target_clinic = clinic
break
# If a specific clinic is mentioned, show all information for that clinic
if target_clinic:
clinic_info = [p for p in passages if target_clinic in p]
if clinic_info:
return f"🏥 **الرد:** \n" + "\n".join(clinic_info)
# For questions about doctors or clinics
if any(word in user_question for word in ["عيادة", "عيادات", "دكتور", "دكاترة", "دكتورة", "مواعيد"]):
# Check if asking about a specific type of clinic
for clinic_type in ["الأسنان", "الباطنة", "الجلدية", "المسالك", "النساء", "الأنف", "الرمد", "الحضانة", "المعمل", "الأطفال", "الجهاز", "التخاطب"]:
if clinic_type in user_question:
clinic_info = [p for p in passages if clinic_type in p]
if clinic_info:
return f"🏥 **الرد:** \n" + "\n".join(clinic_info)
# If no specific clinic type mentioned, return all clinic information
return f"💡 **الرد:** \n" + "\n".join([p for p in passages if 'عيادة' in p])
# If no specific clinic found, use semantic search if available
if embedder and corpus_embeddings is not None:
try:
question_embedding = embedder.encode(user_question, convert_to_tensor=True)
hits = util.semantic_search(question_embedding, corpus_embeddings, top_k=k)
matched_passages = [passages[hit['corpus_id']] for hit in hits[0]]
if matched_passages:
hospital_info = "\n".join(matched_passages)
return f"💡 **الرد:** {hospital_info}"
except Exception as e:
print(f"Error in semantic search: {e}")
# If no match found in any source, return a helpful message
return f"💡 **الرد:** عذراً، لا يمكنني العثور على إجابة محددة لسؤالك. يرجى استشارة الطبيب للحصول على المشورة الطبية المناسبة."
def answer_question(user_question):
try:
answer = check_lab_or_radiology(user_question)
if answer:
return f"💡 **الرد:** {answer}"
return answer_question_from_excel(user_question)
except Exception as e:
return f"⚠️ خطأ: {str(e)}"
def ask_question(question):
"""
Function to handle question answering with error handling
"""
try:
if not question or question.strip() == "":
return "❌ خطأ: السؤال مطلوب"
answer = answer_question(question.strip())
return answer
except Exception as e:
return f"❌ خطأ: {str(e)}"
# Create Gradio interface
with gr.Blocks(
title="نظام الأسئلة والأجوبة الطبي",
theme=gr.themes.Soft(),
css="""
.gradio-container {
font-family: 'Arial', sans-serif;
direction: rtl;
text-align: right;
}
.gr-button {
background: linear-gradient(45deg, #4CAF50, #45a049);
color: white;
font-weight: bold;
}
.gr-textbox {
text-align: right;
direction: rtl;
}
"""
) as demo:
gr.Markdown(
"""
# 🏥 نظام الأسئلة والأجوبة الطبي
### اسأل أي سؤال واحصل على إجابة ذكية!
يمكنك السؤال عن:
- 🏥 مواعيد العيادات والأطباء
- 🧪 التحاليل الطبية والمعمل
- 🩺 النصائح الطبية العامة
- 📋 أسعار الكشف والخدمات
""",
elem_id="header"
)
with gr.Row():
with gr.Column(scale=4):
question_input = gr.Textbox(
label="سؤالك",
placeholder="اكتب سؤالك هنا...",
lines=3,
text_align="right",
rtl=True
)
with gr.Column(scale=1):
submit_btn = gr.Button(
"اسأل السؤال",
variant="primary",
size="lg"
)
answer_output = gr.Textbox(
label="الإجابة",
lines=10,
interactive=False,
text_align="right",
rtl=True
)
# Example questions
gr.Examples(
examples=[
["ما هي مواعيد عيادة الأسنان؟"],
["هل يوجد تحليل صورة دم؟"],
["علاج الحمى"],
["مين دكاترة الأطفال وميعادهم؟"],
["ما هي تحاليل السكر؟"]
],
inputs=question_input,
label="أمثلة على الأسئلة"
)
# Set up the interaction
submit_btn.click(
fn=ask_question,
inputs=question_input,
outputs=answer_output
)
# Also allow Enter key to submit
question_input.submit(
fn=ask_question,
inputs=question_input,
outputs=answer_output
)
if __name__ == "__main__":
print("Starting Hospital Q&A System...")
# Launch the Gradio app
demo.launch(
server_name="0.0.0.0", # Equivalent to Flask's host='0.0.0.0'
server_port=7860, # Default Gradio port (you can change to 5000 if preferred)
share=False, # Set to True if you want a public link
debug=True,
show_error=True
)