Spaces:
Sleeping
Sleeping
app and requirements files
Browse files- app.py +132 -0
- requirements.txt +0 -0
app.py
ADDED
@@ -0,0 +1,132 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import gradio as gr
|
2 |
+
import json
|
3 |
+
import os
|
4 |
+
import re
|
5 |
+
import logging
|
6 |
+
from datetime import datetime
|
7 |
+
from transformers import pipeline
|
8 |
+
import google.generativeai as genai
|
9 |
+
|
10 |
+
# Configure Gemini API
|
11 |
+
GEMINI_API_KEY = "AIzaSyBxpTHcJP3dmR9Pqppp4zmc2Tfut6nic6A"
|
12 |
+
genai.configure(api_key=GEMINI_API_KEY)
|
13 |
+
model = genai.GenerativeModel(model_name="models/gemini-2.0-flash")
|
14 |
+
|
15 |
+
# NER pipeline
|
16 |
+
NER_MODEL = "raynardj/ner-disease-ncbi-bionlp-bc5cdr-pubmed"
|
17 |
+
ers = pipeline(task="ner", model=NER_MODEL, tokenizer=NER_MODEL)
|
18 |
+
|
19 |
+
# Chat history file
|
20 |
+
CHAT_RECORD_FILE = "chat_records.json"
|
21 |
+
|
22 |
+
def load_records():
|
23 |
+
if os.path.exists(CHAT_RECORD_FILE):
|
24 |
+
with open(CHAT_RECORD_FILE, "r") as f:
|
25 |
+
return json.load(f)
|
26 |
+
return []
|
27 |
+
|
28 |
+
def save_record(chat_history):
|
29 |
+
records = load_records()
|
30 |
+
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
31 |
+
records.append({"timestamp": timestamp, "history": chat_history})
|
32 |
+
with open(CHAT_RECORD_FILE, "w") as f:
|
33 |
+
json.dump(records, f, indent=2)
|
34 |
+
|
35 |
+
health_keywords = [
|
36 |
+
"fever", "cold", "headache", "pain", "diabetes", "pressure", "bp", "covid",
|
37 |
+
"infection", "symptom", "cancer", "flu", "aids", "allergy", "disease", "vomit", "asthma",
|
38 |
+
"medicine", "tablet", "ill", "sick", "nausea", "health", "injury", "cough", "treatment",
|
39 |
+
"doctor", "hospital", "clinic", "vaccine", "antibiotic", "therapy", "mental health", "stress",
|
40 |
+
"anxiety", "depression", "diet", "nutrition", "fitness", "exercise", "weight loss", "cholesterol",
|
41 |
+
"thyroid", "migraine", "burn", "fracture", "wound", "emergency", "blood sugar", "sugar", "heart", "lungs"
|
42 |
+
]
|
43 |
+
|
44 |
+
def is_health_related(text):
|
45 |
+
return any(re.search(rf"\\b{re.escape(word)}\\b", text.lower()) for word in health_keywords)
|
46 |
+
|
47 |
+
def extract_diseases(text):
|
48 |
+
entities = ers(text)
|
49 |
+
return set(ent['word'] for ent in entities if 'disease' in ent.get('entity', '').lower())
|
50 |
+
|
51 |
+
def highlight_diseases(text):
|
52 |
+
diseases = extract_diseases(text)
|
53 |
+
for disease in diseases:
|
54 |
+
text = re.sub(fr"\\b({re.escape(disease)})\\b", r"<mark>\\1</mark>", text, flags=re.IGNORECASE)
|
55 |
+
return text
|
56 |
+
|
57 |
+
def ask_gemini(prompt):
|
58 |
+
try:
|
59 |
+
response = model.generate_content(prompt)
|
60 |
+
return response.text.strip()
|
61 |
+
except Exception as e:
|
62 |
+
logging.error(e)
|
63 |
+
return "⚠️ An unexpected error occurred."
|
64 |
+
|
65 |
+
def respond(name, age, gender, topic, user_input, history):
|
66 |
+
chat_history = history or []
|
67 |
+
chat_history.append(("You", user_input))
|
68 |
+
|
69 |
+
if is_health_related(user_input):
|
70 |
+
if not (name and age and gender):
|
71 |
+
response = "⚠️ Please fill in your name, age, and gender."
|
72 |
+
elif not age.isdigit() or not (0 <= int(age) <= 120):
|
73 |
+
response = "⚠️ Please enter a valid age (0-120)."
|
74 |
+
else:
|
75 |
+
prompt = f"""
|
76 |
+
You are a helpful AI healthcare assistant.
|
77 |
+
Provide simple, safe, general health-related answers without diagnoses or prescriptions.
|
78 |
+
|
79 |
+
User Info:
|
80 |
+
Name: {name}
|
81 |
+
Age: {age}
|
82 |
+
Gender: {gender}
|
83 |
+
|
84 |
+
Topic: {topic}
|
85 |
+
|
86 |
+
User's Question: {user_input}
|
87 |
+
"""
|
88 |
+
response = ask_gemini(prompt)
|
89 |
+
else:
|
90 |
+
prompt = f"""
|
91 |
+
You are a friendly, polite assistant.
|
92 |
+
Respond naturally and supportively.
|
93 |
+
|
94 |
+
Topic: {topic}
|
95 |
+
|
96 |
+
User's Message:
|
97 |
+
{user_input}
|
98 |
+
"""
|
99 |
+
response = ask_gemini(prompt)
|
100 |
+
|
101 |
+
chat_history.append(("Gemini", response))
|
102 |
+
save_record(chat_history)
|
103 |
+
|
104 |
+
# Format display with highlighting
|
105 |
+
chat_display = "\n".join(
|
106 |
+
f"<b>{sender}:</b> {highlight_diseases(msg) if sender != 'You' else msg}"
|
107 |
+
for sender, msg in chat_history
|
108 |
+
)
|
109 |
+
return chat_display, chat_history
|
110 |
+
|
111 |
+
def export_json(history):
|
112 |
+
return json.dumps(history, indent=2)
|
113 |
+
|
114 |
+
with gr.Blocks(css="mark { background-color: #ffeb3b; font-weight: bold; }") as demo:
|
115 |
+
gr.Markdown("# 🩺 Gemini Healthcare Assistant")
|
116 |
+
|
117 |
+
with gr.Accordion("User Info", open=True):
|
118 |
+
name = gr.Textbox(label="Name")
|
119 |
+
age = gr.Textbox(label="Age")
|
120 |
+
gender = gr.Dropdown(["Male", "Female", "Other"], label="Gender")
|
121 |
+
topic = gr.Radio(["General", "Mental Health", "Diet", "Fitness", "Stress"], label="Topic", value="General")
|
122 |
+
|
123 |
+
chat = gr.Textbox(label="Ask something", placeholder="Type your question here")
|
124 |
+
output = gr.HTML()
|
125 |
+
state = gr.State([])
|
126 |
+
|
127 |
+
btn = gr.Button("💬 Send")
|
128 |
+
btn.click(fn=respond, inputs=[name, age, gender, topic, chat, state], outputs=[output, state])
|
129 |
+
|
130 |
+
gr.File(label="⬇️ Export Chat as JSON", value=export_json, interactive=True, file_types=[".json"])
|
131 |
+
|
132 |
+
demo.launch()
|
requirements.txt
ADDED
Binary file (102 Bytes). View file
|
|