Anthropic SDK
The Anthropic SDK gets a governed AsyncAnthropic client pointed at the Omni
Gateway LLM proxy, with the SDK’s shared transport and proxy headers passed
straight into the client constructor.
What you get
- A native
anthropic.AsyncAnthropicclient. - Full header and transport injection, on
anthropic0.x and 1.x. - Supported at
connection_kwargs().
Requires a Format=Anthropic proxy. The native Anthropic Messages route
(POST /<base-path>/v1/messages) is only served by a proxy provisioned with
the Anthropic ingress Format. Default DDK proxies are Format=OpenAI: there,
/v1/messages returns 404 and Claude is reachable only as an upstream
provider through the OpenAI-compatible adapters. See
Model access for how ingress Format works.
Install
pip install "donkey-kit[anthropic]"This installs the newest anthropic release. anthropic 0.x (from 0.40) works
too, so a project that holds it below 1.0 needs no change.
Quickstart
Python
from donkey_kit.integrations.anthropic import client
llm = client()llm is a real anthropic.AsyncAnthropic instance. Unlike the other
adapters, the factory takes no model argument — pass the model ID per call,
as the Anthropic SDK expects:
reply = await llm.messages.create(
model="claude-...",
max_tokens=1024,
messages=[{"role": "user", "content": "Say hi in three words."}],
)Three ways to construct
1. Off a shared Donkey instance:
from donkey_kit import Donkey
async with Donkey.from_env() as donkey:
llm = donkey.anthropic.client()2. Module-level factory (shortest):
from donkey_kit.integrations.anthropic import client
llm = client()3. Governed kwargs, native constructor:
from donkey_kit import Donkey
from anthropic import AsyncAnthropic
async with Donkey.from_env() as donkey:
llm = AsyncAnthropic(**donkey.anthropic.connection_kwargs())Manual equivalent
from anthropic import AsyncAnthropic
llm = AsyncAnthropic(
base_url=..., # from DONKEY_LLM_PROXY_URL, no /v1 suffix
api_key=...,
default_headers=..., # client_id / client_secret header pair
http_client=..., # sends through the SDK's shared transport (see below)
max_retries=0, # the SDK retries in its own transport layer
)connection_kwargs() returns exactly these keys, so you can drop the factory
and construct AsyncAnthropic by hand at any time.
Which http_client you get depends on the installed anthropic:
anthropic | Built on | http_client |
|---|---|---|
| 0.x | httpx | A non-owning httpx.AsyncClient view that sends through the shared client. |
| 1.0 and later | httpx2 | An httpx2.AsyncClient whose transport sends every request through the shared client. |
anthropic 1.0 moved to httpx2, Pydantic’s continuation of httpx, and
rejects any httpx client with a TypeError. The bridged httpx2 client keeps
one HTTP stack: the governed headers, retries, the GenAI span, budget tracking
and donkey.last_call all run in the shared client either way. If you bring
your own http_client instead, use an httpx2.AsyncClient on 1.0 and later.
Notes
client(), notmodel(...). The other adapters return a framework object already bound to a model ID, because their native constructors acceptmodel.AsyncAnthropicis a bare client and the model ID is an argument to.messages.create(), sodonkey.anthropic.client()takes no model argument.- Async only. The adapter returns
AsyncAnthropic; there is no governed syncanthropic.Anthropic.connection_kwargs()carries the SDK’s async client, so spread it only intoAsyncAnthropic. A syncAnthropicyou build yourself does not go through the SDK’s transport. - Proxy Format. MuleSoft Model Proxy offers three ingress Formats (OpenAI /
Gemini / Anthropic), fixed when the proxy is created
(MuleSoft docs ). A
Format=Anthropicproxy returns a native Anthropic body from/v1/messagesand 404s an OpenAI-shaped/chat/completionsrequest. Auth is the sameclient_id/client_secretheader pair as every other proxy. To use the native surface, setDONKEY_LLM_PROXY_URL(orllm_proxy_url) to aFormat=Anthropicproxy. - What
donkey.last_callreads. On a native Anthropic proxy,request_idis Anthropic’s ownrequest-idheader.cached_tokensandcache_write_tokenscome fromcache_read_input_tokensandcache_creation_input_tokens. Streamed calls fillinput_tokensand the cache counts frommessage_startandoutput_tokensfrommessage_delta. Anthropic reports no total, sototal_tokensisNone. Itsinput_tokensexcludes both cache counts, while OpenAI’s includescached_tokens. Add the cache counts back in before you compare cost across providers. - Closing the client.
AsyncAnthropic.close(), and leavingasync with AsyncAnthropic(...), closes itshttp_client. On both stacks that is not the shared client (the bridge on 1.0 and later, the view on 0.x), so the shared client stays open and laterclient()calls keep working. To end the connection pool, close theDonkey(async with Donkey.from_env()orawait donkey.aclose()).
See the error taxonomy for how proxy rejections surface as typed exceptions, and the verification ledger for the current status of every constructor signature this adapter depends on.