Skip to Content
RiusSDKPython reference

Python reference

Generated from the glassflow-ai 0.7.0 docstrings, covering the Python SDK’s public API surface module by module. Wording fixes happen upstream in the SDK repository, never here.

glassflow.client

SDK entrypoint: configure OpenTelemetry and export GenAI traces via OTLP.

build_span_exporter

def build_span_exporter(config: GlassflowConfig) -> SpanExporter

Build the default OTLP/HTTP span exporter for a resolved config.

Arguments:

  • config - A resolved configuration; the exporter posts to config.traces_endpoint with config.headers.

Returns:

A ready-to-use OTLP/HTTP SpanExporter.

GlassflowClient Objects

class GlassflowClient()

Handle over a configured tracer provider.

Returned by init. Exposes the lifecycle operations (flush, shutdown) and tracer access for the pipeline it owns; the resolved configuration is available as client.config.

get_tracer

def get_tracer(name: str = TRACER_NAME) -> trace.Tracer

Return a tracer bound to this client’s provider.

Arguments:

  • name - Instrumentation scope name; defaults to the SDK’s own.

flush

def flush(timeout_millis: int = 30_000) -> bool

Force-flush pending spans. Returns False on timeout.

shutdown

def shutdown() -> None

Drain pending spans and stop. Releases the global init() slot.

Also stops the heartbeat thread and sends its final stopped ping, so the backend can tell a clean shutdown from a vanished agent.

init

def init(*, endpoint: str | None = None, api_key: str | None = None, service_name: str | None = None, headers: dict[str, str] | None = None, disabled: bool | None = None, sample_rate: float | None = None, capture_content: bool | None = None, mask: Callable[[Any], Any] | None = None, instruments: Sequence[str] | None = None, span_exporter: SpanExporter | None = None, heartbeat: bool | None = None, heartbeat_interval: float | None = None, agent_name: str | None = None, heartbeat_transport: Callable[[dict[str, Any]], None] | None = None, partial_spans: bool | None = None, partial_spans_delay: float | None = None, set_global: bool = True) -> GlassflowClient

Initialize the SDK: build a tracer provider that exports OTLP traces.

Calling init() again while a global client is active logs a warning and returns the existing client unchanged (the OpenTelemetry global tracer provider is write-once); call shutdown() on it first to reconfigure.

Arguments:

  • endpoint - Base OTLP endpoint. Traces are sent to <endpoint>/v1/traces.
  • api_key - API key; injected as an Authorization: Bearer header.
  • service_name - Value for the service.name resource attribute.
  • headers - Extra headers for the OTLP exporter.
  • disabled - If True, no exporter is attached (spans are dropped).
  • sample_rate - Head sampling ratio 0.0-1.0 (whole-trace). Default 1.0.
  • capture_content - If False, strip prompt/response content at export. Default True.
  • mask - Redact content attribute values at export (applies to all spans).
  • instruments - Auto-instrumentation selection. None (default) enables every bundled instrumentor whose package is installed; a list restricts to those names; [] disables auto-instrumentation. Instrumentors are process-global, so with set_global=False they are only enabled when instruments is passed explicitly.
  • span_exporter - Override the default OTLP exporter (useful for testing).
  • heartbeat - Enable the agent-lifetime heartbeat thread (GLASSFLOW_HEARTBEAT; default off this release). Pings <endpoint>/v1/heartbeat from init until process exit so the platform can tell a live-but-idle agent from a vanished one.
  • heartbeat_interval - Seconds between pings (default 15, clamped to [5, 300]; the backend derives staleness from this).
  • agent_name - Identity heartbeats group under; defaults to service_name.
  • heartbeat_transport - Override the heartbeat HTTP transport (useful for testing, like span_exporter).
  • set_global - Register the provider as the global OpenTelemetry provider.

get_tracer

def get_tracer(name: str = TRACER_NAME) -> trace.Tracer

Return a tracer from the globally configured provider.

