Python SDK

trefur-observe — observability and safety telemetry for AI agents, with auto-instrumentation for Anthropic, OpenAI, LangChain, CrewAI, and friends.

Install

pip install trefur-observe

Optional extras pre-install the upstream SDKs:

pip install "trefur-observe[anthropic]"
pip install "trefur-observe[openai]"
pip install "trefur-observe[langchain]"
pip install "trefur-observe[crewai]"
pip install "trefur-observe[all]"

Init

import os
from anthropic import Anthropic
from trefur_observe import TrefurObserve, patch_anthropic

TrefurObserve.init(
    api_key=os.environ["TREFUR_API_KEY"],
    agent={"name": os.environ.get("TREFUR_AGENT_NAME", "my-agent")},
)

client = Anthropic()
patch_anthropic(TrefurObserve.get_instance())

Flushing on exit

Telemetry is buffered and shipped by a background flush every 5s. TrefurObserve.init() registers an atexit hook that flushes on a normal interpreter exit (including after an unhandled exception), so a short script's first trace still lands. For scripts that may raise or call a hard os._exit(), wrap your run in try/finally and call shutdown() to flush explicitly:

observe = TrefurObserve.init(api_key=os.environ["TREFUR_API_KEY"])

try:
    # ... your agent code ...
    client.messages.create(...)
finally:
    observe.shutdown()  # flush buffered telemetry (also runs on exception)

Configuration options

OptionTypeDefaultNotes
api_keystrrequiredtrf_obs_*
endpointstrhttps://observe.trefur.comIngest endpoint override
debugboolFalseVerbose logging
batch_sizeint10Buffer size before auto-flush
flush_intervalfloat5.0Periodic flush interval, in seconds
auto_instrumentboolTrueAuto-patch known SDKs
sqlboolFalseOpt-in auto-patch of psycopg2 / asyncpg / SQLAlchemy
capture_subprocessboolTruePatch subprocess for CLI captures
subprocess_filterlist[str]allLimit to specific binary names
agentdictdetectedExplicit agent identity

Framework adapters

from trefur_observe import (
    patch_anthropic,
    patch_openai,
    patch_gemini,
    patch_langchain,
    patch_crewai,
    patch_claude_agent_sdk,
    patch_playwright_sdk,
    patch_selenium,
)

Generic in-process instrumentors

from trefur_observe import TrefurObserve, observe

TrefurObserve.init(api_key=os.environ["TREFUR_API_KEY"])

# Patch HTTP libs, subprocess, and pathlib I/O in one call.
observe(http=True, fs=True, exec=True)
AxisModules patchedstep_type
httprequests, aiohttp, urllib.requesthttp_call
execsubprocess.{run, Popen, check_output, check_call}, os.system, asyncio.create_subprocess_*exec_subprocess / cli_exec
fspathlib.Path.{read,write}_{text,bytes} and unlinkfile_read / file_write / file_delete

Environment variables

Canonical list: env-vars reference.

Troubleshooting

SymptomFix
patch_anthropic appears to do nothing.Make sure TrefurObserve.init(...) ran first. Set debug=True to surface failures.
async code: spans don't nest.Use parent_run_scope(...) from trefur_observe.context to propagate the parent run id across asyncio task boundaries.
I want to mute the SDK in tests.Set TREFUR_DISABLED=true in the environment. Short-circuits every emit.

Source + tests live in trefur-ai/trefur-sdks under python/observe-python. License: Apache 2.0.