Skip to main content

metergraph (Python)

Zero-runtime-dependency capture for OpenAI, Anthropic, and Gemini clients. wrap() initializes capture from the environment, so setup is one line per client; call metergraph.init(...) before the first wrap() only to pass options in code.

import metergraph
from openai import OpenAI

# Anthropic() and google-genai's genai.Client() wrap the same way.
client = metergraph.wrap(OpenAI())
metergraph.set_session("ticket-123")

with metergraph.route("ticket-classifier", unit="answer", capture_text=True):
    model = metergraph.model_for("ticket-classifier", default="gpt-4.1-mini")
    client.chat.completions.create(model=model, messages=[...])

# Emit this after the user-visible task resolves. It shares the bounded async
# transport and contains no prompt or output content.
metergraph.record_outcome(
    "ticket-classifier",
    model=model,
    task_completed=True,
    feedback_score=1,
    turns_to_resolution=2,
    escalated=False,
)

Configuration:

  • METERGRAPH_APP_TOKEN — required bearer token
  • METERGRAPH_INGEST_URL — optional override; defaults to the hosted HTTPS endpoint
  • METERGRAPH_CAPTURE_TEXT=1 — opt in to content capture globally; default is metadata-only
  • METERGRAPH_DISABLED=1 — process kill switch
  • METERGRAPH_QUEUE_SIZE, METERGRAPH_BATCH_SIZE, METERGRAPH_FLUSH_SECONDS

Delivery is bounded and off the request path. Queue overflow or a collector outage drops capture and increments internal counters; it never changes the provider call. Each wire batch is bounded to 512 KiB after optional gzip. capture_text=True or False on route() overrides the global content policy for that route. Config reads are ETag-aware and fail open to the default model. record_outcome requires a stable session ID and the model actually used so a session-sticky canary can compare task completion and optional feedback, turn-count, escalation, abandonment, edit-distance, and regeneration signals.

OpenAI Batch API output JSONL is captured per inference when a wrapped client.files.content() / retrieve_content() result is read. Anthropic message batches are captured per inference while iterating a wrapped client.messages.batches.results() result. Run result consumption inside a route() context so the asynchronous batch retains its product route. Batch rows carry real per-result usage and the batch pricing flag; job-management polls themselves are not miscounted as model calls.

Set up with an AI coding agent

Paste this into Claude Code, Codex, Cursor, or any coding agent inside the codebase you want instrumented:

Instrument this codebase's LLM API costs with the `metergraph` PyPI package
(https://github.com/PioneerSquareLabs/metergraphsdk): pip install metergraph,
then wrap every OpenAI()/AsyncOpenAI(), Anthropic()/AsyncAnthropic(), and
genai.Client() construction in place, e.g. client = metergraph.wrap(OpenAI()).
wrap() returns the same client and initializes itself from the environment:
METERGRAPH_APP_TOKEN is required (capture is silently off without it) and
METERGRAPH_INGEST_URL is only for self-hosted servers. Add both to
.env.example, and never commit a real token. Capture is metadata-only (tokens,
latency, model, no prompt/completion content) and fail-open, so do not change
call sites, arguments, or error handling; sync, async, and streaming work
unchanged. Attribution to the calling function is automatic; optionally pin
stable names on key LLM-calling functions with @metergraph.track. On
serverless, call metergraph.flush() before the handler returns. When done,
list every client you wrapped and flag LLM calls made outside the official
openai / anthropic / google-genai SDKs, since those are not captured.

Download files

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

Source Distribution

metergraph-0.2.1.tar.gz (30.0 kB view details)

Uploaded Source

Built Distribution

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

metergraph-0.2.1-py3-none-any.whl (22.3 kB view details)

Uploaded Python 3

File details

Details for the file metergraph-0.2.1.tar.gz.

File metadata

  • Download URL: metergraph-0.2.1.tar.gz
  • Upload date:
  • Size: 30.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.13.3

File hashes

Hashes for metergraph-0.2.1.tar.gz
Algorithm Hash digest
SHA256 91bd38ef1db3eb6c0c5e4a1a89934b50227b854567e266b0fec642dcc18b2c4c
MD5 ab64407d37cb801c704ebc27a2df5039
BLAKE2b-256 ce097536c754a00123ec1c56e7658935804f49dcf18db12dd4739c82df3d0247

See more details on using hashes here.

File details

Details for the file metergraph-0.2.1-py3-none-any.whl.

File metadata

  • Download URL: metergraph-0.2.1-py3-none-any.whl
  • Upload date:
  • Size: 22.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.13.3

File hashes

Hashes for metergraph-0.2.1-py3-none-any.whl
Algorithm Hash digest
SHA256 d2169d8e5effd7edbdff283159900627f07469b4318ea437afa770143b3bf44d
MD5 550e199c89363795f4fefb2e3a4a29db
BLAKE2b-256 66b1b5d220297f8302eb81d5a0769a32cb849554d9fecbbde0a5324e985d1ed9

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 Sentry Error logging StatusPage Status page