Spaces:
Sleeping
Sleeping
| # 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}" |