Testing / app.py
DreamStream-1's picture
Update app.py
4a3e857 verified
import os
import gradio as gr
import nltk
import numpy as np
import tflearn
import random
import json
import pickle
from nltk.tokenize import word_tokenize
from nltk.stem.lancaster import LancasterStemmer
from transformers import AutoTokenizer, AutoModelForSequenceClassification, pipeline
import googlemaps
import folium
import torch
# Suppress TensorFlow warnings
os.environ["CUDA_VISIBLE_DEVICES"] = "-1"
os.environ["TF_CPP_MIN_LOG_LEVEL"] = "3"
# Download necessary NLTK resources
nltk.download("punkt")
stemmer = LancasterStemmer()
# Load intents and chatbot training data
with open("intents.json") as file:
intents_data = json.load(file)
with open("data.pickle", "rb") as f:
words, labels, training, output = pickle.load(f)
# Build the chatbot model
net = tflearn.input_data(shape=[None, len(training[0])])
net = tflearn.fully_connected(net, 8)
net = tflearn.fully_connected(net, 8)
net = tflearn.fully_connected(net, len(output[0]), activation="softmax")
net = tflearn.regression(net)
chatbot_model = tflearn.DNN(net)
chatbot_model.load("MentalHealthChatBotmodel.tflearn")
# Hugging Face sentiment and emotion models
tokenizer_sentiment = AutoTokenizer.from_pretrained("cardiffnlp/twitter-roberta-base-sentiment")
model_sentiment = AutoModelForSequenceClassification.from_pretrained("cardiffnlp/twitter-roberta-base-sentiment")
tokenizer_emotion = AutoTokenizer.from_pretrained("j-hartmann/emotion-english-distilroberta-base")
model_emotion = AutoModelForSequenceClassification.from_pretrained("j-hartmann/emotion-english-distilroberta-base")
# Google Maps API Client
gmaps = googlemaps.Client(key=os.getenv("GOOGLE_API_KEY"))
# Helper Functions
def bag_of_words(s, words):
"""Convert user input to bag-of-words vector."""
bag = [0] * len(words)
s_words = word_tokenize(s)
s_words = [stemmer.stem(word.lower()) for word in s_words if word.isalnum()]
for se in s_words:
for i, w in enumerate(words):
if w == se:
bag[i] = 1
return np.array(bag)
def generate_chatbot_response(message, history):
"""Generate chatbot response and maintain conversation history."""
history = history or []
try:
result = chatbot_model.predict([bag_of_words(message, words)])
tag = labels[np.argmax(result)]
response = "I'm sorry, I didn't understand that. πŸ€”"
for intent in intents_data["intents"]:
if intent["tag"] == tag:
response = random.choice(intent["responses"])
break
except Exception as e:
response = f"Error: {e}"
history.append((message, response))
return history, response
def analyze_sentiment(user_input):
"""Analyze sentiment and map to emojis."""
inputs = tokenizer_sentiment(user_input, return_tensors="pt")
with torch.no_grad():
outputs = model_sentiment(**inputs)
sentiment_class = torch.argmax(outputs.logits, dim=1).item()
sentiment_map = ["Negative πŸ˜”", "Neutral 😐", "Positive 😊"]
return f"Sentiment: {sentiment_map[sentiment_class]}"
def detect_emotion(user_input):
"""Detect emotions based on input."""
pipe = pipeline("text-classification", model=model_emotion, tokenizer=tokenizer_emotion)
result = pipe(user_input)
emotion = result[0]["label"].lower().strip()
emotion_map = {
"joy": "Joy 😊",
"anger": "Anger 😠",
"sadness": "Sadness 😒",
"fear": "Fear 😨",
"surprise": "Surprise 😲",
"neutral": "Neutral 😐",
}
return emotion_map.get(emotion, "Unknown πŸ€”"), emotion
def generate_suggestions(emotion):
"""Return relevant suggestions based on detected emotions."""
emotion_key = emotion.lower()
suggestions = {
"joy": [
["Relaxation Techniques", "https://www.helpguide.org/mental-health/meditation/mindful-breathing-meditation"],
["Dealing with Stress", "https://www.helpguide.org/mental-health/anxiety/tips-for-dealing-with-anxiety"],
["Emotional Wellness Toolkit", "https://www.nih.gov/health-information/emotional-wellness-toolkit"],
["Relaxation Video", "https://youtu.be/m1vaUGtyo-A"],
],
"anger": [
["Emotional Wellness Toolkit", "https://www.nih.gov/health-information/emotional-wellness-toolkit"],
["Stress Management Tips", "https://www.health.harvard.edu/health-a-to-z"],
["Dealing with Anger", "https://www.helpguide.org/mental-health/anxiety/tips-for-dealing-with-anxiety"],
["Relaxation Video", "https://youtu.be/MIc299Flibs"],
],
"fear": [
["Mindfulness Practices", "https://www.helpguide.org/mental-health/meditation/mindful-breathing-meditation"],
["Coping with Anxiety", "https://www.helpguide.org/mental-health/anxiety/tips-for-dealing-with-anxiety"],
["Emotional Wellness Toolkit", "https://www.nih.gov/health-information/emotional-wellness-toolkit"],
["Relaxation Video", "https://youtu.be/yGKKz185M5o"],
],
"sadness": [
["Emotional Wellness Toolkit", "https://www.nih.gov/health-information/emotional-wellness-toolkit"],
["Dealing with Anxiety", "https://www.helpguide.org/mental-health/anxiety/tips-for-dealing-with-anxiety"],
["Relaxation Video", "https://youtu.be/-e-4Kx5px_I"],
],
"surprise": [
["Managing Stress", "https://www.health.harvard.edu/health-a-to-z"],
["Coping Strategies", "https://www.helpguide.org/mental-health/anxiety/tips-for-dealing-with-anxiety"],
["Relaxation Video", "https://youtu.be/m1vaUGtyo-A"],
],
}
# Format the output to include HTML anchor tags
formatted_suggestions = [
[title, f'<a href="{link}" target="_blank">{link}</a>'] for title, link in suggestions.get(emotion_key, [["No specific suggestions available.", "#"]])
]
return formatted_suggestions
def get_health_professionals_and_map(location, query):
"""Search nearby healthcare professionals using Google Maps API."""
try:
if not location or not query:
return [], "" # Return empty list if inputs are missing
geo_location = gmaps.geocode(location)
if geo_location:
lat, lng = geo_location[0]["geometry"]["location"].values()
places_result = gmaps.places_nearby(location=(lat, lng), radius=10000, keyword=query)["results"]
professionals = []
map_ = folium.Map(location=(lat, lng), zoom_start=13)
for place in places_result:
# Use a list of values to append each professional
professionals.append([place['name'], place.get('vicinity', 'No address provided')])
folium.Marker(
location=[place["geometry"]["location"]["lat"], place["geometry"]["location"]["lng"]],
popup=f"{place['name']}"
).add_to(map_)
return professionals, map_._repr_html_()
return [], "" # Return empty list if no professionals found
except Exception as e:
return [], "" # Return empty list on exception
# Main Application Logic
def app_function(user_input, location, query, history):
chatbot_history, _ = generate_chatbot_response(user_input, history)
sentiment_result = analyze_sentiment(user_input)
emotion_result, cleaned_emotion = detect_emotion(user_input)
suggestions = generate_suggestions(cleaned_emotion)
professionals, map_html = get_health_professionals_and_map(location, query)
return chatbot_history, sentiment_result, emotion_result, suggestions, professionals, map_html
# CSS Styling
custom_css = """
body {
font-family: 'Roboto', sans-serif;
background-color: #3c6487; /* Set the background color */
color: white;
}
h1 {
background: #ffffff;
color: #000000;
border-radius: 8px;
padding: 10px;
font-weight: bold;
text-align: center;
font-size: 2.5rem;
}
textarea, input {
background: transparent;
color: black;
border: 2px solid orange;
padding: 8px;
font-size: 1rem;
caret-color: black;
outline: none;
border-radius: 8px;
}
textarea:focus, input:focus {
background: transparent;
color: black;
border: 2px solid orange;
outline: none;
}
textarea:hover, input:hover {
background: transparent;
color: black;
border: 2px solid orange;
}
.df-container {
background: white;
color: black;
border: 2px solid orange;
border-radius: 10px;
padding: 10px;
font-size: 14px;
max-height: 400px;
height: auto;
overflow-y: auto;
}
#suggestions-title {
text-align: center !important; /* Ensure the centering is applied */
font-weight: bold !important; /* Ensure bold is applied */
color: white !important; /* Ensure color is applied */
font-size: 4.2rem !important; /* Ensure font size is applied */
margin-bottom: 20px !important; /* Ensure margin is applied */
}
/* Style for the submit button */
.gr-button {
background-color: #ae1c93; /* Set the background color to #ae1c93 */
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1), 0 2px 4px rgba(0, 0, 0, 0.06);
transition: background-color 0.3s ease;
}
.gr-button:hover {
background-color: #8f167b;
}
.gr-button:active {
background-color: #7f156b;
}
"""
# Gradio Application
with gr.Blocks(css=custom_css) as app:
gr.HTML("<h1>🌟 Well-Being Companion</h1>")
with gr.Row():
user_input = gr.Textbox(label="Please Enter Your Message Here")
location = gr.Textbox(label="Please Enter Your Current Location Here")
query = gr.Textbox(label="Please Enter Which Health Professional You Want To Search Nearby")
submit = gr.Button(value="Submit", variant="primary")
chatbot = gr.Chatbot(label="Chat History")
sentiment = gr.Textbox(label="Detected Sentiment")
emotion = gr.Textbox(label="Detected Emotion")
# Adding Suggestions Title with Styled Markdown (Centered and Bold)
gr.Markdown("Suggestions", elem_id="suggestions-title")
suggestions = gr.DataFrame(headers=["Title", "Link"]) # Table for suggestions
professionals = gr.DataFrame(label="Nearby Health Professionals", headers=["Name", "Address"]) # Changed to DataFrame
map_html = gr.HTML(label="Interactive Map")
submit.click(
app_function,
inputs=[user_input, location, query, chatbot],
outputs=[chatbot, sentiment, emotion, suggestions, professionals, map_html],
)
app.launch()