Lightweight API cost tracker for research labs
Project description
Hong Lab AI Cost Tracker
A lightweight Python SDK that transparently tracks LLM API costs. Wrap your existing client with tracker.wrap() — costs are logged automatically.
Supports OpenAI, Google Gemini, Anthropic, and third-party proxies (e.g. apiyihe.org).
Installation
pip install hong-lab-ai-cost
# With specific provider support
pip install "hong-lab-ai-cost[openai]"
pip install "hong-lab-ai-cost[all]" # OpenAI + Gemini + Anthropic
API Keys (Recommended: Use Environment Variables)
You do NOT need to hardcode API keys in your code. Each provider's SDK automatically reads from environment variables — just export them in your shell or .env file:
# OpenAI (including third-party proxies)
export OPENAI_API_KEY="sk-..."
# Google Gemini
export GEMINI_API_KEY="..."
# Anthropic
export ANTHROPIC_API_KEY="sk-ant-..."
This way, your code stays clean and your keys are never exposed in source files. The hong-lab-ai-cost SDK does not handle API keys at all — it only wraps the client for cost tracking. Key management is entirely handled by each provider's own SDK.
💡 Tip: Add these exports to your
~/.bashrc,~/.zshrc, or use a.envfile with python-dotenv to load them automatically.
Usage
OpenAI
from openai import OpenAI
from hong_lab_ai_cost import CostTracker
tracker = CostTracker(project="MyProject", user="kyle", email="kyle@aucklanduni.ac.nz")
client = tracker.wrap(OpenAI()) # Reads OPENAI_API_KEY from environment
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": "Hello!"}],
)
print(tracker.summary())
Google Gemini
from google import genai
from hong_lab_ai_cost import CostTracker
tracker = CostTracker(project="MyProject", user="kyle", email="kyle@aucklanduni.ac.nz")
client = tracker.wrap(genai.Client()) # Reads GEMINI_API_KEY from environment
response = client.models.generate_content(model="gemini-2.5-flash", contents="Hello!")
Anthropic
import anthropic
from hong_lab_ai_cost import CostTracker
tracker = CostTracker(project="MyProject", user="kyle", email="kyle@aucklanduni.ac.nz")
client = tracker.wrap(anthropic.Anthropic()) # Reads ANTHROPIC_API_KEY from environment
response = client.messages.create(
model="claude-3-5-sonnet-20241022",
max_tokens=1024,
messages=[{"role": "user", "content": "Hello!"}],
)
Third-party Proxy
from openai import OpenAI
from hong_lab_ai_cost import CostTracker
tracker = CostTracker(project="MyProject", user="kyle", email="kyle@aucklanduni.ac.nz")
# OPENAI_API_KEY is read from environment; only base_url needs to be specified
client = tracker.wrap(OpenAI(base_url="https://z.apiyihe.org/v1"))
response = client.chat.completions.create(model="gpt-4o-mini", messages=[...])
Manual Recording
For unsupported providers, record usage manually:
tracker.record(model="llama-3-8b", prompt_tokens=1000, completion_tokens=500)
Configuration
All settings can be provided via constructor arguments, environment variables, or a .cost-tracker.yaml file (priority: constructor > env > yaml > defaults).
| Setting | Constructor | Env Variable | Default |
|---|---|---|---|
| Project name | project= |
COST_TRACKER_PROJECT |
"default" |
| User name | user= |
COST_TRACKER_USER |
None |
email= |
COST_TRACKER_EMAIL |
None |
|
| Remote API | remote_url= |
COST_TRACKER_REMOTE_URL |
https://api.honglab.dev |
| Storage dir | storage_dir= |
— | .cost-tracker/ |
Example .cost-tracker.yaml:
project: DentalVLM
user: kyle
email: kyle@aucklanduni.ac.nz
Remote Sync
Remote sync is enabled by default — all usage records are automatically uploaded to https://api.honglab.dev. You do not need to configure anything extra.
Records are uploaded to POST {remote_url}/api/v1/usage/batch with X-Lab-User and X-Lab-Email headers. The server validates these against a whitelist.
If the upload fails (network error, server down), the record is kept locally and retried on the next tracker.flush() or at process exit.
To disable remote sync (local-only mode), explicitly set remote_url to an empty string:
tracker = CostTracker(project="MyProject", user="kyle", email="kyle@aucklanduni.ac.nz", remote_url="")
Or via environment variable:
export COST_TRACKER_REMOTE_URL=""
Pricing
The SDK includes a built-in pricing catalog (pricing_catalog.yaml) with prices for 170+ models from OpenAI, Google, and Anthropic. Costs are calculated automatically based on token usage.
Unknown Models
If you use a model not in the catalog, the SDK logs a warning:
⚠️ Unknown model 'my-custom-model' — cost recorded as $0.00.
You can add pricing manually in your code:
tracker.pricing.set("my-custom-model", "custom", input_per_1m=1.00, output_per_1m=3.00)
Sync Latest Prices
Prices are sourced from LiteLLM's community-maintained database. To update the catalog:
python -m hong_lab_ai_cost.sync_pricing
This fetches the latest prices and merges them into pricing_catalog.yaml. Custom entries you added manually are preserved.
License
MIT
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
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 hong_lab_ai_cost-0.1.5.tar.gz.
File metadata
- Download URL: hong_lab_ai_cost-0.1.5.tar.gz
- Upload date:
- Size: 19.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c474233daccb2c6136897396feeef8024f8c20291ca865cef6bc9d7fa417c055
|
|
| MD5 |
63736ff8ce7ef6d63e8ea7d67b734a9f
|
|
| BLAKE2b-256 |
f0cdf7625f0ac1dc7d73ff371a47c7adb8c3f445e5746294c64b58d2ca161fa6
|
File details
Details for the file hong_lab_ai_cost-0.1.5-py3-none-any.whl.
File metadata
- Download URL: hong_lab_ai_cost-0.1.5-py3-none-any.whl
- Upload date:
- Size: 20.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
096a52cca241fb56e58ec303f795de2235950dbc47842cacdceff2dca8a5ea24
|
|
| MD5 |
821bf58c56a6a716d32c50bf98976161
|
|
| BLAKE2b-256 |
0816d83f207b8e3776927f2343d57d3fd18d5bf474444d510f0f2e172a11fdd6
|