Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -1,138 +1,155 @@
|
|
| 1 |
import gradio as gr
|
| 2 |
import os
|
| 3 |
import requests
|
|
|
|
| 4 |
|
| 5 |
# Mistral API setup
|
| 6 |
-
MISTRAL_API_KEY = os.getenv("MISTRAL_API_KEY", "your_api_key_here")
|
| 7 |
MISTRAL_API_URL = "https://api.mistral.ai/v1/chat/completions"
|
| 8 |
|
| 9 |
-
|
| 10 |
-
|
| 11 |
-
|
| 12 |
-
"
|
| 13 |
-
"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 14 |
}
|
|
|
|
| 15 |
|
| 16 |
-
|
| 17 |
-
|
| 18 |
-
|
| 19 |
-
|
| 20 |
-
|
| 21 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 22 |
|
|
|
|
|
|
|
| 23 |
try:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 24 |
response = requests.post(MISTRAL_API_URL, headers=headers, json=payload, timeout=10)
|
| 25 |
response.raise_for_status()
|
| 26 |
return response.json()['choices'][0]['message']['content']
|
| 27 |
-
except
|
| 28 |
-
return
|
| 29 |
-
except Exception as e:
|
| 30 |
-
return f"An unexpected error occurred. Please try rephrasing your question."
|
| 31 |
-
|
| 32 |
-
def generate_medical_response(name, message):
|
| 33 |
-
"""Generate structured medical response"""
|
| 34 |
-
prompt = f"""You are Dr. Alex, an experienced physician. {name} asks: "{message}"
|
| 35 |
|
| 36 |
-
|
| 37 |
-
|
| 38 |
-
|
| 39 |
-
|
|
|
|
|
|
|
| 40 |
|
| 41 |
-
|
| 42 |
-
|
| 43 |
-
|
| 44 |
-
|
| 45 |
|
| 46 |
-
[
|
| 47 |
-
-
|
| 48 |
-
|
|
|
|
| 49 |
|
| 50 |
-
|
| 51 |
-
- Symptoms that require immediate medical attention
|
| 52 |
|
| 53 |
-
|
| 54 |
-
|
| 55 |
-
|
| 56 |
|
| 57 |
-
|
| 58 |
-
|
|
|
|
| 59 |
|
| 60 |
-
|
| 61 |
|
| 62 |
-
|
| 63 |
-
|
| 64 |
-
message_lower = message.lower()
|
| 65 |
-
|
| 66 |
-
# Simple greetings
|
| 67 |
-
if any(word in message_lower for word in ['hello', 'hi', 'hey']):
|
| 68 |
-
return f"""Hello {name}! I'm Dr. Alex. How can I assist you today?
|
| 69 |
|
| 70 |
-
|
| 71 |
-
|
| 72 |
-
|
| 73 |
-
|
| 74 |
-
|
| 75 |
-
|
| 76 |
-
|
| 77 |
-
|
| 78 |
-
# Medical responses
|
| 79 |
-
return generate_medical_response(name, message)
|
| 80 |
|
| 81 |
# Gradio Interface
|
| 82 |
-
with gr.Blocks(title="Dr. Alex
|
| 83 |
-
gr.Markdown("#
|
|
|
|
| 84 |
|
| 85 |
-
|
| 86 |
-
|
|
|
|
|
|
|
|
|
|
| 87 |
|
| 88 |
-
|
| 89 |
-
|
| 90 |
-
|
| 91 |
-
|
| 92 |
-
|
| 93 |
-
|
| 94 |
-
|
| 95 |
-
|
| 96 |
-
|
| 97 |
-
|
| 98 |
-
|
| 99 |
-
|
| 100 |
-
|
| 101 |
-
with gr.TabItem("Structured Symptom Checker"):
|
| 102 |
-
gr.Markdown(f"## {name.value}, let's thoroughly evaluate your symptoms")
|
| 103 |
-
with gr.Row():
|
| 104 |
-
with gr.Column():
|
| 105 |
-
age = gr.Number(label="Your Age", minimum=1, maximum=120)
|
| 106 |
-
gender = gr.Radio(choices=["Male", "Female", "Other"], label="Gender")
|
| 107 |
-
symptoms = gr.Textbox(label="Describe your symptoms in detail", lines=3,
|
| 108 |
-
placeholder="Include location, nature of pain, triggers, etc.")
|
| 109 |
-
duration = gr.Dropdown(
|
| 110 |
-
choices=["Less than 24 hours", "1-3 days", "4-7 days", "1-2 weeks", "2-4 weeks", "More than 1 month"],
|
| 111 |
-
label="Duration of symptoms"
|
| 112 |
-
)
|
| 113 |
-
severity = gr.Slider(1, 10, step=1, label="Pain/Severity level (1-10)")
|
| 114 |
-
aggravating_factors = gr.Textbox(label="What makes it worse?", lines=2)
|
| 115 |
-
relieving_factors = gr.Textbox(label="What provides relief?", lines=2)
|
| 116 |
-
analyze_btn = gr.Button("Get Detailed Medical Advice", variant="primary")
|
| 117 |
-
|
| 118 |
-
with gr.Column():
|
| 119 |
-
analysis_output = gr.Textbox(label="Dr. Alex's Professional Evaluation", lines=15, interactive=False)
|
| 120 |
-
|
| 121 |
-
analyze_btn.click(
|
| 122 |
-
lambda age, gender, symptoms, duration, severity, aggravating, relieving: generate_medical_response(
|
| 123 |
-
name.value,
|
| 124 |
-
f"As a {age}-year-old {gender}, I've had: {symptoms} for {duration}. Severity: {severity}/10. Gets worse with {aggravating} and better with {relieving}."
|
| 125 |
-
),
|
| 126 |
-
inputs=[age, gender, symptoms, duration, severity, aggravating_factors, relieving_factors],
|
| 127 |
-
outputs=analysis_output
|
| 128 |
)
|
| 129 |
|
| 130 |
-
gr.Markdown("""
|
| 131 |
-
<div style='background:#f8f9fa;padding:20px;border-radius:10px;margin-top:20px;'>
|
| 132 |
-
<h3>Important Disclaimer</h3>
|
| 133 |
-
<p>This AI provides general health information only, not medical advice. Always consult a qualified healthcare provider for personal medical concerns. In emergencies, contact your local emergency services immediately.</p>
|
| 134 |
-
</div>
|
| 135 |
-
""")
|
| 136 |
-
|
| 137 |
-
# Launch app
|
| 138 |
demo.launch()
|
|
|
|
| 1 |
import gradio as gr
|
| 2 |
import os
|
| 3 |
import requests
|
| 4 |
+
from datetime import datetime
|
| 5 |
|
| 6 |
# Mistral API setup
|
| 7 |
+
MISTRAL_API_KEY = os.getenv("MISTRAL_API_KEY", "your_api_key_here")
|
| 8 |
MISTRAL_API_URL = "https://api.mistral.ai/v1/chat/completions"
|
| 9 |
|
| 10 |
+
# Local medical knowledge base
|
| 11 |
+
MEDICAL_KNOWLEDGE = {
|
| 12 |
+
"headache": {
|
| 13 |
+
"assessment": "Could be tension-type, migraine, or other common headache",
|
| 14 |
+
"recommendations": [
|
| 15 |
+
"Rest in a quiet, dark room",
|
| 16 |
+
"Apply cold compress to forehead",
|
| 17 |
+
"Hydrate well (at least 8 glasses water/day)",
|
| 18 |
+
"Try gentle neck stretches",
|
| 19 |
+
"Consider OTC pain relievers (ibuprofen 200-400mg or paracetamol 500mg)"
|
| 20 |
+
],
|
| 21 |
+
"warnings": [
|
| 22 |
+
"If sudden/severe 'thunderclap' headache",
|
| 23 |
+
"If with fever, stiff neck, or confusion",
|
| 24 |
+
"If following head injury"
|
| 25 |
+
]
|
| 26 |
+
},
|
| 27 |
+
"fever": {
|
| 28 |
+
"assessment": "Common symptom of infection or inflammation",
|
| 29 |
+
"recommendations": [
|
| 30 |
+
"Rest and increase fluid intake",
|
| 31 |
+
"Use light clothing and keep room cool",
|
| 32 |
+
"Sponge with lukewarm water if uncomfortable",
|
| 33 |
+
"Paracetamol 500mg every 6 hours (max 4 doses/day)",
|
| 34 |
+
"Monitor temperature every 4 hours"
|
| 35 |
+
],
|
| 36 |
+
"warnings": [
|
| 37 |
+
"Fever >39°C lasting >3 days",
|
| 38 |
+
"If with rash, difficulty breathing, or seizures",
|
| 39 |
+
"In infants <3 months with any fever"
|
| 40 |
+
]
|
| 41 |
+
},
|
| 42 |
+
"sore throat": {
|
| 43 |
+
"assessment": "Often viral, but could be strep throat",
|
| 44 |
+
"recommendations": [
|
| 45 |
+
"Gargle with warm salt water 3-4 times daily",
|
| 46 |
+
"Drink warm liquids (tea with honey)",
|
| 47 |
+
"Use throat lozenges",
|
| 48 |
+
"Stay hydrated",
|
| 49 |
+
"Rest your voice"
|
| 50 |
+
],
|
| 51 |
+
"warnings": [
|
| 52 |
+
"Difficulty swallowing or breathing",
|
| 53 |
+
"White patches on tonsils",
|
| 54 |
+
"Fever >38.5°C with throat pain"
|
| 55 |
+
]
|
| 56 |
}
|
| 57 |
+
}
|
| 58 |
|
| 59 |
+
def get_local_advice(symptom):
|
| 60 |
+
"""Get structured medical advice from local knowledge base"""
|
| 61 |
+
symptom_lower = symptom.lower()
|
| 62 |
+
for key in MEDICAL_KNOWLEDGE:
|
| 63 |
+
if key in symptom_lower:
|
| 64 |
+
knowledge = MEDICAL_KNOWLEDGE[key]
|
| 65 |
+
response = "🔍 [Assessment]\n- " + knowledge["assessment"] + "\n\n"
|
| 66 |
+
response += "💡 [Self-Care Recommendations]\n" + "\n".join(["• " + item for item in knowledge["recommendations"]]) + "\n\n"
|
| 67 |
+
response += "⚠️ [When to Seek Medical Care]\n" + "\n".join(["• " + item for item in knowledge["warnings"]]) + "\n\n"
|
| 68 |
+
response += "📅 [Follow-up]\n• Re-evaluate in 2-3 days if not improving\n• See doctor if symptoms worsen or persist beyond 5 days"
|
| 69 |
+
return response
|
| 70 |
+
return None
|
| 71 |
|
| 72 |
+
def query_mistral(prompt):
|
| 73 |
+
"""Try API first, fallback to local knowledge"""
|
| 74 |
try:
|
| 75 |
+
headers = {"Authorization": f"Bearer {MISTRAL_API_KEY}", "Content-Type": "application/json"}
|
| 76 |
+
payload = {
|
| 77 |
+
"model": "mistral-tiny",
|
| 78 |
+
"messages": [{"role": "user", "content": prompt}],
|
| 79 |
+
"temperature": 0.7,
|
| 80 |
+
"max_tokens": 1024
|
| 81 |
+
}
|
| 82 |
response = requests.post(MISTRAL_API_URL, headers=headers, json=payload, timeout=10)
|
| 83 |
response.raise_for_status()
|
| 84 |
return response.json()['choices'][0]['message']['content']
|
| 85 |
+
except:
|
| 86 |
+
return None
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 87 |
|
| 88 |
+
def generate_response(name, message):
|
| 89 |
+
"""Generate medical response with fallback"""
|
| 90 |
+
# First try local knowledge base
|
| 91 |
+
local_response = get_local_advice(message)
|
| 92 |
+
if local_response:
|
| 93 |
+
return f"Hello {name},\n\n{local_response}\n\nWishing you good health,\nDr. Alex"
|
| 94 |
|
| 95 |
+
# Then try API
|
| 96 |
+
prompt = f"""As Dr. Alex, provide structured advice for {name} who reports: "{message}"
|
| 97 |
+
|
| 98 |
+
Format response with these sections:
|
| 99 |
|
| 100 |
+
[Assessment] - Brief professional evaluation
|
| 101 |
+
[Self-Care Recommendations] - 3-5 specific actionable steps
|
| 102 |
+
[When to Seek Medical Care] - Clear warning signs
|
| 103 |
+
[Follow-up] - Monitoring advice
|
| 104 |
|
| 105 |
+
Use bullet points, professional yet compassionate tone."""
|
|
|
|
| 106 |
|
| 107 |
+
api_response = query_mistral(prompt)
|
| 108 |
+
if api_response:
|
| 109 |
+
return api_response
|
| 110 |
|
| 111 |
+
# Final fallback
|
| 112 |
+
common_conditions = "\n".join([f"- {cond}" for cond in MEDICAL_KNOWLEDGE.keys()])
|
| 113 |
+
return f"""Hello {name},
|
| 114 |
|
| 115 |
+
I'm currently unable to access detailed medical databases. For general advice:
|
| 116 |
|
| 117 |
+
Common conditions I can advise on:
|
| 118 |
+
{common_conditions}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 119 |
|
| 120 |
+
For immediate concerns:
|
| 121 |
+
• Contact your local healthcare provider
|
| 122 |
+
• In emergencies, call your local emergency number
|
| 123 |
+
|
| 124 |
+
Please try asking about one of these common conditions or consult a healthcare professional.
|
| 125 |
+
|
| 126 |
+
Best regards,
|
| 127 |
+
Dr. Alex"""
|
|
|
|
|
|
|
| 128 |
|
| 129 |
# Gradio Interface
|
| 130 |
+
with gr.Blocks(title="Dr. Alex Medical Advisor", theme=gr.themes.Soft()) as demo:
|
| 131 |
+
gr.Markdown("# 🩺 Dr. Alex - General Health Advisor")
|
| 132 |
+
name = gr.Textbox(label="Your Name", placeholder="Enter your name")
|
| 133 |
|
| 134 |
+
with gr.Tab("Health Consultation"):
|
| 135 |
+
gr.Markdown("## Describe your health concern")
|
| 136 |
+
msg = gr.Textbox(label="Symptoms/Question", lines=3)
|
| 137 |
+
submit_btn = gr.Button("Get Medical Advice")
|
| 138 |
+
output = gr.Textbox(label="Dr. Alex's Advice", lines=15, interactive=False)
|
| 139 |
|
| 140 |
+
submit_btn.click(
|
| 141 |
+
fn=lambda name, msg: generate_response(name, msg),
|
| 142 |
+
inputs=[name, msg],
|
| 143 |
+
outputs=output
|
| 144 |
+
)
|
| 145 |
+
|
| 146 |
+
gr.Markdown("### Common Health Topics")
|
| 147 |
+
with gr.Row():
|
| 148 |
+
for condition in MEDICAL_KNOWLEDGE:
|
| 149 |
+
gr.Button(condition.capitalize()).click(
|
| 150 |
+
fn=lambda name, cond=condition: generate_response(name, cond),
|
| 151 |
+
inputs=[name],
|
| 152 |
+
outputs=output
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 153 |
)
|
| 154 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 155 |
demo.launch()
|