glassflow.observe

The @observe decorator: trace the developer’s own functions.

Wraps sync, async, generator, and async-generator functions (and methods), recording timing, inputs/outputs, and exceptions as an OpenTelemetry span. Spans nest automatically via OTel context propagation and are exported through whatever provider init() configured (a no-op if the SDK was never initialized).

observe

def observe(func: Callable[..., Any] | None = None, *, name: str | None = None, capture_input: bool = True, capture_output: bool = True, kind: SpanKind = SpanKind.CHAIN) -> Any

Decorate a function so each call is traced as a span.

Usable bare (@observe) or parameterized (@observe(name=..., ...)). Supports sync functions, async def functions, generators, and async generators; for generators the span covers the whole iteration and the tracing context is attached only around each step. Exceptions are recorded with ERROR status and always re-raised.

Arguments:

  • func - The decorated function (filled in by bare @observe usage).
  • name - Span name; defaults to the function’s __qualname__.
  • capture_input - Record call arguments as JSON in input.value.
  • capture_output - Record the return value as JSON in output.value.
  • kind - Span taxonomy (openinference.span.kind); default CHAIN.

Returns:

The wrapped function (or a decorator, when used parameterized).

glassflow.spans

Manual span API.

Two surfaces, following the OpenTelemetry / Langfuse / Laminar convention:

  • start_as_current_span is the context manager: it activates the span in the OTel context (so children nest under it) and auto-ends it.
  • start_span is manual: it returns an Observation you must .end(). The span is parented to the current span at creation but is NOT set as current and does NOT auto-record exceptions. For lifetimes a with block can’t express (streaming, callbacks, passing a span across boundaries).

start_generation / start_as_current_generation are the LLM-specialized equivalents.

Observation Objects

class Observation()

Handle for annotating a span from start_span / start_as_current_span.

Wraps an OpenTelemetry span and exposes the annotation surface for generic (non-LLM) spans: input, output, and arbitrary attributes. Inputs and outputs are serialized to JSON (with a repr fallback) and truncated at 8192 characters.

set_input

def set_input(value: Any) -> None

Record the span input (the input.value attribute).

Arguments:

  • value - Any value; serialized to JSON with a repr fallback.

set_output

def set_output(value: Any) -> None

Record the span output (the output.value attribute).

Arguments:

  • value - Any value; serialized to JSON with a repr fallback.

set_attribute

def set_attribute(key: str, value: Any) -> None

Set an arbitrary attribute on the underlying span.

Arguments:

  • key - Attribute name.
  • value - An OpenTelemetry-compatible attribute value.

update

def update(*, input: Any = None, output: Any = None) -> None

Record input and/or output in one call.

Arguments:

  • input - When not None, forwarded to :meth:set_input.
  • output - When not None, forwarded to :meth:set_output.

end

def end() -> None

End the underlying span.

Required for spans created with start_span; spans from start_as_current_span end automatically when the block exits.

start_span

def start_span(name: str, *, kind: SpanKind = SpanKind.CHAIN, input: Any = None) -> Observation

Create a span and return an Observation. You MUST call .end().

The span is parented to the current span at creation, but is not set as the current span and does not auto-record exceptions. Use start_as_current_span for block-scoped tracing.

start_as_current_span

@contextmanager def start_as_current_span(name: str, *, kind: SpanKind = SpanKind.CHAIN, input: Any = None) -> Iterator[Observation]

Open a span as the current span and yield an Observation; auto-ends.

Exceptions raised in the block are recorded and set the span status to ERROR (OpenTelemetry’s start_as_current_span default), then re-raised.

glassflow.generation

LLM generation capture helpers.

start_as_current_generation (context manager) and start_generation (manual, requires .end()) open an LLM-kind span and return a Generation handle for recording gen_ai-native attributes (messages, model, usage, finish reason). LLM spans are therefore readable by any gen_ai-compatible consumer.

Generation Objects

class Generation()

