Skip to main content

Tiny stdlib-only client that emits LLM call + outcome economics to a Margin ingest API.

Project description

margin-meter (Python SDK)

The tiny client a Python project imports to connect to Margin. It wraps your LLM calls and records their outcomes, emitting each one over HTTP to a Margin ingest API (POST /api/ingest/calls / /api/ingest/outcomes), authenticated with a per-project ingest key. This is the customer-shaped path — the same SDK a stranger drops in — not the in-process meter Margin runs on itself.

  • Standalone + stdlib-only. No dependency on Margin's server code and no third-party deps. The default transport is urllib.
  • Fail-safe. A failed emit returns an IngestResult(ok=False, …) instead of crashing your app. Pass raise_on_error=True for strict/CI behaviour.
  • Provenance-honest. is_simulated is carried through untouched; the written source is forced server-side to your key's project — you cannot spoof another project's economics.

Install

Published as a git-installable subpath of the Margin repo (no PyPI account needed pre-launch):

pip install "git+https://github.com/subhsubh24/Margin.ai.git#subdirectory=sdk/python"

Configure

Two environment variables — the deployed API base and your project's key:

export MARGIN_INGEST_URL="https://margin-ai-rho.vercel.app"
export MARGIN_INGEST_KEY="mgk_…"   # issued by the Margin owner (see below)

The Margin owner issues your project a key with the provisioning CLI in the Margin repo:

python3 scripts/issue_ingest_key.py <your-project-slug>

The raw mgk_… key is shown once — only its hash is stored. Give it to your project as MARGIN_INGEST_KEY.

Use

from margin_meter import MarginMeter

meter = MarginMeter()  # reads MARGIN_INGEST_URL + MARGIN_INGEST_KEY

# 1) Wrap the LLM call — latency is timed automatically, cost computed server-side.
with meter.measure(workflow_id="fit-scoring", provider="google",
                   model="gemini-2.5-flash") as m:
    resp = call_the_model(...)
    m.set_tokens(input_tokens=1200, output_tokens=300, cache_read_tokens=800)

# 2) Record the outcome it produced (the unit of productivity).
meter.record_outcome(workflow_id="fit-scoring", passed=True,
                     quality_score=0.94, quality_method="ground_truth")

Or record a call directly (when you already have the token counts):

res = meter.record_call(
    workflow_id="fit-scoring", provider="google", model="gemini-2.5-flash",
    input_tokens=1200, output_tokens=300, cache_read_tokens=800,
)
if not res.ok:
    log.warning("margin ingest failed: %s (%s)", res.error, res.status_code)

API

Method Emits to Notes
record_call(...) POST /api/ingest/calls cost computed from the pricing table when cost_usd omitted
record_outcome(...) POST /api/ingest/outcomes quality_method records HOW the score was graded
measure(...) record_call on exit context manager; times latency, status="error" on exception

Every method returns an IngestResult(ok, status_code, body, error). ok is True only on HTTP 200; body holds call_id/outcome_id + source.

Testing against a live app (no network)

The network boundary is a single transport.post(path, json=..., headers=...) protocol, which a FastAPI TestClient satisfies exactly — so you can exercise the real ingest endpoints hermetically by injecting one:

from fastapi.testclient import TestClient
import asgi
from margin_meter import MarginMeter

meter = MarginMeter(api_key=raw_key, transport=TestClient(asgi.app),
                    raise_on_error=True)

Rate + validation bounds

Ingest is auth'd, validated, and rate-bounded server-side. A bad key → 401, a malformed/implausible row → 422, and a full rolling per-project window → 429. In fail-safe mode these come back as IngestResult(ok=False, status_code=…).

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

margin_meter-0.1.0.tar.gz (7.2 kB view details)

Uploaded Source

Built Distribution

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

margin_meter-0.1.0-py3-none-any.whl (8.0 kB view details)

Uploaded Python 3

File details

Details for the file margin_meter-0.1.0.tar.gz.

File metadata

  • Download URL: margin_meter-0.1.0.tar.gz
  • Upload date:
  • Size: 7.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.0

File hashes

Hashes for margin_meter-0.1.0.tar.gz
Algorithm Hash digest
SHA256 5edf83fd89f17b9b459da5fee5b504b1d32c953f2487e73c9f81bf424b05402e
MD5 5681849abd21d75b36fde018b99e4525
BLAKE2b-256 2f044dae01340f9ef4d2ca8019a6767143b48c485a4dc206466397fc07100af8

See more details on using hashes here.

File details

Details for the file margin_meter-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: margin_meter-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 8.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.0

File hashes

Hashes for margin_meter-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 ea811ace5836cab6c7abc8064bee97af073ec3183073ed5fc481c7cc93a0cf51
MD5 d803f46daae8656b2b748febd173b324
BLAKE2b-256 c16bb9c6ec096e86e41f6273a122956cab64dc3de54b7b11dda843e018cc1e8e

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