Anthropic
Use Solwyn with Anthropic — sync and async examples, cache normalization, model support
import os
from anthropic import Anthropic
from solwyn import Solwyn
client = Solwyn(
Anthropic(),
api_key=os.environ["SOLWYN_API_KEY"],
)
response = client.messages.create(
model="claude-sonnet-4-5",
max_tokens=1024,
messages=[{"role": "user", "content": "Explain how a CPU works in two sentences."}],
)
print(response.content[0].text)
client.close()Sync usage
Pass an anthropic.Anthropic client to Solwyn(). Calls use client.messages.create(), exactly like the standard Anthropic SDK:
import os
from anthropic import Anthropic
from solwyn import Solwyn
with Solwyn(
Anthropic(),
api_key=os.environ["SOLWYN_API_KEY"],
) as client:
response = client.messages.create(
model="claude-sonnet-4-5",
max_tokens=1024,
messages=[
{"role": "user", "content": "Explain how a CPU works in two sentences."},
],
system="You are a helpful assistant.",
)
print(response.content[0].text)Async usage
Pass an anthropic.AsyncAnthropic client to AsyncSolwyn():
import asyncio
import os
from anthropic import AsyncAnthropic
from solwyn import AsyncSolwyn
async def main():
async with AsyncSolwyn(
AsyncAnthropic(),
api_key=os.environ["SOLWYN_API_KEY"],
) as client:
response = await client.messages.create(
model="claude-sonnet-4-5",
max_tokens=1024,
messages=[
{"role": "user", "content": "Explain how a CPU works in two sentences."},
],
system="You are a helpful assistant.",
)
print(response.content[0].text)
asyncio.run(main())Supported models
The SDK recognizes Anthropic models by the claude-* prefix:
| Prefix | Examples |
|---|---|
claude-* | claude-sonnet-4-5, claude-opus-4-5, claude-haiku-4-5 |
Anthropic is priced for text only — chat through messages.create and, since 0.9.0, beta.messages.create. A media surface requested from a wrapped Anthropic client (embeddings, for instance) fails loud with UnsupportedSurfaceError rather than running untracked. See the provider × modality matrix.
Beta Messages
SDK v0.9.0+. client.beta.messages.create(...) is metered the same way as messages.create — budget-checked and settled on sync and async clients, streaming or not, including the Bedrock, Vertex, and Foundry platform clients. Beta features such as server-side compaction are therefore budget-checked and settled.
response = client.beta.messages.create(
model="claude-sonnet-4-5",
max_tokens=1024,
messages=[{"role": "user", "content": "Hello!"}],
)- Beta request fields (
betas,context_management,compaction, ...) pass through untouched and are never recorded. - A beta call fails over only to other Anthropic entries in your
fallback=chain, never to a different provider: beta-only fields have no equivalent elsewhere. Cross-provider entries are skipped for these calls. - The other beta Messages helpers —
beta.messages.stream,.parse,.tool_runner,.count_tokens,beta.messages.thread, batches, and the raw/streaming response mirrors — stay unmetered and follow youron_unmeteredposture, like their non-beta counterparts. - Upgrading from 0.8.0: remove
beta.messages.createfromacknowledge_untracked. A stale token for a now-metered leaf raisesConfigurationError.
Cache normalization
Anthropic reports prompt cache tokens as separate additive fields -- the base input_tokens does not include cache tokens. Solwyn normalizes these into a single input_tokens total:
normalized input_tokens = base input_tokens
+ cache_read_input_tokens
+ cache_creation_input_tokens| Normalized field | Anthropic API source |
|---|---|
input_tokens | usage.input_tokens + usage.cache_read_input_tokens + usage.cache_creation_input_tokens |
output_tokens | usage.output_tokens |
cached_input_tokens | usage.cache_read_input_tokens |
cache_creation_5m_tokens | usage.cache_creation.ephemeral_5m_input_tokens |
cache_creation_1h_tokens | usage.cache_creation.ephemeral_1h_input_tokens |
Cache-creation TTL split
Anthropic prices cache writes differently by time-to-live: the 5-minute TTL is billed at 1.25× the base input rate, the 1-hour TTL at 2×. Solwyn captures the two separately so the Cloud API can price each correctly:
cache_creation_5m_tokens— written with 5-minute TTL (1.25× rate)cache_creation_1h_tokens— written with 1-hour TTL (2× rate)
Older or non-beta responses expose only an aggregate usage.cache_creation_input_tokens without the per-TTL cache_creation sub-object. When only the aggregate is present, Solwyn attributes it to cache_creation_5m_tokens. All cache fields may be absent on older API responses and default to 0.
Server-side compaction
SDK v0.9.0+. Anthropic reports server-side compaction usage only in usage.iterations, and excludes it from the top-level usage fields. Solwyn sums every type == "compaction" entry and adds it to the settled input, output, and cache counts, using the same normalization as the top level, for streaming and non-streaming calls. Other iteration types are already covered by the top-level fields.
token_details also carries the compaction share as subsets of those totals. Each key is omitted when zero, so a call without compaction sends the same payload as before:
| Field | Compaction share of |
|---|---|
compaction_input_tokens | input_tokens |
compaction_cached_input_tokens | cached_input_tokens |
compaction_cache_creation_5m_tokens | cache_creation_5m_tokens |
compaction_cache_creation_1h_tokens | cache_creation_1h_tokens |
compaction_output_tokens | output_tokens |
For streams, see What gets reported.
Supported anthropic SDK versions
solwyn[anthropic] declares anthropic>=0.50. Coverage is exercised against the 0.50.0 floor, the 0.80.0 (parse), 1.0.0 (stable files / skills), and 1.14.0 (native OpenTelemetry) breakpoints, and the current release — 2.3.0 as of SDK 0.9.0. Anthropic versions below 1.14 remain fully supported with no behavior change.
SDK v0.9.0+: Anthropic 2.x is supported with no wrapper change; beta Messages metering and compaction settlement work unchanged on 2.x.
SDK v0.6.0+: Anthropic 1.x is supported on its httpx2 HTTP stack. Solwyn never imports httpx2; it recognizes the stack by identity from the client you pass in. Two things follow:
- The per-hop bound from failover tuning is delivered as a native
httpx2.Timeoutwhen the SDK can prove the client's own timeout class, and as a granular(connect, read, write, pool)tuple otherwise. The transport bound is correct either way; in the fallback only Anthropic's informationalx-stainless-read-timeoutheader degrades. httpx2transport errors are classified at the same position as theirhttpxtwins: connect and pool timeouts and connection errors fail over; read and write timeouts and protocol errors are post-send ambiguous and re-raise under the defaultfailover_idempotency="safe".
Anthropic 1.0 promoted files and skills to stable. Solwyn classifies every leaf under them — files.upload, files.list, files.download, skills.create, skills.versions.create, and the rest — as unmetered spend, so they follow your ordinary on_unmetered posture (warn once by default) and are acknowledgeable by exact token, rather than resolving as unknown-surface drift.
SDK v0.7.0+: the surface ledger is audited against Anthropic 1.4. Its beta.organization.* admin tree — api_keys, invites, users, workspaces, service_accounts, federation, rate_limits, compliance_settings, external_keys, and their sub-resources — is guarded as namespaces whose leaf operations are unmetered spend, as are beta.webhooks.parse_unverified and the with_raw_response / with_streaming_response variants of messages.batches.results. Nothing previously classified moved, and no Anthropic rule changed in SDK 0.8.0.
SDK v0.9.0+: the ledger is audited through Anthropic 2.3. Newly guarded administration surfaces — the top-level organization and user_profiles trees, beta.user_profiles.action_urls and beta.user_profiles.delete, workspaces.rate_limits.update under both organization and beta.organization, and beta.organization.analytics (including cost / usage), plugins, plugin_marketplaces, rbac_groups, rbac_roles, spend_limits, telemetry_destinations, webhooks, and claude_tag — are unmetered spend, follow on_unmetered, and need exact acknowledgment tokens in strict mode. beta.messages.thread, whose server-held thread turns Solwyn cannot budget or settle, is unmetered too. The client's open_telemetry option is silent configuration.
SDK v0.9.0+: wrapped AnthropicBedrock and AnthropicBedrockMantle clients (sync and async) keep the caller's http_client on every provider call, and AnthropicBedrock also keeps its aws_profile. Previously a client configured with a named AWS profile could fail to resolve credentials, and a custom transport or proxy was bypassed.
To tag Anthropic's native OpenTelemetry spans with the active run ID, see Anthropic conversation IDs.
Reasoning tokens limitation
Anthropic folds extended thinking tokens into output_tokens and does not report them as a separate field. As a result, reasoning_tokens is always 0 for Anthropic responses. This is a known limitation of the Anthropic API, not the Solwyn SDK.
The Solwyn Cloud API accounts for this when computing costs -- extended thinking output tokens are priced correctly using the total output_tokens count.
Passthrough attributes
Any attribute not intercepted by Solwyn is resolved against the underlying anthropic.Anthropic client through the coverage guard. SDK v0.6.0+: unmetered capabilities — messages.count_tokens, models.list, completions.create (pre-1.0 clients only), files.*, skills.*, the beta.* tree (except beta.messages.create, metered since 0.9.0) — warn once per process by default and are then forwarded; on_unmetered="raise" refuses them, "allow" silences them, and acknowledge_untracked exempts exact leaves.