Skip to main content

Rius Python SDK

OpenTelemetry-native tracing for AI agents and LLM applications. glassflow-rius emits OpenTelemetry GenAI traces over OTLP to the managed GlassFlow observability platform (or any OTLP-compatible backend).

Status: alpha. APIs may change.

Install

pip install glassflow-rius

Quickstart

import rius
from rius import observe, start_as_current_generation, start_as_current_span
from rius.semconv import SpanKind

rius.init(
    api_key="glassflow_...",          # or set RIUS_API_KEY
    service_name="my-agent",          # or set RIUS_SERVICE_NAME
)

# 1. Decorator — trace a whole function
@observe
def handle(query: str) -> str: ...

# 2. Context manager — trace a block
with start_as_current_span("retrieve", kind=SpanKind.RETRIEVER) as obs:
    obs.set_output(docs)

# 3. LLM generations — gen_ai-native
with start_as_current_generation("chat", model="gpt-4o", input=messages) as gen:
    gen.set_output(reply)
    gen.set_usage(input_tokens=42, output_tokens=17)

Each surface has a manual variant for lifetimes a with block can't express (streaming, callbacks): start_span(...) / start_generation(...) return a handle you .update() and must .end() yourself.

Configuration is resolved from explicit arguments first, then environment variables:

Argument Environment variable Default Description
endpoint RIUS_ENDPOINT https://ingest.eu.console.rius-glassflow.com Base OTLP endpoint. Traces are sent to <endpoint>/v1/traces.
api_key RIUS_API_KEY — Injected as an Authorization: Bearer <key> header on every export.
service_name RIUS_SERVICE_NAME unknown_service Sets the OpenTelemetry service.name resource attribute.
disabled RIUS_DISABLED false Kill switch. When true, spans are created but never exported.
sample_rate RIUS_SAMPLE_RATE 1.0 Head sampling ratio 0.0–1.0 (whole-trace; children follow root).
capture_content RIUS_CAPTURE_CONTENT true When false, prompt/response content is stripped at export (metadata still sent).

mask is a code-only option (no env var): pass a callable to init(mask=...) and it is applied to every content attribute value at export, across our spans and any bundled third-party instrumentation. A mask that accepts a key keyword also receives the attribute key, for per-attribute decisions.

Both controls cover the whole span, not just its attributes: event and link attributes, the exception.message / exception.stacktrace of a recorded exception, and the ERROR status description, since provider errors routinely echo the rejected request back. With capture_content=False those are stripped and the status code and exception.type are kept, so failures stay visible; with a mask, the mask runs over them (the status description is offered under key="status.description").

rius.init(mask=lambda value: "[REDACTED]")   # redact all captured content
rius.init(mask=lambda value, *, key: hash_pii(value) if "input" in key else value)
rius.init(capture_content=False)             # drop content entirely, keep metadata

Auto-instrumentation

The SDK bundles existing OTel instrumentors (OpenInference) as optional extras, so a single install captures your LLM provider and framework calls. Install the extras you need and init() enables whatever it finds; the instrumentation spans nest under your @observe / start_as_current_span traces automatically.

pip install "glassflow-rius[openai]"        # one provider
pip install "glassflow-rius[instruments]"   # everything supported

An extra installs the instrumentation for a library, never the library itself, so the SDK never pins or upgrades the versions your code runs against: glassflow-rius[anthropic] expects anthropic to be your own dependency, which it already is in any project that calls Anthropic. An extra installed without its library makes init() log a DependencyConflict from OpenTelemetry and leaves that one integration off.

rius.init()                          # auto-enables installed instrumentors
rius.init(instruments=["openai"])    # restrict to specific ones
rius.init(instruments=[])            # disable auto-instrumentation

Supported instruments: openai, anthropic, langchain, llama-index, litellm, and mcp. Content captured by instrumentors is covered by the same mask / capture_content controls as our own spans.

The mcp instrument is built in and has no extra: there is no third-party instrumentation to install, and an extra that installed mcp for you would break the rule above. If the mcp package is present, every ClientSession.call_tool() your agent makes becomes a first-class TOOL span (execute_tool <name>) with gen_ai.tool.name, the arguments and result as input.value/output.value, latency, and error status (including tools that return isError results).

