Spaces:
Configuration error
Configuration error
Update app.py
Browse files
app.py
CHANGED
@@ -1,10 +1,12 @@
|
|
1 |
import streamlit as st
|
2 |
import google.generativeai as genai
|
3 |
-
from
|
4 |
-
import os
|
5 |
import json
|
|
|
|
|
|
|
6 |
|
7 |
-
#
|
8 |
st.set_page_config(
|
9 |
page_title="HerCorners",
|
10 |
page_icon="π",
|
@@ -12,62 +14,360 @@ st.set_page_config(
|
|
12 |
initial_sidebar_state="expanded"
|
13 |
)
|
14 |
|
15 |
-
#
|
16 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
17 |
try:
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
# For Hugging Face
|
22 |
-
os.environ["HUGGINGFACE_API_TOKEN"] = st.secrets["HUGGINGFACE_API_KEY"]
|
23 |
-
|
24 |
-
return True
|
25 |
except Exception as e:
|
26 |
-
|
27 |
-
return False
|
28 |
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
38 |
|
39 |
-
|
40 |
-
class
|
41 |
-
|
42 |
-
|
43 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
44 |
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
53 |
|
54 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
55 |
|
56 |
-
# Main execution
|
57 |
def main():
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
|
|
71 |
|
72 |
if __name__ == "__main__":
|
73 |
main()
|
|
|
1 |
import streamlit as st
|
2 |
import google.generativeai as genai
|
3 |
+
from audio_recorder_streamlit import audio_recorder
|
|
|
4 |
import json
|
5 |
+
import time
|
6 |
+
from datetime import datetime
|
7 |
+
import plotly.graph_objects as go
|
8 |
|
9 |
+
# Page Configuration
|
10 |
st.set_page_config(
|
11 |
page_title="HerCorners",
|
12 |
page_icon="π",
|
|
|
14 |
initial_sidebar_state="expanded"
|
15 |
)
|
16 |
|
17 |
+
# Custom CSS
|
18 |
+
st.markdown("""
|
19 |
+
<style>
|
20 |
+
/* Main Styles */
|
21 |
+
.stApp {
|
22 |
+
background-color: #fafafa;
|
23 |
+
}
|
24 |
+
|
25 |
+
/* Cards */
|
26 |
+
.mentor-card, .story-card, .achievement-card {
|
27 |
+
background: linear-gradient(145deg, #ffffff, #f5f7fa);
|
28 |
+
border-radius: 20px;
|
29 |
+
padding: 20px;
|
30 |
+
margin: 10px 0;
|
31 |
+
box-shadow: 5px 5px 15px rgba(0,0,0,0.08);
|
32 |
+
transition: transform 0.3s ease;
|
33 |
+
}
|
34 |
+
.mentor-card:hover {
|
35 |
+
transform: translateY(-5px);
|
36 |
+
}
|
37 |
+
|
38 |
+
/* Chat Messages */
|
39 |
+
.chat-message {
|
40 |
+
padding: 15px;
|
41 |
+
border-radius: 15px;
|
42 |
+
margin: 10px 0;
|
43 |
+
max-width: 80%;
|
44 |
+
}
|
45 |
+
.user-message {
|
46 |
+
background: linear-gradient(135deg, #ff6b6b, #ff8787);
|
47 |
+
color: white;
|
48 |
+
margin-left: 20%;
|
49 |
+
}
|
50 |
+
.mentor-message {
|
51 |
+
background: linear-gradient(135deg, #f6f8fd, #f1f4f9);
|
52 |
+
margin-right: 20%;
|
53 |
+
}
|
54 |
+
|
55 |
+
/* Headers */
|
56 |
+
.corner-header {
|
57 |
+
background: linear-gradient(135deg, #ff6b6b, #ff8787);
|
58 |
+
color: white;
|
59 |
+
padding: 20px;
|
60 |
+
border-radius: 15px;
|
61 |
+
margin-bottom: 20px;
|
62 |
+
}
|
63 |
+
|
64 |
+
/* Buttons */
|
65 |
+
.custom-button {
|
66 |
+
background: linear-gradient(135deg, #ff6b6b, #ff8787);
|
67 |
+
color: white;
|
68 |
+
padding: 10px 20px;
|
69 |
+
border-radius: 25px;
|
70 |
+
border: none;
|
71 |
+
cursor: pointer;
|
72 |
+
transition: all 0.3s ease;
|
73 |
+
}
|
74 |
+
.custom-button:hover {
|
75 |
+
transform: scale(1.05);
|
76 |
+
}
|
77 |
+
|
78 |
+
/* Progress Bars */
|
79 |
+
.progress-bar {
|
80 |
+
height: 10px;
|
81 |
+
border-radius: 5px;
|
82 |
+
background: linear-gradient(135deg, #ff6b6b, #ff8787);
|
83 |
+
}
|
84 |
+
</style>
|
85 |
+
""", unsafe_allow_html=True)
|
86 |
+
|
87 |
+
# Initialize Gemini
|
88 |
+
if 'GEMINI_API_KEY' in st.secrets:
|
89 |
+
genai.configure(api_key=st.secrets["GEMINI_API_KEY"])
|
90 |
+
model = genai.GenerativeModel('gemini-1.0-pro')
|
91 |
+
else:
|
92 |
+
st.error("Please configure your Gemini API key in the Space settings.")
|
93 |
+
|
94 |
+
# Mentor Profiles
|
95 |
+
MENTORS = {
|
96 |
+
"Sara Blakely": {
|
97 |
+
"role": "Founder of Spanx",
|
98 |
+
"expertise": ["Entrepreneurship", "Product Development", "Business Scaling"],
|
99 |
+
"style": "encouraging and practical",
|
100 |
+
"background": "Started with $5,000 and built a billion-dollar company",
|
101 |
+
"color": "#ff6b6b",
|
102 |
+
"quote": "Don't be intimidated by what you don't know."
|
103 |
+
},
|
104 |
+
"Oprah Winfrey": {
|
105 |
+
"role": "Media Mogul & Philanthropist",
|
106 |
+
"expertise": ["Leadership", "Personal Growth", "Media"],
|
107 |
+
"style": "inspiring and wise",
|
108 |
+
"background": "Built a media empire and became one of the most influential voices",
|
109 |
+
"color": "#9b59b6",
|
110 |
+
"quote": "The biggest adventure you can take is to live the life of your dreams."
|
111 |
+
},
|
112 |
+
"Reshma Saujani": {
|
113 |
+
"role": "Founder of Girls Who Code",
|
114 |
+
"expertise": ["Tech Education", "Coding", "Leadership"],
|
115 |
+
"style": "tech-savvy and empowering",
|
116 |
+
"background": "Founded organization to close the gender gap in technology",
|
117 |
+
"color": "#3498db",
|
118 |
+
"quote": "Perfect is the enemy of good."
|
119 |
+
},
|
120 |
+
"Rihanna": {
|
121 |
+
"role": "Founder of Fenty Beauty",
|
122 |
+
"expertise": ["Brand Building", "Creative Business", "Fashion"],
|
123 |
+
"style": "confident and creative",
|
124 |
+
"background": "Built a diverse business empire spanning music, fashion, and beauty",
|
125 |
+
"color": "#e74c3c",
|
126 |
+
"quote": "The minute you learn to love yourself, you won't want to be anyone else."
|
127 |
+
}
|
128 |
+
}
|
129 |
+
|
130 |
+
# Session State Initialization
|
131 |
+
if 'messages' not in st.session_state:
|
132 |
+
st.session_state.messages = []
|
133 |
+
if 'achievements' not in st.session_state:
|
134 |
+
st.session_state.achievements = []
|
135 |
+
if 'learning_progress' not in st.session_state:
|
136 |
+
st.session_state.learning_progress = {}
|
137 |
+
if 'support_messages' not in st.session_state:
|
138 |
+
st.session_state.support_messages = []
|
139 |
+
|
140 |
+
def generate_mentor_response(mentor, message):
|
141 |
+
"""Generate mentor response using Gemini"""
|
142 |
+
prompt = f"""
|
143 |
+
You are {mentor}, {MENTORS[mentor]['role']}.
|
144 |
+
Your expertise: {', '.join(MENTORS[mentor]['expertise'])}
|
145 |
+
Your style is {MENTORS[mentor]['style']}
|
146 |
+
Background: {MENTORS[mentor]['background']}
|
147 |
+
|
148 |
+
Respond to this message as if you are {mentor}, keeping your response:
|
149 |
+
1. Personal and authentic to your style
|
150 |
+
2. Drawing from your real experiences
|
151 |
+
3. Providing actionable advice
|
152 |
+
4. Under 100 words
|
153 |
+
|
154 |
+
User message: {message}
|
155 |
+
"""
|
156 |
+
|
157 |
try:
|
158 |
+
response = model.generate_content(prompt)
|
159 |
+
return response.text
|
|
|
|
|
|
|
|
|
|
|
160 |
except Exception as e:
|
161 |
+
return f"I apologize, but I'm having trouble connecting right now. Please try again. Error: {str(e)}"
|
|
|
162 |
|
163 |
+
def generate_support_response(story):
|
164 |
+
"""Generate emotional support response"""
|
165 |
+
prompt = f"""
|
166 |
+
As a supportive AI mentor, respond to this personal story with empathy and encouragement.
|
167 |
+
Keep in mind:
|
168 |
+
1. Validate their feelings
|
169 |
+
2. Offer gentle support
|
170 |
+
3. Provide hope and perspective
|
171 |
+
4. Suggest practical next steps if appropriate
|
172 |
+
|
173 |
+
Story: {story}
|
174 |
+
"""
|
175 |
+
|
176 |
+
try:
|
177 |
+
response = model.generate_content(prompt)
|
178 |
+
return response.text
|
179 |
+
except Exception as e:
|
180 |
+
return f"I apologize, but I'm having trouble connecting right now. Please try again. Error: {str(e)}"
|
181 |
+
|
182 |
+
def generate_learning_content(topic):
|
183 |
+
"""Generate educational content"""
|
184 |
+
prompt = f"""
|
185 |
+
Create a structured lesson about {topic} specifically for women entrepreneurs.
|
186 |
+
Include:
|
187 |
+
1. Key concepts
|
188 |
+
2. Practical examples
|
189 |
+
3. Action steps
|
190 |
+
4. Success stories of women in this field
|
191 |
+
"""
|
192 |
+
|
193 |
+
try:
|
194 |
+
response = model.generate_content(prompt)
|
195 |
+
return response.text
|
196 |
+
except Exception as e:
|
197 |
+
return f"Unable to generate lesson content. Please try again. Error: {str(e)}"
|
198 |
|
199 |
+
def she_legends_corner():
|
200 |
+
st.markdown("<div class='corner-header'><h1>π She-Legends</h1></div>", unsafe_allow_html=True)
|
201 |
+
|
202 |
+
# Mentor Selection
|
203 |
+
col1, col2 = st.columns([1, 2])
|
204 |
+
|
205 |
+
with col1:
|
206 |
+
mentor = st.selectbox("Choose your mentor", list(MENTORS.keys()))
|
207 |
+
if mentor:
|
208 |
+
st.markdown(f"""
|
209 |
+
<div class="mentor-card">
|
210 |
+
<h3>{mentor}</h3>
|
211 |
+
<p><em>{MENTORS[mentor]['role']}</em></p>
|
212 |
+
<p>"{MENTORS[mentor]['quote']}"</p>
|
213 |
+
</div>
|
214 |
+
""", unsafe_allow_html=True)
|
215 |
+
|
216 |
+
with col2:
|
217 |
+
if mentor:
|
218 |
+
message = st.text_area("Your message to " + mentor)
|
219 |
+
col1, col2 = st.columns([1, 1])
|
220 |
+
with col1:
|
221 |
+
if st.button("Send Message", key="text_message"):
|
222 |
+
response = generate_mentor_response(mentor, message)
|
223 |
+
st.session_state.messages.append({"role": "user", "content": message})
|
224 |
+
st.session_state.messages.append({"role": "mentor", "content": response})
|
225 |
+
|
226 |
+
with col2:
|
227 |
+
audio_bytes = audio_recorder()
|
228 |
+
if audio_bytes:
|
229 |
+
st.audio(audio_bytes, format="audio/wav")
|
230 |
+
response = generate_mentor_response(mentor, "Voice message received")
|
231 |
+
st.session_state.messages.append({"role": "mentor", "content": response})
|
232 |
+
|
233 |
+
# Display Chat History
|
234 |
+
for msg in st.session_state.messages:
|
235 |
+
div_class = "user-message" if msg["role"] == "user" else "mentor-message"
|
236 |
+
st.markdown(f"""
|
237 |
+
<div class="chat-message {div_class}">
|
238 |
+
{msg["content"]}
|
239 |
+
</div>
|
240 |
+
""", unsafe_allow_html=True)
|
241 |
+
|
242 |
+
def she_melted_mascara_corner():
|
243 |
+
st.markdown("<div class='corner-header'><h1>π She-Melted Mascara</h1></div>", unsafe_allow_html=True)
|
244 |
+
|
245 |
+
tab1, tab2, tab3 = st.tabs(["Share Story", "Voice Note", "Community Support"])
|
246 |
+
|
247 |
+
with tab1:
|
248 |
+
story = st.text_area("Share your story anonymously...")
|
249 |
+
if st.button("Get Support"):
|
250 |
+
support = generate_support_response(story)
|
251 |
+
st.session_state.support_messages.append({
|
252 |
+
"story": story,
|
253 |
+
"support": support,
|
254 |
+
"timestamp": datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
255 |
+
})
|
256 |
+
st.markdown(f"""
|
257 |
+
<div class="chat-message mentor-message">
|
258 |
+
{support}
|
259 |
+
</div>
|
260 |
+
""", unsafe_allow_html=True)
|
261 |
+
|
262 |
+
with tab2:
|
263 |
+
st.write("Record your voice note")
|
264 |
+
audio_bytes = audio_recorder()
|
265 |
+
if audio_bytes:
|
266 |
+
st.audio(audio_bytes, format="audio/wav")
|
267 |
+
support = generate_support_response("Voice message received")
|
268 |
+
st.markdown(f"""
|
269 |
+
<div class="chat-message mentor-message">
|
270 |
+
{support}
|
271 |
+
</div>
|
272 |
+
""", unsafe_allow_html=True)
|
273 |
+
|
274 |
+
with tab3:
|
275 |
+
st.write("Recent Community Support")
|
276 |
+
for msg in reversed(st.session_state.support_messages[-5:]):
|
277 |
+
st.markdown(f"""
|
278 |
+
<div class="story-card">
|
279 |
+
<p><em>{msg['timestamp']}</em></p>
|
280 |
+
<p>{msg['support']}</p>
|
281 |
+
</div>
|
282 |
+
""", unsafe_allow_html=True)
|
283 |
+
|
284 |
+
def she_glows_corner():
|
285 |
+
st.markdown("<div class='corner-header'><h1>β¨ She-Glows</h1></div>", unsafe_allow_html=True)
|
286 |
+
|
287 |
+
# Learning Paths
|
288 |
+
col1, col2 = st.columns([2, 1])
|
289 |
+
|
290 |
+
with col1:
|
291 |
+
topics = {
|
292 |
+
"Financial Literacy": ["Budgeting", "Investing", "Financial Planning"],
|
293 |
+
"Entrepreneurship": ["Business Planning", "Marketing", "Funding"],
|
294 |
+
"Leadership": ["Communication", "Team Building", "Decision Making"]
|
295 |
+
}
|
296 |
+
|
297 |
+
selected_topic = st.selectbox("Choose your learning path", list(topics.keys()))
|
298 |
+
selected_module = st.selectbox("Select module", topics[selected_topic])
|
299 |
|
300 |
+
if st.button("Start Learning"):
|
301 |
+
content = generate_learning_content(selected_module)
|
302 |
+
st.markdown(f"""
|
303 |
+
<div class="mentor-card">
|
304 |
+
<h3>{selected_module}</h3>
|
305 |
+
{content}
|
306 |
+
</div>
|
307 |
+
""", unsafe_allow_html=True)
|
308 |
+
|
309 |
+
# Update progress
|
310 |
+
if selected_topic not in st.session_state.learning_progress:
|
311 |
+
st.session_state.learning_progress[selected_topic] = 0
|
312 |
+
st.session_state.learning_progress[selected_topic] += 33
|
313 |
+
if st.session_state.learning_progress[selected_topic] > 100:
|
314 |
+
st.session_state.learning_progress[selected_topic] = 100
|
315 |
+
|
316 |
+
with col2:
|
317 |
+
st.write("Your Progress")
|
318 |
+
for topic, progress in st.session_state.learning_progress.items():
|
319 |
+
st.write(f"{topic}: {progress}%")
|
320 |
+
st.progress(progress / 100)
|
321 |
|
322 |
+
def she_fuels_corner():
|
323 |
+
st.markdown("<div class='corner-header'><h1>β‘ She-Fuels</h1></div>", unsafe_allow_html=True)
|
324 |
+
|
325 |
+
col1, col2 = st.columns([1, 1])
|
326 |
+
|
327 |
+
with col1:
|
328 |
+
st.write("Share Your Achievement")
|
329 |
+
achievement = st.text_area("What did you accomplish?")
|
330 |
+
achievement_type = st.selectbox(
|
331 |
+
"Type of Achievement",
|
332 |
+
["Business Milestone", "Learning Achievement", "Personal Growth"]
|
333 |
+
)
|
334 |
+
|
335 |
+
if st.button("Share with Community"):
|
336 |
+
st.session_state.achievements.append({
|
337 |
+
"achievement": achievement,
|
338 |
+
"type": achievement_type,
|
339 |
+
"timestamp": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
|
340 |
+
"likes": 0
|
341 |
+
})
|
342 |
+
st.success("Achievement shared! π")
|
343 |
+
st.balloons()
|
344 |
+
|
345 |
+
with col2:
|
346 |
+
st.write("Community Achievements")
|
347 |
+
for achievement in reversed(st.session_state.achievements):
|
348 |
+
st.markdown(f"""
|
349 |
+
<div class="achievement-card">
|
350 |
+
<p><strong>{achievement['type']}</strong></p>
|
351 |
+
<p>{achievement['achievement']}</p>
|
352 |
+
<p><em>{achievement['timestamp']}</em></p>
|
353 |
+
</div>
|
354 |
+
""", unsafe_allow_html=True)
|
355 |
|
|
|
356 |
def main():
|
357 |
+
st.sidebar.title("π HerCorners")
|
358 |
+
corner = st.sidebar.radio(
|
359 |
+
"Choose your corner",
|
360 |
+
["She-Legends", "She-Melted Mascara", "She-Glows", "She-Fuels"]
|
361 |
+
)
|
362 |
+
|
363 |
+
if corner == "She-Legends":
|
364 |
+
she_legends_corner()
|
365 |
+
elif corner == "She-Melted Mascara":
|
366 |
+
she_melted_mascara_corner()
|
367 |
+
elif corner == "She-Glows":
|
368 |
+
she_glows_corner()
|
369 |
+
elif corner == "She-Fuels":
|
370 |
+
she_fuels_corner()
|
371 |
|
372 |
if __name__ == "__main__":
|
373 |
main()
|