anthropic review
`anthropic` is Anthropic's Python SDK for the Claude API. It maps Messages requests, streamed events, tool calls, batches, files, token counts, and errors onto typed Python objects, with matching synchronous and asyncio clients. The current 1.1.0 release adds Organization API endpoints and an `updates` display mode for thinking. The larger change arrived in 1.0: Python 3.10 became the minimum, the transport moved to `httpx2`, the old Text Completions client disappeared, and raw-response reads changed. Our installed 1.0.0 distribution carried `py.typed`, so mypy and Pyright can inspect the package without third-party stubs.
Our anthropic 1.0.0 install took 0.9 seconds, used 19 MB across 15 packages, and produced 0 pip-audit findings, but its cold import took 12.94 seconds. Install the current 1.1.0 SDK for a Python service committed to Claude; keep a provider adapter or plain HTTP boundary when vendor portability matters more than the official typed surface.
We installed it
| Install | ✓ · 0.9s | 15 packages on disk · 19 MB |
| Import | ✓ | import anthropic in 12.94s · pure Python · py.typed · requires Python >=3.10 |
| Known vulns | 0 | (pip-audit) |
Answers from our run
Does anthropic install cleanly?
Yes. In a fresh container with an empty cache, pip install anthropic finished in 0.9s, leaving 15 packages and 19 MB on disk. pip-audit reported no known vulnerabilities.
What does anthropic need to run?
Python >=3.10, and nothing compiled: it is pure Python. In our run import anthropic succeeded in 12.94s, and the package ships py.typed for type checkers.
anthropic or openai: which should you use?
openai: Choose it when the application is built around OpenAI endpoints and response types. Our anthropic 1.0.0 install took 0.9 seconds, used 19 MB across 15 packages, and produced 0 pip-audit findings, but its cold import took 12.94 seconds.
When should you not use anthropic?
One application must swap among model vendors behind the same call signature. This SDK exposes Claude concepts directly; LiteLLM or an application-owned adapter is a cleaner provider boundary.
Discussed on
- hnAnthropic acquires Bun2,192 points
- hnZig Creator Calls Spade a Spade, Anthropic Blows Smoke1,554 points
- hnS&P 500 rejects SpaceX, also blocking entry for OpenAI and Anthropic1,484 points
- hnI’ve joined Anthropic1,431 points
- hnI am directing the Department of War to designate Anthropic a supply-chain risk1,362 points
Use it if
- A Python service calls Claude directly and should use Anthropic's request and response types instead of maintaining JSON shapes by hand.
- The same codebase needs blocking calls, asyncio calls, server streaming, and message batches with a consistent client surface.
- Your workflow uses tool calls, structured output, token counting, uploaded files, or request IDs and benefits from SDK helpers for those Claude-specific features.
- Claude is reached through Anthropic, Amazon Bedrock, or Google Vertex AI and separate official client classes are preferable to a provider-neutral wrapper.
- One application must swap among model vendors behind the same call signature. This SDK exposes Claude concepts directly; LiteLLM or an application-owned adapter is a cleaner provider boundary.
- Your observability or test stack patches `httpx`. Since 1.0 the SDK uses `httpx2`, so HTTPX instrumentation, respx, pytest-httpx, Sentry hooks, or VCR recording can miss its traffic until process startup aliases the modules.
- The code still calls `client.completions.create()`, imports `HUMAN_PROMPT`, or passes removed sampling arguments directly. Version 1 requires a Messages migration and rejects several former parameters at the method boundary.
- Python 3.9 is still a deployment target. The supported floor is Python 3.10, while our measured import used Python 3.12.
- You expect a declared tool to run safely on its own. A tool schema tells Claude what it may request; your application must authorize the call, validate the input, execute it, and return the matching result.
Setup reality
We installed anthropic 1.0.0 in a clean Python 3.12 Bookworm container. The install finished in 0.9 seconds and left 15 packages occupying 19 MB. pip-audit found 0 known vulnerabilities. The distribution reported 16 direct dependencies, required Python 3.10 or newer, contained only Python code, and shipped py.typed. import anthropic succeeded, but took 12.94 seconds in that cold, cache-free sandbox. Measure startup in your own short-lived worker before putting it on a latency-sensitive path.
Anthropic() reads ANTHROPIC_API_KEY; every generation still needs a model, max_tokens, and message content. Bedrock and Vertex use their own client classes, optional extras, cloud credential chains, regions, and provider model IDs. Reuse a client across requests so its connection pool earns its keep. A context manager or an explicit close() is appropriate when the client lifetime is shorter than the process.
Version 1 replaces httpx objects with httpx2 objects. Plain numeric timeouts still work, while a custom old httpx.Client raises TypeError during client construction. Instrumentation can fail more quietly because a tracer that patches only httpx never sees httpx2 traffic. The migration guide's httpx2.alias_httpx() must run before any httpx import and belongs in an application entry point, not a reusable package.
The client retries connection failures plus selected 408, 409, 429, and 5xx responses. Adding another retry loop can multiply billable calls, so cap attempts and make tool side effects idempotent. Streaming helpers own an open response and should stay inside their context manager. On AsyncAnthropic, raw-response parse(), read(), text(), and json() calls are awaitable. Version 1.1.0 adds Organization endpoints, but it does not undo these 1.0 migration rules.
Patterns
Send a Messages API request create-message
from anthropic import Anthropic
client = Anthropic()
message = client.messages.create(
model="claude-opus-5", max_tokens=800,
messages=[{"role": "user", "content": "Explain this traceback"}],
)
print(message.content[0].text)`Anthropic()` uses `ANTHROPIC_API_KEY`. A response may contain several block types, so inspect each block's `type` before reading `text`.
Supply system instructions set-system-prompt
message = client.messages.create(
model="claude-opus-5", max_tokens=500,
system="Return concise Python review comments.",
messages=[{"role": "user", "content": diff}],
)The Messages API accepts instructions through the top-level `system` argument, not a message with a `system` role.
Print streamed text stream-response
with client.messages.stream(
model="claude-opus-5", max_tokens=1000,
messages=[{"role": "user", "content": "Draft a release note"}],
) as stream:
for text in stream.text_stream:
print(text, end="", flush=True)
final_message = stream.get_final_message()The stream holds an HTTP response open. Iterate and collect the final message before leaving the context manager.
Make an asyncio request call-async-client
import asyncio
from anthropic import AsyncAnthropic
async def main():
async with AsyncAnthropic() as client:
message = await client.messages.create(
model="claude-opus-5", max_tokens=500,
messages=[{"role": "user", "content": "Summarize this log"}],
)
print(message.content[0].text)
asyncio.run(main())Keep an async client on one event loop. The context manager closes its pooled connections when `main()` exits.
Describe an application tool declare-tool
tools = [{
"name": "lookup_order",
"description": "Return an order by numeric ID",
"input_schema": {
"type": "object",
"properties": {"order_id": {"type": "integer"}},
"required": ["order_id"],
"additionalProperties": False,
},
}]A JSON Schema constrains requested arguments, but your execution boundary still needs authorization and validation.
Continue after a tool call submit-tool-result
call = next(block for block in message.content if block.type == "tool_use")
order = lookup_order(call.input["order_id"])
result = {
"type": "tool_result",
"tool_use_id": call.id,
"content": str(order),
}Pair a result with the exact `tool_use_id` and include the preceding assistant content when sending the next message.
Count input tokens count-tokens
count = client.messages.count_tokens(
model="claude-opus-5",
messages=[{"role": "user", "content": prompt}],
)
print(count.input_tokens)Token counting is a server request tied to the selected model. Pass the same blocks planned for generation.
Branch on SDK error classes handle-errors
import anthropic
try:
message = client.messages.create(...)
except anthropic.RateLimitError as exc:
queue_for_later(exc)
except anthropic.APIConnectionError as exc:
record_network_failure(exc)
except anthropic.APIStatusError as exc:
record_http_failure(exc.status_code, exc.request_id)Internal retries may run before an exception reaches this handler. Include them in the total attempt budget.
Set connect and total timeouts configure-timeouts
import httpx2
from anthropic import Anthropic
client = Anthropic(
timeout=httpx2.Timeout(45.0, connect=5.0),
max_retries=1,
)Version 1 accepts `httpx2` objects. An object constructed by the old `httpx` package is the wrong runtime type.
Read response metadata inspect-raw-response
response = client.messages.with_raw_response.create(
model="claude-opus-5", max_tokens=300,
messages=[{"role": "user", "content": "Hello"}],
)
print(response.request_id, response.status_code)
message = response.parse()With `AsyncAnthropic`, `parse()`, `read()`, `text()`, and `json()` are coroutines in version 1.
Call Claude through Bedrock use-bedrock
from anthropic import AnthropicBedrock
client = AnthropicBedrock(aws_region="us-west-2")
message = client.messages.create(
model=bedrock_model_id, max_tokens=500,
messages=[{"role": "user", "content": "Summarize this ticket"}],
)Install the `bedrock` extra. Version 1 requires a region and uses the AWS credential chain.
Call Claude through Vertex AI use-vertex
from anthropic import AnthropicVertex
client = AnthropicVertex(project_id=gcp_project_id, region="us-east5")
message = client.messages.create(
model=vertex_model_id, max_tokens=500,
messages=[{"role": "user", "content": "Classify this ticket"}],
)Install the `vertex` extra and use Application Default Credentials plus a Vertex model identifier.
Alternatives
| Package | Registry | Pick it when |
|---|---|---|
| openai | PyPI | Choose it when the application is built around OpenAI endpoints and response types. |
| google-genai | PyPI | Choose it for Gemini models and Google-native file or media workflows. |
| litellm | PyPI | Choose it when provider routing and fallback policy matter more than direct access to Claude-specific types. |
| httpx | PyPI | Choose a plain HTTP client when you need a small custom integration and will own Claude wire formats and error handling. |
More ai / ml guides
openai · mcp · huggingface-hub · @modelcontextprotocol/sdk · scikit-learn · tiktoken · the whole shelf →
How this guide is made: grounded in the library's documentation, release notes, changelog, and issue history, on a fixed rubric — not a hands-on install of every release. The 50 most-downloaded entries are additionally install-verified in clean containers. Corrections: contact the desk.

