Python providers
Wrap OpenAI, Azure OpenAI, Cohere, Anthropic, Gemini, Bedrock, LiteLLM, Deepgram, ElevenLabs, and OpenAI Realtime with the Python SDK.
Pass your native client to sp.wrap(). The provider is auto-detected.
For OpenRouter, you can instead configure Broadcast to hosted OTLP. Do not wrap and Broadcast the same calls unless both paths carry the same generation ID.
OpenAI
from openai import OpenAI, AsyncOpenAI
client = sp.wrap(OpenAI())
response = client.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": "Hello!"}],
)
async_client = sp.wrap(AsyncOpenAI())Streaming works transparently. The cost event is submitted when the stream completes.
Azure OpenAI
Wrap AzureOpenAI (or an OpenAI client pointed at an Azure endpoint). SuperPenguin detects Azure from the host (*.openai.azure.com, *.services.ai.azure.com, and related Azure AI hosts). There is no separate Azure wrapper.
Azure region is not auto-captured. Typical Azure hosts use a resource name, not a region, so pass wrap-level region and deployment_type if you want SDK estimates to use the matching rate card. Omit both for Global Standard (the default).
from openai import AzureOpenAI
client = sp.wrap(
AzureOpenAI(
azure_endpoint="https://my-resource.openai.azure.com",
api_key="...",
api_version="2024-10-21",
),
region="eastus2",
deployment_type="regional",
)| Deployment | What to pass |
|---|---|
| Global Standard | omit region and deployment_type |
| Data Zone | deployment_type="data-zone" |
| Regional | region (location code, e.g. eastus2) and deployment_type="regional" |
region must be the Azure location code from the portal / ARM (eastus2, westeurope, swedencentral). Case does not matter (EastUS2 works). Display names (East US 2) and AWS-style ids (us-east-2) will not match, so the estimate falls back to Global. For deployment_type, use exactly "regional" or "data-zone" (keep the hyphen). Passing only region is not enough for regional rates. Connecting Azure for billed spend already uses invoice amounts; these fields only affect SDK estimates. See Batch and service-tier pricing.
Cohere
Cohere support is available in Python SDK 0.15.0 and later. Install or upgrade
with pip install --upgrade 'superpenguin[cohere]>=0.15.0'.
Wrap cohere.ClientV2 or cohere.AsyncClientV2 from the optional cohere
dependency (version 7.2 or later in the 7.x series). Both synchronous and
asynchronous calls are supported.
Compatible APIs and models
The following model and API combinations have been verified. Other model IDs
are not covered by this list. Model availability depends on your provider
account and, for Bedrock, AWS region. The Bedrock combinations below were
verified in us-west-2.
| API | Operation | Verified model |
|---|---|---|
| Cohere native | Text Embed | embed-v5.0-fast |
| Cohere native | Rerank | rerank-v4.0-fast |
| Cohere native | Chat, including streaming | command-r7b-12-2024 |
| Cohere OpenAI-compatible | Text Embed | embed-v5.0-pro |
| Cohere OpenAI-compatible | Chat, including streaming | command-r7b-12-2024 |
| AWS Bedrock InvokeModel | Text Embed | cohere.embed-english-v3 |
| AWS Bedrock InvokeModel or Agent Runtime | Rerank | cohere.rerank-v3-5:0 |
For AWS Bedrock, wrap a boto3 or aioboto3 client. Cohere
BedrockClient Embed and BedrockClientV2 Rerank are also supported with
synchronous clients. Read or close AWS response bodies after each request.
Native Cohere example
Native Embed accepts input_type to distinguish search documents from queries.
Replace the API key placeholders with your own keys.
import cohere
import superpenguin as sp
sp.init(api_key="YOUR_SUPERPENGUIN_KEY")
client = sp.wrap(cohere.ClientV2(api_key="YOUR_COHERE_KEY"))
response = client.embed(
model="embed-v5.0-fast",
texts=["A small penguin."],
input_type="search_document",
embedding_types=["float"],
)
sp.flush()OpenAI-compatible example
Wrap an OpenAI client using Cohere's compatibility URL and a Cohere API key.
Omit input_type for this endpoint.
from openai import OpenAI
import superpenguin as sp
sp.init(api_key="YOUR_SUPERPENGUIN_KEY")
client = sp.wrap(OpenAI(
api_key="YOUR_COHERE_KEY",
base_url="https://api.cohere.ai/compatibility/v1",
))
response = client.embeddings.create(
model="embed-v5.0-pro",
input=["A small penguin."],
encoding_format="float",
)
sp.flush()Usage and cost
SuperPenguin uses the provider's reported input/output tokens for Chat, input tokens for Embed, and billed search units for native Rerank. Cost also requires a matching price for the model and API. Missing usage or pricing leaves cost unknown; it does not mean the request was free.
Bedrock Rerank requests are tracked, but responses without billed search units have unknown per-request cost. SuperPenguin does not estimate search units from the number of documents or results. The AWS Agent Runtime Rerank response does not include billed usage. Connecting AWS billing can supply aggregate billed spend, but does not fill in these individual request costs.
Consume Chat streams fully to receive their final usage. A stream that ends before usage arrives can leave usage and cost unknown. Usage telemetry does not include document bodies or embedding vectors.
Not supported
- Rerank through Cohere's OpenAI-compatible endpoint. Use the native Cohere client for Rerank.
input_typeon OpenAI-compatible Embed requests. Cohere's endpoint rejects this parameter, including when sent through the OpenAI SDK's extra request body options. Omit it, or use native Embed to specify search documents or queries. See Cohere's supported parameters.- Usage tracking for batch jobs, image or multimodal Embed, Parse, Transcribe and SageMaker. These operations and deployment paths are outside this integration's coverage.
Retired Bedrock Chat models
The Bedrock models cohere.command-r-v1:0 and cohere.command-r-plus-v1:0
reached end of life on August 19, 2026.
Use direct Cohere Chat with a model from the compatibility table above.
Doubleword
Wrap an OpenAI client pointed at https://api.doubleword.ai/v1. SuperPenguin attributes the billed route as doubleword (the model maker stays in model_vendor). Scope custom prices to doubleword.
Anthropic
from anthropic import Anthropic
client = sp.wrap(Anthropic())
response = client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=1024,
messages=[{"role": "user", "content": "Hello!"}],
)Google Gemini (AI Studio or Vertex AI)
from google import genai
client = sp.wrap(genai.Client(api_key="..."))
# Or Vertex: genai.Client(vertexai=True, project="my-gcp", location="us-central1")
response = client.models.generate_content(
model="gemini-2.5-pro",
contents="Hello!",
)Both generate_content and generate_content_stream are tracked (sync and async). Tiered Gemini pricing is applied server-side from input token count.
AWS Bedrock
import boto3
client = sp.wrap(
boto3.client("bedrock-runtime", region_name="us-west-2"),
metadata={"customer_id": "cust_acme_123", "feature": "doc_summary"},
deployment_type="global", # optional cross-region / global profiles
)
response = client.converse(
modelId="anthropic.claude-3-5-sonnet-20241022-v2:0",
messages=[{"role": "user", "content": [{"text": "Hello!"}]}],
)Wrapped methods: converse and converse_stream (boto3 sync / aioboto3 async). The wrapper sends usage only; the server prices rows with the aws_bedrock rate card. Region is auto-captured from meta.region_name or the endpoint host. invoke_model is not wrapped in v1.
LiteLLM
import litellm
sp.patch_litellm(metadata={"environment": "production"})
response = litellm.completion(
model="openai/gpt-4o",
messages=[{"role": "user", "content": "Hello!"}],
)Every litellm.completion() / litellm.acompletion() call is tracked after patching. SuperPenguin captures billed cost when LiteLLM includes it on the response. You do not pass region.
Deepgram
from deepgram import DeepgramClient, PrerecordedOptions
dg = sp.wrap(
DeepgramClient(api_key="..."),
metadata={"feature": "podcasts"},
tier="growth", # optional Growth-plan SKU
)
result = dg.listen.rest.v("1").transcribe_url(
{"url": "https://example.com/episode.mp3"},
PrerecordedOptions(model="nova-3", multilingual=True),
)Rows include audio_seconds and estimated cost.
ElevenLabs
from elevenlabs.client import ElevenLabs
el = sp.wrap(ElevenLabs(api_key="..."), metadata={"feature": "ivr-greeting"})
audio = el.text_to_speech.convert(
voice_id="21m00Tcm4TlvDq8ikWAM",
text="Welcome to SuperPenguin",
model_id="eleven_flash_v2_5",
)OpenAI Realtime API
Realtime is a WebSocket event stream, not a create() call. Wrap the connection:
client = OpenAI()
with client.realtime.connect(model="gpt-realtime") as conn:
conn = sp.wrap_realtime(conn, metadata={"feature": "voice-agent"})
conn.response.create()
for event in conn:
... # usage tracked on response.doneEach completed turn emits input/output tokens with audio portions as separate input_audio_tokens / output_audio_tokens legs. For WebRTC or raw sockets, use sp.track_realtime_event(event, model="gpt-realtime").