Track, budget, and understand the cost of your AI API calls
Project description
tokenmeter
Track, budget, and understand the cost of your AI API calls.
Installation
# Core (zero dependencies)
uv pip install smalldreamcollective-tokenmeter
# With CLI
uv pip install "smalldreamcollective-tokenmeter[cli]" # adds click
# With accurate token counting
uv pip install "smalldreamcollective-tokenmeter[openai]" # adds tiktoken
uv pip install "smalldreamcollective-tokenmeter[anthropic]" # adds anthropic SDK
uv pip install "smalldreamcollective-tokenmeter[all]" # CLI + both providers
# With interactive terminal dashboard
uv pip install "smalldreamcollective-tokenmeter[tui]" # adds textual + plotext
Quick Start
import tokenmeter
meter = tokenmeter.Meter()
# Estimate cost before calling an API
cost = meter.estimate("Explain quantum computing", model="claude-sonnet-4-5")
print(f"Estimated input cost: ${cost}")
# Record actual usage from an API response
import anthropic
client = anthropic.Anthropic()
response = client.messages.create(
model="claude-sonnet-4-5",
max_tokens=1024,
messages=[{"role": "user", "content": "Hello"}],
)
record = meter.record(response)
print(f"This call cost: ${record.total_cost}")
# Query spending
print(f"Session total: ${meter.total()}")
print(meter.summary(group_by="model"))
Works the same way with OpenAI:
import openai
client = openai.OpenAI()
response = client.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": "Hello"}],
)
record = meter.record(response)
Budgets & Alerts
meter = tokenmeter.Meter(storage="sqlite")
# Set spending limits
meter.set_budget(limit=10.00, period="daily", action="block")
meter.set_budget(limit=100.00, period="monthly", action="warn")
# Get notified at thresholds
meter.alerts.set_thresholds([0.5, 0.8, 0.95])
meter.on_alert(lambda status, msg: print(f"ALERT: {msg}"))
# Check before making expensive calls
estimated = meter.estimate(long_prompt, model="claude-opus-4-6")
if meter.budget.would_exceed(estimated):
print("Would exceed budget — switching to cheaper model")
# Enforce hard limits (raises BudgetExceededError)
meter.budget.enforce(estimated)
Budget periods: "daily", "weekly", "monthly", "total"
Budget actions: "warn" (log to stderr) or "block" (raise BudgetExceededError)
Storage Backends
# In-memory (default) — fast, lost on exit
meter = tokenmeter.Meter(storage="memory")
# SQLite — persistent, queryable
meter = tokenmeter.Meter(storage="sqlite", db_path="~/.tokenmeter/usage.db")
# JSON Lines — simple file, easy to inspect
meter = tokenmeter.Meter(storage="jsonl", path="./usage.jsonl")
Filtering & Tags
# Tag your API calls
meter.record(response, feature="chatbot", env="production", user_id="alice")
# Filter spending
meter.total(provider="anthropic")
meter.total(model="claude-sonnet-4-5")
meter.total(user_id="alice")
meter.total(tags={"feature": "chatbot"})
# Aggregate
meter.summary(group_by="model")
meter.summary(group_by="provider")
meter.summary(group_by="user_id")
Adding Custom Providers
from tokenmeter.providers._base import Provider
from tokenmeter import Meter, ModelPricing
from decimal import Decimal
class GeminiProvider(Provider):
@property
def name(self):
return "google"
def count_tokens_local(self, text, model):
return len(text) // 4 # heuristic
def extract_usage(self, response):
return {
"input_tokens": response.usage_metadata.prompt_token_count,
"output_tokens": response.usage_metadata.candidates_token_count,
}
def extract_model(self, response):
return response.model_version
def matches_response(self, response):
return "google" in type(response).__module__
meter = Meter()
meter._provider_registry.register(GeminiProvider())
meter._pricing.register(ModelPricing(
model_id="gemini-2.0-flash",
provider="google",
input_per_mtok=Decimal("0.10"),
output_per_mtok=Decimal("0.40"),
))
Standalone Cost Calculation
You can use the cost calculator directly without tracking:
from tokenmeter import CostCalculator
calc = CostCalculator()
cost = calc.calculate(model="gpt-4o", input_tokens=1500, output_tokens=500)
print(f"Cost: ${cost}")
# Itemized breakdown
details = calc.calculate_detailed(model="claude-opus-4-6", input_tokens=10000, output_tokens=5000)
print(f"Input: ${details['input_cost']}, Output: ${details['output_cost']}")
API Reference
Meter (main entry point)
| Method | Description |
|---|---|
Meter(storage, session_id, user_id) |
Create a meter. Storage: "memory", "sqlite", "jsonl" |
.estimate(text, model) |
Estimate input cost for text |
.record(response, user_id, **tags) |
Record actual usage from API response |
.total(**filters) |
Get total spending (filterable) |
.summary(group_by) |
Aggregate by "model", "provider", "user_id", "session_id" |
.set_budget(limit, period, action) |
Set a spending limit |
.check_budget() |
Check all budget statuses |
.on_alert(callback) |
Register alert callback (BudgetStatus, str) -> None |
Sub-components (accessible via meter.*)
| Component | Description |
|---|---|
meter.cost |
CostCalculator — stateless cost math |
meter.tokens |
TokenCounter — local + API-based token counting |
meter.tracker |
UsageTracker — record/query/aggregate usage |
meter.budget |
BudgetManager — limits & enforcement |
meter.alerts |
AlertManager — thresholds & callbacks |
Supported Models
Anthropic: Claude Opus 4.6, 4.5, 4.1, 4 | Sonnet 4.5, 4 | Haiku 4.5, 3.5, 3
OpenAI: GPT-5.1, 5, 5-mini, 5-nano | GPT-4.1, 4.1-mini, 4.1-nano | GPT-4o, 4o-mini | o3, o3-mini, o4-mini, o1
CLI
Install with uv pip install "tokenmeter[cli]" to get the tokenmeter command.
# Send a prompt and track the cost
tokenmeter prompt "Explain quantum computing" --model claude-sonnet-4-5
echo "Long prompt..." | tokenmeter prompt --model gpt-4o --system "Be concise"
# Estimate cost without sending
tokenmeter estimate "Your prompt text here" --model claude-opus-4-6
# View spending
tokenmeter usage # total spending
tokenmeter usage --by model # grouped by model
tokenmeter usage --by provider # grouped by provider
# View individual records
tokenmeter history # last 20 records
tokenmeter history --limit 50 --provider anthropic
# Manage budgets
tokenmeter budget set 10.00 --period daily --action block
tokenmeter budget set 100.00 --period monthly
tokenmeter budget list # show all budgets with status
tokenmeter budget remove 0 # remove by index
# List supported models with pricing
tokenmeter models
tokenmeter models --provider anthropic
# Clear usage data
tokenmeter clear
API keys
Copy the example env file and fill in your keys:
cp .env.example .env
# then edit .env with your keys
Load the keys before running CLI commands:
# Option A — source once per shell session
source .env && tokenmeter prompt "Hello" --model claude-3-5-haiku-20241022
# Option B — pass the file to uv run (no sourcing needed)
uv run --env-file .env tokenmeter prompt "Hello" --model claude-3-5-haiku-20241022
.env is gitignored and will never be committed.
Run tokenmeter --help for full command reference, or tokenmeter.help() in a Python REPL.
Project details
Release history Release notifications | RSS feed
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 smalldreamcollective_tokenmeter-0.1.0.tar.gz.
File metadata
- Download URL: smalldreamcollective_tokenmeter-0.1.0.tar.gz
- Upload date:
- Size: 42.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.22 {"installer":{"name":"uv","version":"0.9.22","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a7dd007d007ab85cba3ca7933b3c0ee82c1a67edcff47cb9186abce2f622ba69
|
|
| MD5 |
ce011d18e22e5b5a5cb9f73f40dd2f3f
|
|
| BLAKE2b-256 |
c0a92fd08db0bc08087600bb22e65aba9a82f789778c60ccfd631abde9411d50
|
File details
Details for the file smalldreamcollective_tokenmeter-0.1.0-py3-none-any.whl.
File metadata
- Download URL: smalldreamcollective_tokenmeter-0.1.0-py3-none-any.whl
- Upload date:
- Size: 48.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.22 {"installer":{"name":"uv","version":"0.9.22","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4bdee7cc96635c33e4992982fa3f911b0fe8e1615c46a873cd11b3dfc8109f87
|
|
| MD5 |
472accefacb01690719bafc7d7856cac
|
|
| BLAKE2b-256 |
6aecdc979091744d30166e3063efb3bedd9d53207b6bbf95591de22216d46b59
|