Skip to main content

LLM observability SDK for OpenAI and Anthropic

Project description

Asymetry SDK

Observability and tracing for OpenAI & Anthropic workloads – built for modern LLM Ops.

Python 3.13+ License: MIT

asymetry is a zero-code observability layer for LLM applications. It hooks into the official OpenAI and Anthropic SDKs, captures detailed telemetry (latency, token usage, params, errors), enriches it with OpenTelemetry context, and streams everything to the Asymetry backend via a resilient exporter.


Capability Highlights (v0.1.0-alpha)

  • Automatic provider instrumentation – monkey patches OpenAI chat.completions.create and Anthropic messages.create with one call to init_observability().
  • Rich span payloads – request/response payloads, finish reasons, structured token usage (real usage when available, otherwise tiktoken-powered estimates), error objects with stack traces, and trace correlations.
  • Custom tracing hooks – decorators, context managers, and helpers (observe, trace_context, add_span_attribute, add_span_event) powered by OpenTelemetry for arbitrary Python functions.
  • Production-focused exporter – lock-free queue, batching, retry/backoff, graceful shutdown, and queue backpressure so your app stays responsive.
  • OpenTelemetry bridge – automatically starts llm.request spans if none exist, or enriches your active spans with token counts and finish reasons.

Installation

# Poetry
poetry add asymetry

# Pip
pip install asymetry

Requires Python 3.13+ and an active Asymetry API key.


Quick Start

  1. Export credentials
export ASYMETRY_API_KEY="sk_test_..."   # required
export ASYMETRY_ENABLED=true              # optional (default true)
  1. Instrument your app
from asymetry import init_observability, observe
import openai, anthropic

init_observability()

openai_client = openai.OpenAI()
anthropic_client = anthropic.Anthropic()

# OpenAI – fully automatic tracking
response = openai_client.chat.completions.create(
    model="gpt-4o-mini",
    messages=[{"role": "user", "content": "Summarize SOC2."}],
    temperature=0.2,
)

# Anthropic – same queue, no extra work
claude = anthropic_client.messages.create(
    model="claude-3-5-haiku-latest",
    max_tokens=200,
    messages=[{"role": "user", "content": "Summarize SOC2."}],
)

# Custom business logic
@observe(name="process_ticket", attributes={"tier": "gold"})
def process_ticket(ticket_id: str, body: str) -> str:
    ...
    return "ok"
  1. Optional explicit shutdown
from asymetry import shutdown_observability

shutdown_observability(timeout=10)  # flush remaining spans

Configuration Surface

All knobs are environment variables (overrideable via init_observability()):

Variable Purpose Default
ASYMETRY_API_KEY Auth token for ingest required
ASYMETRY_API_URL Ingest endpoint https://api.asymetry.co/v1/ingest
ASYMETRY_ENABLED Master switch true
ASYMETRY_BATCH_SIZE Export batch size 100
ASYMETRY_FLUSH_INTERVAL Seconds between flushes 5.0
ASYMETRY_QUEUE_MAX_SIZE In-memory queue bound 10000
ASYMETRY_MAX_RETRIES Export retry attempts 3
ASYMETRY_REQUEST_TIMEOUT HTTP timeout (s) 10.0

Programmatic overrides:

init_observability(
    api_key="sk_test...",
    enabled=True,
    log_level="DEBUG",
    enable_tracing=True,
)

Telemetry Model

Every captured span is decomposed into three payload types and queued together:

  • LLM Requests – provider, model, timestamp, latency, finish_reason, full prompt/messages, captured outputs, request params, OpenTelemetry identifiers.
  • Token Usage – prompt/completion/total token counts; uses real values when provided by the SDK or falls back to tiktoken or character-based heuristics.
  • Errors – Python exception type/code/message plus truncated stack traces.
  • Trace Spans – when observe/trace_context are used, full OTel spans (attributes, events, IO metadata) are exported alongside LLM calls for end-to-end correlation.

Architecture Snapshot

Your App (OpenAI / Anthropic / custom)
        ↓ monkey-patched clients & decorators
Asymetry Instrumentation (LLM + OTEL)
        ↓
Thread-safe queue (backpressure & drop-old)
        ↓
