Spaces:
Sleeping
Sleeping
File size: 13,267 Bytes
b437175 cb0cd2a 87b5e15 004d749 b437175 87b5e15 b437175 87b5e15 b437175 cb0cd2a 87b5e15 cb0cd2a 87b5e15 cb0cd2a 004d749 cb0cd2a 87b5e15 cb0cd2a e61f017 87b5e15 b437175 004d749 87b5e15 004d749 b437175 87b5e15 cb0cd2a 87b5e15 004d749 87b5e15 cb0cd2a 87b5e15 e61f017 87b5e15 e61f017 87b5e15 e61f017 87b5e15 e61f017 87b5e15 b437175 87b5e15 cb0cd2a 87b5e15 e61f017 87b5e15 e61f017 87b5e15 e61f017 87b5e15 e61f017 87b5e15 e61f017 87b5e15 e61f017 87b5e15 b437175 87b5e15 004d749 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 |
import streamlit as st
from huggingface_hub import InferenceClient
from datetime import datetime
import pandas as pd
import os
import uuid
import json
import re
# Page configuration
st.set_page_config(
page_title="Mental Wellness Diary Analyzer",
page_icon="π§ ",
layout="wide",
initial_sidebar_state="expanded"
)
# Custom CSS for better appearance
st.markdown("""
<style>
.main .block-container {
padding-top: 2rem;
padding-bottom: 2rem;
}
.stTextArea textarea {
font-size: 16px;
}
.journal-history {
border-left: 2px solid #f0f2f6;
padding-left: 20px;
}
.css-1v3fvcr {
background-color: #fcfcff;
}
.stButton button {
background-color: #4e89ae;
color: white;
border-radius: 5px;
padding: 0.5rem 1rem;
font-weight: bold;
}
.stButton button:hover {
background-color: #3d7092;
}
</style>
""", unsafe_allow_html=True)
# App title and description
st.title("π§ Mental Wellness Diary Analyzer")
st.markdown("""
Track your mental wellness journey with AI-powered insights. Write your daily thoughts,
and receive personalized analysis to help you understand your emotional patterns.
""")
# Initialize session state for journal entries
if 'journal_entries' not in st.session_state:
# Try to load from file if it exists
if os.path.exists('journal_entries.json'):
try:
with open('journal_entries.json', 'r') as f:
st.session_state.journal_entries = json.load(f)
except:
st.session_state.journal_entries = []
else:
st.session_state.journal_entries = []
# Hugging Face API setup
def get_hf_api_token():
# First check if token exists in secrets
if hasattr(st, 'secrets') and 'huggingface' in st.secrets:
return st.secrets["huggingface"]["api_token"]
# For local development, check environment variable
return os.environ.get("HF_API_TOKEN")
# Initialize the InferenceClient
@st.cache_resource
def get_inference_client():
api_token = get_hf_api_token()
if not api_token:
st.error("No Hugging Face API token found. Please configure it in your Spaces secrets.")
return None
return InferenceClient(
provider="nebius",
api_key=api_token,
)
# Clean the output to remove thinking process
def clean_output(text):
# Extract only the parts after the headings
cleaned_text = ""
# Extract Emotional tone section
if "Emotional tone:" in text:
match = re.search(r'Emotional tone:(.*?)(?:Recurring themes:|$)', text, re.DOTALL)
if match:
emotional_tone = match.group(1).strip()
cleaned_text += f"π **Emotional tone:** {emotional_tone}\n\n"
# Extract Recurring themes section
if "Recurring themes:" in text:
match = re.search(r'Recurring themes:(.*?)(?:Advice:|$)', text, re.DOTALL)
if match:
themes = match.group(1).strip()
cleaned_text += f"π **Recurring themes:** {themes}\n\n"
# Extract Advice section
if "Advice:" in text:
match = re.search(r'Advice:(.*?)$', text, re.DOTALL)
if match:
advice = match.group(1).strip()
cleaned_text += f"π‘ **Advice:** {advice}"
return cleaned_text if cleaned_text else text
# Function to analyze journal entries
def analyze_journal(entry, model_name="deepseek-ai/DeepSeek-R1"):
client = get_inference_client()
if not client:
return "Error: Could not initialize the Inference Client."
try:
prompt = f"""You are a compassionate mental wellness assistant. Analyze the following journal entry with empathy and provide helpful insights.
Journal entry: "{entry}"
Please provide the following analysis directly, without explaining your thinking process:
1. Emotional tone: Identify the primary emotions expressed in the entry
2. Recurring themes: Note any patterns or important topics mentioned
3. Advice: Offer kind, supportive guidance tailored to what was shared
Format your response with only these three sections, using the exact headings: "Emotional tone:", "Recurring themes:", and "Advice:". Do not include any additional explanations or thinking.
"""
completion = client.chat.completions.create(
model=model_name,
messages=[
{
"role": "user",
"content": prompt
}
],
max_tokens=512,
temperature=0.7,
)
output = completion.choices[0].message.content
# Clean the output to remove any thinking process
return clean_output(output)
except Exception as e:
st.error(f"API Error: {str(e)}")
return f"Error analyzing journal entry: {str(e)}"
# Function to save an entry
def save_entry(entry, analysis):
entry_id = str(uuid.uuid4())
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
# Extract emotional tone for tagging (simplified)
emotional_tone = "neutral"
if "Emotional tone:" in analysis:
tone_text = analysis.split("Emotional tone:")[1].split("\n\n")[0].strip()
if "anxious" in tone_text.lower() or "stress" in tone_text.lower():
emotional_tone = "anxious"
elif "happy" in tone_text.lower() or "joy" in tone_text.lower():
emotional_tone = "happy"
elif "sad" in tone_text.lower() or "depress" in tone_text.lower():
emotional_tone = "sad"
elif "angry" in tone_text.lower() or "frustrat" in tone_text.lower():
emotional_tone = "angry"
new_entry = {
"id": entry_id,
"date": timestamp,
"entry": entry,
"analysis": analysis,
"emotion": emotional_tone
}
st.session_state.journal_entries.append(new_entry)
# Save to file (for spaces persistence)
try:
with open('journal_entries.json', 'w') as f:
json.dump(st.session_state.journal_entries, f)
except Exception as e:
st.warning(f"Could not save entries to file: {str(e)}")
# Sidebar for navigation and settings
with st.sidebar:
st.header("Navigation")
page = st.radio("", ["Write New Entry", "View Journal History"])
st.header("Settings")
model_choice = st.selectbox(
"Language Model",
["deepseek-ai/DeepSeek-R1", "meta-llama/Llama-3-8b-chat", "microsoft/phi-3-mini-4k-instruct"],
index=0,
help="Select which AI model to use for analysis"
)
st.markdown("---")
st.markdown("### About")
st.info("""
This Mental Wellness Diary Analyzer helps you track your emotional wellbeing.
All entries are stored locally in your browser session.
**Disclaimer**: This app is not a substitute for professional mental health support.
""")
# Main content based on selected page
if page == "Write New Entry":
st.header("π New Journal Entry")
# Current date display
st.markdown(f"**Today**: {datetime.now().strftime('%A, %B %d, %Y')}")
# Journal input
journal_entry = st.text_area(
"How are you feeling today?",
height=200,
placeholder="Write about your day, feelings, thoughts, or anything on your mind..."
)
# Mood tracker (optional quick selection)
cols = st.columns(5)
with cols[0]:
mood_happy = st.button("π Happy")
with cols[1]:
mood_calm = st.button("π Calm")
with cols[2]:
mood_anxious = st.button("π° Anxious")
with cols[3]:
mood_sad = st.button("π’ Sad")
with cols[4]:
mood_angry = st.button("π Angry")
# Handle mood button clicks
mood_prefix = ""
if mood_happy:
mood_prefix = "I'm feeling happy today. "
elif mood_calm:
mood_prefix = "I'm feeling calm and relaxed today. "
elif mood_anxious:
mood_prefix = "I'm feeling anxious today. "
elif mood_sad:
mood_prefix = "I'm feeling sad today. "
elif mood_angry:
mood_prefix = "I'm feeling angry and frustrated today. "
if mood_prefix and not journal_entry.startswith(mood_prefix):
journal_entry = mood_prefix + journal_entry
# Analyze button
col1, col2, col3 = st.columns([1, 1, 1])
with col2:
analyze_button = st.button("π§ Analyze My Entry", use_container_width=True)
# Sample entries
with st.expander("Need inspiration? Try a sample entry"):
sample_1 = st.button("Sample: Stressed at work")
sample_2 = st.button("Sample: Good day")
sample_3 = st.button("Sample: Relationship issues")
if sample_1:
journal_entry = "I feel really stressed and anxious about my work. I haven't been sleeping well, and I'm worried about meeting deadlines. My boss keeps adding more tasks, and I don't know how to say no."
elif sample_2:
journal_entry = "Today was a great day! I finished a project I've been working on for weeks, and my team was really impressed. I feel proud of myself and motivated to keep up the good work."
elif sample_3:
journal_entry = "I had an argument with my partner today. We've been fighting a lot lately about small things. I'm not sure if it's just stress or if there's a bigger issue we need to address."
# Analysis section
if analyze_button and journal_entry.strip():
with st.spinner("Analyzing your thoughts..."):
analysis = analyze_journal(journal_entry, model_choice)
st.markdown("### π Your Wellness Insights")
st.markdown(analysis)
# Save option
if st.button("π Save this entry to your journal"):
save_entry(journal_entry, analysis)
st.success("Entry saved successfully!")
# Supportive message
st.markdown("---")
st.markdown("πͺ **Remember**: Writing about your feelings is already a positive step for your mental wellness!")
elif analyze_button:
st.warning("Please write in your journal entry first.")
else: # View Journal History page
st.header("π Your Journal History")
if not st.session_state.journal_entries:
st.info("You haven't saved any journal entries yet. Head to 'Write New Entry' to get started!")
else:
# Filter options
col1, col2 = st.columns(2)
with col1:
filter_option = st.selectbox(
"Filter by emotion:",
["All", "happy", "anxious", "sad", "angry", "neutral"]
)
with col2:
sort_option = st.selectbox(
"Sort by:",
["Newest first", "Oldest first"]
)
# Filter and sort entries
filtered_entries = st.session_state.journal_entries
if filter_option != "All":
filtered_entries = [e for e in filtered_entries if e.get("emotion") == filter_option]
if sort_option == "Newest first":
filtered_entries = sorted(filtered_entries, key=lambda x: x.get("date", ""), reverse=True)
else:
filtered_entries = sorted(filtered_entries, key=lambda x: x.get("date", ""))
# Display entries
for i, entry in enumerate(filtered_entries):
with st.expander(f"π {entry.get('date', 'Unknown date')}"):
st.markdown("#### Journal Entry")
st.write(entry.get("entry", ""))
st.markdown("#### Analysis")
st.markdown(entry.get("analysis", "No analysis available"))
# Delete option
if st.button(f"ποΈ Delete this entry", key=f"delete_{i}"):
st.session_state.journal_entries.remove(entry)
with open('journal_entries.json', 'w') as f:
json.dump(st.session_state.journal_entries, f)
st.experimental_rerun()
# Add insights section if there are enough entries
if len(st.session_state.journal_entries) >= 3:
st.markdown("---")
st.header("π Emotional Trends")
# Create a dataframe for visualization
entries_df = pd.DataFrame(st.session_state.journal_entries)
entries_df['date'] = pd.to_datetime(entries_df['date'])
# Count emotions
emotion_counts = entries_df['emotion'].value_counts()
st.bar_chart(emotion_counts)
# Most common themes - this would require more sophisticated analysis
st.markdown("### Common Themes")
st.info("This feature will analyze common themes across your entries in a future update.")
# Footer
st.markdown("---")
st.caption("""
**Disclaimer**: This app is for educational purposes only and is not a substitute for professional mental health advice, diagnosis, or treatment.
Always seek the advice of your physician or other qualified health provider with any questions regarding a medical condition.
""") |