Handle for recording gen_ai attributes on an LLM span.

Returned by start_generation and start_as_current_generation. Messages passed to :meth:set_input / :meth:set_output are normalized to the GenAI message shape ({"role", "parts": [...]}): bare strings, OpenAI-style dicts (including tool_calls and tool responses), and multimodal content lists are all accepted.

set_input

def set_input(messages: Messages) -> None

Record the request messages (gen_ai.input.messages).

Arguments:

  • messages - A string or list of messages in any supported format; bare strings default to the user role.

set_output

def set_output(messages: Messages) -> None

Record the response messages (gen_ai.output.messages).

Arguments:

  • messages - A string or list of messages in any supported format; bare strings default to the assistant role.

set_response_model

def set_response_model(response_model: str) -> None

Record the model that produced the response (gen_ai.response.model).

Arguments:

  • response_model - Model identifier as reported by the provider, which may differ from the requested model.

set_usage

def set_usage(*, input_tokens: int | None = None, output_tokens: int | None = None) -> None

Record token usage (gen_ai.usage.input_tokens / output_tokens).

Send token counts, never cost: cost is computed server-side from model pricing.

Arguments:

  • input_tokens - Prompt tokens consumed, when known.
  • output_tokens - Completion tokens produced, when known.

record_first_token

def record_first_token() -> None

Mark the arrival of the first streamed token (gen_ai.first_token event).

Call from a streaming loop when the first content chunk arrives; the backend derives time-to-first-token as the event time minus the span start. Idempotent: only the first call records; safe to call unconditionally per chunk. A no-op after end().

set_finish_reasons

def set_finish_reasons(reasons: str | list[str]) -> None

Record why generation stopped (gen_ai.response.finish_reasons).

Arguments:

  • reasons - A single reason (wrapped into a list) or a list of reasons, e.g. "stop", "length", "tool_calls".

update

def update(*, input: Messages | None = None, output: Messages | None = None) -> None

Record input and/or output messages in one call.

Arguments:

  • input - When not None, forwarded to :meth:set_input.
  • output - When not None, forwarded to :meth:set_output.

end

def end() -> None

End the underlying span.

Required for generations created with start_generation; spans from start_as_current_generation end automatically when the block exits.

start_generation

def start_generation(name: str, *, model: str | None = None, provider: str | None = None, input: Messages | None = None, model_parameters: dict[str, Any] | None = None, operation: str = "chat") -> Generation

Create an LLM-kind span and return a Generation. You MUST call .end().

Manual counterpart to start_as_current_generation: not set as current, no auto-recording of exceptions.

Arguments:

  • name - Span name.
  • model - Requested model (gen_ai.request.model).
  • provider - Provider name (gen_ai.provider.name), e.g. "openai".
  • input - Request messages, recorded immediately via set_input.
  • model_parameters - Request parameters, each recorded as gen_ai.request.<key>.
  • operation - Operation name (gen_ai.operation.name); default "chat".

Returns:

A Generation handle; call .end() when the call completes.

start_as_current_generation

@contextmanager def start_as_current_generation( name: str, *, model: str | None = None, provider: str | None = None, input: Messages | None = None, model_parameters: dict[str, Any] | None = None, operation: str = "chat") -> Iterator[Generation]

Open an LLM-kind span as the current span and yield a Generation; auto-ends.

Children created inside the block nest under this span, and exceptions raised in the block are recorded with ERROR status, then re-raised. Accepts the same arguments as start_generation.

Yields:

A Generation handle for recording messages, usage, and response metadata; the span ends when the block exits.

glassflow.config

Configuration resolution for the GlassFlow SDK.

Values are resolved with the precedence: explicit arguments > environment variables > built-in defaults.

GlassflowConfig Objects

@dataclass(frozen=True) class GlassflowConfig()

Resolved, immutable SDK configuration.

Produced by resolve_config (arguments over environment over defaults); consumed by init and build_span_exporter.

traces_endpoint

