Claude API Setup Guide for Python: API Keys, Streaming, Tool Use & Structured Output
Claude API Setup Guide for Python Developers
This comprehensive guide walks you through setting up the Anthropic Claude API in Python — from installation and API key management to advanced features like streaming responses, tool use, and structured output parsing. Whether you’re building a chatbot, an AI agent, or a data pipeline, this guide covers every essential workflow.
Step 1: Install the Anthropic Python SDK
Start by installing the official Anthropic SDK using pip. Python 3.8 or higher is required.
pip install anthropic
For projects using dependency management, add it to your requirements file:
# requirements.txt
anthropic>=0.39.0
Step 2: API Key Management
Obtain your API key from the **Anthropic Console** at console.anthropic.com. Never hardcode API keys in source files.
Option A: Environment Variable (Recommended)
# Linux / macOS
export ANTHROPIC_API_KEY=“YOUR_API_KEY”
Windows PowerShell
$env:ANTHROPIC_API_KEY=“YOUR_API_KEY”
The SDK automatically reads ANTHROPIC_API_KEY from your environment:
from anthropic import Anthropic
client = Anthropic() # picks up ANTHROPIC_API_KEY automatically
Option B: Explicit Initialization
import os
from anthropic import Anthropic
client = Anthropic(api_key=os.environ.get("ANTHROPIC_API_KEY"))
Option C: .env File with python-dotenv
pip install python-dotenv# .env
ANTHROPIC_API_KEY=YOUR_API_KEY
from dotenv import load_dotenv from anthropic import Anthropic
load_dotenv() client = Anthropic()
Security tip: Always add .env to your .gitignore to prevent accidental commits.
Step 3: Send Your First Message
Use the messages.create method to send a basic request to Claude:
from anthropic import Anthropic
client = Anthropic()
response = client.messages.create(
model=“claude-sonnet-4-20250514”,
max_tokens=1024,
messages=[
{“role”: “user”, “content”: “Explain Python decorators in three sentences.”}
]
)
print(response.content[0].text)
Step 4: Streaming Responses
For real-time output — critical in chat UIs and CLI tools — use the streaming API:
from anthropic import Anthropic
client = Anthropic()
with client.messages.stream(
model=“claude-sonnet-4-20250514”,
max_tokens=1024,
messages=[
{“role”: “user”, “content”: “Write a short poem about Python programming.”}
]
) as stream:
for text in stream.text_stream:
print(text, end="", flush=True)
print() # newline after stream completes
The streaming context manager handles connection lifecycle automatically, including cleanup on errors.
Step 5: Tool Use (Function Calling)
Tool use lets Claude invoke functions you define. This is essential for building AI agents that interact with external systems.
from anthropic import Anthropic
import json
client = Anthropic()
tools = [
{
“name”: “get_weather”,
“description”: “Get the current weather for a given city.”,
“input_schema”: {
“type”: “object”,
“properties”: {
“city”: {
“type”: “string”,
“description”: “City name, e.g. San Francisco”
}
},
“required”: [“city”]
}
}
]
response = client.messages.create(
model=“claude-sonnet-4-20250514”,
max_tokens=1024,
tools=tools,
messages=[
{“role”: “user”, “content”: “What is the weather in Tokyo?”}
]
)
Check if Claude wants to use a tool
for block in response.content:
if block.type == “tool_use”:
print(f”Tool: {block.name}”)
print(f”Input: {json.dumps(block.input, indent=2)}”)
# Execute your function here, then send the result back
tool_result_message = {
“role”: “user”,
“content”: [
{
“type”: “tool_result”,
“tool_use_id”: block.id,
“content”: ’{“temperature”: “18°C”, “condition”: “Partly cloudy”}’
}
]
}
# Send the tool result back for Claude’s final answer
follow_up = client.messages.create(
model=“claude-sonnet-4-20250514”,
max_tokens=1024,
tools=tools,
messages=[
{“role”: “user”, “content”: “What is the weather in Tokyo?”},
{“role”: “assistant”, “content”: response.content},
tool_result_message
]
)
print(follow_up.content[0].text)
Step 6: Structured Output Parsing
To get JSON output reliably, combine a system prompt with response parsing:
import json
from anthropic import Anthropic
client = Anthropic()
response = client.messages.create(
model=“claude-sonnet-4-20250514”,
max_tokens=1024,
system=“You are a data extraction assistant. Always respond with valid JSON only, no markdown.”,
messages=[
{
“role”: “user”,
“content”: “Extract structured data: ‘John Smith, age 34, works as a senior engineer at Acme Corp in New York’”
}
]
)
raw_text = response.content[0].text
parsed = json.loads(raw_text)
print(json.dumps(parsed, indent=2))
For guaranteed JSON structure, use tool use with an output schema — Claude will always return data matching your defined input_schema.
Pro Tips for Power Users
- Use system prompts to set persistent behavior, persona, or output format rules across messages.- Set
temperature=0for deterministic, reproducible outputs in production pipelines.- Retry with exponential backoff: The SDK raisesanthropic.RateLimitError. Wrap calls in retry logic for high-throughput applications.- Track token usage viaresponse.usage.input_tokensandresponse.usage.output_tokensto monitor costs.- Use the async client (AsyncAnthropic) for concurrent requests in web servers or async pipelines.- Model selection: Useclaude-sonnet-4-20250514for balanced speed and quality; useclaude-opus-4-20250514for maximum reasoning capability.
Troubleshooting Common Errors
| Error | Cause | Fix |
|---|---|---|
AuthenticationError | Invalid or missing API key | Verify ANTHROPIC_API_KEY is set and valid in your console |
RateLimitError | Too many requests per minute | Implement exponential backoff; check your tier limits |
BadRequestError: max_tokens | max_tokens exceeds model limit | Reduce max_tokens (Claude Sonnet supports up to 8192) |
json.JSONDecodeError | Claude returned non-JSON text | Use tool use for guaranteed JSON, or add explicit system prompt instructions |
APIConnectionError | Network or proxy issue | Check internet connectivity, firewall, or set HTTPS_PROXY |
How do I switch between Claude models in the Python SDK?
Change the model parameter in messages.create(). Use claude-sonnet-4-20250514 for most tasks, claude-haiku-4-5-20251001 for fast low-cost operations, or claude-opus-4-20250514 for complex reasoning. The SDK interface stays identical across all models.
Can I use the Claude API asynchronously in Python?
Yes. Import AsyncAnthropic instead of Anthropic and use await client.messages.create() inside an async function. This is ideal for web frameworks like FastAPI or batch processing with asyncio.gather() for concurrent requests.
What is the best way to ensure Claude returns valid JSON?
The most reliable method is to use tool use (function calling) with a defined input_schema. Claude is constrained to return data matching the schema. For simpler cases, include explicit instructions in the system prompt such as “Respond with valid JSON only” and parse with json.loads() with error handling.