waleedmohd's picture
Update app.py
967751a verified
raw
history blame
9.37 kB
import gradio as gr
from transformers import pipeline
import re
# Load Arabic NLP model for intent classification
intent_classifier_ar = pipeline("text-classification", model="aubmindlab/bert-base-arabertv02")
# Load English NLP model for intent classification
intent_classifier_en = pipeline("text-classification", model="facebook/bart-large-mnli")
# Load language detection model
language_detector = pipeline("text-classification", model="papluca/xlm-roberta-base-language-detection")
# Omdurman National Bank-specific guidelines in Arabic
ONB_GUIDELINES_AR = {
"balance": "يمكنك التحقق من رصيدك عبر الإنترنت أو عبر تطبيق الهاتف الخاص ببنك الوطني.",
"lost_card": "في حالة فقدان البطاقة، اتصل بالرقم 249-123-456-789 فورًا.",
"loan": "شروط القرض تشمل الحد الأدنى للدخل (5000 جنيه سوداني) وتاريخ ائتماني جيد.",
"transfer": "لتحويل الأموال، استخدم تطبيق الهاتف أو الخدمة المصرفية عبر الإنترنت.",
"new_account": "لفتح حساب جديد، قم بزيارة أقرب فرع مع جواز سفرك أو هويتك الوطنية.",
"interest_rates": "أسعار الفائدة على الودائع تتراوح بين 5% إلى 10% سنويًا.",
"branches": "فروعنا موجودة في أم درمان، الخرطوم، وبورتسودان. زيارة موقعنا للتفاصيل.",
"working_hours": "ساعات العمل من 8 صباحًا إلى 3 مساءً من الأحد إلى الخميس.",
"contact": "الاتصال بنا على الرقم 249-123-456-789 أو عبر البريد الإلكتروني [email protected]."
}
# Omdurman National Bank-specific guidelines in English
ONB_GUIDELINES_EN = {
"balance": "You can check your balance online or via the ONB mobile app.",
"lost_card": "In case of a lost card, call 249-123-456-789 immediately.",
"loan": "Loan requirements include minimum income (5000 SDG) and good credit history.",
"transfer": "To transfer funds, use the mobile app or online banking service.",
"new_account": "To open a new account, visit your nearest branch with your passport or national ID.",
"interest_rates": "Interest rates on deposits range from 5% to 10% annually.",
"branches": "Our branches are located in Omdurman, Khartoum, and Port Sudan. Visit our website for details.",
"working_hours": "Working hours are from 8 AM to 3 PM, Sunday to Thursday.",
"contact": "Contact us at 249-123-456-789 or via email at [email protected]."
}
# Map intents to responses
INTENT_KEYWORDS = {
"balance": ["balance", "رصيد", "حساب"],
"lost_card": ["lost", "card", "stolen", "فقدت", "بطاقة", "مسروقة"],
"loan": ["loan", "borrow", "قرض", "استدانة"],
"transfer": ["transfer", "send money", "تحويل", "ارسال"],
"new_account": ["account", "open", "حساب", "فتح"],
"interest_rates": ["interest", "rate", "فائدة", "نسبة"],
"branches": ["branch", "location", "فرع", "موقع"],
"working_hours": ["hours", "time", "ساعات", "وقت"],
"contact": ["contact", "phone", "email", "اتصال", "هاتف", "بريد"]
}
def detect_language(text):
# Use Hugging Face language detection model
result = language_detector(text)
language = result[0]['label']
return language
def classify_intent(message: str, language: str):
# Use appropriate classifier based on language
if language == "ar":
# For Arabic
result = intent_classifier_ar(message)
intent = result[0]['label']
else:
# For English
result = intent_classifier_en(message, candidate_labels=list(INTENT_KEYWORDS.keys()))
intent = result["labels"][0]
# Fallback to keyword matching
if intent not in INTENT_KEYWORDS:
for intent_key, keywords in INTENT_KEYWORDS.items():
for keyword in keywords:
if re.search(r'\b' + re.escape(keyword.lower()) + r'\b', message.lower()):
return intent_key
return "unknown"
return intent
def respond(message: str):
if not message.strip():
return {
"ar": "الرجاء كتابة سؤالك.",
"en": "Please type your question."
}
# Detect language
language = detect_language(message)
# If the language is neither Arabic nor English, default to English
if language != "ar" and language != "en":
language = "en"
# Classify the user's intent
intent = classify_intent(message, language)
# Prepare responses in both languages
responses = {
"ar": "",
"en": ""
}
# If intent is recognized, return the corresponding response
if intent != "unknown":
responses["ar"] = ONB_GUIDELINES_AR.get(intent, "عذرًا، لم يتم التعرف على الخيار المحدد.")
responses["en"] = ONB_GUIDELINES_EN.get(intent, "Sorry, the selected option was not recognized.")
else:
# Default response if no intent is matched
ar_options = ", ".join(list(ONB_GUIDELINES_AR.keys()))
en_options = ", ".join(list(ONB_GUIDELINES_EN.keys()))
responses["ar"] = f"عذرًا، لم أفهم سؤالك. الرجاء إعادة الصياغة أو اختيار أحد الخيارات التالية: {ar_options}"
responses["en"] = f"Sorry, I didn't understand your question. Please rephrase or choose one of the following options: {en_options}"
return responses
# Custom CSS for better UI
custom_css = """
.gradio-container {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}
.chat-message {
padding: 1rem;
border-radius: 10px;
margin-bottom: 1rem;
max-width: 80%;
}
.user-message {
background-color: #e6f7ff;
margin-left: auto;
text-align: right;
}
.bot-message {
background-color: #f0f0f0;
margin-right: auto;
text-align: left;
}
.bot-message-ar {
background-color: #f0f0f0;
margin-left: auto;
text-align: right;
}
.header-section {
background-color: #1a5276;
color: white;
padding: 1rem;
border-radius: 10px;
margin-bottom: 1rem;
text-align: center;
}
.footer-section {
font-size: 0.8rem;
text-align: center;
margin-top: 2rem;
color: #666;
}
.lang-selector {
text-align: right;
margin-bottom: 1rem;
}
"""
# Chat interface with enhanced UI
with gr.Blocks(css=custom_css) as demo:
# Store conversation history
state = gr.State(value=[])
# Store selected language
selected_lang = gr.State(value="ar")
with gr.Row(elem_classes="header-section"):
with gr.Column():
gr.Markdown("# Omdurman National Bank | بنك أم درمان الوطني")
gr.Markdown("### Virtual Banking Assistant | المساعد المصرفي الافتراضي")
with gr.Row():
with gr.Column(elem_classes="lang-selector"):
language_btn = gr.Radio(
["العربية", "English"],
value="العربية",
label="Language | اللغة"
)
with gr.Row():
chat_box = gr.Chatbot(elem_id="chatbox", height=400)
with gr.Row():
with gr.Column(scale=8):
text_input = gr.Textbox(
placeholder="Type your question here | اكتب سؤالك هنا",
label="",
elem_id="chat-input"
)
with gr.Column(scale=1):
submit_btn = gr.Button("Send | إرسال", variant="primary")
with gr.Row(elem_classes="footer-section"):
gr.Markdown("© 2025 Omdurman National Bank. All Rights Reserved. | جميع الحقوق محفوظة لبنك أم درمان الوطني ٢٠٢٥ ©")
# Update language state when language is changed
def update_language(lang):
if lang == "العربية":
return "ar"
else:
return "en"
language_btn.change(
fn=update_language,
inputs=language_btn,
outputs=selected_lang
)
# Handle message submission
def on_submit(message, chat_history, lang):
if not message.strip():
return "", chat_history
# Add user message to chat history
chat_history.append([message, None])
# Get response
responses = respond(message)
# Select response based on language
response = responses[lang]
# Update bot response in chat history
chat_history[-1][1] = response
return "", chat_history
# Link inputs and button to response function
submit_btn.click(
fn=on_submit,
inputs=[text_input, chat_box, selected_lang],
outputs=[text_input, chat_box]
)
# Also trigger on Enter key
text_input.submit(
fn=on_submit,
inputs=[text_input, chat_box, selected_lang],
outputs=[text_input, chat_box]
)
if __name__ == "__main__":
demo.launch(
server_name="0.0.0.0",
server_port=7860,
share=True # Enable public link
)