telemetry-dev-openrouter
OpenRouter SDK instrumentation for telemetry.dev. It wraps the official openrouter Python SDK
and emits telemetry.dev generation and embedding spans through telemetry-dev.
Install
pip install telemetry-dev-openrouter
Initialize the core SDK first:
import telemetry_dev
telemetry_dev.init(
api_key="td_live_...",
service_name="my-service",
)
Per-client wrapping
from openrouter import OpenRouter
from telemetry_dev_openrouter import wrap_open_router
client = wrap_open_router(OpenRouter(api_key="sk-or-v1-..."))
client.chat.send(
model="openai/gpt-4o-mini",
messages=[{"role": "user", "content": "Tell me a joke about OpenTelemetry"}],
)
Use this when you want explicit control over which clients are instrumented. The same wrapped
client supports synchronous methods and their *_async counterparts.
Global instrumentation
from openrouter import OpenRouter
from telemetry_dev_openrouter import instrument_openrouter, uninstrument_openrouter
instrument_openrouter()
client = OpenRouter(api_key="sk-or-v1-...")
try:
client.responses.send(model="openai/gpt-4o-mini", input="Explain OpenTelemetry briefly")
finally:
uninstrument_openrouter()
Use this as the app-wide one-liner at startup when all OpenRouter clients should be instrumented.
Repeated wrapping or global instrumentation is safe, and uninstrument_openrouter() restores the
original SDK methods.
Instrumented surfaces
Synchronous and asynchronous variants are covered:
client.chat.send(...)andclient.chat.send_async(...)client.responses.send(...)andclient.responses.send_async(...)client.embeddings.generate(...)andclient.embeddings.generate_async(...)
All spans use gen_ai.provider.name = "openrouter". Generation spans capture the request model and
input, supported sampling parameters, response model and ID, finish reasons, output messages, and
token usage. Embedding spans capture the request input, request and response models, and token
usage; embedding vectors are intentionally not captured as output.
When OpenRouter returns cost information, the integration records gen_ai.usage.cost from
usage.cost. If that field is absent, it falls back to
usage.cost_details.upstream_inference_cost. The cost attribute is omitted when neither value is
available.
Streaming
Chat and Responses API streams are traced for sync and async callers. The integration accumulates captured output, records time to first chunk, and maps terminal usage and cost when OpenRouter provides them. Terminal Responses API events close the span, including completed, failed, incomplete, and error events.
Responses stream output can include reconstructed output items followed by bounded
{"type": "telemetry.dev.response_stream_event", "event_type": ..., "payload": ...} entries for
consumed image-generation lifecycle and partial-image events, apply-patch diff events, fusion
lifecycle, analysis, and panel events, web-search lifecycle events, and debug timing events.
OpenRouter debug upstream request-body echoes are not retained. These provider-event entries share
the stream capture budget and set
telemetry.dev.capture.truncated = true when only a prefix can be retained.
Requests are passed to OpenRouter unchanged. The integration does not add or modify
stream_options, so streaming usage and cost are available only when they are present in the
stream returned by OpenRouter.
Failure behavior
Instrumentation is fail-open when telemetry_dev.init() has not been called: OpenRouter requests
still execute and return their normal SDK values without exporting telemetry.
Limitations
- Unconsumed streams end their spans only when the stream is exhausted, errors, or is closed.
- Streaming output is retained only up to the core SDK capture budget; terminal metadata and usage
can still be recorded after the budget is reached. A span with partial captured output includes
telemetry.dev.capture.truncated = true. - Only the SDK methods listed above are instrumented in this version.
Development
From sdks/python-openrouter:
uv sync
uv run ruff format .
uv run pytest
uv run ruff format --check .
uv run ruff check .
uv run pyright
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 telemetry_dev_openrouter-0.1.1.tar.gz.
File metadata
- Download URL: telemetry_dev_openrouter-0.1.1.tar.gz
- Upload date:
- Size: 12.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
uv/0.12.5 {"installer":{"name":"uv","version":"0.12.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
018bb2a6282c5a4457c1a34ae18d7cd9a567d1bfcfc92f53f8edfc8908f41a6b
|
|
| MD5 |
0fcee3b3cd47b289fe7b1a3c8898e68f
|
|
| BLAKE2b-256 |
ea3a1ae4bbd15c4db23f896c88ca6e163ab007e860006028499a6a46dafa855a
|
File details
Details for the file telemetry_dev_openrouter-0.1.1-py3-none-any.whl.
File metadata
- Download URL: telemetry_dev_openrouter-0.1.1-py3-none-any.whl
- Upload date:
- Size: 12.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
uv/0.12.5 {"installer":{"name":"uv","version":"0.12.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d03a96d6b6deb50f1f687301ef5db8499db914c891d91b04619841eb7426078e
|
|
| MD5 |
eec6aae33f076683375ff21ffc55822a
|
|
| BLAKE2b-256 |
f7f3e3a8517baefbd36fc9aac474856fd4fb80b0a15d2bf085cfc228bb5a559d
|