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) ⚠️ Partial See examples/test_streaming.py for current behavior; chunk-level telemetry still WIP.
Anthropic messages.create (sync) Handles system prompt + tool use blocks; always captures usage.
Anthropic Streaming ⚠️ Partial Events enumerated in tests; telemetry enrichment planned.
Custom code @observe, trace_context OpenTelemetry spans exported via same queue.

Roadmap items (tracked via GitHub issues): async client support, streaming deltas, 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.4.tar.gz (26.6 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.4-py3-none-any.whl (28.4 kB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for asymetry-0.1.4.tar.gz
Algorithm Hash digest
SHA256 a62d5fb8f282388b5e384f7618194c837cb455c238c8ffdc8bff235f9cee6f34
MD5 da63306ed98329f39d448c26bc899d96
BLAKE2b-256 c14c8be9bb902446ea0425ae36ee2bad58b12e9d0a48b3701b8cdbfcaee58cb6

See more details on using hashes here.

File details

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

File metadata

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

File hashes

Hashes for asymetry-0.1.4-py3-none-any.whl
Algorithm Hash digest
SHA256 440fbccdef87f010f51e59ed77e7ac63ed6d088ade9f348e961ac05e83b6fa74
MD5 c32dfa9078efc30d5398b4f21f8b2a83
BLAKE2b-256 f257e05dc122ea75cae28465ac04a9ebb50afcf60c7ee1ad617d012fd59c80bd

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