AstroTalk / ai_interpreter.py
cryogenic22's picture
Update ai_interpreter.py
9197fac verified
# ai_interpreter.py
"""
AI interpretation module using Claude API.
Handles astrological interpretations and user interactions.
"""
from typing import Dict, Any
import streamlit as st
import os
from anthropic import Anthropic
class AstroAI:
"""Handles AI-powered astrological interpretations"""
def __init__(self):
# Try multiple methods to get the API key
api_key = None
# Method 1: Try Streamlit secrets
try:
api_key = st.secrets["CLAUDE_API_KEY"]
except Exception:
pass
# Method 2: Try environment variable
if not api_key:
api_key = os.getenv("CLAUDE_API_KEY")
# Method 3: Try direct input if in development
if not api_key and not os.getenv('PRODUCTION'):
api_key = st.text_input("Enter your Claude API key:", type="password")
if api_key:
os.environ["CLAUDE_API_KEY"] = api_key
if not api_key:
raise ValueError("""
CLAUDE_API_KEY not found. Please set it using one of these methods:
1. Add to .streamlit/secrets.toml: CLAUDE_API_KEY = "your-key-here"
2. Set environment variable: export CLAUDE_API_KEY="your-key-here"
3. Enter it directly in the app (development mode only)
""")
self.client = Anthropic(api_key=api_key)
st.session_state['api_initialized'] = True
def _format_chart_data(self, chart_data: Dict[str, Any]) -> str:
"""Convert chart data to a readable format for the AI"""
formatted = "Birth Chart Analysis:\n\n"
# Format planetary positions
formatted += "Planetary Positions:\n"
for planet, data in chart_data['planets'].items():
if 'error' not in data:
retrograde = data.get('retrograde', False)
house = data.get('house', 'Unknown')
formatted += (f"{planet}: {data['degrees']:.1f}° {data['sign']} "
f"in House {house}"
f"{' (Retrograde)' if retrograde else ''}\n")
# Format aspects
if 'aspects' in chart_data and chart_data['aspects']:
formatted += "\nMajor Aspects:\n"
for aspect in chart_data['aspects']:
formatted += (f"{aspect['planet1']} {aspect['aspect']} {aspect['planet2']} "
f"(Orb: {aspect['orb']}°)\n")
# Format element and modality balances
if 'patterns' in chart_data:
if 'elements' in chart_data['patterns']:
formatted += "\nElement Balance:\n"
for element, count in chart_data['patterns']['elements'].items():
formatted += f"{element}: {count} planets\n"
if 'modalities' in chart_data['patterns']:
formatted += "\nModality Balance:\n"
for modality, count in chart_data['patterns']['modalities'].items():
formatted += f"{modality}: {count} planets\n"
return formatted
def get_interpretation(self, chart_data: Dict[str, Any], question: str) -> str:
"""Generate an astrological interpretation based on the chart and user's question"""
try:
formatted_chart = self._format_chart_data(chart_data)
system_prompt = """You are an expert astrologer with deep knowledge of both modern and traditional astrology.
When interpreting charts:
- Focus on the specific question asked while considering the whole chart context
- Provide practical, actionable insights
- Balance technical astrological terms with clear explanations
- Consider aspect patterns, dignities, and dispositors
- Include both challenging and supportive elements
- Be honest but constructive in your interpretations
"""
# Print debug information
st.write("Sending request to Claude API...")
response = self.client.messages.create(
model="claude-3-sonnet-20240229",
max_tokens=1000,
system=system_prompt,
messages=[{
"role": "user",
"content": f"""Based on the following birth chart data:
{formatted_chart}
Question: {question}
Please provide an insightful astrological interpretation focusing specifically on the question asked."""
}]
)
return response.content[0].text
except Exception as e:
error_message = f"Error generating interpretation: {str(e)}"
st.error(error_message)
return f"I apologize, but I encountered an error: {error_message}"
def get_initial_analysis(self, chart_data: Dict[str, Any]) -> str:
"""Generate an initial overview analysis of the birth chart"""
try:
formatted_chart = self._format_chart_data(chart_data)
system_prompt = """You are a skilled astrologer providing initial birth chart readings.
In your analysis:
- Start with the most prominent features of the chart
- Highlight significant patterns and configurations
- Discuss the balance of elements and modalities
- Note any particularly strong or challenged planets
- Keep the tone informative and encouraging
- Use clear language while preserving astrological accuracy
Structure your response with clear sections and insights.
"""
# Print debug information
st.write("Generating initial analysis...")
response = self.client.messages.create(
model="claude-3-sonnet-20240229",
max_tokens=1500,
system=system_prompt,
messages=[{
"role": "user",
"content": f"""Please provide an initial overview analysis of this birth chart:
{formatted_chart}
Focus on the most significant patterns and features that form the core themes of this chart."""
}]
)
return response.content[0].text
except Exception as e:
error_message = f"Error generating initial analysis: {str(e)}"
st.error(error_message)
return f"I apologize, but I encountered an error: {error_message}"