https://github.com/langchain-ai/langchain-sandbox
https://github.com/langchain-ai/langchain-sandbox
Last synced: about 1 year ago
JSON representation
- Host: GitHub
- URL: https://github.com/langchain-ai/langchain-sandbox
- Owner: langchain-ai
- Created: 2025-04-15T15:21:02.000Z (about 1 year ago)
- Default Branch: main
- Last Pushed: 2025-04-25T19:26:01.000Z (about 1 year ago)
- Last Synced: 2025-05-04T09:17:56.985Z (about 1 year ago)
- Language: Python
- Size: 197 KB
- Stars: 10
- Watchers: 5
- Forks: 0
- Open Issues: 3
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
- awesome-agent-runtime-security - langchain-sandbox - based library sandboxing for isolating untrusted components within a process; [wassette](https://microsoft.github.io/wassette/latest/concepts.html) applies WASM at fine-grained component boundaries. [V8 Isolates](https://blog.cloudflare.com/safe-in-the-sandbox-security-hardening-for-cloudflare-workers/) offer a lightweight per-request isolation model as an alternative to containers or VMs — see also Cloudflare's [Dynamic Worker Loader](https://blog.cloudflare.com/dynamic-workers/) for on-demand per-agent V8 sandboxes with capability-scoped env bindings and optional network blocking. [Deno Deploy Sandbox](https://deno.com/deploy/sandbox) is a managed sandbox API that gives each execution a dedicated Firecracker microVM. (Sandboxing & Isolation)
README
# 🛡️ LangChain Sandbox
> A secure environment for running Python code using Pyodide (WebAssembly) and Deno
[](https://www.python.org/downloads/)
[](https://deno.land/)
[](https://opensource.org/licenses/MIT)
## 📋 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.AsyncClient` instead of `requests`.
## 🚀 Quick Install
1. Install Deno (required): https://docs.deno.com/runtime/getting_started/installation/
2. Install `langchain-sandbox`:
```bash
pip install langchain-sandbox
```
## 💡 Example Usage
```python
from langchain_sandbox import PyodideSandbox
# Create a sandbox instance
sandbox = PyodideSandbox(
"./sessions", # Directory to store session files
# 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, session_id="123"))
# CodeExecutionResult(
# result=None,
# stdout='[1 2 3]',
# stderr=None,
# status='success',
# execution_time=2.8578367233276367
# )
# Can still access a previous result!
print(await sandbox.execute("float(x[0])", session_id="123"))
# CodeExecutionResult(
# result=1,
# stdout=None,
# stderr=None,
# status='success',
# execution_time=2.7027177810668945
# )
```
### Using as a tool
You can use `PyodideSandbox` as a LangChain tool:
```python
from langchain_sandbox import PyodideSandboxTool
tool = PyodideSandboxTool()
result = await tool.ainvoke("print('Hello, world!')")
```
If you want to persist state between code executions (to persist variables, imports,
and definitions, etc.), you need to invoke the tool with `thread_id` in the config:
```python
code = """\
import numpy as np
x = np.array([1, 2, 3])
print(x)
"""
result = await tool.ainvoke(
code,
config={"configurable": {"thread_id": "123"}},
)
second_result = await tool.ainvoke(
"print(float(x[0]))", # tool is aware of the previous result
config={"configurable": {"thread_id": "123"}},
)
```
### Using with an agent
You can use `PyodideSandboxTool` inside a LangGraph agent. If you are using this tool inside an agent, you can invoke the agent with a config, and it will automatically be passed to the tool:
```python
from langgraph.prebuilt import create_react_agent
from langgraph.checkpoint.memory import InMemorySaver
from langchain_sandbox import PyodideSandboxTool
tool = PyodideSandboxTool()
agent = create_react_agent(
"anthropic:claude-3-7-sonnet-latest",
tools=[tool],
checkpointer=InMemorySaver()
)
result = await agent.ainvoke(
{"messages": [{"role": "user", "content": "what's 5 + 7?"}]},
config={"configurable": {"thread_id": "123"}},
)
second_result = await agent.ainvoke(
{"messages": [{"role": "user", "content": "what's the sine of that?"}]},
config={"configurable": {"thread_id": "123"}},
)
```
See full examples here:
* [ReAct agent](examples/react_agent.py)
* [CodeAct agent](examples/codeact_agent.py)
## 🧩 Components
The sandbox consists of two main components:
- **`pyodide-sandbox-js`**: JavaScript/TypeScript module using Deno to provide the core sandboxing functionality.
- **`sandbox-py`**: Contains `PyodideSandbox` which just wraps the JavaScript/TypeScript module and executes it as a subprocess.