Garvitj commited on
Commit
5442d6b
ยท
verified ยท
1 Parent(s): b1f4c12

Update src/app.py

Browse files
Files changed (1) hide show
  1. src/app.py +71 -63
src/app.py CHANGED
@@ -2,6 +2,7 @@ import streamlit as st
2
  import cv2
3
  import numpy as np
4
  import os
 
5
  from dotenv import load_dotenv
6
  from st_audiorec import st_audiorec
7
  from analysis import (
@@ -11,7 +12,7 @@ from analysis import (
11
  get_llm_response
12
  )
13
 
14
- # --- LOAD .ENV FILE ---
15
  load_dotenv()
16
 
17
  # Page configuration
@@ -21,102 +22,82 @@ st.set_page_config(
21
  layout="wide"
22
  )
23
 
24
- # --- SESSION STATE INITIALIZATION ---
25
- # This is the "secure vault" to save our data
26
- if "camera_bytes" not in st.session_state:
27
- st.session_state.camera_bytes = None
28
- if "audio_bytes" not in st.session_state:
29
- st.session_state.audio_bytes = None
30
- if "user_query" not in st.session_state:
31
- st.session_state.user_query = ""
32
-
33
- # --- CALLBACK FUNCTIONS ---
34
- # These functions run *immediately* when a widget changes,
35
- # saving the data to the "secure vault" *before* the re-run.
36
-
37
- def camera_on_change():
38
- """Saves the raw bytes of the photo or clears it."""
39
- if st.session_state.camera_widget_buffer is not None:
40
- st.session_state.camera_bytes = st.session_state.camera_widget_buffer.getvalue()
41
- else:
42
- st.session_state.camera_bytes = None
43
-
44
- def query_on_change():
45
- """Saves the text query."""
46
- st.session_state.user_query = st.session_state.query_widget_buffer
47
-
48
- # --- UI LAYOUT ---
49
-
50
  st.title("๐Ÿค– Empathetic AI Assistant")
51
  st.markdown("""
52
  This AI assistant analyzes your emotional state through:
53
  - ๐Ÿ“ธ **Facial Expression** (from camera)
54
  - ๐ŸŽค **Vocal Tone** (from microphone)
55
  - ๐Ÿ’ฌ **Spoken Words** (transcribed from audio)
 
 
56
  """)
 
57
  st.divider()
58
 
 
59
  col1, col2 = st.columns([1, 1])
60
 
61
  with col1:
62
  st.subheader("๐Ÿ“ธ 1. Capture Your Expression")
63
- # We MUST use 'key' and 'on_change'
64
- st.camera_input(
65
- "Take a snapshot",
66
- key="camera_widget_buffer",
67
- on_change=camera_on_change
68
- )
69
 
70
  with col2:
71
  st.subheader("๐Ÿ’ญ 2. Your Query")
72
- st.text_area(
73
  "What would you like to ask?",
74
  placeholder="Type your question or concern here...",
75
- height=100,
76
- key="query_widget_buffer",
77
- on_change=query_on_change
78
  )
79
 
80
  st.divider()
81
 
82
  st.subheader("๐ŸŽ™๏ธ 3. Record Your Voice")
83
  st.write("Click the microphone to record your voice, then click 'Analyze' below.")
84
- audio_data = st_audiorec()
85
-
86
- # When new audio comes in, save it to our "vault"
87
- if audio_data is not None:
88
- st.session_state.audio_bytes = audio_data
89
 
90
  st.divider()
91
 
92
- # --- ANALYSIS BUTTON ---
93
  if st.button("๐Ÿง  Analyze My Emotion & Answer", type="primary", use_container_width=True):
94
 
95
- # We check our "secure vault" variables, not the widgets
96
- if not st.session_state.camera_bytes:
97
  st.error("โŒ Please take a snapshot using the camera first!")
98
- elif not st.session_state.audio_bytes:
99
  st.error("โŒ Please record your voice first!")
100
- elif not st.session_state.user_query.strip():
101
  st.error("โŒ Please enter your query!")
102
  else:
103
- # --- PROCESSING ---
104
  with st.spinner("๐Ÿ“ธ Processing facial expression..."):
105
  try:
106
- file_bytes = np.asarray(bytearray(st.session_state.camera_bytes), dtype=np.uint8)
107
  image = cv2.imdecode(file_bytes, cv2.IMREAD_COLOR)
108
- cv2.imwrite("temp_image.jpg", image)
109
- facial_emotion = get_facial_emotion("temp_image.jpg")
 
 
 
 
 
 
110
  except Exception as e:
111
  st.error(f"Error processing image: {e}")
112
  facial_emotion = "neutral"
113
 
 
114
  with st.spinner("๐ŸŽต Saving and analyzing audio..."):
115
  try:
116
- with open("temp_audio.wav", "wb") as f:
117
- f.write(st.session_state.audio_bytes)
118
- voice_emotion = get_voice_emotion("temp_audio.wav")
119
- transcript = get_transcript("temp_audio.wav")
 
 
 
 
 
120
  except Exception as e:
121
  st.error(f"Error processing audio: {e}")
122
  voice_emotion = "neutral"
@@ -125,27 +106,48 @@ if st.button("๐Ÿง  Analyze My Emotion & Answer", type="primary", use_container_w
125
  # Display analysis results
126
  st.divider()
127
  st.subheader("๐Ÿ“Š Emotional Analysis Results")
 
128
  col_a, col_b, col_c = st.columns(3)
129
- with col_a: st.metric(label="๐Ÿ˜Š Facial Emotion", value=facial_emotion.capitalize())
130
- with col_b: st.metric(label="๐ŸŽค Vocal Tone", value=voice_emotion.capitalize())
131
- with col_c: st.metric(label="๐Ÿ’ฌ Speech Detected", value="Yes" if transcript else "No")
132
- if transcript: st.info(f"**Transcription:** {transcript}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
133
 
134
  # Step 5: Get empathetic AI response
135
  st.divider()
136
  with st.spinner("๐Ÿค– Empathetic AI is thinking..."):
137
  ai_response = get_llm_response(
138
- user_query=st.session_state.user_query,
139
  face=facial_emotion,
140
  voice=voice_emotion,
141
  text=transcript
142
  )
143
 
 
144
  st.subheader("๐Ÿ’™ Empathetic Response")
145
  st.markdown(ai_response)
 
 
146
  st.balloons()
147
 
148
- # --- SIDEBAR (No changes needed) ---
149
  with st.sidebar:
150
  st.header("โ„น๏ธ How to Use")
151
  st.markdown("""
@@ -155,17 +157,23 @@ with st.sidebar:
155
  4. **Click the 'Analyze' button**
156
  5. **Receive** your response
157
  """)
 
158
  st.divider()
 
159
  st.header("๐Ÿ”‘ Setup Requirements")
160
  st.markdown("""
161
- Make sure these environment variables are set in your
162
- Hugging Face Space **Settings > Repository secrets**:
 
 
163
  ```
164
  ROBOFLOW_API_KEY="your_key"
165
  GROQ_API_KEY="your_key"
166
  ```
167
  """)
 
168
  st.divider()
 
169
  st.header("๐Ÿ› ๏ธ Tech Stack")
170
  st.markdown("""
171
  - **Frontend:** Streamlit
 
2
  import cv2
3
  import numpy as np
4
  import os
5
+ import tempfile # <-- 1. IMPORT TEMPFILE
6
  from dotenv import load_dotenv
7
  from st_audiorec import st_audiorec
8
  from analysis import (
 
12
  get_llm_response
13
  )
14
 
15
+ # Load the .env file
16
  load_dotenv()
17
 
18
  # Page configuration
 
22
  layout="wide"
23
  )
24
 
25
+ # Title and description
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
26
  st.title("๐Ÿค– Empathetic AI Assistant")
27
  st.markdown("""
28
  This AI assistant analyzes your emotional state through:
29
  - ๐Ÿ“ธ **Facial Expression** (from camera)
30
  - ๐ŸŽค **Vocal Tone** (from microphone)
31
  - ๐Ÿ’ฌ **Spoken Words** (transcribed from audio)
32
+
33
+ Then provides an empathetic, context-aware response to your query.
34
  """)
35
+
36
  st.divider()
37
 
38
+ # Create two columns for layout
39
  col1, col2 = st.columns([1, 1])
40
 
41
  with col1:
42
  st.subheader("๐Ÿ“ธ 1. Capture Your Expression")
43
+ camera_image = st.camera_input("Take a snapshot")
 
 
 
 
 
44
 
45
  with col2:
46
  st.subheader("๐Ÿ’ญ 2. Your Query")
47
+ user_query = st.text_area(
48
  "What would you like to ask?",
49
  placeholder="Type your question or concern here...",
50
+ height=100
 
 
51
  )
52
 
53
  st.divider()
54
 
55
  st.subheader("๐ŸŽ™๏ธ 3. Record Your Voice")
56
  st.write("Click the microphone to record your voice, then click 'Analyze' below.")
57
+ audio_bytes = st_audiorec()
 
 
 
 
58
 
59
  st.divider()
60
 
61
+ # Main action button
62
  if st.button("๐Ÿง  Analyze My Emotion & Answer", type="primary", use_container_width=True):
63
 
64
+ # Validation
65
+ if not camera_image:
66
  st.error("โŒ Please take a snapshot using the camera first!")
67
+ elif not audio_bytes:
68
  st.error("โŒ Please record your voice first!")
69
+ elif not user_query.strip():
70
  st.error("โŒ Please enter your query!")
71
  else:
72
+ # Step 1: Process camera image
73
  with st.spinner("๐Ÿ“ธ Processing facial expression..."):
74
  try:
75
+ file_bytes = np.asarray(bytearray(camera_image.read()), dtype=np.uint8)
76
  image = cv2.imdecode(file_bytes, cv2.IMREAD_COLOR)
77
+
78
+ # --- 2. USE A NAMED TEMPORARY FILE FOR THE IMAGE ---
79
+ with tempfile.NamedTemporaryFile(delete=True, suffix=".jpg") as temp_img:
80
+ cv2.imwrite(temp_img.name, image)
81
+ # Pass the unique temp file's name for analysis
82
+ facial_emotion = get_facial_emotion(temp_img.name)
83
+ # The temp_img file is now automatically deleted
84
+
85
  except Exception as e:
86
  st.error(f"Error processing image: {e}")
87
  facial_emotion = "neutral"
88
 
89
+ # Step 2: Process recorded audio
90
  with st.spinner("๐ŸŽต Saving and analyzing audio..."):
91
  try:
92
+ # --- 3. USE A NAMED TEMPORARY FILE FOR THE AUDIO ---
93
+ with tempfile.NamedTemporaryFile(delete=True, suffix=".wav") as temp_aud:
94
+ temp_aud.write(audio_bytes)
95
+
96
+ # Pass the unique temp file's name for analysis
97
+ voice_emotion = get_voice_emotion(temp_aud.name)
98
+ transcript = get_transcript(temp_aud.name)
99
+ # The temp_aud file is now automatically deleted
100
+
101
  except Exception as e:
102
  st.error(f"Error processing audio: {e}")
103
  voice_emotion = "neutral"
 
106
  # Display analysis results
107
  st.divider()
108
  st.subheader("๐Ÿ“Š Emotional Analysis Results")
109
+
110
  col_a, col_b, col_c = st.columns(3)
111
+
112
+ with col_a:
113
+ st.metric(
114
+ label="๐Ÿ˜Š Facial Emotion",
115
+ value=facial_emotion.capitalize()
116
+ )
117
+
118
+ with col_b:
119
+ st.metric(
120
+ label="๐ŸŽค Vocal Tone",
121
+ value=voice_emotion.capitalize()
122
+ )
123
+
124
+ with col_c:
125
+ st.metric(
126
+ label="๐Ÿ’ฌ Speech Detected",
127
+ value="Yes" if transcript else "No"
128
+ )
129
+
130
+ if transcript:
131
+ st.info(f"**Transcription:** {transcript}")
132
 
133
  # Step 5: Get empathetic AI response
134
  st.divider()
135
  with st.spinner("๐Ÿค– Empathetic AI is thinking..."):
136
  ai_response = get_llm_response(
137
+ user_query=user_query,
138
  face=facial_emotion,
139
  voice=voice_emotion,
140
  text=transcript
141
  )
142
 
143
+ # Display final response
144
  st.subheader("๐Ÿ’™ Empathetic Response")
145
  st.markdown(ai_response)
146
+
147
+ # Success feedback
148
  st.balloons()
149
 
150
+ # Sidebar with instructions
151
  with st.sidebar:
152
  st.header("โ„น๏ธ How to Use")
153
  st.markdown("""
 
157
  4. **Click the 'Analyze' button**
158
  5. **Receive** your response
159
  """)
160
+
161
  st.divider()
162
+
163
  st.header("๐Ÿ”‘ Setup Requirements")
164
  st.markdown("""
165
+ Make sure these environment variables are set.
166
+
167
+ Create a `.env` file in the same
168
+ directory as `app.py`:
169
  ```
170
  ROBOFLOW_API_KEY="your_key"
171
  GROQ_API_KEY="your_key"
172
  ```
173
  """)
174
+
175
  st.divider()
176
+
177
  st.header("๐Ÿ› ๏ธ Tech Stack")
178
  st.markdown("""
179
  - **Frontend:** Streamlit