Skip to main content

Bench Python SDK · Beta

Beta, version 0.1.0. Pin versions and test upgrades in staging.

Trace Python applications, agents and tools without changing their behavior. Python 3.10+. No third-party runtime dependencies. Apache-2.0.

Install with python -m pip install trybench-sdk. The Python import is bench_sdk.

import os
from bench_sdk import Bench

bench = Bench(
    api_key=os.environ["BENCH_API_KEY"],
    repository="your-team/your-app",
    branch="main",
    environment="staging",
    system_name="Support agent",
    endpoint=os.environ.get("BENCH_API_BASE_URL", "https://api.trybench.ai"),
)

try:
    with bench.trace("support-request", kind="AGENT") as span:
        # Call your existing application here.
        result = handle_request()
        span.set_output(result)
finally:
    # Deliver success and failure events after this application's work finishes.
    bench.shutdown()

Use the same with bench.trace(...) around await agent.ainvoke(...) in an async application, then await bench.aflush(). Context is preserved across await points and inherited by nested tasks. Wrap tools in nested spans with kind="TOOL". Separate requests started outside a parent get separate trace IDs.

Works with explicit wrappers around Deep Agents, LangGraph, LangChain, model clients and custom Python code. It does not automatically instrument framework internals or consume a streaming result; keep the span open while reading the stream.

Inputs, outputs and custom attributes are omitted by default. With permission, set capture_content=True, pass input=... and call span.set_output(...). Built-in matching removes common secrets, emails, supported phone numbers, IPv4 addresses, card patterns and sensitive structured fields before transmission. Add a redact(value) callback for application-specific data. These rules do not recognize every personal detail in free text.

Set component_id to a real prompt component from Bench to link the event to its criteria. Use operational attributes such as gen_ai.usage.input_tokens and gen_ai.usage.output_tokens for usage counts. Never invent component IDs.

The queue defaults to 200 spans. Flush explicitly at request or process lifecycle boundaries. Transient delivery failures retry once with unchanged IDs, then drop the batch. bench.stats reports queued and dropped spans. on_error(message) receives a fixed message, without content or keys. A telemetry failure does not replace an application exception. This is a bounded queue, not durable storage.

Test your application

await bench.evaluate_system(...) calls your application's request handler with pinned cases. It captures the real nested tool/model traces, compares the final output and independently observed state, and returns a redacted report locally. Use a test database and test service credentials.

report = await bench.evaluate_system(
    source_revision=os.environ["GIT_COMMIT_SHA"],  # Full 40-character commit SHA
    context_revision="refund-policy-v1",
    cases=[{
        "id": "outside-refund-policy", "split": "regression",
        "input": {"days": 45}, "expected_output": {"refunded": False},
        "forbidden_tools": ["issue-refund"],
    }],
    run=lambda request, context: handle_request(request),
)
assert report["summary"]["status"] == "completed"
assert all(case["status"] == "passed" for case in report["cases"])
# Explicit upload, only when you want this report saved in Bench:
await bench.publish_system_evaluation(int(os.environ["BENCH_SYSTEM_ID"]), report)

run(input, context) and observe(context) may be synchronous or asynchronous. When a case has expected_state, supply observe to read the authoritative test state. Context provides case_id, cancelled, signal, deadline and raise_if_cancelled(). Inputs are JSON snapshots; changes inside the application do not change the case's assertions.

await bench.simulate_system(...) accepts the same revisions and cases, plus create_session(initial_state, context). Cases use input={"initial_state": {...}, "turns": [...]} and require expected_state. Return an object with turn(message, context), observe() and close() methods. A fresh session receives 1 to 20 scripted customer turns. Bench snapshots observed state before closing the session. context.turn_index identifies the turn.

Both helpers use a 30-second timeout per case, configurable with timeout up to 300 seconds. Pass a threading.Event as cancel_event to stop the suite. Missing assertions, missing state, unfinished traces and timeouts remain incomplete. Callbacks must honor cancellation; Python cannot forcibly stop a synchronous thread. Await all child work and isolate external side effects. These helpers are local execution, not a process sandbox or a hosted verification claim.

Tests record redacted content even when production capture is metadata-only, so use synthetic inputs. Reports are not uploaded and paid checks are not started unless you take a separate explicit action. Automatic framework adapters are coming soon.

Run checks from this directory:

PYTHONPATH=src python -m unittest discover -s tests -v
python -m build
python -m twine check dist/*

See Bench documentation and the repository's publishing guide.

Latency, tool calls and cost

Every recorded call carries start/end timestamps, status, parent span ID and an automatically measured bench.duration_ms from a monotonic clock. Wrap each tool execution, including retries, with a TOOL span to retain its individual timing. Use gen_ai.operation.name=execute_tool and gen_ai.tool.name for tool identity. Production sampling can omit traces; a rate of 1 records each instrumented call. The bounded delivery queue is not a guarantee against network or process loss.

Add gen_ai.provider.name, gen_ai.request.model, gen_ai.response.model, gen_ai.usage.input_tokens and gen_ai.usage.output_tokens when your provider returns them. Add bench.cost.usd for the cost of that individual call and bench.cost.source as reported or estimated. For estimates, also include bench.cost.pricing_version. These fields survive metadata-only capture, so you can measure usage without recording prompts or responses. Missing cost is unknown, not zero. Do not repeat a child cost on its parent or count overlapping token categories twice. The SDK does not guess provider prices or a tool's own charges.

The gen_ai.* names follow selected OpenTelemetry conventions. bench.cost.* and bench.duration_ms are Bench extensions. Events currently use Bench JSON over HTTPS; this release is not an OTLP exporter or collector.

Release files for trybench-sdk 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for trybench-sdk 0.1.0
File Size Uploaded
trybench_sdk-0.1.0.tar.gz 25.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for trybench-sdk 0.1.0
File Interpreter ABI Platform
trybench_sdk-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 44.4 kB

Release files / trybench_sdk-0.1.0.tar.gz

Download URL trybench_sdk-0.1.0.tar.gz
Size 25.8 kB
Tags Source
SHA-256 checksum
How to use checksums
b77c6c941bf1f21281857484ce2c8962ccabed67554f1c162f4d96ba23fd4a9c
BLAKE2b-256 checksum
How to use checksums
c3e1261ce005972bbd429c46590fbe7310e768ab27cedc770999e9b74c5419d1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.11.3

Release files / trybench_sdk-0.1.0-py3-none-any.whl

Download URL trybench_sdk-0.1.0-py3-none-any.whl
Size 18.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
0e9cddf8453e1df0af0a21ba55d5477352cd652defae8023c1c5664df96d4ce4
BLAKE2b-256 checksum
How to use checksums
fedeef794c24b27c42e26636127a44af5051ea39f34674fadeb236796e1af6ab
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.11.3

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page