ratel-ai-telemetry (Python)
Raw API of ratel-ai-telemetry — the ratel.* overlay on OpenTelemetry gen_ai spans for Python.
v0.1.2 · Python · PyPI · source
Generated from the doc comments at
ratel-ai/ratel@3be0ecb— do not edit by hand. Regenerate withpnpm sync:apiinapps/docs.
Classes
AuthOutcome
Outcome of an MCP auth flow. Carried by ratel.auth.outcome; NEEDS_AUTH is the 401-driven AuthNeeds case (ADR-0007 auth_needs).
Attributes:
FAILED = 'failed'NEEDS_AUTH = 'needs_auth'OK = 'ok'REFRESHED = 'refreshed'
Origin
Whether a ratel.* span was a direct library call or synthesized by the agent inside its loop. Carried by ratel.origin; mirrors the local trace Origin (ADR-0007).
A str-Enum: each member equals its exact wire string, so it is usable directly as an OTel attribute value.
Attributes:
AGENT = 'agent'DIRECT = 'direct'
SearchTarget
What a ratel.search span was searching. Carried by ratel.search.target; folds capability-tool search and skill search into one span shape.
Attributes:
SKILL = 'skill'TOOL = 'tool'
ContentCapture
Message/tool content capture modes for OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT (CONVENTIONS.md § Capture gating). Default off.
Attributes:
EVENT_ONLY = 'EVENT_ONLY'NO_CONTENT = 'NO_CONTENT'SPAN_AND_EVENT = 'SPAN_AND_EVENT'SPAN_ONLY = 'SPAN_ONLY'
OtlpConfig
OtlpConfig(url: str, headers: dict[str, str], service_name: str)Resolved exporter configuration; the pure core of init().
Attributes:
headers: dict[str, str]service_name: strurl: str
TelemetryHandle
What init() returns: a shutdown handle, not a full provider.
Both the enabled path (a live TracerProvider) and the disabled/no-op path satisfy this,
so the return type is honest either way. Emit spans through the global OpenTelemetry API
(opentelemetry.trace.get_tracer(...)), not off this handle — init() registers the
provider globally.
force_flush
force_flush(timeout_millis: int = 30000) -> boolshutdown
shutdown() -> AnyFunctions
init
init(*, api_key: str | None = None, endpoint: str | None = None, headers: Mapping[str, str] | None = None, service_name: str | None = None, span_filter: SpanFilter | None = None, enabled: bool = True) -> TelemetryHandleWire an OTLP http/protobuf exporter + batch processor + service.name resource,
register it as the global tracer provider, and return a shutdown handle (call
handle.shutdown() / handle.force_flush()). Emit spans through the global OTel API
(opentelemetry.trace.get_tracer(...)); everything else is the untouched OTel SDK.
init() owns the global provider, so it exports every span by default (unlike ratel_span_processor, whose default gen_ai./ratel. filter exists for sharing a provider); pass span_filter to narrow it. Repeated calls return the original Ratel-owned handle. It raises — pointing at ratel_span_processor — if a foreign provider is already registered globally. On first setup, pass enabled=False for an OTel-free no-op handle that needs no endpoint; once Ratel owns the provider, repeated calls return it regardless of options. Enabled initialization needs the [otlp] extra and raises a clear error without it.
Shutdown is terminal: after handle.shutdown(), a later init() raises rather than hand back the dead provider (OTel's global provider is set once per process). Note that the handle is shared across repeated calls, so shutting it down stops export for every caller.
resolve_otlp_config
resolve_otlp_config(*, api_key: str | None = None, endpoint: str | None = None, headers: Mapping[str, str] | None = None, service_name: str | None = None, env: Mapping[str, str] | None = None) -> OtlpConfigResolve init() options into concrete exporter config.
Accepts either api_key= (falling back to RATEL_API_KEY; endpoint defaults to RATEL_URL; Authorization: Bearer) or endpoint=/headers= (custom endpoint / collector). The forms compose: explicit endpoint/api_key values win over their environment fallbacks. An explicit api_key sets the Bearer header; the RATEL_API_KEY fallback applies only when neither api_key nor an explicit Authorization header is given, so ambient env never clobbers auth the caller set on purpose. env is injectable so the precedence is testable without a network.
content_capture_mode
content_capture_mode(env: Mapping[str, str] | None = None) -> ContentCaptureParse the ecosystem content-capture gate. A mode set via set_content_capture wins outright (env is the fallback, as in OTel); otherwise defaults to NO_CONTENT when unset/empty/unrecognized. The legacy boolean form maps true to full capture (SPAN_AND_EVENT) and false to none.
set_content_capture
set_content_capture(mode: ContentCapture | str | None) -> intProgrammatically set the content-capture mode. While set, content_capture_mode() returns this mode regardless of OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT — programmatic config wins over the environment, matching how OpenTelemetry treats env vars as the fallback for code-level configuration. Pass None to clear the override unconditionally and return to env-driven parsing.
The mode is validated like the env var (case-insensitive, legacy true/false/1/0 accepted) and raises a ValueError on anything unrecognized — failing loud at config time instead of storing a value that would both disable capture and mask the env var.
Returns a generation token identifying this call as the current owner of the override; pass it to clear_content_capture to clear only if no newer set has happened since (the safe form for shutdown/teardown hooks).
clear_content_capture
clear_content_capture(generation: int) -> NoneClear the programmatic content-capture override, but only when generation — the token returned by set_content_capture — still identifies the most recent set. A stale token no-ops, so an old handle shutting down late cannot clobber an override a newer caller installed (and silently re-enable, or disable, capture via the env fallback). For an unconditional clear, use set_content_capture(None).
ratel_signal_filter
ratel_signal_filter(span: ReadableSpan) -> boolDefault span filter: forward only signal-bearing spans — a ratel.* span name, or any attribute key under gen_ai.* / ratel.*.
This is what lets Ratel share a provider with e.g. Langfuse + the Vercel AI SDK and ingest only the gen_ai/ratel signal (the AI SDK's gen_ai.* spans + Ratel's own ratel.search / execute_tool), dropping the framework's ai.* wrapper noise.
ratel_span_exporter
ratel_span_exporter(*, api_key: str | None = None, endpoint: str | None = None, headers: Mapping[str, str] | None = None) -> SpanExporterBuild the OTLP http/protobuf span exporter at the resolved Ratel endpoint.
The standalone exporter for callers wiring their own span-processor; ratel_span_processor batches over it. Carries no resource — the caller's provider owns service.name. Needs the [otlp] extra; raises a clear error otherwise.
ratel_span_processor
ratel_span_processor(*, api_key: str | None = None, endpoint: str | None = None, headers: Mapping[str, str] | None = None, span_filter: SpanFilter | None = None, enabled: bool = True) -> SpanProcessorA BatchSpanProcessor over the Ratel OTLP exporter that forwards only the spans passing
span_filter (default ratel_signal_filter; pass lambda _s: True to forward everything).
Add it to your own provider (provider.add_span_processor(ratel_span_processor(...))) to
send Ratel telemetry alongside another provider — no global side effects, no resource.
Greenfield apps that want Ratel to own the provider should call init() instead. Pass
enabled=False for an OTel-free no-op processor that needs no endpoint. Enabled processors
need the [otlp] extra and raise a clear error without it.
Constants
CAPTURE_CONTENT_ENV: Final = 'OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT'— The ecosystem instrumentation env var gating message/tool content capture. Default off; honored by init() rather than a Ratel-invented flag (CONVENTIONS.md § Capture gating). Values: legacy boolean, or the enum NO_CONTENT (default) / SPAN_ONLY / EVENT_ONLY / SPAN_AND_EVENT.EXECUTE_TOOL: Final = 'execute_tool'— execute_tool — the gen_ai.operation.name value for a tool invocation. Deliberately the standard OTel gen_ai operation, not a bespoke ratel.invoke span, so a generic OTel backend already understands it (locked 2026-07-05). The invoke is enriched with ratel.* attributes.GEN_AI_INFERENCE_DETAILS: Final = 'gen_ai.client.inference.operation.details'— gen_ai.client.inference.operation.details — the event that carries message text and tool-call content (never span attributes). Borrowed from gen_ai (Tier 1).GEN_AI_OPERATION_NAME: Final = 'gen_ai.operation.name'— gen_ai.operation.name — set to EXECUTE_TOOL for a tool invocation.GEN_AI_TOOL_CALL_ARGUMENTS: Final = 'gen_ai.tool.call.arguments'— gen_ai.tool.call.arguments — tool arguments (Opt-In content, gated).GEN_AI_TOOL_CALL_ID: Final = 'gen_ai.tool.call.id'— gen_ai.tool.call.id — tool call id, when available.GEN_AI_TOOL_CALL_RESULT: Final = 'gen_ai.tool.call.result'— gen_ai.tool.call.result — tool result (Opt-In content, gated).GEN_AI_TOOL_NAME: Final = 'gen_ai.tool.name'— gen_ai.tool.name — the capability tool id.RATEL_AUTH_FLOW: Final = 'ratel.auth.flow'— ratel.auth.flow — MCP auth flow.RATEL_AUTH_OUTCOME: Final = 'ratel.auth.outcome'— ratel.auth.outcome — "ok" / "refreshed" / "needs_auth" / "failed" (see AuthOutcome).RATEL_ORIGIN: Final = 'ratel.origin'— ratel.origin — direct library call vs agent-synthesized (shared attribute).RATEL_SEARCH: Final = 'ratel.search'— ratel.search — capability search (unifies tool-search and skill-search).RATEL_SEARCH_HIT_COUNT: Final = 'ratel.search.hit_count'— ratel.search.hit_count — results returned.RATEL_SEARCH_QUERY: Final = 'ratel.search.query'— ratel.search.query — the search text (content, gated like message content).RATEL_SEARCH_RESULTS: Final = 'ratel.search.results'— ratel.search.results — Opt-In event carrying hit ids + scores + per-stage BM25 timing; gated like content. The ratel.search span itself carries only counts.RATEL_SEARCH_TARGET: Final = 'ratel.search.target'— ratel.search.target — "tool" or "skill" (see SearchTarget).RATEL_SEARCH_TOP_K: Final = 'ratel.search.top_k'— ratel.search.top_k — requested result count.RATEL_SKILL_ID: Final = 'ratel.skill.id'— ratel.skill.id — skill loaded on the ratel.skill.load span.RATEL_SKILL_LOAD: Final = 'ratel.skill.load'— ratel.skill.load — skill content load (get_skill_content).RATEL_TOOL_ARGS_SIZE_BYTES: Final = 'ratel.tool.args_size_bytes'— ratel.tool.args_size_bytes — argument payload size on the execute_tool span.RATEL_UPSTREAM_REGISTER: Final = 'ratel.upstream.register'— ratel.upstream.register — upstream-MCP ingest.RATEL_UPSTREAM_SERVER: Final = 'ratel.upstream.server'— ratel.upstream.server — upstream MCP server backing a tool / auth flow.RATEL_UPSTREAM_TOOL_COUNT: Final = 'ratel.upstream.tool_count'— ratel.upstream.tool_count — tools ingested on register.RATEL_UPSTREAM_TRANSPORT: Final = 'ratel.upstream.transport'— ratel.upstream.transport — "stdio" / "http" / "sse" / ...SEMCONV_VERSION: Final = '1.42.0'— The pinned OpenTelemetry semantic-conventions version this vocabulary tracks (the gen_ai group). The pin is the contract; consumers read against this exact version, never "latest" (CONVENTIONS.md § The pin).API_KEY_ENV = 'RATEL_API_KEY'— Env var whose value is the default API key when api_key= is omitted.ENDPOINT_ENV = 'RATEL_URL'— Env var whose value is the default OTLP endpoint.DEFAULT_SERVICE_NAME = 'ratel'— service.name used when the caller does not pass one.SpanFilter = Callable[['ReadableSpan'], bool]— Predicate deciding whether a finished span is forwarded to Ratel.