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.
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
maskcallable 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, orclient.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.
- Merge changes to
mainusing Conventional Commits (feat:→ minor,fix:→ patch,feat!:/BREAKING CHANGE→ major). - release-please keeps a Release PR open that bumps
__version__and updatesCHANGELOG.md. Merge it when you want to cut a release. - 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.12.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| glassflow_rius-0.12.0.tar.gz | 172.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| glassflow_rius-0.12.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 217.7 kB
Release files / glassflow_rius-0.12.0.tar.gz
| Download URL | glassflow_rius-0.12.0.tar.gz |
|---|---|
| Size | 172.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
65ab1c39514f469ab07549616127ff0f9bccb3bbdc5b4056f2632cf956001769
|
|
BLAKE2b-256 checksum How to use checksums |
beb647f5ee03b2012815cf5a98a77a1155dc75fe61ade99b3a7a58331768d241
|
| 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 Aug 20, 2026.
Transparency logRelease files / glassflow_rius-0.12.0-py3-none-any.whl
| Download URL | glassflow_rius-0.12.0-py3-none-any.whl |
|---|---|
| Size | 44.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
004742b65725907f5c2bc096ff9cc33e684377dbc1229f0ea209d92ed2b82ebb
|
|
BLAKE2b-256 checksum How to use checksums |
800559cbc1afba7f6cba38e678b5c4dfbb0760f506cee7b9dadfd32a58e3c6ca
|
| 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 Aug 20, 2026.
Transparency log