Getting Started

Python async wrapper — live attribution without a proxy

A drop-in wrapper around the OpenAI and Anthropic Python SDKs that reports usage to Cognocient asynchronously. Zero added latency, but no pre-call enforcement — the honest tradeoff explained.

A drop-in wrapper import for the OpenAI and Anthropic Python SDKs. Swap one import, add a key, and get live cost attribution — without changing your base_url or routing traffic through a proxy.

pip install cognocient[openai]
# Before
from openai import OpenAI
client = OpenAI(api_key="sk-...")
 
# After
from cognocient import CognocientOpenAI as OpenAI
client = OpenAI(
    api_key="sk-...",              # your own real OpenAI key, unchanged
    cognocient_key="sk-cog-...",   # the same proxy key you'd use with the proxy
)
 
client.chat.completions.create(
    model="gpt-4o",
    messages=[{"role": "user", "content": "hello"}],
    cognocient_feature="support-bot",  # optional attribution
)

Every method the real SDK exposes still works unchanged. This wrapper only intercepts chat.completions.create() (messages.create() for Anthropic) to report usage after the fact.

Security — read this before you decide

This is not more secure than the proxy

It's a different tradeoff, not a strictly better one — we're not going to tell you otherwise.

With the proxy, your real provider API key lives server-side, under Cognocient's control, in one place. With this wrapper, your key stays in your own application process and calls the provider directly — exactly as it does today without Cognocient at all. Some security teams prefer that (no third-party network hop in the request path); others are less comfortable with third-party code executing inside their process with key access. Both are reasonable positions.

What this wrapper honestly gives you over the proxy:

  • Zero added request latency, in the practical sense — see the measured benchmark below. Reporting happens after your real call already returned, on a background thread, off the critical path.
  • Zero risk of a Cognocient outage affecting your production call. If Cognocient's ingestion API is down, your call to OpenAI or Anthropic still completes normally.

What you give up versus the proxy: pre-call enforcement. Because Cognocient only hears about a call after it already happened, budgets configured in Cognocient cannot block or degrade a call made through this wrapper before it fires. Your dashboard will say so explicitly for any account using this path — see Budget Enforcement.

Measured latency overhead

200 warm-up calls excluded, 2,000 timed iterations per leg, both legs hitting the same in-process mock transport (no real network call to OpenAI or to Cognocient — see methodology below).

p50p95p99mean
Raw SDK call0.7675ms0.8537ms1.1672ms0.7807ms
Wrapped call0.7827ms0.8701ms1.1897ms0.7961ms
Added overhead+0.0152ms+0.0153ms

What this number does and doesn't include

This measures only the wrapper's own interception code on your request path — timing the call, stripping cognocient_* kwargs, and queuing a report. It does not include real network latency to OpenAI/Anthropic or to Cognocient's ingestion API, because reporting runs on a background thread your request never waits on — that's the architectural claim this benchmark exists to check, not assume. Reproduce it yourself: cognocient-python-wrapper/benchmark/benchmark_wrapper_overhead.py, no real API keys required.

Reliability

Reporting is fire-and-forget on a background thread with a bounded local queue, flushed every few seconds or every 50 calls, whichever comes first. If the ingestion API is slow, down, or unreachable:

  • Your real provider call is completely unaffected — it already happened before reporting was attempted.
  • No exception is ever raised into your code from a reporting failure.
  • No retry loop that could pile up work in your process — a failed batch is dropped and logged locally, not retried.

This is verified by an actual test that simulates an unreachable ingestion endpoint and asserts the real call still completes normally — cognocient-python-wrapper/tests/test_reporter_failure_isolation.py, not just claimed in this paragraph.

Known limitation: streaming isn't reported yet

stream=True calls are passed through to the real SDK completely unmodified — your application behaves identically — but are not currently reported to Cognocient. Usage totals aren't available until a stream completes, and reliably capturing them requires wrapping the stream iterator itself, which this version doesn't do. If most of your traffic streams, use the proxy or the CSV/OTel importer instead for now.

Attribution fields

Same field names the proxy accepts as X-Cost-* headers, passed as keyword arguments instead — see Attribution Headers.

Wrapper kwargProxy header
cognocient_featureX-Cost-Feature
cognocient_departmentX-Cost-Department
cognocient_userX-Cost-User
cognocient_sessionX-Cost-Session
cognocient_tierX-Cost-Tier
cognocient_projectX-Cost-Project
cognocient_gl_accountX-Cost-GL-Account
cognocient_workloadX-Cost-Workload
cognocient_outcomeX-Cost-Outcome
cognocient_run_idX-Cost-Run-ID

Frequently asked questions

On this page