anthropic
The official Python SDK for Anthropic's Claude API. It wraps the Messages API with typed request and response models built on httpx and pydantic, ships both sync and async clients, and includes streaming helpers, tool-use support, and token counting. Optional extras add AWS Bedrock, Google Vertex, an aiohttp transport, MCP types, and webhook verification. It is an API client, not an agent framework: prompts, memory, and orchestration loops stay in your code.
If you call Claude from Python, use this; there is no serious case for hand-rolling the HTTP layer. Treat the 0.x version number as real advice: pin it and read release notes before upgrading.
Use it if
- You call Claude models from Python and want the official typed client instead of hand-rolled httpx requests
- You need the same call shapes against the Claude API, AWS Bedrock, or Google Vertex; the SDK ships dedicated client classes and extras for each
- You want async support and SSE streaming handled for you, including a context-manager streaming helper that cleans up connections
- You want provider-agnostic code; a router layer like litellm swaps models without touching call sites, this SDK is Claude-only by design
- You are allergic to 0.x churn: the package sits at 0.120.2 with frequent releases, so pin the version and read changelogs, minor bumps can move helper APIs
- You expect agent loops, memory, or tool execution out of the box; this is a thin API client and all of that is your code (or a separate agent framework)
Setup reality
pip install anthropic plus an ANTHROPIC_API_KEY env var and you are making requests in five lines; the client reads the key by default. The rough edges: max_tokens is a required argument on every messages.create call, the version is still 0.x so unpinned installs can pick up breaking minors, Bedrock and Vertex each need their own extra (anthropic[bedrock], anthropic[vertex]) plus separate cloud auth, and configuration follows httpx idioms (httpx.Timeout objects, proxies on the transport) rather than the requests-style knobs many Python devs reach for first.
Patterns
Send a message to Claudecreate-message
import os
from anthropic import Anthropic
client = Anthropic() # reads ANTHROPIC_API_KEY
message = client.messages.create(
model="claude-opus-4-6",
max_tokens=1024,
messages=[{"role": "user", "content": "Hello, Claude"}],
)
print(message.content[0].text)max_tokens is required on every call, unlike the OpenAI SDK; content comes back as a list of typed blocks, not a plain string.
Set a system promptsystem-prompt
message = client.messages.create(
model="claude-opus-4-6",
max_tokens=1024,
system="You are a terse code reviewer.",
messages=[{"role": "user", "content": "Review this diff..."}],
)system is a top-level parameter, not a message role; a {'role': 'system'} message raises an error.
Stream a responsestream-text
with client.messages.stream(
model="claude-opus-4-6",
max_tokens=1024,
messages=[{"role": "user", "content": "Write a limerick about CI"}],
) as stream:
for text in stream.text_stream:
print(text, end="", flush=True)
final = stream.get_final_message()The context manager closes the SSE connection for you; text_stream yields only text deltas, and get_final_message() returns the assembled message.
Use the async clientasync-client
import asyncio
from anthropic import AsyncAnthropic
client = AsyncAnthropic()
async def main():
message = await client.messages.create(
model="claude-opus-4-6",
max_tokens=1024,
messages=[{"role": "user", "content": "Hello"}],
)
print(message.content[0].text)
asyncio.run(main())Sync and async clients mirror each other method for method; do not share one client across event loops.
Define a tool and return its resulttool-use
message = client.messages.create(
model="claude-opus-4-6",
max_tokens=1024,
tools=[{
"name": "get_weather",
"description": "Get current weather for a city",
"input_schema": {
"type": "object",
"properties": {"city": {"type": "string"}},
"required": ["city"],
},
}],
messages=[{"role": "user", "content": "Weather in Pune?"}],
)
if message.stop_reason == "tool_use":
block = next(b for b in message.content if b.type == "tool_use")
result = my_weather_lookup(**block.input)
followup = client.messages.create(
model="claude-opus-4-6",
max_tokens=1024,
tools=[...], # same tools list
messages=[
{"role": "user", "content": "Weather in Pune?"},
{"role": "assistant", "content": message.content},
{"role": "user", "content": [{
"type": "tool_result",
"tool_use_id": block.id,
"content": str(result),
}]},
],
)The SDK never executes tools; you run the function and send a tool_result block back, echoing the full assistant content in the history.
Send an imagevision-image
import base64
with open("chart.png", "rb") as f:
data = base64.standard_b64encode(f.read()).decode()
message = client.messages.create(
model="claude-opus-4-6",
max_tokens=1024,
messages=[{
"role": "user",
"content": [
{"type": "image", "source": {
"type": "base64",
"media_type": "image/png",
"data": data,
}},
{"type": "text", "text": "What does this chart show?"},
],
}],
)media_type must match the actual bytes (image/png, image/jpeg, image/webp, image/gif) or the API rejects the request.
Handle API errors by typehandle-errors
import anthropic
try:
client.messages.create(
model="claude-opus-4-6",
max_tokens=1024,
messages=[{"role": "user", "content": "Hello"}],
)
except anthropic.RateLimitError:
... # 429: back off
except anthropic.APIStatusError as e:
print(e.status_code, e.response)
except anthropic.APIConnectionError:
... # network problemRate limits and transient server errors are already retried automatically (default 2 retries) before these exceptions reach you.
Configure retries and timeoutsconfigure-retries-timeout
import httpx
from anthropic import Anthropic
client = Anthropic(
max_retries=0, # default is 2
timeout=httpx.Timeout(60.0, connect=5.0),
)
# or per request
client.with_options(max_retries=5).messages.create(
model="claude-opus-4-6",
max_tokens=1024,
messages=[{"role": "user", "content": "Hello"}],
)Timeouts are httpx-style; pass a plain float for a global cap or an httpx.Timeout for per-phase control.
Count tokens before sendingcount-tokens
count = client.messages.count_tokens(
model="claude-opus-4-6",
messages=[{"role": "user", "content": "Hello, Claude"}],
)
print(count.input_tokens)Counting runs server-side without generating anything; counts are model-specific, so pass the same model you will call with.
Call Claude through AWS Bedrockbedrock-client
# pip install 'anthropic[bedrock]'
from anthropic import AnthropicBedrock
client = AnthropicBedrock(aws_region="us-west-2")
message = client.messages.create(
model="anthropic.claude-opus-4-6-v1:0",
max_tokens=1024,
messages=[{"role": "user", "content": "Hello"}],
)Auth comes from the standard AWS credential chain, not ANTHROPIC_API_KEY, and Bedrock uses its own model id format; check the ids enabled in your AWS account.
Alternatives
| Package | Registry | Pick it when |
|---|---|---|
| openai | PyPI | The equivalent official client if you are on OpenAI models |
| litellm | PyPI | One interface over many providers, Claude included, when you expect to swap models |
| langchain-anthropic | PyPI | You are already inside LangChain and want Claude as a chat model there |