Skip to main content
Last updated on

LangGraph SDK (Python)

The OpenBox LangGraph SDK connects your compiled LangGraph graph to OpenBox. It handles event capture, telemetry collection, and trust evaluation with a single function call — no graph changes required.

GuideDescription
ConfigurationEnvironment variables and handler parameters
Error HandlingHandle governance decisions and failures in your code
Integration WalkthroughEnd-to-end guide for wiring a governed LangGraph handler into a service
Event ModelUnderstand graph runs, signals, activities, and payload shapes
Approvals and GuardrailsHow verdicts, approvals, and guardrails are enforced at runtime
TelemetryHTTP, database, traced-function, and optional file capture behavior
TroubleshootingDiagnose startup, policy, approvals, telemetry, and UI interpretation issues
What the SDK Does

The SDK's primary job is to connect your LangGraph graph to OpenBox and send LangGraph events to the platform. All trust logic, policies, and UI management happens on the platform — not in the SDK.

Philosophy

The SDK is intentionally minimal:

  • One function call to wrap your compiled graph (create_openbox_graph_handler)
  • Zero graph changes — keep writing LangGraph as normal; only the invocation changes
  • Automatic telemetry — captures LangGraph v2 events, HTTP, database, and custom traced-function operations
  • 3-layer governance — event stream, hook interception, and OpenTelemetry spans work together

Installation

Package: openbox-langgraph-sdk-python Requires: Python 3.11+

uv add openbox-langgraph-sdk-python

# Or with pip
pip install openbox-langgraph-sdk-python

Function Signature

def create_openbox_graph_handler(
graph: CompiledGraph,
*,
api_url: str,
api_key: str,
agent_did: str | None = None,
agent_private_key: str | None = None,
agent_name: str | None = None,
# + governance, instrumentation, and handler options
) -> OpenBoxLangGraphHandler

Returns an OpenBoxLangGraphHandler that wraps your compiled graph with OpenBox interceptors, telemetry, and governance configured. The handler exposes the same ainvoke, invoke, and astream interface as the underlying graph.

Newly created OpenBox agents require DID signing by default. Configure agent_did and agent_private_key together unless Require signing is disabled for the registered agent, and store the private key as a per-agent secret.

See Configuration for the full parameter list.

What the SDK Captures

The SDK automatically captures and sends to OpenBox:

LangGraph Events

  • Tool start / tool end (with inputs and outputs)
  • Chat model start / chat model end (with prompts and responses)
  • Node execution events (started, completed)
  • Agent action and observation events

HTTP Telemetry

  • Request/response bodies (for LLM calls, external requests)
  • Headers and status codes
  • Request duration and timing

Database Operations (Optional)

  • SQL queries (PostgreSQL, MySQL, SQLite via SQLAlchemy)
  • NoSQL operations (MongoDB, Redis)

File I/O (Optional Lower-Level Setup)

  • File read/write operations
  • File paths and sizes

All captured data is evaluated against your trust policies on the OpenBox platform.

3-Layer Governance

The SDK enforces governance at three layers simultaneously:

LayerMechanismWhat It Covers
Layer 1: Event StreamLangGraph v2 callback eventsTool calls, LLM invocations, node transitions
Layer 2: Hook GovernanceMonkey-patched HTTP/DB hooks and optional file hooksExternal API calls, database queries, optional file operations
Layer 3: Activity ContextOpenTelemetry spansFull distributed trace of every operation

Tracing

The @traced decorator wraps any function in an OpenTelemetry span so it appears in session replay. It works on both sync and async functions.

Import

from openbox_langgraph.tracing import traced

Basic Usage

@traced
def process_data(input_data):
return transform(input_data)

@traced
async def fetch_data(url):
return await http_get(url)

With Options

@traced(
name="custom-span-name",
capture_args=True, # Capture function arguments (default: True)
capture_result=True, # Capture return value (default: True)
capture_exception=True, # Capture exception details on error (default: True)
max_arg_length=2000, # Max length for serialized arguments (default: 2000)
)
async def process_sensitive_data(data):
return await handle(data)

Streaming

The handler exposes astream_governed() for token-by-token streaming with governance applied at each step:

governed = create_openbox_graph_handler(
graph=app,
api_url=os.getenv("OPENBOX_URL"),
api_key=os.getenv("OPENBOX_API_KEY"),
agent_did=os.getenv("OPENBOX_AGENT_DID"),
agent_private_key=os.getenv("OPENBOX_AGENT_PRIVATE_KEY"),
agent_name="MyAgent",
)

async for chunk in governed.astream_governed(
{"messages": [("user", "Hello")]},
stream_mode="values",
):
print(chunk)

Governance events fire between chunks — a BLOCK verdict raises GovernanceBlockedError mid-stream. See Error Handling for handling patterns.

Next Steps

  1. Configuration — Configure timeouts, fail policies, and exclusions
  2. Integration Walkthrough — Wire OpenBox into a real LangGraph service
  3. Error Handling — Handle governance decisions in your code