Skip to main content

GlassFlow SDK — OpenTelemetry-native tracing for AI agents and LLM applications.

Project description

GlassFlow Python SDK

OpenTelemetry-native tracing for AI agents and LLM applications. glassflow-ai 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-ai

Quickstart

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

glassflow.init(
    api_key="glassflow_...",          # or set GLASSFLOW_API_KEY
    service_name="my-agent",          # or set GLASSFLOW_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 GLASSFLOW_ENDPOINT https://ingest.glassflow.dev Base OTLP endpoint. Traces are sent to <endpoint>/v1/traces.
api_key GLASSFLOW_API_KEY Injected as an Authorization: Bearer <key> header on every export.
service_name GLASSFLOW_SERVICE_NAME unknown_service Sets the OpenTelemetry service.name resource attribute.
disabled GLASSFLOW_DISABLED false Kill switch. When true, spans are created but never exported.
sample_rate GLASSFLOW_SAMPLE_RATE 1.0 Head sampling ratio 0.01.0 (whole-trace; children follow root).
capture_content GLASSFLOW_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.

glassflow.init(mask=lambda value: "[REDACTED]")   # redact all captured content
glassflow.init(mask=lambda value, *, key: hash_pii(value) if "input" in key else value)
glassflow.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-ai[openai]"        # one provider
pip install "glassflow-ai[instruments]"   # everything supported
glassflow.init()                          # auto-enables installed instrumentors
glassflow.init(instruments=["openai"])    # restrict to specific ones
glassflow.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: if the mcp package is installed, 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

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

glassflow_ai-0.4.0.tar.gz (137.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

glassflow_ai-0.4.0-py3-none-any.whl (22.6 kB view details)

Uploaded Python 3

File details

Details for the file glassflow_ai-0.4.0.tar.gz.

File metadata

  • Download URL: glassflow_ai-0.4.0.tar.gz
  • Upload date:
  • Size: 137.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for glassflow_ai-0.4.0.tar.gz
Algorithm Hash digest
SHA256 6cc1ff4cd8427d6a6010a2bbfb454f03c2e73e1fa277cf2f8b51471112a0bae1
MD5 2e0ad163a97309ddb6dd21da848aa098
BLAKE2b-256 d0250b2903bba7a231f5692b3c45c89378dfa3911993c1e7d5e33f6cfd233aa2

See more details on using hashes here.

Provenance

The following attestation bundles were made for glassflow_ai-0.4.0.tar.gz:

Publisher: release.yml on glassflow/glassflow-python

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file glassflow_ai-0.4.0-py3-none-any.whl.

File metadata

  • Download URL: glassflow_ai-0.4.0-py3-none-any.whl
  • Upload date:
  • Size: 22.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for glassflow_ai-0.4.0-py3-none-any.whl
Algorithm Hash digest
SHA256 4f2954d8383be46e473797b2926345b1f290fdf952f57e94c5d6fee075669701
MD5 4cefb39c8cbf299dd1b3f9328b346293
BLAKE2b-256 f6a19dc920834e44edf62679e9af63d339a043fc5dad2879c5dfd5d54b386eb3

See more details on using hashes here.

Provenance

The following attestation bundles were made for glassflow_ai-0.4.0-py3-none-any.whl:

Publisher: release.yml on glassflow/glassflow-python

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page