LangSmith Sandbox Module.
This module provides sandboxed code execution capabilities through the LangSmith Sandbox API.
Example:
from langsmith.sandbox import SandboxClient
client = SandboxClient()
snapshot = client.create_snapshot( docker_image="python:3.12-slim", name="python-snapshot" ) with client.sandbox(snapshot_id=snapshot.id) as sb: result = sb.run("python --version") print(result.stdout)
from langsmith.sandbox import AsyncSandboxClient
async with AsyncSandboxClient() as client: snapshot = await client.create_snapshot( docker_image="python:3.12-slim", name="python-snapshot" ) async with await client.sandbox(snapshot_id=snapshot.id) as sb: result = await sb.run("python --version") print(result.stdout)
Async client for interacting with the Sandbox Server API.
This client provides an async interface for managing sandboxes and snapshots.
Represents an active sandbox for running commands and file operations async.
This class is typically obtained from AsyncSandboxClient.sandbox() and supports the async context manager protocol for automatic cleanup.
Client for interacting with the Sandbox Server API.
This client provides a simple interface for managing sandboxes and snapshots.
Raised when a command exceeds its timeout.
Raised when dataplane_url is not available for the sandbox.
This occurs when the sandbox-router URL is not configured for the cluster.
Raised when organization quota limits are exceeded.
Users should contact support@langchain.dev to increase quotas.
Raised when creating a resource that already exists.
Raised when resource provisioning fails.
Raised when deleting a resource that is still in use.
Raised when updating a resource name to one that already exists.
Raised when a resource is not found.
Raised when an operation times out.
Raised when the API endpoint returns an unexpected error.
For example, this is raised for wrong URL or path.
Raised when authentication fails (invalid or missing API key).
Base exception for sandbox client errors.
Raised when connection to the sandbox server fails.
Raised when attempting to interact with a sandbox that is not ready.
Raised when a sandbox operation fails (run, read, write).
Raised when the server sends a 1001 Going Away close frame.
This indicates a server hot-reload, not a true connection failure. The command is still running on the server.
This is a subclass of SandboxConnectionError, so the auto-reconnect logic in CommandHandle catches it along with all other connection errors. The distinction matters for retry strategy: SandboxServerReloadError triggers immediate reconnect (no backoff), while other SandboxConnectionError triggers exponential backoff.
Users typically never see this exception — it's handled internally.
Nothing is listening on the target port inside the sandbox.
Base exception for TCP tunnel errors.
The daemon rejected the port as not allowed.
Protocol version mismatch between the tunnel client and the daemon.
Raised when request validation fails.
This includes:
Async handle to a running command with streaming output and auto-reconnect.
Async iterable, yielding OutputChunk objects (stdout and stderr interleaved in arrival order). Access .result after iteration to get the full ExecutionResult.
Auto-reconnect behavior:
Construction modes (controlled by command_id):
command_id="", the default): call
await handle._ensure_started() after construction to read the
server's "started" message and populate command_id / pid.command_id set): skips the started-message
read, since reconnect streams don't emit one.Async variant of :class:ServiceURL with auto-refreshing token.
Properties and HTTP helpers are async. Use with
:meth:AsyncSandboxClient.service or :meth:AsyncSandbox.service.
Example::
svc = await sb.service(port=3000)
resp = await svc.get("/api/data")
print(await svc.get_browser_url())
Handle to a running command with streaming output and auto-reconnect.
Iterable, yielding OutputChunk objects (stdout and stderr interleaved in arrival order). Access .result after iteration to get the full ExecutionResult.
Auto-reconnect behavior:
The auto-reconnect is transparent -- the iterator reconnects and continues yielding chunks without any user intervention. If all reconnect attempts are exhausted, SandboxConnectionError is raised.
Construction modes (controlled by command_id):
command_id="", the default): the constructor
eagerly reads the server's "started" message to populate
command_id and pid before returning.command_id set): skips the started-message
read, since reconnect streams don't emit one.Result of executing a command in a sandbox.
A single chunk of streaming output from command execution.
Lightweight provisioning status for any async-created resource.
Authenticated URL for accessing an HTTP service running in a sandbox.
Properties auto-refresh the token transparently when it nears expiry.
HTTP helper methods (.get, .post, etc.) inject the auth header
automatically.
When constructed by :meth:SandboxClient.service or
:meth:Sandbox.service, the object holds an internal refresher that
re-calls the API to obtain a fresh token before the current one expires.
Example::
svc = sb.service(port=3000)
resp = svc.get("/api/data") # token injected + auto-refreshed
print(svc.browser_url) # always-fresh URL
Represents a sandbox snapshot.
Snapshots are built from Docker images or captured from running sandboxes. They are used to create new sandboxes.
Represents an active sandbox for running commands and file operations.
This class is typically obtained from SandboxClient.sandbox() and supports the context manager protocol for automatic cleanup.
Async wrapper around :class:Tunnel.
The underlying tunnel runs in background threads (TCP listener + bridges); async context-manager methods delegate to the sync tunnel via the event loop's executor.
Usage::
async with await sandbox.tunnel(remote_port=5432) as t:
conn = await asyncpg.connect(host="127.0.0.1", port=t.local_port)
TCP tunnel to a port inside a sandbox.
Opens a local TCP listener and forwards each accepted connection through a yamux-multiplexed WebSocket to the daemon, which dials the target port inside the sandbox.
Typically used as a context manager::
with sandbox.tunnel(remote_port=5432) as t:
conn = psycopg2.connect(host="127.0.0.1", port=t.local_port)
Or with explicit lifecycle::
t = sandbox.tunnel(remote_port=5432)
# ... use tunnel ...
t.close()