llm-cost
Plug-and-play LLM token/cost tracking SDK with multiple sinks (SQLite, Postgres, Supabase, HTTP collector) and comprehensive audit metadata.
Features
- 🎯 Decorator-first DX:
@track_costfor non-streaming,finalize_llm_callfor streaming - 🔒 Multi-tenant safe: Idempotent upserts scoped to
workspace_idorproject_id - 📊 Audit-ready: Every row includes
usage_rawandrates_usedfor provable cost recomputation - 🚀 Non-blocking: Background batcher with bounded queue and outbox fallback
- 💰 Dynamic pricing: Fetch live rates from OpenRouter with local cache
- 🔌 Pluggable sinks: SQLite (default), Postgres/Supabase, HTTP collector
- 🛡️ Privacy by default: No prompt/response content captured
Quick Start
import llm_cost as cost
# Initialize with Supabase (or SQLite, Postgres, HTTP)
cost.init_supabase(
supabase_url="https://your-project.supabase.co",
supabase_key="your-service-role-key",
)
# Set sticky context (workspace, session, user)
cost.set_context({
"workspace_id": "ws-123",
"session_id": "sess-456",
"user_id": "user-789",
})
# Track non-streaming calls
from openai import OpenAI
client = OpenAI()
@cost.track_cost(model_arg='model', provider='openai')
def run_completion(model: str, prompt: str):
return client.chat.completions.create(
model=model,
messages=[{"role": "user", "content": prompt}],
)
response = run_completion(model="gpt-4o", prompt="Hello!")
# Track streaming calls
@cost.track_cost(mode='defer')
def run_streaming(model: str, prompt: str):
return client.chat.completions.create(
model=model,
messages=[{"role": "user", "content": prompt}],
stream=True,
)
stream = run_streaming(model="gpt-4o", prompt="Hello!")
tokens_in, tokens_out = 0, 0
for chunk in stream:
# ... process chunk
pass
# Finalize with actual token counts
cost.finalize_llm_call(
provider="openai",
model="gpt-4o",
tokens_in=tokens_in,
tokens_out=tokens_out,
request_id=cost.new_request_id(),
)
Configuration
All config can be set via environment variables or passed to init():
# Supabase mode
export SUPABASE_URL=https://your-project.supabase.co
export SUPABASE_SERVICE_ROLE_KEY=your-key
# SQLite mode (default)
export COST_SINK_DSN=sqlite:///./llm_cost.db
# HTTP collector mode
export COST_COLLECTOR_ENDPOINT=https://your-collector.com/v1/batch
export COST_WRITE_KEY=your-write-key
# Flush behavior
export COST_FLUSH_AT=20
export COST_FLUSH_INTERVAL_MS=3000
Audit Metadata
Every ledger row includes:
{
"context": {
"metadata": {
"billing": {
"usage_raw": {
"prompt_tokens": 123,
"completion_tokens": 456,
"reasoning_tokens": 100,
"cached_input_tokens": 50
},
"rates_used": {
"input_rate": 1.25,
"cached_input_rate": 0.125,
"output_rate": 10.0,
"reasoning_rate": 10.0,
"model_resolved": "gpt-4o",
"pricing_source": "default",
"pricing_version": "abc123"
}
}
}
}
}
This enables:
- Row-by-row cost recomputation
- Audit trails for billing disputes
- Reconciliation jobs to detect drift
Installation
pip install llm-cost
License
MIT
Links
Metadata
Release files for orchestra-llm-cost 0.1.4
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| orchestra_llm_cost-0.1.4.tar.gz | 17.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| orchestra_llm_cost-0.1.4-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 36.7 kB
Release files / orchestra_llm_cost-0.1.4.tar.gz
| Download URL | orchestra_llm_cost-0.1.4.tar.gz |
|---|---|
| Size | 17.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
dae8c96bb3d916a5890e0ddc5055128efca2303b34fcfe5fa7b00fb28752aa02
|
|
BLAKE2b-256 checksum How to use checksums |
23d7ca8de79da2958706344293668216b4dbea05864dee3876f4446a62299281
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.9.6
|
Release files / orchestra_llm_cost-0.1.4-py3-none-any.whl
| Download URL | orchestra_llm_cost-0.1.4-py3-none-any.whl |
|---|---|
| Size | 18.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
f982fe6d16fb5b7d9ec08b04d8e4d499b5f8b1874c2fe6662fe25f2ffd9f7e32
|
|
BLAKE2b-256 checksum How to use checksums |
b7d8db1fcef1f80ee88e619981ea0b3077ff7bb8e169d4f2aa21029c91192582
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.9.6
|