Skip to main content

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(...) and client.chat.send_async(...)
  • client.responses.send(...) and client.responses.send_async(...)
  • client.embeddings.generate(...) and client.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 up to 64 KiB and 1,024 items; terminal metadata and usage can still be recorded after the bound is reached. The configured max_attribute_length does not shrink this retention bound; the core applies it to the exported attribute after the mask runs.
  • A chat stream that is cut at the bound, closed early, or fails, and a Responses stream that is cut at the bound, ends without a terminal response, or ends with an error event set telemetry.dev.capture.truncated = true. With a mask configured, the incomplete reconstructed output is omitted because the mask cannot inspect the complete value.
  • Only the SDK methods listed above are instrumented in this version.
  • Video generation (client.video_generation) is not traced; submitted and polled video jobs produce no spans.

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

Metadata

Release files for telemetry-dev-openrouter 0.1.6

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for telemetry-dev-openrouter 0.1.6
File Size Uploaded
telemetry_dev_openrouter-0.1.6.tar.gz 14.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for telemetry-dev-openrouter 0.1.6
File Interpreter ABI Platform
telemetry_dev_openrouter-0.1.6-py3-none-any.whl Python 3 none any Details

Total release size: 29.2 kB

Release files / telemetry_dev_openrouter-0.1.6.tar.gz

Download URL telemetry_dev_openrouter-0.1.6.tar.gz
Size 14.2 kB
Tags Source
SHA-256 checksum
How to use checksums
cecb9c5efa8457aac01202d84e7d3b3eb1e1809d754a776e29f1d7212a056e37
BLAKE2b-256 checksum
How to use checksums
6c3b5f164b9d8593fc146747d495a37cd15d23ace891e72ad19b33ea5861f37e
Upload date
Uploaded using Trusted Publishing?
What is 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}

Release files / telemetry_dev_openrouter-0.1.6-py3-none-any.whl

Download URL telemetry_dev_openrouter-0.1.6-py3-none-any.whl
Size 15.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
a76c577a0221e7b596714d379fd4858fd20221f6eaf45a145c87faf95aa227f9
BLAKE2b-256 checksum
How to use checksums
263ef7edcd99c9f845e6e7b6ffd5299f0485fceadc7b00898fe3777ac57d1ade
Upload date
Uploaded using Trusted Publishing?
What is 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}

Release history Release notifications | RSS feed

This release

0.1.6 This release

2 release files

0.1.5

2 release files

0.1.4

2 release files

0.1.3

2 release files

0.1.2

2 release files

0.1.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page