weckr-sdk
AI cost and margin intelligence for SaaS founders. See exactly which users
cost more than they pay, per LLM call, zero added latency. The Python
counterpart of the TypeScript @weckr/sdk.
Try it live
See the dashboard with real data. No signup needed. 👉 https://app.useweckr.com/demo
Install
pip install weckr-sdk
Zero runtime dependencies. Bring your own LLM SDK:
pip install weckr-sdk openai # for OpenAI
pip install weckr-sdk anthropic # for Anthropic
pip install weckr-sdk google-genai # for Gemini (new SDK)
pip install weckr-sdk openai # for Kimi via Moonshot (uses the OpenAI client)
# or all at once:
pip install "weckr-sdk[all]"
Quick start
import os
from openai import OpenAI
from weckr import Weckr
openai_client = OpenAI() # reads OPENAI_API_KEY from env
wk = Weckr(
api_key=os.environ["WK_API_KEY"],
plans={"free": 0, "pro": 29, "business": 99},
)
result = wk.chat(
openai_client,
{
"model": "gpt-4o-mini",
"messages": [{"role": "user", "content": "Summarize this."}],
"user_id": user.id,
"feature": "ai-summary",
"plan": user.plan,
},
)
print(result.choices[0].message.content)
See your own data in the dashboard: https://app.useweckr.com/dashboard Try the demo without signing up: https://app.useweckr.com/demo
The original LLM call runs unchanged and returns the original result. After it resolves, Weckr fires an async log POST to the Weckr API on a background thread, fire-and-forget, so it never blocks your request path.
Anthropic
from anthropic import Anthropic
from weckr import Weckr
anthropic_client = Anthropic()
wk = Weckr(api_key=os.environ["WK_API_KEY"], plans={"pro": 29})
msg = wk.chat(
anthropic_client,
{
"model": "claude-sonnet-4",
"max_tokens": 1024,
"messages": [{"role": "user", "content": "Hello!"}],
"user_id": user.id,
"plan": "pro",
},
)
Gemini
from google import genai
from weckr import Weckr
genai_client = genai.Client()
wk = Weckr(api_key=os.environ["WK_API_KEY"], plans={"pro": 29})
resp = wk.chat(
genai_client,
{
"model": "gemini-2.5-flash",
"messages": [{"role": "user", "content": "Hello!"}],
"user_id": user.id,
"plan": "pro",
},
)
Kimi (Moonshot AI)
Kimi is OpenAI-compatible. Point the OpenAI client at Moonshot's base URL and wrap
it with wk.chat. Weckr auto-detects Kimi from the base URL, so it's the same call
shape as OpenAI.
import os
from openai import OpenAI
from weckr import Weckr
kimi_client = OpenAI(
api_key=os.environ["MOONSHOT_API_KEY"],
base_url="https://api.moonshot.ai/v1", # or https://api.moonshot.cn/v1
)
wk = Weckr(api_key=os.environ["WK_API_KEY"], plans={"pro": 29})
resp = wk.chat(
kimi_client,
{
"model": "kimi-k2.6",
"messages": [{"role": "user", "content": "Hello!"}],
"user_id": user.id,
"plan": "pro",
},
)
Caps + downgrades
Set per-plan spending caps in the dashboard. When a user crosses their cap:
action: "block":wk.chat()raisesWeckrCapErrorand the LLM call is never made.action: "downgrade": the SDK silently swaps the model for a cheaper one in the same provider (gpt-4o→gpt-4o-mini,claude-opus-4→claude-sonnet-4, etc.) and emits a one-timeWeckrDowngradeWarningper (user, model) pair.
from weckr import Weckr, WeckrCapError, WeckrConfigError
try:
wk.chat(openai_client, {...})
except WeckrCapError as e:
show_upgrade_prompt(e.user_id, e.cap)
except WeckrConfigError as e:
# Typo'd api key, revoked key, or `plan` not in the plans dict,
# fail-CLOSED so cap enforcement isn't silently disabled.
alert_backend_team(e.code, str(e))
Short-lived processes (Lambda, cron, CLI)
wk.chat() returns as soon as the LLM call resolves; the log POST runs on a
daemon thread. In short-lived processes (Lambda, cron jobs, CLI scripts),
call wk.flush() before exit so the daemon thread isn't torn down mid-POST:
wk.chat(openai_client, {...})
wk.flush() # default 5s timeout
What gets logged
Every successful call (and every failed LLM call) lands in the dashboard:
{
"userId": "u_42",
"feature": "ai-summary",
"model": "gpt-4o-mini",
"provider": "openai",
"inputTokens": 12,
"outputTokens": 2,
"costUsd": 0.000003,
"latencyMs": 1218,
"planName": "pro",
"planRevenueUsd": 29.0,
"timestamp": "2026-06-15T07:52:18.086515+00:00",
}
Cost is recomputed server-side from (model, input_tokens, output_tokens),
so clients cannot forge cost values. Margin is planRevenueUsd - costUsd
(negative means you're losing money on that user); the dashboard derives it
on read from SUM(revenue) - SUM(cost) for full precision.
Supported models
- OpenAI:
gpt-4o,gpt-4o-mini,gpt-4-turbo,gpt-4,gpt-3.5-turbo,o1-preview,o1-mini - Anthropic:
claude-opus-4,claude-sonnet-4,claude-haiku-4-5,claude-3-5-sonnet,claude-3-5-haiku,claude-3-opus - Gemini:
gemini-2.5-pro,gemini-2.5-flash,gemini-1.5-pro,gemini-1.5-flash - Kimi (Moonshot AI):
kimi-k2.6,kimi-k3,kimi-k2.5,kimi-k2(point the OpenAI client athttps://api.moonshot.ai/v1)
Dated variants (gpt-4o-2024-08-06, claude-3-5-sonnet-latest, …) resolve
to the matching family by longest-prefix lookup.
Dashboard
View cost / margin / per-user / per-feature breakdowns at https://app.useweckr.com/dashboard.
License
MIT
Release files for weckr-sdk 0.3.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 | |
|---|---|---|---|
| weckr_sdk-0.3.0.tar.gz | 17.7 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| weckr_sdk-0.3.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 39.8 kB
Release files / weckr_sdk-0.3.0.tar.gz
| Download URL | weckr_sdk-0.3.0.tar.gz |
|---|---|
| Size | 17.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
f135a4819730036e22a128a106fdcdf4a7e96b84f257694092fd7d79c50422e5
|
|
BLAKE2b-256 checksum How to use checksums |
b3390718f2af335c98386c76a5c6e843b48f0eb72fe83b968759370959ac54b3
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.9.6
|
Release files / weckr_sdk-0.3.0-py3-none-any.whl
| Download URL | weckr_sdk-0.3.0-py3-none-any.whl |
|---|---|
| Size | 22.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
bcdfcc4ceb83d708ecc69c497c547280ea029572017d3c7c45ec5acdcedce867
|
|
BLAKE2b-256 checksum How to use checksums |
958416928f9272eb1dd178cec17c74f99a8976f7bb909a2f875a70c298b0a40f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.9.6
|