Installing and Configuring the Anthropic Python SDK
The official anthropic Python package is the recommended way to call the Claude API from Python.
It handles authentication headers, request serialization, retries, and response parsing so you don't have to build that plumbing yourself.
This page covers installing it, configuring a client, and making your first real call.
Summary
The anthropic package installs with a single pip install anthropic command into any Python 3.8+ environment.
A client instance, anthropic.Anthropic(), is the object you configure once and reuse for every call in your application.
By default it reads your API key from ANTHROPIC_API_KEY, but you can override the key, timeout, retry count, and even the base URL through constructor arguments.
There's also an async client, anthropic.AsyncAnthropic, with the same interface for use inside asyncio applications.
Getting configuration right once, in one place, avoids scattering ad-hoc client instances with inconsistent settings across a codebase.
Recipe
Quick-reference recipe card - copy-paste ready.
pip install anthropic
export ANTHROPIC_API_KEY="sk-ant-..."import anthropic
client = anthropic.Anthropic()
response = client.messages.create(
model="claude-sonnet-5-20260630",
max_tokens=200,
messages=[{"role": "user", "content": "Confirm the SDK is installed correctly."}],
)
print(response.content[0].text)When to reach for this:
- Starting any new Python project that calls Claude.
- You want automatic retries, typed responses, and streaming support without writing raw HTTP code.
- You're building either a synchronous script or an
asyncio-based service (useAsyncAnthropicfor the latter).
Working Example
import os
import anthropic
# A recommended virtual environment first:
# python -m venv .venv && source .venv/bin/activate
# pip install anthropic
def build_client() -> anthropic.Anthropic:
return anthropic.Anthropic(
api_key=os.environ["ANTHROPIC_API_KEY"],
timeout=30.0, # seconds, per request
max_retries=2, # automatic retries for 429/5xx responses
)
def main() -> None:
client = build_client()
response = client.messages.create(
model="claude-sonnet-5-20260630",
max_tokens=150,
messages=[
{"role": "user", "content": "List three uses for the anthropic Python SDK."}
],
)
print(response.content[0].text)
print(f"Tokens used: {response.usage.input_tokens} in / {response.usage.output_tokens} out")
if __name__ == "__main__":
main()What this demonstrates:
- Building the client once, in a dedicated function, rather than constructing it inline everywhere it's used.
- Setting explicit
timeoutandmax_retriesinstead of relying on defaults, which matters once you're past a quick test. - Reading
usageoff the response to track token consumption alongside the generated text.
Deep Dive
How It Works
pip install anthropicpulls the package (and its HTTP dependencies) from PyPI; it supports Python 3.8 and newer.- Package managers like
poetry add anthropicoruv add anthropicwork identically and are recommended for projects that pin dependencies. anthropic.Anthropic()is a synchronous client:client.messages.create(...)blocks until the response (or the full stream) is received.anthropic.AsyncAnthropic()mirrors the same method names but returns awaitables, for use insideasync deffunctions.- Every client is safe to construct once and reuse across many calls; there's no need to build a new client per request.
Useful Constructor Options
| Option | Type | Default | Purpose |
|---|---|---|---|
api_key | str | reads ANTHROPIC_API_KEY | Override or explicitly pass the API key |
timeout | float or httpx.Timeout | SDK default (several minutes) | Max time to wait for a request/response |
max_retries | int | 2 | Automatic retries for 429/5xx with backoff |
base_url | str | Anthropic's default API URL | Point at a proxy, gateway, or test endpoint |
The Async Client
import asyncio
import anthropic
async def main() -> None:
client = anthropic.AsyncAnthropic()
response = await client.messages.create(
model="claude-haiku-4-5-20260601",
max_tokens=100,
messages=[{"role": "user", "content": "Say hi asynchronously."}],
)
print(response.content[0].text)
asyncio.run(main())Python Notes
# Reuse one client instance across a module or app rather than
# constructing a new one per function call - connections and
# retry configuration are set up once, at import or startup time.
import anthropic
client = anthropic.Anthropic() # module-level, created once
def summarize(text: str) -> str:
response = client.messages.create(
model="claude-haiku-4-5-20260601",
max_tokens=200,
messages=[{"role": "user", "content": f"Summarize: {text}"}],
)
return response.content[0].textGotchas
- Installing into the system Python instead of a virtual environment. This causes version conflicts across unrelated projects over time. Fix: create a virtual environment (
venv,poetry, oruv) per project before installing. - Constructing a new client on every function call. This is wasteful and can bypass connection reuse. Fix: build the client once, at module or application startup, and pass it around or reuse a module-level instance.
- Using the sync client inside an
async deffunction.client.messages.create(...)blocks the event loop when called synchronously inside async code. Fix: useanthropic.AsyncAnthropicwithawaitinside async functions. - Not pinning the SDK version in production. An unpinned
anthropicdependency can pull in breaking changes on a fresh install. Fix: pin a specific version range inrequirements.txtor your lockfile, and upgrade deliberately. - Overriding
base_urlaccidentally by copying example config. Pointing at the wrong URL causes confusing connection errors that look unrelated to configuration. Fix: only setbase_urlintentionally (e.g. for a proxy), and remove it if copied from an unrelated example. - Assuming
timeoutcovers the whole streaming response. For long streamed generations, a too-short timeout can cut off a legitimate in-progress stream. Fix: set a longer timeout for streaming use cases, or use per-request timeout overrides.
Alternatives
| Alternative | Use When | Don't Use When |
|---|---|---|
Official anthropic Python SDK | Almost always, for Python projects | Never, this is the recommended default |
Raw HTTP client (requests/httpx) | You need to avoid the dependency, or you're debugging at the HTTP level | You want built-in retries, typed responses, and streaming parsing |
anthropic.AsyncAnthropic | High-concurrency asyncio services | Simple scripts where sync code is simpler to read and debug |
FAQs
What Python versions does the anthropic SDK support?
Python 3.8 and newer; check the package's PyPI page for the exact current floor, since minimum supported versions can shift across major SDK releases.
Do I need to set ANTHROPIC_API_KEY if I pass api_key explicitly?
No, an explicit api_key argument to anthropic.Anthropic(api_key=...) takes precedence over the environment variable.
What's the difference between Anthropic and AsyncAnthropic?
Anthropic is a synchronous client whose methods block until complete; AsyncAnthropic exposes the same methods as awaitables for use inside asyncio code.
Should I create a new client for every request?
No, construct one client instance and reuse it across your application; there's no benefit to recreating it per call and it adds unnecessary overhead.
What does max_retries actually retry?
Transient failures, 429 rate-limit responses and 5xx server errors, using exponential backoff; it does not retry 400-class validation errors, since those won't succeed on retry.
Can I use the SDK behind a corporate proxy or custom gateway?
Yes, pass a base_url argument pointing at your proxy or gateway when constructing the client.
How do I know if my installation succeeded?
Run a minimal script that constructs a client and makes one messages.create() call; a successful response confirms both installation and authentication.
Is a virtual environment required?
Not strictly required, but strongly recommended, it isolates the anthropic package version from other projects on the same machine.
What happens if I call the sync client's create() method inside an async function?
It runs synchronously and blocks the event loop for the duration of the call, which can stall other concurrent async work; use AsyncAnthropic instead in async code.
Can I set a global default model so I don't repeat it on every call?
Not directly via the constructor since model is a per-call parameter, but you can wrap the client in your own helper function or class that supplies a default model argument.
Does the timeout option apply per request or for the whole client lifetime?
Per request; it's how long a single messages.create() call is allowed to take before raising a timeout error.
Related
- Claude API Fundamentals Basics - your first several working calls.
- Authenticating Claude API Calls with the x-api-key Header - key configuration in depth.
- Building a Reusable Claude API Client Wrapper - wrapping the client with app-wide defaults.
- Handling Rate Limits with Exponential Backoff - what
max_retriesdoes under the hood.
Stack versions: Written against the Claude model lineup current as of ~June 2026 - Claude Fable 5, Claude Opus 4.8, Claude Sonnet 5 (the default), and Claude Haiku 4.5 - and the official
anthropicPython SDK (latest 0.x release). Model names, SDK versions, and pricing move quickly - verify current specifics at platform.claude.com/docs before relying on them.