SacredTexts.SOS / app.py
jostlebot's picture
Reorder traditions: Torah/Talmud, Jesus Following, Quran first
4dbeb86
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("---")