LLM usage telemetry SDK for Cloptima reporting, attribution, and analytics
Project description
Cloptima LLM Observability Python SDK
Capture LLM usage telemetry from your application and send it to Cloptima for cost reporting, attribution, and analytics.
This SDK is designed for teams that want observability without replacing their existing provider clients, wrappers, retries, auth, or application security controls.
Install
pip install cloptima-llm-observability
If you want the httpx transport helpers:
pip install "cloptima-llm-observability[httpx]"
Quick start
Required configuration:
CLOPTIMA_LLM_OBSERVABILITY_API_KEYCLOPTIMA_LLM_OBSERVABILITY_APP_ID
Recommended while testing:
CLOPTIMA_LLM_OBSERVABILITY_ENVIRONMENT=dev
from cloptima_llm_observability import extract_openai_usage, init_from_env
cloptima = init_from_env()
result = cloptima.observe_call(
provider="openai",
model="gpt-4.1-mini",
call=lambda: summary_service.generate(prompt),
extract_usage=extract_openai_usage,
feature_id="summary_generation",
workflow_id="support_agent",
fire_and_forget=False,
)
By default, the SDK sends bearer-authenticated HTTPS requests to Cloptima at https://api.cloptima.ai/v1/ai/integrations/sdk/events.
If the required configuration is missing, init_from_env() returns a disabled pass-through client so local development and tests do not break.
Choose your integration path
Call-site or wrapper boundary
This is the default path for most teams.
Use it when you already know the provider, model, and business context at the point where your code calls an LLM or an existing AI wrapper.
observe_call(...)for direct integrationcreate_observed_call(...)for reusable wrapperswrap_observed_service(...)to instrument customer-owned service classes
from cloptima_llm_observability import (
extract_openai_usage,
init_from_env,
wrap_observed_service,
)
class SummaryService:
def generate_summary(self, prompt: str):
return openai.responses.create(model="gpt-4.1-mini", input=prompt)
cloptima = init_from_env()
summary_service = wrap_observed_service(
cloptima,
SummaryService(),
{
"generate_summary": {
"kind": "call",
"options": {
"provider": "openai",
"model": "gpt-4.1-mini",
"extract_usage": extract_openai_usage,
"fire_and_forget": False,
},
"resolve_overrides": lambda prompt: {
"attribution": {
"feature_id": "summary_generation",
},
},
}
},
)
Context-first attribution
Use context helpers when you want workflow or feature attribution to apply across nested calls without threading more parameters through your own service signatures.
with_attribution(...)run_with_attribution(...)with_workflow(...)with_task(...)@workflow(...)@task(...)
from cloptima_llm_observability import with_task, with_workflow
with with_workflow("support_agent", tenant_id="acme-prod"):
with with_task("draft_reply", team_id="customer-support"):
summary_service.generate_summary(prompt)
Per-call attribution still works and overrides context when needed.
Shared transport integration
If your application centralizes outbound LLM calls behind httpx, instrument that shared boundary:
import httpx
from cloptima_llm_observability import init_from_env, instrument_httpx_transport
cloptima = init_from_env()
transport = instrument_httpx_transport(
httpx.HTTPTransport(),
cloptima=cloptima,
provider="openai",
model="gpt-4o-mini",
fire_and_forget=False,
)
client = httpx.Client(transport=transport)
This gives broad coverage, but it has less business context than call-site or wrapper-boundary integration.
OTLP delivery to Cloptima
Use otlp_http when your enterprise prefers OpenTelemetry-compatible payloads but still wants to send that telemetry to Cloptima.
cloptima_httpis the default delivery modeotlp_httpsends OpenTelemetry-compatible payloads to Cloptima's OTLP receiver
CLOPTIMA_LLM_OBSERVABILITY_DELIVERY_MODE=otlp_http
CLOPTIMA_LLM_OBSERVABILITY_OTLP_SERVICE_NAME=agent-api
CLOPTIMA_LLM_OBSERVABILITY_OTLP_SERVICE_VERSION=2026.06.14
If you already operate an OTEL collector and emit GenAI spans, you can also send OTLP data to Cloptima without using this SDK. Use the SDK OTLP mode when you want application-managed instrumentation that still fits an OTLP-shaped delivery contract.
Built-in extractors and compatibility
Built-in usage extractors cover:
- OpenAI
- Azure OpenAI
- Anthropic
- Gemini
- Vertex AI
- Bedrock
If a provider response shape drifts, you do not need to replace the whole extractor path. Compose or patch it instead:
try_extract_usage(...)compose_usage_extractors(...)with_usage_overrides(...)create_mapped_usage_extractor(...)list_supported_providers()
Attribution fields
Common ownership and reporting fields:
app_idenvironmentteam_idfeature_idworkflow_idcost_centerbusiness_unitproducttenant_idend_customer_idcustomer_segmentrelease
Set defaults once in default_attribution, set them in context, or override them per call.
Metadata and privacy
Use metadata_policy to control how custom metadata is retained:
metadata_onlyallowlisted_metadatastrict_finopsdebug_observability
Sensitive-looking keys such as prompts, messages, credentials, and secrets are treated conservatively by default.
Validation and local previews
Use these helpers in local tests, CI, or rollout checks:
preview_event_payload(...)preview_batch_payload(...)preview_otlp_request(...)validate_payload(...)
They build or validate payloads in memory and do not send network traffic.
Examples
Public examples live in examples/:
basic.py: direct call-site integrationcustom_wrapper.py: existing service wrapper integrationworkflow_context.py: context-first attribution without signature bloathttpx_transport.py: sharedhttpxintegrationotlp_basic.py: OTLP-compatible delivery to Cloptimaopenai_basic.py,anthropic_basic.py,gemini_basic.py: provider-specific extractor examples
Troubleshooting
No telemetry arrives:
- verify the API key is valid for Cloptima telemetry ingestion
- check
client.is_enabled() - inspect a sample event with
validate_payload(preview_event_payload(...))
Unexpected provider response shape:
- start with the closest built-in extractor
- patch field differences with
with_usage_overrides(...)orcreate_mapped_usage_extractor(...) - compare against
list_supported_providers()if you need a supported-provider snapshot
Support
- Issues:
https://github.com/cloptima/cloptima-llm-observability-python/issues - Security: see
SECURITY.md - Product support:
hello@cloptima.ai
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 cloptima_llm_observability-0.1.2.tar.gz.
File metadata
- Download URL: cloptima_llm_observability-0.1.2.tar.gz
- Upload date:
- Size: 47.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
401712f6af4ff351d6c7abb9fbb0e6d82025fa8367d84eabdf5f11dbadee76fc
|
|
| MD5 |
872e84ca862d60a047fc6171dfb633a4
|
|
| BLAKE2b-256 |
2b61f50985f61335ecd70fcb1463f80d7a2669cc3c5589731ff4fcd58bfc5e84
|
Provenance
The following attestation bundles were made for cloptima_llm_observability-0.1.2.tar.gz:
Publisher:
release.yml on cloptima/cloptima-llm-observability-python
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
cloptima_llm_observability-0.1.2.tar.gz -
Subject digest:
401712f6af4ff351d6c7abb9fbb0e6d82025fa8367d84eabdf5f11dbadee76fc - Sigstore transparency entry: 1818488586
- Sigstore integration time:
-
Permalink:
cloptima/cloptima-llm-observability-python@25a2107a99cff463a70a3d1da70b156dfe491828 -
Branch / Tag:
refs/tags/v0.1.2 - Owner: https://github.com/cloptima
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@25a2107a99cff463a70a3d1da70b156dfe491828 -
Trigger Event:
push
-
Statement type:
File details
Details for the file cloptima_llm_observability-0.1.2-py3-none-any.whl.
File metadata
- Download URL: cloptima_llm_observability-0.1.2-py3-none-any.whl
- Upload date:
- Size: 28.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bc9cbafb3cb5ff2c94c22467204d792bc8a9053f869a4ccfb662bc840dcaab7c
|
|
| MD5 |
5952fa97e9cc9a1843e1651156dc29b3
|
|
| BLAKE2b-256 |
c2a25302ddb90e858627e0209cc358b6ec5a973ab7d758a417ab3bcaa89cb779
|
Provenance
The following attestation bundles were made for cloptima_llm_observability-0.1.2-py3-none-any.whl:
Publisher:
release.yml on cloptima/cloptima-llm-observability-python
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
cloptima_llm_observability-0.1.2-py3-none-any.whl -
Subject digest:
bc9cbafb3cb5ff2c94c22467204d792bc8a9053f869a4ccfb662bc840dcaab7c - Sigstore transparency entry: 1818488604
- Sigstore integration time:
-
Permalink:
cloptima/cloptima-llm-observability-python@25a2107a99cff463a70a3d1da70b156dfe491828 -
Branch / Tag:
refs/tags/v0.1.2 - Owner: https://github.com/cloptima
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@25a2107a99cff463a70a3d1da70b156dfe491828 -
Trigger Event:
push
-
Statement type: