Shresthh03 commited on
Commit
bee1bed
·
verified ·
1 Parent(s): 1b68c82

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +120 -149
app.py CHANGED
@@ -1,165 +1,136 @@
1
- import gradio as gr
2
- import openai
3
- import os
4
  import json
5
  import random
6
  import requests
7
- from transformers import pipeline
8
- from datetime import datetime
9
-
10
- # --- Setup ---
11
- openai.api_key = os.getenv("OPENAI_API_KEY")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
12
 
13
- emotion_classifier = pipeline("text-classification",
14
- model="j-hartmann/emotion-english-distilroberta-base")
 
 
 
 
 
 
 
 
 
 
 
15
 
16
- USER_FILE = "user_data.json"
17
- QUOTE_API = "https://api.quotable.io/random"
18
 
19
- LOCAL_QUOTES = [
20
- "Every sunrise brings new hope. Keep shining.",
21
- "You are capable of more than you realize.",
22
- "Each step, no matter how small, is progress.",
23
- "Difficult roads often lead to beautiful destinations.",
24
- "The best time for new beginnings is now.",
25
- "Your inner light never fades—let it guide you."
26
- ]
27
 
28
- # --- Helper functions ---
29
  def load_user_data():
30
- if os.path.exists(USER_FILE):
31
- with open(USER_FILE, "r") as f:
32
  return json.load(f)
33
- return {}
34
 
35
- def save_user_data(data):
36
- with open(USER_FILE, "w") as f:
37
- json.dump(data, f, indent=2)
38
 
39
- def fetch_quote():
40
- try:
41
- r = requests.get(QUOTE_API, timeout=5)
42
- if r.status_code == 200:
43
- q = r.json()
44
- return f"“{q['content']}” — {q['author']}"
45
- except Exception:
46
- pass
47
- return random.choice(LOCAL_QUOTES)
48
-
49
- def classify_emotion(text):
50
- try:
51
- result = emotion_classifier(text)
52
- return result[0]["label"].lower()
53
- except Exception:
54
- return "neutral"
55
-
56
- def get_color_for_emotion(e):
57
- palette = {
58
- "happy": "#fff59d",
59
- "joy": "#fff59d",
60
- "sad": "#90caf9",
61
- "angry": "#ff8a65",
62
- "calm": "#a5d6a7",
63
- "motivated": "#ffcc80",
64
- "neutral": "#eeeeee",
65
- }
66
- return palette.get(e.lower(), "#f5f5f5")
67
-
68
- # --- Core logic ---
69
- def chat_with_bot(message, name, age, audio=None):
70
- if not message and audio:
71
- # if user spoke instead of typed
72
- import speech_recognition as sr
73
- recognizer = sr.Recognizer()
74
- with sr.AudioFile(audio) as src:
75
- audio_data = recognizer.record(src)
76
- try:
77
- message = recognizer.recognize_google(audio_data)
78
- except Exception:
79
- message = "..."
80
-
81
- if not message:
82
- return "Please say or type something.", None, None
83
-
84
- user_id = "default"
85
- users = load_user_data()
86
- user = users.get(user_id, {"name": name, "age": age, "recent_mood": "neutral"})
87
- emotion = classify_emotion(message)
88
-
89
- # Motivational triggers
90
- if "motivate" in message.lower() or "guidance" in message.lower():
91
- quote = fetch_quote()
92
- user["recent_mood"] = "motivated"
93
- users[user_id] = user
94
- save_user_data(users)
95
- return quote, None, get_color_for_emotion("motivated")
96
-
97
- # Normal empathetic reply
98
- prompt = f"""
99
- You are a warm, empathetic emotional support companion.
100
- The user's name is {name}, age {age}, currently feeling {emotion}.
101
- Reply with kindness, encouragement, and positivity.
102
- Avoid therapy or diagnosis.
103
-
104
- User: {message}
105
- Assistant:
106
- """
107
- try:
108
- response = openai.ChatCompletion.create(
109
  model="gpt-4o-mini",
110
- messages=[{"role": "user", "content": prompt}],
111
- temperature=0.8
 
 
112
  )
