Implementation:Anthropics Anthropic sdk python BaseClient
| Knowledge Sources | |
|---|---|
| Domains | SDK_Infrastructure, HTTP_Client |
| Last Updated | 2026-02-15 12:00 GMT |
Overview
This page documents the core HTTP client infrastructure classes -- BaseClient, SyncAPIClient, and AsyncAPIClient -- that provide the foundational request/response lifecycle for all Anthropic API interactions.
Description
The _base_client.py module is the most critical infrastructure file in the SDK. It defines a three-tier class hierarchy: BaseClient contains shared logic for header construction, URL preparation, retry/backoff calculation, response parsing, and platform telemetry. SyncAPIClient and AsyncAPIClient extend BaseClient with synchronous and asynchronous HTTP verb methods (get, post, put, patch, delete) respectively, wrapping httpx.Client and httpx.AsyncClient.
The module also implements pagination infrastructure via BaseSyncPage and BaseAsyncPage, default httpx client configurations with TCP keep-alive socket options and proxy support (_DefaultHttpxClient, _DefaultAsyncHttpxClient), and helper classes such as PageInfo and AsyncPaginator. The retry logic implements exponential backoff with jitter, respects Retry-After headers, and retries on status codes 408, 409, 429, and 5xx.
Usage
These classes are not instantiated directly by end users. Instead, the Anthropic and AsyncAnthropic client classes in _client.py inherit from SyncAPIClient and AsyncAPIClient respectively. All API resource methods (e.g., messages.create()) ultimately delegate to the HTTP verb methods defined here.
Code Reference
Source Location
- Repository: Anthropic SDK Python
- File:
src/anthropic/_base_client.py - Lines: 1-2267
- Key classes:
BaseClient(line 368),SyncAPIClient(line 910),AsyncAPIClient(line 1548)
Signature
class BaseClient(Generic[_HttpxClientT, _DefaultStreamT]):
_client: _HttpxClientT
_version: str
_base_url: URL
max_retries: int
timeout: Union[float, Timeout, None]
_strict_response_validation: bool
_idempotency_header: str | None
_default_stream_cls: type[_DefaultStreamT] | None = None
def __init__(
self,
*,
version: str,
base_url: str | URL,
_strict_response_validation: bool,
max_retries: int = DEFAULT_MAX_RETRIES,
timeout: float | Timeout | None = DEFAULT_TIMEOUT,
custom_headers: Mapping[str, str] | None = None,
custom_query: Mapping[str, object] | None = None,
) -> None
class SyncAPIClient(BaseClient[httpx.Client, Stream[Any]]):
def __init__(
self,
*,
version: str,
base_url: str | URL,
max_retries: int = DEFAULT_MAX_RETRIES,
timeout: float | Timeout | None | NotGiven = not_given,
http_client: httpx.Client | None = None,
custom_headers: Mapping[str, str] | None = None,
custom_query: Mapping[str, object] | None = None,
_strict_response_validation: bool,
) -> None
class AsyncAPIClient(BaseClient[httpx.AsyncClient, AsyncStream[Any]]):
def __init__(
self,
*,
version: str,
base_url: str | URL,
_strict_response_validation: bool,
max_retries: int = DEFAULT_MAX_RETRIES,
timeout: float | Timeout | None | NotGiven = not_given,
http_client: httpx.AsyncClient | None = None,
custom_headers: Mapping[str, str] | None = None,
custom_query: Mapping[str, object] | None = None,
) -> None
Import
from anthropic._base_client import SyncAPIClient, AsyncAPIClient, BaseClient
I/O Contract
Inputs
| Name | Type | Required | Description |
|---|---|---|---|
version |
str |
Yes | SDK version string used in User-Agent and telemetry headers |
base_url |
URL | Yes | Root URL for all API requests; trailing slash is enforced automatically |
max_retries |
int |
No (default: 2) | Maximum number of automatic retries on transient failures |
timeout |
Timeout | None | No (default: 600s) | Request timeout; defaults to 10 minutes total with 5 second connect |
http_client |
httpx.AsyncClient | None | No | Custom httpx client for advanced transport configuration |
custom_headers |
None | No | Extra HTTP headers sent with every request |
custom_query |
None | No | Extra query parameters appended to every request URL |
_strict_response_validation |
bool |
Yes | When True, uses validate_type() instead of construct_type() for response parsing
|
Outputs
| Name | Type | Description |
|---|---|---|
ResponseT |
Generic type parameter | Parsed response object; type depends on the cast_to argument passed to request methods
|
Stream[T] / AsyncStream[T] |
Stream wrapper | Returned when stream=True is passed to request methods
|
Key Methods
HTTP Verb Methods
Both SyncAPIClient and AsyncAPIClient provide:
# SyncAPIClient
def get(self, path: str, *, cast_to: Type[ResponseT], options: RequestOptions = {}, stream: bool = False) -> ResponseT
def post(self, path: str, *, cast_to: Type[ResponseT], body: Body | None = None, options: RequestOptions = {}, stream: bool = False) -> ResponseT
def put(self, path: str, *, cast_to: Type[ResponseT], body: Body | None = None, options: RequestOptions = {}) -> ResponseT
def patch(self, path: str, *, cast_to: Type[ResponseT], body: Body | None = None, options: RequestOptions = {}) -> ResponseT
def delete(self, path: str, *, cast_to: Type[ResponseT], options: RequestOptions = {}) -> ResponseT
# AsyncAPIClient (same signatures, all async)
async def get(...) -> ResponseT
async def post(...) -> ResponseT | _AsyncStreamT
Retry Logic
The retry mechanism in _retry_request / _retry_request implements:
- Exponential backoff with jitter: Starts at
INITIAL_RETRY_DELAY(0.5s) and caps atMAX_RETRY_DELAY(8s) - Retry-After header support: Respects both seconds and HTTP-date formats
- Retryable status codes: 408 (timeout), 409 (conflict), 429 (rate limit), 5xx (server errors)
- x-should-retry header: Server can explicitly override retry behavior
Usage Examples
Basic Usage (via Anthropic client)
import anthropic
# SyncAPIClient is used internally by Anthropic
client = anthropic.Anthropic(api_key="sk-ant-...")
# All resource methods delegate to SyncAPIClient.post() / .get() etc.
message = client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=1024,
messages=[{"role": "user", "content": "Hello"}],
)
# AsyncAPIClient is used internally by AsyncAnthropic
async_client = anthropic.AsyncAnthropic(api_key="sk-ant-...")
message = await async_client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=1024,
messages=[{"role": "user", "content": "Hello"}],
)
Context Manager Support
# Sync
with anthropic.Anthropic() as client:
response = client.messages.create(...)
# Async
async with anthropic.AsyncAnthropic() as client:
response = await client.messages.create(...)
Dependencies
- httpx -- HTTP transport layer (
httpx.Client,httpx.AsyncClient,httpx.Timeout) - anyio -- Async sleep for retry backoff
- pydantic --
PrivateAttrfor pagination page models - distro -- Linux distribution detection for telemetry headers
Related Pages
Implements Principle
Used By
- Implementation:Anthropics_Anthropic_sdk_python_Anthropic_Client_Init
- Implementation:Anthropics_Anthropic_sdk_python_Messages_Create