Stock_Agent_optimized / services /claude_service.py
cryogenic22's picture
Update services/claude_service.py
7ac4ae7 verified
# src/services/claude_service.py
import base64
from anthropic import Anthropic
import streamlit as st
from config.settings import ANTHROPIC_API_KEY, CLAUDE_MODEL
class ClaudeService:
def __init__(self):
"""Initialize Claude service with API key from HuggingFace secrets"""
if not ANTHROPIC_API_KEY:
raise ValueError("Anthropic API key not found in HuggingFace secrets. Please ensure ANTHROPIC_API_KEY is set in your space's secrets.")
self.client = Anthropic(api_key=ANTHROPIC_API_KEY)
self.model = CLAUDE_MODEL
def analyze_image(self, image_data, prompt):
"""Analyze image using Claude Vision"""
try:
encoded_image = base64.b64encode(image_data).decode('utf-8')
message = self.client.messages.create(
model=self.model,
max_tokens=1000,
messages=[{
"role": "user",
"content": [
{
"type": "text",
"text": prompt
},
{
"type": "image",
"source": {
"type": "base64",
"media_type": "image/jpeg",
"data": encoded_image
}
}
]
}]
)
return message.content[0].text
except Exception as e:
st.error(f"Error in image analysis: {str(e)}")
return None
def analyze_multiple_images(self, image_data_list, prompt):
"""Analyze multiple images together using Claude Vision"""
try:
# Create content list with prompt and all images
content = [{"type": "text", "text": prompt}]
# Add all images to the content
for idx, image_data in enumerate(image_data_list):
encoded_image = base64.b64encode(image_data).decode('utf-8')
content.append({
"type": "image",
"source": {
"type": "base64",
"media_type": "image/jpeg",
"data": encoded_image
}
})
message = self.client.messages.create(
model=self.model,
max_tokens=1500, # Increased for multiple image analysis
messages=[{
"role": "user",
"content": content
}]
)
return message.content[0].text
except Exception as e:
st.error(f"Error in multiple image analysis: {str(e)}")
return None
def detect_chart_type(self, image_data):
"""Detect chart type from image"""
prompt = """What type of financial chart is this?
Choose from: Candlestick, Line, OHLC, Area, or Other.
Just respond with one word."""
result = self.analyze_image(image_data, prompt)
return result.strip() if result else "Other"
def generate_diagram(self, prompt):
"""Generate an SVG diagram using Claude"""
try:
message = self.client.messages.create(
model=self.model,
max_tokens=1000,
messages=[{
"role": "user",
"content": f"""Please create an SVG diagram based on this request: {prompt}
Make the diagram clean, professional, and educational.
Use standard SVG elements and ensure the viewBox is properly set.
Keep colors accessible and include clear labels."""
}]
)
response = message.content[0].text
# Extract SVG content if present
if '<svg' in response and '</svg>' in response:
svg_start = response.find('<svg')
svg_end = response.find('</svg>') + 6
return response[svg_start:svg_end]
return None
except Exception as e:
st.error(f"Error generating diagram: {str(e)}")
return None
def generate_educational_content(self, prompt):
"""Generate educational content using Claude"""
try:
message = self.client.messages.create(
model=self.model,
max_tokens=1500,
messages=[{
"role": "user",
"content": prompt
}]
)
return message.content[0].text
except Exception as e:
st.error(f"Error generating educational content: {str(e)}")
return None
def get_educational_content(self, concept):
"""Get educational content about trading concepts"""
try:
message = self.client.messages.create(
model=self.model,
max_tokens=1000,
messages=[{
"role": "user",
"content": f"""Please explain the trading concept '{concept}'
in a clear, educational way. Include:
1. Basic Definition
2. How it Works
3. Key Characteristics
4. When to Look for It
5. Trading Implications
6. Common Mistakes to Avoid
7. Real-World Example"""
}]
)
return message.content[0].text
except Exception as e:
st.error(f"Error getting educational content: {str(e)}")
return None
def continue_analysis(self, question, previous_analysis, image_data=None):
"""Continue analysis based on follow-up question"""
try:
content = [
{
"type": "text",
"text": f"""Previous analysis: {previous_analysis}
User's follow-up question: {question}
Please provide a detailed answer to the follow-up question,
maintaining the context of the previous analysis."""
}
]
if image_data:
encoded_image = base64.b64encode(image_data).decode('utf-8')
content.append({
"type": "image",
"source": {
"type": "base64",
"media_type": "image/jpeg",
"data": encoded_image
}
})
message = self.client.messages.create(
model=self.model,
max_tokens=1000,
messages=[{"role": "user", "content": content}]
)
return message.content[0].text
except Exception as e:
st.error(f"Error in follow-up analysis: {str(e)}")
return None