🛡️ LangChain Sandbox
A secure environment for running Python code using Pyodide (WebAssembly) and Deno
📋 Overview
LangChain Sandbox provides a secure environment for executing untrusted Python code. It leverages Pyodide (Python compiled to WebAssembly) to run Python code in a sandboxed environment.
✨ Key Features
- 🔒 Security - Isolated execution environment with configurable permissions
- 💻 Local Execution - No remote execution or Docker containers needed
- 🔄 Session Support - Maintain state across multiple code executions
Limitations
- Latency: There is a few seconds of latency when starting the sandbox per run
- File access: Currently not supported. You will not be able to access the files written by the sandbox.
- Network requests: If you need to make network requests please use
httpx.AsyncClientinstead ofrequests.
🚀 Quick Install
-
Install Deno (required): https://docs.deno.com/runtime/getting_started/installation/
-
Install
langchain-sandbox:pip install langchain-sandbox
💡 Example Usage
from langchain_sandbox import PyodideSandbox
# Create a sandbox instance
sandbox = PyodideSandbox(
# Allow Pyodide to install python packages that
# might be required.
allow_net=True,
)
code = """\
import numpy as np
x = np.array([1, 2, 3])
print(x)
"""
# Execute Python code
print(await sandbox.execute(code))
# CodeExecutionResult(
# result=None,
# stdout='[1 2 3]',
# stderr=None,
# status='success',
# execution_time=2.8578367233276367,
# session_metadata={'created': '2025-05-15T21:26:37.204Z', 'lastModified': '2025-05-15T21:26:37.831Z', 'packages': ['numpy']},
# session_bytes=None
# )
Stateful Sandbox
If you want to persist state between code executions (to persist variables, imports,
and definitions, etc.), you can set stateful=True in the sandbox. This will return
session_bytes and session_metadata that you can pass to .execute().
[!warning]
session_bytescontains pickled session state. It should not be unpickled and is only meant to be used by the sandbox itself
sandbox = PyodideSandbox(
# Create stateful sandbox
stateful=True,
# Allow Pyodide to install python packages that
# might be required.
allow_net=True,
)
code = """\
import numpy as np
x = np.array([1, 2, 3])
print(x)
"""
result = await sandbox.execute(code)
# Pass previous result
print(await sandbox.execute("float(x[0])", session_bytes=result.session_bytes, session_metadata=result.session_metadata))
# CodeExecutionResult(
# result=1,
# stdout=None,
# stderr=None,
# status='success',
# execution_time=2.7027177810668945
# session_metadata={'created': '2025-05-15T21:27:57.120Z', 'lastModified': '2025-05-15T21:28:00.061Z', 'packages': ['numpy', 'dill']},
# session_bytes=b'\x80\x04\x95d\x01\x00..."
# )
Using as a tool
You can use PyodideSandbox as a LangChain tool:
from langchain_sandbox import PyodideSandboxTool
tool = PyodideSandboxTool()
result = await tool.ainvoke("print('Hello, world!')")
Using with an agent
You can use sandbox tools inside a LangGraph agent:
from langgraph.prebuilt import create_react_agent
from langchain_sandbox import PyodideSandboxTool
tool = PyodideSandboxTool(
# Allow Pyodide to install python packages that
# might be required.
allow_net=True
)
agent = create_react_agent(
"anthropic:claude-3-7-sonnet-latest",
tools=[tool],
)
result = await agent.ainvoke(
{"messages": [{"role": "user", "content": "what's 5 + 7?"}]},
)
Stateful Tool
[!important] Stateful
PyodideSandboxToolworks only in LangGraph agents that use the prebuiltcreate_react_agentorToolNode.
If you want to persist state between code executions (to persist variables, imports,
and definitions, etc.), you need to set stateful=True:
from langgraph.prebuilt import create_react_agent
from langgraph.prebuilt.chat_agent_executor import AgentState
from langgraph.checkpoint.memory import InMemorySaver
from langchain_sandbox import PyodideSandboxTool, PyodideSandbox
class State(AgentState):
# important: add session_bytes & session_metadata keys to your graph state schema -
# these keys are required to store the session data between tool invocations.
# `session_bytes` contains pickled session state. It should not be unpickled
# and is only meant to be used by the sandbox itself
session_bytes: bytes
session_metadata: dict
tool = PyodideSandboxTool(
# Create stateful sandbox
stateful=True,
# Allow Pyodide to install python packages that
# might be required.
allow_net=True
)
agent = create_react_agent(
"anthropic:claude-3-7-sonnet-latest",
tools=[tool],
checkpointer=InMemorySaver(),
state_schema=State
)
result = await agent.ainvoke(
{
"messages": [
{"role": "user", "content": "what's 5 + 7? save result as 'a'"}
],
"session_bytes": None,
"session_metadata": None
},
config={"configurable": {"thread_id": "123"}},
)
second_result = await agent.ainvoke(
{"messages": [{"role": "user", "content": "what's the sine of 'a'?"}]},
config={"configurable": {"thread_id": "123"}},
)
See full examples here:
🧩 Components
The sandbox consists of two main components:
pyodide-sandbox-js: JavaScript/TypeScript module using Deno to provide the core sandboxing functionality.sandbox-py: ContainsPyodideSandboxwhich just wraps the JavaScript/TypeScript module and executes it as a subprocess.
Metadata
Release files for langchain_sandbox_zp 0.0.8
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| langchain_sandbox_zp-0.0.8.tar.gz | 80.0 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| langchain_sandbox_zp-0.0.8-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 90.0 kB
Release files / langchain_sandbox_zp-0.0.8.tar.gz
| Download URL | langchain_sandbox_zp-0.0.8.tar.gz |
|---|---|
| Size | 80.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
b8777647c05cb28da1971716599fdf68d18da6bc221115537eeb58b6d4132df9
|
|
BLAKE2b-256 checksum How to use checksums |
2a4a680d8a850ade336500dfd95db1368e5396e0bef17e44b36a7dbb65eac69b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.8.4
|
Release files / langchain_sandbox_zp-0.0.8-py3-none-any.whl
| Download URL | langchain_sandbox_zp-0.0.8-py3-none-any.whl |
|---|---|
| Size | 9.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
cfe940707b8c5c2212ba9b2bbcbead6f1d82344809a2cf3f2bae836c695d3d96
|
|
BLAKE2b-256 checksum How to use checksums |
1e63ede204a635748a844c6858f6bedaf7f2689d2aa9eda23f5497b529f1e117
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.8.4
|