Metadata-only collector for measuring the energy, carbon, water and land of AI inference.
Project description
tetrameter (Python)
Metadata-only collector for measuring the energy, carbon, water and land of AI
inference. Sibling of @kumokodo/tetrameter-sdk; both produce identical
rows, so a company running Python and TypeScript sees one shape of data.
pip install tetrameter
import tetrameter
tetrameter.configure() # reads TETRAMETER_ENDPOINT and TETRAMETER_KEY
with tetrameter.trace(outcome="debate judged", customer=org_id):
response = client.messages.create(...)
tetrameter.record_anthropic_message(response, feature="reviewer")
tetrameter.flush()
What it will not do
Carry prompt or completion text. sanitize keeps a fixed allow-list of
fields and drops everything else, so record(**response.__dict__) cannot leak a
completion even by accident. A deny-list would need updating every time a provider
added a field, and the first time somebody forgot, prompt text would be stored.
Raise. record() swallows its own failures. Instrumentation that can break
the application it observes gets removed rather than fixed.
Run without credentials. configure() returns None when
TETRAMETER_ENDPOINT and TETRAMETER_KEY are not both set, and the collector
stays inert. A developer machine records nothing instead of writing
production-shaped rows into a production organisation.
Retry a failed batch. A retry queue inside a telemetry client is a memory leak
waiting for an outage. Ingest is idempotent on (org, id) so a retry made
elsewhere — a proxy, a load balancer — is harmless instead.
Traces
A trace is one thing your business asked for. Wrap the outer function and every call beneath it joins, with no id threaded through call sites.
Exactly one trace per delivered outcome: a nested one opens a second trace id
and splits one piece of work into two, understating the cost of both.
For runtimes that re-enter the same logical trace in separate invocations —
Inngest steps, for instance — pass trace_id explicitly. A fresh random id per
step turns eight steps into eight traces each claiming a whole outcome, which
multiplies the outcome count and divides the per-outcome footprint. Both
flattering.
Adapters
| Function | For |
|---|---|
record_anthropic_message |
anthropic.messages.create |
record_openai_completion |
OpenAI chat completions |
record_embedding |
Any embedding call |
record_failure |
A call that raised |
Each reads usage counters and nothing else.
Two are worth explaining, because the TypeScript SDK shipped both bugs and this package pins them from the start:
- Anthropic's three token buckets stay apart.
input_tokensis ordinary,cache_read_input_tokensis the cheap one, andcache_creation_input_tokensis the expensive one — 1.25× input on the five-minute TTL, 2× on the one-hour. Folding writes into input under-prices the write turn while the reads after it stay exact, so any measured caching saving reads high. - Embeddings report usage under a different name, and reading only one of them
records every embedding as
0/0with no error — indistinguishable from a call that genuinely cost nothing.
Licence
Apache-2.0. The methodology is meant to be checked, so the code that produces the numbers is readable.
Releasing
Tagged, like the npm packages, and published by GitHub Actions through PyPI Trusted Publishing — no API token exists anywhere.
git tag python-v0.1.0 && git push --tags
The workflow refuses to publish a tag whose version does not match
pyproject.toml, and verifies the built wheel actually contains the package and
its licence before uploading. Both checks are cheap, and a version on PyPI cannot
be replaced or yanked into non-existence afterwards — unlike npm there is not even
a 72-hour window.
One-time setup on PyPI, under the project's Publishing settings. Because
tetrameter has never been uploaded, this is added as a pending publisher,
which is how a project is bootstrapped without a token:
| Field | Value |
|---|---|
| PyPI project name | tetrameter |
| Owner | samwsimpson |
| Repository name | tetrameter-core |
| Workflow name | publish-python.yml |
| Environment name | pypi-publish |
Then create a GitHub environment called pypi-publish and restrict its
deployment branches and tags to python-v*, so the workflow can only run from a
release tag.
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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file tetrameter-0.1.0.tar.gz.
File metadata
- Download URL: tetrameter-0.1.0.tar.gz
- Upload date:
- Size: 17.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e82f2d665a0ff076f6d73e7b02c59aafeaa3eb4ee1f48d1777da46cf1479e370
|
|
| MD5 |
882979855d0f40361c469561ac17c9b6
|
|
| BLAKE2b-256 |
26140a8ed15f5a21a1819b160568334e7c9fe414091e4da98b6a92d328f8d056
|
Provenance
The following attestation bundles were made for tetrameter-0.1.0.tar.gz:
Publisher:
publish-python.yml on samwsimpson/tetrameter-core
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
tetrameter-0.1.0.tar.gz -
Subject digest:
e82f2d665a0ff076f6d73e7b02c59aafeaa3eb4ee1f48d1777da46cf1479e370 - Sigstore transparency entry: 2338010166
- Sigstore integration time:
-
Permalink:
samwsimpson/tetrameter-core@734b231df32afddb2fb490906c0cd723e95b9fd9 -
Branch / Tag:
refs/tags/python-v0.1.0 - Owner: https://github.com/samwsimpson
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-python.yml@734b231df32afddb2fb490906c0cd723e95b9fd9 -
Trigger Event:
push
-
Statement type:
File details
Details for the file tetrameter-0.1.0-py3-none-any.whl.
File metadata
- Download URL: tetrameter-0.1.0-py3-none-any.whl
- Upload date:
- Size: 17.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3782f1b3264c8961f2c7c66f47ac79f0081324c59fccac6730bd75d81e549ca8
|
|
| MD5 |
07333b81fea5828e478103f9bad0b382
|
|
| BLAKE2b-256 |
244c90291d164ba7b7ba74e22ceaa60ec63c8d8d3993e36d579a5723557056cc
|
Provenance
The following attestation bundles were made for tetrameter-0.1.0-py3-none-any.whl:
Publisher:
publish-python.yml on samwsimpson/tetrameter-core
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
tetrameter-0.1.0-py3-none-any.whl -
Subject digest:
3782f1b3264c8961f2c7c66f47ac79f0081324c59fccac6730bd75d81e549ca8 - Sigstore transparency entry: 2338010182
- Sigstore integration time:
-
Permalink:
samwsimpson/tetrameter-core@734b231df32afddb2fb490906c0cd723e95b9fd9 -
Branch / Tag:
refs/tags/python-v0.1.0 - Owner: https://github.com/samwsimpson
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-python.yml@734b231df32afddb2fb490906c0cd723e95b9fd9 -
Trigger Event:
push
-
Statement type: