Skip to main content

theta/obsrv Python SDK — multimodal agent tracing for text, images, audio, video, and robotics sensors

Project description

theta-obsrv

Python SDK for theta/obsrv — multimodal agent tracing for LLM + tool + robotics workflows. Text, images, audio, video, and sensor frames flow through a single with client.trace(...) as t: ... API.

Install

pip install theta-obsrv
# optional extras
pip install "theta-obsrv[openai,anthropic,pil]"

Python 3.10+.

Quickstart (zero-config)

export THETA_API_KEY=tk_live_...
export THETA_PROJECT=proj_abc
from theta_observability import trace

with trace("checkout-agent", run_type="eval") as t:
    with t.step(name="plan", type="llm", model="claude-opus-4.6") as s:
        s.log_message(role="user", text="Buy milk", images=["./screen.png"])
        s.log_message(role="assistant", text="Clicking the Buy button.")
        s.set_token_usage(input=900, output=120)

The module-level trace() constructs a process-global TraceClient from environment variables and auto-flushes at interpreter exit.

Explicit client

from theta_observability import TraceClient

client = TraceClient(api_key="...", project="proj_abc")
with client.trace("checkout", metadata={"git_sha": "abc"}) as t:
    ...
client.flush(timeout=5.0)

Constructor options

arg default purpose
api_key $THETA_API_KEY project API key
project $THETA_PROJECT project id
base_url $THETA_BASE_URLtheta-observability-api-749071050118.asia-south1.run.app ingest API
flush_interval 0.5 seconds
max_batch 100 events per flush
timeout 10 HTTP timeout (seconds)
debug False log retries + 4xx responses

Full DX example — multimodal

from pathlib import Path
from theta_observability import TraceClient

client = TraceClient()

with client.trace(
    name="checkout-agent",
    run_type="eval",
    use_case="web-shopping",
    platform="web",
    tags=["demo", "multimodal"],
    metadata={"git_sha": "abc"},
) as t:

    # 1. LLM step with an image
    with t.step(name="plan", type="llm", model="claude-opus-4.6") as s:
        s.log_message(role="user", text="Buy milk", images=[Path("screen.png")])
        s.log_message(role="assistant", text="Clicking the Buy button.")
        s.set_token_usage(input=1820, output=412)

    # 2. Tool step
    with t.step(name="click", type="tool") as s:
        s.log_tool_call(
            name="browser.click",
            arguments={"selector": "#buy"},
            result={"ok": True},
            latency_ms=45,
        )

    # 3. Robotics step with a sensor frame
    with t.step(name="capture", type="robotics") as s:
        s.log_sensor_frame(modality="camera", source="rgb.mp4", fps=30.0)

    t.annotate(label="good", score=1.0, comment="demo")
    t.set_cost(0.0133)

Attachments accept str | pathlib.Path | bytes | io.BufferedReader | PIL.Image.Image. Each upload requests a signed URL from the ingest API and PUTs the blob directly to GCS; the returned gs:// uri is embedded in the trace JSON.

Decorator

@client.observe(name="plan", type="llm", model="gpt-4o")
def plan(goal: str) -> str:
    ...

@client.observe(type="tool")
async def fetch(url: str) -> str:
    ...

If no trace is active when the function is called, a trace is created just for that call. Otherwise the step joins the surrounding trace.

Framework integrations

from openai import OpenAI
from theta_observability import TraceClient
from theta_observability.integrations.openai import wrap_openai

obs = TraceClient()
oai = wrap_openai(OpenAI(), obs)

with obs.trace("qa"):
    oai.chat.completions.create(
        model="gpt-4o",
        messages=[{"role": "user", "content": "Hello"}],
    )

wrap_openai and wrap_anthropic patch chat.completions.create / messages.create (sync + async + streaming) to emit an llm step with model, messages, response text, and token usage.

Reliability notes

  • Fail-soft: all network errors are logged but never raised into user code.
  • Thread-safe: a single client can be shared across threads; traces use a ContextVar so nested steps work correctly in async code.
  • At-exit flush: an atexit handler flushes outstanding batches with a 2-second grace period. Call client.flush(timeout=...) before shutdown if you need a hard guarantee.
  • Retries: 5xx and 429 responses are retried with exponential backoff (up to 5 attempts). 4xx responses are dropped (and logged in debug=True).

Development

pip install -e ".[dev,openai,anthropic]"
pytest

Tests use httpx.MockTransport to stub the ingest API — no network required.

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

theta_obsrv-0.1.0.tar.gz (83.3 kB view details)

Uploaded Source

Built Distribution

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

theta_obsrv-0.1.0-py3-none-any.whl (31.4 kB view details)

Uploaded Python 3

File details

Details for the file theta_obsrv-0.1.0.tar.gz.

File metadata

  • Download URL: theta_obsrv-0.1.0.tar.gz
  • Upload date:
  • Size: 83.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for theta_obsrv-0.1.0.tar.gz
Algorithm Hash digest
SHA256 f0be97c42bce2bd1a1b9344b0de5e4c2b184b2a80f7a1d5e475e551fa70e4c52
MD5 ce721a825056bec8ac982c2b28f57ee4
BLAKE2b-256 119895d5eb541ea3c512787b3dc60c6726ab57fc66255960e98f366b707e797e

See more details on using hashes here.

Provenance

The following attestation bundles were made for theta_obsrv-0.1.0.tar.gz:

Publisher: publish-python-sdk.yml on theta-rl-lab/theta-observability

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

File details

Details for the file theta_obsrv-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: theta_obsrv-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 31.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for theta_obsrv-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 b3b7a67b7d934132083c5ac70527cc322a2262f539f5d910df04c17164628bad
MD5 8d8995b304fc175530a0f2b7bb1b57d9
BLAKE2b-256 cde0881c4042fab80ef3111ae92f67b6632a79799cef15c97ef6554353503f7f

See more details on using hashes here.

Provenance

The following attestation bundles were made for theta_obsrv-0.1.0-py3-none-any.whl:

Publisher: publish-python-sdk.yml on theta-rl-lab/theta-observability

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