Background exporter thread
        ↓ async HTTP client (httpx)
Asymetry ingest API (batch + retry)

Key guarantees:

  • Non-blocking: SDK calls enqueue telemetry without touching the network path.
  • Resilient exporter: time or size-based flush, exponential backoff, graceful shutdown hook via atexit.
  • Queue safety: bounded queue protects your app; oldest spans are dropped if pressure persists.

Instrumentation Coverage

Provider API Status Notes
OpenAI chat.completions.create (sync) Token usage extracted when OpenAI returns usage; otherwise estimated.
OpenAI Streaming (stream=True) Full telemetry: content accumulation, tool calls, token usage (real with stream_options or estimated), time-to-first-token. See examples/example_streaming_openai.py.
Anthropic messages.create (sync) Handles system prompt + tool use blocks; always captures usage.
Anthropic Streaming Full telemetry: event processing, content accumulation, tool uses, real token usage from message events. See examples/example_streaming_anthropic.py.
Custom code @observe, trace_context OpenTelemetry spans exported via same queue.

Roadmap items (tracked via GitHub issues): async client support, additional providers, custom span ingestion, SDK-specific extras.


Examples

The examples/ directory doubles as runnable docs:

  • basic_usage.py – OpenAI quick start and error capture.
  • advanced_usage.py – custom configuration, workload simulation, batching demo.
  • multi-llm.py – single init that tracks both OpenAI and Anthropic.
  • example_tracing.py – custom tracing helpers (functions, contexts, events).
  • test_streaming.py – current streaming behavior + gap analysis.

Run with Poetry:

poetry install
poetry run python examples/basic_usage.py

Troubleshooting Cheatsheet

  • Missing API key – set ASYMETRY_API_KEY or pass api_key= to init_observability.
  • OpenAI / Anthropic not found – install the relevant SDK (pip install openai anthropic); instrumentation gracefully skips absent providers.
  • tiktoken warnings – install tiktoken for precise usage numbers; otherwise we fallback to character estimates.
  • Need verbose logs – pass log_level="DEBUG" to surface exporter + instrumentation details.
  • Lingering spans on exit – call shutdown_observability(timeout=10) before terminating short-lived scripts/tests.

Contributing & Local Dev

git clone https://github.com/asymetry-official/asymetry-sdk
cd asymetry
poetry install
poetry run pytest       # coming soon
poetry run python examples/basic_usage.py

We welcome PRs for new providers, better streaming support, and tracing improvements. Please discuss major changes via GitHub issues first.


License & Links

Made with ❤️ by the Asymetry team.

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

asymetry-0.1.8.tar.gz (35.4 kB view details)

Uploaded Source

Built Distribution

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

asymetry-0.1.8-py3-none-any.whl (37.9 kB view details)

Uploaded Python 3

File details

Details for the file asymetry-0.1.8.tar.gz.

File metadata

  • Download URL: asymetry-0.1.8.tar.gz
  • Upload date:
  • Size: 35.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.2.1 CPython/3.13.2 Darwin/25.2.0

File hashes

Hashes for asymetry-0.1.8.tar.gz
Algorithm Hash digest
SHA256 95d292a765bd67fc54f753f467c7269d0bd7f513f6f32deada856eeed5332912
MD5 aa838f5bfb249aed74ddbb3d13b180bd
BLAKE2b-256 5f8c075c53ce8402f859c8ef0d172a8b4b5919453088045e5cbeaf2d0eddc2b6

See more details on using hashes here.

File details

Details for the file asymetry-0.1.8-py3-none-any.whl.

File metadata

  • Download URL: asymetry-0.1.8-py3-none-any.whl
  • Upload date:
  • Size: 37.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.2.1 CPython/3.13.2 Darwin/25.2.0

File hashes

Hashes for asymetry-0.1.8-py3-none-any.whl
Algorithm Hash digest
SHA256 eed4a8c03f6d74ad46d516fb84c7ae31afe99285305026670db1fc033b045fc7
MD5 6e7a6dd78bf7f64f13999f705d8154c1
BLAKE2b-256 00d79af0e93a459dde032ca7874bcf6bf6f2e3fa4a5a7dc97bedfdf1d8a81699

See more details on using hashes here.

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