Python SDK for fin (badboy) - track LLM usage events; import as fin_sdk
Project description
fin-badboy-sdk — Python SDK
Track AI/LLM usage events from Python applications. PyPI: fin-badboy-sdk (import package remains fin_sdk).
Install
From PyPI (package name fin-badboy-sdk).
pip install fin-badboy-sdk
Quick Start
import time
from openai import OpenAI
from fin_sdk import FinClient
client = OpenAI()
fin = FinClient()
start = time.time()
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": "Hello"}],
)
fin.track_response(
response,
provider="openai",
feature_id="chat",
latency_ms=(time.time() - start) * 1000,
)
Product environment (development | production) is not passed into track_response—it is set on the server from your API key (Epic 21). Use a key that matches the fin deployment URL.
Configuration
Set environment variables (read at construction time):
export FIN_INGEST_URL=https://events.badboy.dev
export FIN_API_KEY=sk-your-api-key
For experiment resolution (resolve_model / experiment), also set FIN_API_URL (api-nest base URL), for example https://api.badboy.dev.
Or pass explicitly:
fin = FinClient(
ingest_url="https://events.badboy.dev",
api_key="sk-your-api-key",
)
For local development, set ingest_url to your local events service base URL (no trailing slash).
API
track_response(response=None, *, provider, feature_id, ...)
Build and POST a usage event from a provider response. response is positional-or-keyword; all other parameters are keyword-only.
| Parameter | Type | Required | Description |
|---|---|---|---|
response |
Any |
No | Raw LLM response; SDK auto-extracts usage + model |
provider |
str |
Yes | Use a key from Supported Providers below (aligned with Fin’s global pricing model for server-side cost), or any string with explicit usage / model |
feature_id |
str |
Yes | Workflow/feature name |
model |
str |
No | Override or fallback |
usage |
dict |
No | {"input_tokens": N, "output_tokens": N, "total_tokens": N} (snake_case; converted to camelCase internally) |
latency_ms |
float |
No | End-to-end latency in milliseconds |
error |
bool |
No | True on error path (zeroes usage) |
tenant_id |
str |
No | Your end-user/customer ID |
plan_tier |
str |
No | e.g. "free", "pro" |
outcome |
str |
No | e.g. "success", "refusal" |
cost |
float |
No | Client-supplied cost in USD |
idempotency_key |
str |
No | De-duplicate retries |
Cost: pass cost when you trust your own figure (e.g. provider billing). Omit it to let Fin derive an estimate from its global pricing model using provider, model, usage, and event time. The same applies to track() when you build the full camelCase payload.
track(payload, *, idempotency_key=None)
Post a pre-built event dict. All keys must be camelCase. Missing required fields are logged and the event is silently skipped.
Epic 21: track_response does not send environment; the events service sets it from the API key. Required fields for track() match the public ingest schema (featureId, provider, model, usage, timestamp, etc.) — not environment.
Supported Providers
These keys align with Fin’s global pricing model (same provider ids as server-side cost lookup).
| Provider key | Extraction |
|---|---|
"openai" |
usage.prompt_tokens → inputTokens, usage.completion_tokens → outputTokens, usage.total_tokens → totalTokens; model |
"groq" |
Same as "openai" |
"azure_openai" |
Same as "openai" |
"mistral" |
Same as "openai" (Mistral chat API is OpenAI-compatible) |
"anthropic" |
usage.input_tokens → inputTokens, usage.output_tokens → outputTokens; totalTokens derived as input + output; model |
"google" |
usageMetadata.promptTokenCount, .candidatesTokenCount, .totalTokenCount (snake_case variants supported); model from model, modelVersion, or model_version |
Other provider strings still work: pass usage and model explicitly on track_response, or use track() with a full camelCase payload.
Error Handling
The SDK never raises on ingest failure. HTTP errors and network issues are logged via logging.getLogger("fin_sdk") with a [fin-sdk] ingest failed: prefix. Your application flow is never disrupted.
Full Documentation
See docs/getting-started.md for the complete integration guide.
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 fin_badboy_sdk-0.2.1.tar.gz.
File metadata
- Download URL: fin_badboy_sdk-0.2.1.tar.gz
- Upload date:
- Size: 13.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f7efc633e7b08839643ad283a38739e8c3f42fd9acb1fd9fac99154a1b23041f
|
|
| MD5 |
419ddaadb81e33f9242fd1dbce6ea845
|
|
| BLAKE2b-256 |
d1bb3a6fef0faffa2af46d2ba3e7f3a1f8c9c0045e84e1e4f1fafcb291518ca0
|
File details
Details for the file fin_badboy_sdk-0.2.1-py3-none-any.whl.
File metadata
- Download URL: fin_badboy_sdk-0.2.1-py3-none-any.whl
- Upload date:
- Size: 10.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ea90fe9dc4f6cfbe10b623bfca9bb8b7bac3db631cc061e33c33d20b4f300656
|
|
| MD5 |
1453969bf3a5642df3f5b40251ff0762
|
|
| BLAKE2b-256 |
387360f7439adcab0e53c7805f8f1cc0f7499b489a198f83ab5a68380021cb9e
|