Anthropic Provider
InfraPrism provides a drop-in replacement for the official Anthropic Python SDK, enabling cost tracking for all Claude models.
Installation
pip install infraprism
The InfraPrism SDK includes the Anthropic SDK as a dependency.
Basic Usage
Replace your Anthropic import with InfraPrism:
# Before
from anthropic import Anthropic
client = Anthropic()
# After
from infraprism import InfraPrismAnthropic
client = InfraPrismAnthropic()
All existing code continues to work:
response = client.messages.create(
model="claude-3-5-sonnet-20241022",
max_tokens=1024,
messages=[{"role": "user", "content": "Hello, Claude!"}],
)
print(response.content[0].text)
Adding Cost Attribution
Add entity parameters to track costs:
response = client.messages.create(
model="claude-3-5-sonnet-20241022",
max_tokens=1024,
messages=[{"role": "user", "content": "Explain machine learning"}],
entity_type="customer",
entity_id="acme-corp",
tags={"feature": "ai-assistant"},
)
Supported Models
InfraPrism tracks costs for all Claude models:
| Model | Input (per 1M tokens) | Output (per 1M tokens) |
|---|---|---|
| claude-3-5-sonnet | $3.00 | $15.00 |
| claude-3-5-haiku | $0.80 | $4.00 |
| claude-3-opus | $15.00 | $75.00 |
| claude-3-sonnet | $3.00 | $15.00 |
| claude-3-haiku | $0.25 | $1.25 |
Prices are updated automatically. Check the dashboard for current rates.
Streaming
Streaming is fully supported:
with client.messages.stream(
model="claude-3-5-sonnet-20241022",
max_tokens=1024,
messages=[{"role": "user", "content": "Write a poem"}],
entity_type="team",
entity_id="creative",
) as stream:
for text in stream.text_stream:
print(text, end="")
Token counts are calculated after the stream completes.
Async Support
Use the async client for async/await patterns:
from infraprism import AsyncInfraPrismAnthropic
import asyncio
async def main():
client = AsyncInfraPrismAnthropic()
response = await client.messages.create(
model="claude-3-5-sonnet-20241022",
max_tokens=1024,
messages=[{"role": "user", "content": "Hello!"}],
entity_type="customer",
entity_id="acme-corp",
)
print(response.content[0].text)
asyncio.run(main())
System Prompts
System prompts work as expected:
response = client.messages.create(
model="claude-3-5-sonnet-20241022",
max_tokens=1024,
system="You are a helpful coding assistant.",
messages=[{"role": "user", "content": "How do I sort a list in Python?"}],
entity_type="employee",
entity_id="eng-123",
)
Privacy Note: System prompts are never sent to InfraPrism—only token counts.
Tool Use
Claude’s tool use is fully supported:
tools = [
{
"name": "get_weather",
"description": "Get the current weather for a location",
"input_schema": {
"type": "object",
"properties": {
"location": {"type": "string", "description": "City name"}
},
"required": ["location"]
}
}
]
response = client.messages.create(
model="claude-3-5-sonnet-20241022",
max_tokens=1024,
tools=tools,
messages=[{"role": "user", "content": "What's the weather in Tokyo?"}],
entity_type="project",
entity_id="weather-bot",
)
Privacy Note: Tool definitions and results are not tracked—only token counts and costs.
Vision (Image Inputs)
Claude’s vision capabilities are supported:
import base64
# From URL
response = client.messages.create(
model="claude-3-5-sonnet-20241022",
max_tokens=1024,
messages=[
{
"role": "user",
"content": [
{
"type": "image",
"source": {
"type": "url",
"url": "https://example.com/image.jpg"
}
},
{"type": "text", "text": "Describe this image"}
]
}
],
entity_type="customer",
entity_id="acme-corp",
)
# From base64
with open("image.jpg", "rb") as f:
image_data = base64.standard_b64encode(f.read()).decode("utf-8")
response = client.messages.create(
model="claude-3-5-sonnet-20241022",
max_tokens=1024,
messages=[
{
"role": "user",
"content": [
{
"type": "image",
"source": {
"type": "base64",
"media_type": "image/jpeg",
"data": image_data
}
},
{"type": "text", "text": "What's in this image?"}
]
}
],
entity_type="customer",
entity_id="acme-corp",
)
Privacy Note: Images are never sent to InfraPrism.
Multi-Turn Conversations
Track costs across conversation turns:
messages = []
# First turn
messages.append({"role": "user", "content": "What is Python?"})
response = client.messages.create(
model="claude-3-5-sonnet-20241022",
max_tokens=1024,
messages=messages,
entity_type="customer",
entity_id="acme-corp",
session_id="conv-123", # Track as part of a session
)
messages.append({"role": "assistant", "content": response.content[0].text})
# Second turn
messages.append({"role": "user", "content": "What are its main features?"})
response = client.messages.create(
model="claude-3-5-sonnet-20241022",
max_tokens=1024,
messages=messages,
entity_type="customer",
entity_id="acme-corp",
session_id="conv-123",
)
See Sessions for more on conversation tracking.
Error Handling
Errors from Anthropic are passed through unchanged:
from anthropic import APIError
try:
response = client.messages.create(
model="claude-3-5-sonnet-20241022",
max_tokens=1024,
messages=[{"role": "user", "content": "Hello"}],
entity_type="customer",
entity_id="acme-corp",
)
except APIError as e:
print(f"Anthropic error: {e}")
Failed requests are not tracked.
Configuration
client = InfraPrismAnthropic(
api_key="sk-ant-...", # Anthropic key
infraprism_api_key="ip-...", # InfraPrism key
infraprism_environment="production",
)
Next Steps
- OpenAI Provider - Track OpenAI costs
- Azure OpenAI - Use with Azure
- Sessions - Track multi-turn conversations