Skip to main content

Metadata-only usage tracking for Anthropic and OpenAI — swap one import line.

Project description

Tokenwise Python SDK

Metadata-only usage tracking for Anthropic and OpenAI. Swap one import line and every API call's token counts and latency flow to your Tokenwise dashboard — with zero access to your prompts or responses.

- from anthropic import Anthropic
+ from tokenwise import Anthropic

Your code is otherwise unchanged: the wrapper exposes the identical interface, forwards every call to the official SDK, and returns its response untouched.

Why it's safe

  • Metadata only. The SDK reads exactly: model, input_tokens, output_tokens, cache_read_input_tokens, cache_creation_input_tokens, latency_ms, timestamp, endpoint. It never reads or transmits prompt text, response text, system prompts, or tool definitions. (Contrast with proxy-based tools, which see all your traffic.)
  • Non-blocking. Events are queued and sent on a background daemon thread. If Tokenwise is slow or down, your AI calls complete normally.
  • Fail-silent + bounded. Up to 1,000 events buffer when offline; the oldest drop silently if the buffer fills. Capture never raises, never waits.

Install

pip install tokenwise-sdk[anthropic]   # if you use Anthropic
pip install tokenwise-sdk[openai]      # if you use OpenAI
pip install tokenwise-sdk[anthropic,openai]

anthropic and openai are optional extras — install only what you use.

Configure

Set your Tokenwise key (from the dashboard, looks like tw_...):

export TOKENWISE_API_KEY=tw_your_key
# optional:
export TOKENWISE_API_URL=https://tokenwise-production-aa59.up.railway.app   # default
export TOKENWISE_DISABLED=true                       # emergency kill switch

Precedence for every setting: constructor argument > environment variable > default. If no key is configured the SDK runs disabled and your AI calls behave exactly as the official SDK.

Usage

# Pattern 1 — key from environment
import os
os.environ["TOKENWISE_API_KEY"] = "tw_abc123"
from tokenwise import Anthropic
client = Anthropic(api_key="sk-ant-...")
msg = client.messages.create(
    model="claude-sonnet-4-6",
    max_tokens=256,
    messages=[{"role": "user", "content": "Hello"}],
)

# Pattern 2 — key passed explicitly
from tokenwise import Anthropic
client = Anthropic(api_key="sk-ant-...", tokenwise_key="tw_abc123")

# Pattern 3 — OpenAI
from tokenwise import OpenAI
client = OpenAI(api_key="sk-...", tokenwise_key="tw_abc123")
client.chat.completions.create(
    model="gpt-5.4",
    messages=[{"role": "user", "content": "Hello"}],
)

Streaming and async work the same way:

# Streaming (sync) — usage captured on stream completion
with client.messages.create(..., stream=True) as stream:
    for event in stream:
        ...

# Async
from tokenwise import AsyncAnthropic
client = AsyncAnthropic(api_key="sk-ant-...", tokenwise_key="tw_abc123")
msg = await client.messages.create(...)

What's instrumented (v1)

Provider Method Streaming
Anthropic messages.create ✅ usage read from the event stream (request unchanged)
OpenAI chat.completions.create ✅ see note below

Other methods pass through and work, but aren't yet recorded. (OpenAI Responses API and legacy completions are planned.)

Note on OpenAI streaming

OpenAI only returns token usage on a streamed response when the request includes stream_options={"include_usage": True}. When you stream without supplying your own stream_options, Tokenwise injects it for you so usage can be captured. This adds one final usage-only chunk (with an empty choices list) to the stream. If you already pass stream_options, Tokenwise respects yours and does not modify the request (in that case usage is captured only if you enabled it).

Latency semantics

For non-streaming calls, latency_ms is the wall-clock time of the call. For streaming calls it is the total stream duration (until the last chunk is consumed), which includes time your code spends between chunks — events from streaming calls carry streamed: true so this is distinguishable.

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

tokenwise_sdk-0.1.1.tar.gz (17.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

tokenwise_sdk-0.1.1-py3-none-any.whl (13.9 kB view details)

Uploaded Python 3

File details

Details for the file tokenwise_sdk-0.1.1.tar.gz.

File metadata

  • Download URL: tokenwise_sdk-0.1.1.tar.gz
  • Upload date:
  • Size: 17.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.5

File hashes

Hashes for tokenwise_sdk-0.1.1.tar.gz
Algorithm Hash digest
SHA256 32a4edc44f95d8c27c7daf89524861b1441e8cde51e156e2647a2dcb22d73307
MD5 2aa74db982efbd45250ee41dae28d855
BLAKE2b-256 0387aa1e2cab44ac2f69276dd277488caef6bb376cd9c6c0ff89ac3e3c38c425

See more details on using hashes here.

File details

Details for the file tokenwise_sdk-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: tokenwise_sdk-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 13.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.5

File hashes

Hashes for tokenwise_sdk-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 1055960088bc6a2d26a79753affb2b1d35f67e137d2967a5f0aaa085b29e4509
MD5 2dfb8c04afa06ca951d17c5ae2d4d141
BLAKE2b-256 caefea1a74df04c1520b97ba73799da25463145a404bdb03dbd8cc0c3d3eb6d9

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page