Costimizer AI observability SDK for LLM FinOps
Project description
Costimizer Python SDK
Capture LLM calls and send them to Costimizer FinOps.
Install only the provider client you use
pip install "costimizer[openai]"
pip install "costimizer[openrouter]"
pip install "costimizer[otel-langchain]" # LangChain auto-instrument
pip install "costimizer[otel-openai]" # native OpenAI auto-instrument
Core SDK (httpx only) installs with:
pip install costimizer
OpenAI
pip install "costimizer[openai]"
from costimizer import Costimizer
from costimizer.ai.openai import OpenAI
costimizer = Costimizer(
project_token="fo_ingest_your_key",
host="https://api.costimizer.ai",
)
client = OpenAI(
api_key="sk-...",
costimizer_client=costimizer,
)
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": "Hello"}],
costimizer_trace_name="support-chat",
)
costimizer.shutdown()
OpenRouter
OpenRouter uses the OpenAI-compatible API, so it installs the openai package:
pip install "costimizer[openrouter]"
from costimizer import Costimizer
from costimizer.ai.openrouter import OpenRouter
costimizer = Costimizer(project_token="fo_ingest_your_key")
client = OpenRouter(
api_key="sk-or-...",
costimizer_client=costimizer,
)
response = client.chat.completions.create(
model="anthropic/claude-3.5-sonnet",
messages=[{"role": "user", "content": "Hello"}],
costimizer_trace_name="router-chat",
)
costimizer.shutdown()
LangChain (callback — OpenRouter / LangGraph)
Use this when your app calls models through OpenRouter (or any LangChain chat model) and you pass callbacks manually — e.g. LangGraph agents with many parallel LLM steps.
pip install "costimizer[langchain]"
Ingest key: create with provider: "openrouter" so it matches every generation event.
import os
from costimizer import Costimizer
from costimizer.langchain import CostimizerCallbackHandler
costimizer = Costimizer(
project_token=os.environ["COSTIMIZER_PROJECT_TOKEN"],
host=os.environ.get("COSTIMIZER_HOST", "https://stgfinops.costimizer.ai"),
debug=True,
)
callbacks = [
CostimizerCallbackHandler(
costimizer,
trace_name="costimizer-support-chat",
distinct_id="user-123",
provider="openrouter",
base_url="https://openrouter.ai/api/v1/",
)
]
# Pass the same callbacks list into every LangChain model factory / invoke:
# model_handler.get_sonnet(callbacks=callbacks)
# model_handler.get_haiku(callbacks=callbacks)
# Flush queued events when the agent turn finishes:
costimizer.shutdown()
| Env var | Purpose |
|---|---|
COSTIMIZER_PROJECT_TOKEN |
Ingest key (fo_ingest_...) |
COSTIMIZER_HOST |
FinOps API base URL |
COSTIMIZER_PROVIDER |
Optional default ingest provider (openrouter) |
COSTIMIZER_BASE_URL |
Optional default LLM base URL on events |
COSTIMIZER_DEBUG |
Log ingest success/failure to stderr |
The callback tracks each LangChain run_id separately, so parallel asyncio.gather LLM calls in LangGraph do not overwrite each other's input/output.
LangChain (callback — OpenAI)
pip install "costimizer[langchain]"
from costimizer import Costimizer
from costimizer.langchain import CostimizerCallbackHandler
from langchain_openai import ChatOpenAI
costimizer = Costimizer(project_token="fo_ingest_your_key")
handler = CostimizerCallbackHandler(
costimizer,
trace_name="support-chat",
distinct_id="user-123",
provider="openai",
base_url="https://api.openai.com/v1/",
)
model = ChatOpenAI(model="gpt-4o-mini", temperature=0.7, seed=42)
model.invoke("Hello", config={"callbacks": [handler]})
costimizer.shutdown()
OpenTelemetry (native OpenAI)
pip install "costimizer[otel-openai]"
from costimizer import Costimizer
from costimizer.otel import instrument
import openai
costimizer = Costimizer(project_token="fo_ingest_your_key")
instrument(costimizer, openai=True, trace_name="support-chat")
client = openai.OpenAI()
client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": "Hello"}],
)
costimizer.shutdown()
Optional tracking fields
All provider wrappers accept the same Costimizer-only kwargs:
| Kwarg | Purpose |
|---|---|
costimizer_trace_name |
Label for dashboards |
costimizer_trace_id |
Group related calls |
costimizer_distinct_id |
User or session ID |
costimizer_properties |
Custom metadata dict |
costimizer_privacy_mode |
"metadata_only" (default) or "full_content" |
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 costimizer-0.1.8.tar.gz.
File metadata
- Download URL: costimizer-0.1.8.tar.gz
- Upload date:
- Size: 16.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c26b80af6586010105b25d260cc92a53dc10cea5c63be4818bdbdcb905049f17
|
|
| MD5 |
1152efddd4f3dc06a702facd4dfab08b
|
|
| BLAKE2b-256 |
f88832aafce7636d428d43d63beb837b76f79936a09bcc74d267f034d9829eed
|
File details
Details for the file costimizer-0.1.8-py3-none-any.whl.
File metadata
- Download URL: costimizer-0.1.8-py3-none-any.whl
- Upload date:
- Size: 20.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4e48d9ec65e1aced211b1e20935f4128eb4dc5d53cfaf229072748bdc4ac0396
|
|
| MD5 |
1eee2a2d6ac33d8461c83b701b6c5be2
|
|
| BLAKE2b-256 |
c49709038d5d02f565e399abcc0ab97ebc179fbc27b71e155be056ccc59d734e
|