noburn
Hard LLM spend enforcement for Python — pre-call budget checks and per-user metering.
Check a planned LLM call against project-, per-user-, and per-run budget caps before you make it, then record what it actually cost.
Install
pip install noburn
Requires Python ≥ 3.9. No third-party dependencies. Ships type hints (py.typed).
Quick start
import os
from noburn import NoburnGuard
guard = NoburnGuard(
api_key=os.environ["NOBURN_API_KEY"],
project_id=os.environ["NOBURN_PROJECT_ID"],
budget_cap_usd=10.0, # optional local fallback cap
on_error="allow", # "allow" (default, fail-open) | "block" (fail-closed)
)
decision = guard.check(
model="gpt-4o",
estimated_tokens_in=1000,
estimated_tokens_out=300,
end_user_id="user_123", # optional — enforces that user's cap
)
if decision.blocked:
raise RuntimeError(f"Blocked by noburn: {decision.block_reason}")
# ... make your LLM call ...
guard.record(
model="gpt-4o",
tokens_in=980,
tokens_out=290,
cost_usd=0.005,
was_blocked=False,
end_user_id="user_123",
)
record() is fire-and-forget — it returns immediately (delivery happens on a
background daemon thread) and never raises, so it adds no latency to your call
path.
Agent runs
Bound a single agent invocation with its own cap:
run = guard.start_run(budget_cap_usd=0.5)
decision = guard.check(
model="gpt-4o",
estimated_tokens_in=1000,
estimated_tokens_out=300,
run_id=run.run_id,
)
guard.record(model="gpt-4o", tokens_in=980, tokens_out=290,
cost_usd=0.005, was_blocked=False, run_id=run.run_id)
summary = guard.end_run(run.run_id) # EndRunResult(status=..., spend_usd=..., ...)
Behavior
check()never raises exceptNoburnAuthError(bad key). Every call asks the server for an authoritative decision; if the server is unreachable it falls back to a local in-memory check.on_errorcontrols that fallback when nothing local blocks the call:"allow"(default) fails open so a noburn outage never breaks your app;"block"fails closed (block_reason="noburn_unreachable").start_run()raises on network/auth error (NoburnTimeoutErroron timeout) — a run must be registered before you proceed.
Note:
check()/start_run()use blocking HTTP. In async apps, run them in a thread executor (e.g.await asyncio.to_thread(guard.check, ...)).
License
MIT
Release files for noburn 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| noburn-0.1.0.tar.gz | 11.3 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| noburn-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 19.4 kB
Release files / noburn-0.1.0.tar.gz
| Download URL | noburn-0.1.0.tar.gz |
|---|---|
| Size | 11.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
c30dcc65d36b918aa24ed3c298de332f5ecf793cd22c80584b32cb0d0b76105e
|
|
BLAKE2b-256 checksum How to use checksums |
4025c99242eaac223ce4aed689de9119a0fa29b288f7f7666ebf02227cd0f40c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.4
|
Release files / noburn-0.1.0-py3-none-any.whl
| Download URL | noburn-0.1.0-py3-none-any.whl |
|---|---|
| Size | 8.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
88e59bf2f4ef4757cf7e1211264edd60af22142beebdbde7d72110911937f516
|
|
BLAKE2b-256 checksum How to use checksums |
4184ce65c5b64bfd6c24704f1933441e3fef1658f4f3eefd56329f22368a2403
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.4
|