Spaces:
Sleeping
Sleeping
| import os | |
| import streamlit as st | |
| from anthropic import Anthropic | |
| from dotenv import load_dotenv | |
| # Load environment variables | |
| load_dotenv() | |
| # Configure Streamlit page settings | |
| st.set_page_config( | |
| page_title="Sacred Texts", | |
| page_icon="🕊️", | |
| layout="centered", | |
| ) | |
| # Initialize Anthropic client | |
| def get_api_key(): | |
| # Try getting from Streamlit secrets first (for Hugging Face deployment) | |
| try: | |
| if hasattr(st.secrets, "anthropic_key"): | |
| return st.secrets.anthropic_key | |
| except Exception: | |
| pass | |
| # Fall back to environment variable (for local development) | |
| env_key = os.getenv("ANTHROPIC_API_KEY") | |
| if env_key: | |
| return env_key | |
| return None | |
| try: | |
| api_key = get_api_key() | |
| if not api_key: | |
| st.error("Anthropic API Key not found. Please ensure it's set in Hugging Face secrets or local .env file.") | |
| st.stop() | |
| client = Anthropic(api_key=api_key) | |
| except Exception as e: | |
| st.error(f"Failed to configure Anthropic client: {e}") | |
| st.stop() | |
| # Wisdom traditions with descriptions | |
| TRADITIONS = { | |
| "Torah/Talmud": "Jewish scripture and rabbinic wisdom", | |
| "Jesus Following": "Christian scripture and teachings", | |
| "Quran": "Islamic scripture", | |
| "Buddhist Texts": "Sutras, Dhammapada, and Buddhist teachings", | |
| "Rumi": "Sufi poetry and mysticism", | |
| "Brené Brown": "Modern wisdom on vulnerability, courage, and connection" | |
| } | |
| # System prompt template | |
| def get_system_prompt(tradition): | |
| return f"""You are a wisdom companion offering support through sacred and meaningful texts. | |
| The user draws wisdom from: {tradition} | |
| Based on what they share, provide ONE relevant quote, verse, or passage that speaks to their situation with compassion, grounding, or insight. | |
| Guidelines: | |
| - Choose a quote that feels applicable to their specific situation | |
| - The quote should offer comfort, perspective, or gentle wisdom | |
| - Include a clear citation (book/chapter/verse, or source/work for authors) | |
| - Keep your response focused - just the quote and citation, no additional commentary | |
| Format your response EXACTLY as: | |
| [The quote text] | |
| — [Citation]""" | |
| # Initialize session state | |
| if "current_quote" not in st.session_state: | |
| st.session_state.current_quote = None | |
| if "last_context" not in st.session_state: | |
| st.session_state.last_context = None | |
| if "selected_tradition" not in st.session_state: | |
| st.session_state.selected_tradition = None | |
| def get_wisdom_quote(tradition, context): | |
| """Fetch a wisdom quote from Claude based on tradition and context.""" | |
| try: | |
| response = client.messages.create( | |
| model="claude-sonnet-4-20250514", | |
| system=get_system_prompt(tradition), | |
| messages=[{ | |
| "role": "user", | |
| "content": f"Here's my situation:\n\n{context}" | |
| }], | |
| max_tokens=500 | |
| ) | |
| return response.content[0].text | |
| except Exception as e: | |
| return f"Unable to retrieve wisdom: {e}" | |
| # Custom CSS for quote card styling | |
| st.markdown(""" | |
| <style> | |
| .quote-card { | |
| background: linear-gradient(135deg, #f5f7fa 0%, #e4e8ec 100%); | |
| border-left: 4px solid #6b7280; | |
| padding: 1.5rem; | |
| border-radius: 8px; | |
| margin: 1rem 0; | |
| font-style: italic; | |
| font-size: 1.1rem; | |
| line-height: 1.6; | |
| color: #374151; | |
| } | |
| .quote-source { | |
| font-style: normal; | |
| font-size: 0.95rem; | |
| color: #6b7280; | |
| margin-top: 0.75rem; | |
| text-align: right; | |
| } | |
| .header-subtitle { | |
| text-align: center; | |
| font-size: 1.1rem; | |
| color: #6b7280; | |
| margin-bottom: 2rem; | |
| font-style: italic; | |
| } | |
| .stButton > button { | |
| width: 100%; | |
| } | |
| </style> | |
| """, unsafe_allow_html=True) | |
| # Header | |
| st.markdown("<h1 style='text-align: center; color: #333;'>🕊️ Sacred Texts</h1>", unsafe_allow_html=True) | |
| st.markdown("<p class='header-subtitle'>Need some wisdom right now?</p>", unsafe_allow_html=True) | |
| # Tradition selector | |
| tradition = st.selectbox( | |
| "Choose your wisdom tradition", | |
| options=list(TRADITIONS.keys()), | |
| format_func=lambda x: f"{x} — {TRADITIONS[x]}", | |
| help="Select the spiritual or philosophical tradition you'd like to draw wisdom from" | |
| ) | |
| # Context input | |
| st.markdown("### What's the situation?") | |
| context = st.text_area( | |
| "Describe your situation", | |
| placeholder="Describe what's happening...", | |
| height=150, | |
| label_visibility="collapsed" | |
| ) | |
| # Get Wisdom button | |
| col1, col2, col3 = st.columns([1, 2, 1]) | |
| with col2: | |
| get_wisdom = st.button("🙏 Get Wisdom", use_container_width=True, type="primary") | |
| # Handle getting new wisdom | |
| if get_wisdom: | |
| if context.strip(): | |
| with st.spinner("Finding wisdom..."): | |
| st.session_state.current_quote = get_wisdom_quote(tradition, context) | |
| st.session_state.last_context = context | |
| st.session_state.selected_tradition = tradition | |
| else: | |
| st.warning("Please share some context about the conversation first.") | |
| # Display quote if we have one | |
| if st.session_state.current_quote: | |
| st.markdown("---") | |
| st.markdown(f""" | |
| <div class="quote-card"> | |
| {st.session_state.current_quote} | |
| </div> | |
| """, unsafe_allow_html=True) | |
| # Get Another Quote button | |
| col1, col2, col3 = st.columns([1, 2, 1]) | |
| with col2: | |
| if st.button("🔄 Get Another Quote", use_container_width=True): | |
| if st.session_state.last_context: | |
| with st.spinner("Finding more wisdom..."): | |
| st.session_state.current_quote = get_wisdom_quote( | |
| st.session_state.selected_tradition or tradition, | |
| st.session_state.last_context | |
| ) | |
| st.rerun() | |
| # Sidebar | |
| with st.sidebar: | |
| st.markdown(""" | |
| ### About | |
| Pick a tradition. Describe your situation. Get wisdom. | |
| --- | |
| **Created by** | |
| [Jocelyn Skillman, LMHC](http://www.jocelynskillman.com) | |
| 📬 [Substack](https://jocelynskillmanlmhc.substack.com/) | |
| """) | |
| # Footer | |
| st.markdown("---") | |