113
- reply = response.choices[0].message["content"].strip()
114
- except Exception:
115
- reply = "I'm here for you. Tell me how you’re feeling today."
116
-
117
- # Save user state
118
- user["recent_mood"] = emotion
119
- user["last_active"] = datetime.utcnow().strftime("%Y-%m-%d")
120
- users[user_id] = user
121
- save_user_data(users)
122
-
123
- return reply, reply, get_color_for_emotion(emotion)
124
-
125
- # --- Gradio UI ---
126
- with gr.Blocks(title="Empathetic Voice Chatbot 🌼") as app:
127
- gr.Markdown(
128
- "## 🌼 Empathetic Voice Chatbot\n"
129
- "Speak or type your feelings — your friendly listener will respond with warmth and understanding."
130
- )
131
-
132
- with gr.Row():
133
- name = gr.Textbox(label="Your Name", value="Alex")
134
- age = gr.Number(label="Your Age", value=25)
135
-
136
- chatbox = gr.Textbox(label="Type your message", placeholder="Say something or click record below...")
137
- mic = gr.Audio(sources=["microphone"], type="filepath", label="🎤 Speak here")
138
- output_text = gr.Textbox(label="Assistant's Response")
139
- audio_reply = gr.Audio(label="🔊 Spoken Reply")
140
-
141
- send_btn = gr.Button("Send / Talk 💬")
142
-
143
- def respond(msg, n, a, aud):
144
- text_reply, tts_text, color = chat_with_bot(msg, n, a, aud)
145
- if tts_text:
146
- speech = openai.audio.speech.with_streaming_response.create(
147
- model="gpt-4o-mini-tts",
148
- voice="alloy",
149
- input=tts_text
150
- )
151
- out_path = "reply.mp3"
152
- import requests
153
-
154
- speech = requests.get(speech_url)
155
- with open("speech.mp3", "wb") as f:
156
- f.write(speech.content)
157
  else:
158
- out_path = None
159
- # Dynamically change background color
160
- app.theme = None
161
- return gr.update(value=text_reply), out_path
 
 
 
 
 
 
162
 
163
- send_btn.click(respond, [chatbox, name, age, mic], [output_text, audio_reply])
164
 
165
- app.launch()
 
 
1
+ import os
 
 
2
  import json
3
  import random
4
  import requests
5
+ from datetime import datetime, timedelta
6
+ from flask import Flask, request, jsonify
7
+ from transformers import AutoTokenizer, AutoModelForSequenceClassification
8
+ import torch
9
+ from openai import OpenAI
10
+
11
+ app = Flask(__name__)
12
+
13
+ # Initialize OpenAI client
14
+ client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
15
+
16
+ # Load emotion model
17
+ tokenizer = AutoTokenizer.from_pretrained("j-hartmann/emotion-english-distilroberta-base")
18
+ model = AutoModelForSequenceClassification.from_pretrained("j-hartmann/emotion-english-distilroberta-base")
19
+ emotion_labels = [
20
+ "anger",
21
+ "disgust",
22
+ "fear",
23
+ "joy",
24
+ "neutral",
25
+ "sadness",
26
+ "surprise"
27
+ ]
28
 
29
+ # Motivational / spiritual quotes (non-religious and respectful)
30
+ motivational_quotes = [
31
+ "Believe you can and you’re halfway there.",
32
+ "Every day is a new beginning; take a deep breath and start again.",
33
+ "The only way out is through. You’ve got this.",
34
+ "Storms don’t last forever — keep moving forward.",
35
+ "Even the smallest step in the right direction is progress.",
36
+ "You are stronger than you think and more capable than you realize.",
37
+ "Let your hope, not your hurt, shape your future.",
38
+ "Peace begins the moment you choose to stop fighting yourself.",
39
+ "Light will always find its way through the cracks.",
40
+ "Take things one heartbeat at a time — you are doing enough."
41
+ ]
42
 