Instrumentors patch libraries process-wide, so a scoped client (init(set_global=False)) only enables them when instruments=[...] is passed explicitly. Calling init() again while a client is active logs a warning and returns the existing client unchanged; call client.shutdown() first to reconfigure.

Reliability

Export is designed to never block or crash your application:

  • Async batched export. Spans are queued in-process and exported in batches from a background thread (BatchSpanProcessor). Span creation stays fast even when the backend is slow or unreachable.
  • Retries. Transient failures (connection errors, 429/5xx) are retried with exponential backoff and jitter, bounded by the export timeout.
  • Graceful degradation. If the backend stays down, spans are dropped and an error is logged — exceptions never propagate into application code. A failing mask callable drops only the affected attribute value (fail closed), never the batch.
  • Flush on shutdown. Pending spans are flushed automatically at interpreter exit. Call client.flush() to force an export, or client.shutdown() to drain and stop.

Batching and backpressure are tunable via the standard OpenTelemetry env vars: OTEL_BSP_MAX_QUEUE_SIZE (default 2048; spans beyond this are dropped), OTEL_BSP_SCHEDULE_DELAY (default 5000 ms), OTEL_BSP_MAX_EXPORT_BATCH_SIZE (default 512), and OTEL_BSP_EXPORT_TIMEOUT (default 30000 ms).

Development

uv sync --group dev
uv run pytest
uv run ruff check . && uv run ruff format --check .
uv run mypy

Releasing

Releases are automated with release-please and published to PyPI via Trusted Publishing.

  1. Merge changes to main using Conventional Commits (feat: → minor, fix: → patch, feat!:/BREAKING CHANGE → major).
  2. release-please keeps a Release PR open that bumps __version__ and updates CHANGELOG.md. Merge it when you want to cut a release.
  3. Merging tags vX.Y.Z, creates a GitHub Release, and publishes to PyPI automatically.

Non-conventional commits are ignored for versioning.

License

MIT

Metadata

Release files for glassflow-rius 0.17.0

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

Source distribution (sdist)

Source distribution for glassflow-rius 0.17.0
File Size Uploaded
glassflow_rius-0.17.0.tar.gz 208.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for glassflow-rius 0.17.0
File Interpreter ABI Platform
glassflow_rius-0.17.0-py3-none-any.whl Python 3 none any Details

Total release size: 271.5 kB

Release files / glassflow_rius-0.17.0.tar.gz

Download URL glassflow_rius-0.17.0.tar.gz
Size 208.4 kB
Tags Source
SHA-256 checksum
How to use checksums
2bb2492ec0fea5e44e9c374cd36e24b0cac49138e8ca6f5f967db8904f60073a
BLAKE2b-256 checksum
How to use checksums
4875a4efbb437c03812c5d6732f4f5c32dda17ebb745d0fe0c9a7dabbe6f2464
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 21, 2026.

Transparency log

Release files / glassflow_rius-0.17.0-py3-none-any.whl

Download URL glassflow_rius-0.17.0-py3-none-any.whl
Size 63.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
2ade3d25a3dc9ca4c68c6801ce792dd0304272e1138acf2678b6fb75a9a18c72
BLAKE2b-256 checksum
How to use checksums
9f0ae9e1f70bf554bfeb7a068156fcd1571ffa40ae54f5bbe2a3c75b0000f718
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 21, 2026.

Transparency log

Release history Release notifications | RSS feed

1.3.0

2 release files

1.2.0

2 release files

1.1.1

2 release files

1.1.0

2 release files

1.0.2

2 release files

1.0.1

2 release files

1.0.0

2 release files

This release

0.17.0 This release

2 release files

0.16.0

2 release files

0.15.1

2 release files

0.15.0

2 release files

0.14.0

2 release files

0.13.0

2 release files

0.12.0

2 release files

0.11.0

2 release files

0.10.0

2 release files

0.9.1

2 release files

0.9.0

2 release files

0.8.2

2 release files

0.8.1

2 release files

0.8.0

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