@property def traces_endpoint() -> str

Full OTLP/HTTP traces URL (<endpoint>/v1/traces).

heartbeat_endpoint

@property def heartbeat_endpoint() -> str

Heartbeat URL (<endpoint>/v1/heartbeat), same host as traces.

resolve_config

def resolve_config( *, endpoint: str | None = None, api_key: str | None = None, service_name: str | None = None, headers: dict[str, str] | None = None, disabled: bool | None = None, sample_rate: float | None = None, capture_content: bool | None = None, heartbeat: bool | None = None, heartbeat_interval: float | None = None, agent_name: str | None = None, partial_spans: bool | None = None, partial_spans_delay: float | None = None) -> GlassflowConfig

Resolve SDK configuration from arguments, environment, then defaults.

Explicit arguments win over GLASSFLOW_* environment variables, which win over built-in defaults. sample_rate is clamped to [0.0, 1.0] with a warning; boolean environment variables accept 1/true/ yes/on (case-insensitive).

Arguments:

  • endpoint - Base OTLP endpoint (GLASSFLOW_ENDPOINT).
  • api_key - Bearer token for the managed platform (GLASSFLOW_API_KEY); None sends no Authorization header.
  • service_name - service.name resource attribute (GLASSFLOW_SERVICE_NAME).
  • headers - Extra exporter headers; an explicit Authorization entry wins over api_key.
  • disabled - Kill switch (GLASSFLOW_DISABLED); spans are dropped in-process.
  • sample_rate - Head-sampling ratio for root traces (GLASSFLOW_SAMPLE_RATE).
  • capture_content - When False, content attributes are stripped at export (GLASSFLOW_CAPTURE_CONTENT).
  • heartbeat - Enable the agent-lifetime heartbeat thread (GLASSFLOW_HEARTBEAT). Off by default this release.
  • heartbeat_interval - Seconds between pings (GLASSFLOW_HEARTBEAT_INTERVAL), clamped to [5, 300]; the backend derives staleness from this, so the bounds are part of the wire contract.
  • agent_name - Identity heartbeats group under (GLASSFLOW_AGENT_NAME); defaults to service_name so the agents view and the traces view agree on what an “agent” is.
  • partial_spans - Export a content-free pending snapshot of every sampled span at span START (GLASSFLOW_PARTIAL_SPANS), so in-flight work is visible and crashes leave a record. Off by default until the backend’s unfinished-spans storage ships.
  • partial_spans_delay - Debounce for pending snapshots (GLASSFLOW_PARTIAL_SPANS_DELAY), clamped to [0, 60] seconds. 0 (default) emits at span start; N emits only if the span is still open after N seconds — spans that finish sooner cost no network at all.

Returns:

The resolved, immutable GlassflowConfig.

glassflow.semconv

Semantic conventions for the GlassFlow SDK.

Centralizes the OpenTelemetry instrumentation-scope name, the span-kind taxonomy, and span attribute keys. Span kinds use the OpenInference openinference.span.kind values (understood across the ecosystem); LLM specifics use OTel GenAI gen_ai.*.

SpanKind Objects

class SpanKind(str, Enum)

Observation kind. Values are OpenInference openinference.span.kind values.

  • AGENT: an agent invocation or run
  • LLM: a model call (generations use this)
  • TOOL: a tool execution
  • RETRIEVER: a retrieval / search step
  • EMBEDDING: an embedding computation
  • CHAIN: a generic processing step (the default)

kind_attributes

def kind_attributes(kind: SpanKind) -> dict[str, str]

Identity attributes for a span of kind, for setting at CREATION.

Pending snapshots (pending.py) are built at on_start, so taxonomy set via set_attribute afterwards is invisible to them — passing these at span creation is what makes a pending span classifiable.

set_span_kind

def set_span_kind(span: Span, kind: SpanKind) -> None

Stamp a span with its OpenInference kind and (if applicable) gen_ai operation.

Last updated on