43
+ # Path for storing user data
44
+ USER_DATA_FILE = "user_data.json"
45
 
 
 
 
 
 
 
 
 
46
 
 
47
  def load_user_data():
48
+ if os.path.exists(USER_DATA_FILE):
49
+ with open(USER_DATA_FILE, "r") as f:
50
  return json.load(f)
51
+ return {"name": "", "age": "", "last_mood": "", "last_interaction": str(datetime.utcnow()), "missed_days": 0}
52
 
 
 
 
53
 
54
+ def save_user_data(data):
55
+ with open(USER_DATA_FILE, "w") as f:
56
+ json.dump(data, f)
57
+
58
+
59
+ @app.route("/chat", methods=["POST"])
60
+ def respond():
61
+ data = request.get_json()
62
+ message = data.get("message", "")
63
+ user_name = data.get("name", "friend")
64
+ user_age = data.get("age", "unknown")
65
+
66
+ user_data = load_user_data()
67
+
68
+ # Emotion detection
69
+ inputs = tokenizer(message, return_tensors="pt")
70
+ with torch.no_grad():
71
+ outputs = model(**inputs)
72
+ emotion_label = emotion_labels[int(torch.argmax(outputs.logits))]
73
+
74
+ # Motivational or guidance request
75
+ motivational_keywords = ["give me guidance", "i need motivation", "motivate me", "inspire me"]
76
+ if any(kw in message.lower() for kw in motivational_keywords):
77
+ quote = random.choice(motivational_quotes)
78
+ ai_reply = f"Here’s something to lift your spirit, {user_name}: {quote}"
79
+ else:
80
+ # Empathetic chat completion
81
+ system_prompt = f"You are a warm, kind, and empathetic emotional support assistant for {user_name}, age {user_age}. Be comforting and understanding, but not a therapist."
82
+ response = client.chat.completions.create(
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
83
  model="gpt-4o-mini",
84
+ messages=[
85
+ {"role": "system", "content": system_prompt},
86
+ {"role": "user", "content": message},
87
+ ],
88
  )
89
+ ai_reply = response.choices[0].message.content.strip()
90
+
91
+ # Daily check-in system
92
+ last_time = datetime.fromisoformat(user_data.get("last_interaction", str(datetime.utcnow())))
93
+ now = datetime.utcnow()
94
+ days_diff = (now - last_time).days
95
+
96
+ if days_diff >= 1:
97
+ user_data["missed_days"] += days_diff
98
+ else:
99
+ user_data["missed_days"] = 0
100
+
101
+ user_data.update({
102
+ "name": user_name,
103
+ "age": user_age,
104
+ "last_mood": emotion_label,
105
+ "last_interaction": str(now)
106
+ })
107
+ save_user_data(user_data)
108
+
109
+ if user_data["missed_days"] >= 3:
110
+ ai_reply = f"We missed you, {user_name}! Hope you’re okay. Remember, I’m always here to listen 💛"
111
+
112
+ # Optional text-to-speech (non-blocking)
113
+ try:
114
+ speech_url = "https://api.openai.com/v1/audio/speech"
115
+ headers = {"Authorization": f"Bearer {os.getenv('OPENAI_API_KEY')}"}
116
+ payload = {"model": "gpt-4o-mini-tts", "voice": "alloy", "input": ai_reply}
117
+ speech = requests.post(speech_url, headers=headers, json=payload)
118
+
119
+ if speech.status_code == 200:
120
+ with open("speech.mp3", "wb") as f:
121
+ f.write(speech.content)
 
 
 
 
 
 
 
 
 
 
 
122
  else:
123
+ print("Speech generation failed:", speech.text)
124
+ except Exception as e:
125
+ print("Speech block error:", e)
126
+
127
+ return jsonify({"response": ai_reply, "emotion": emotion_label})
128
+
129
+
130
+ @app.route("/")
131
+ def index():
132
+ return jsonify({"message": "Emotional Support Chatbot API is running!"})
133
 
 
134
 
135
+ if __name__ == "__main__":
136
+ app.run(host="0.0.0.0", port=7860)