Skip to main content

🛡️ LangChain Sandbox

A secure environment for running Python code using Pyodide (WebAssembly) and Deno

Python 3.10+ Deno License: 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:

    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_bytes contains 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 PyodideSandboxTool works only in LangGraph agents that use the prebuilt create_react_agent or ToolNode.

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: Contains PyodideSandbox which 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)

Source distribution for langchain_sandbox_zp 0.0.8
File Size Uploaded
langchain_sandbox_zp-0.0.8.tar.gz 80.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for langchain_sandbox_zp 0.0.8
File Interpreter ABI Platform
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

Release history Release notifications | RSS feed

This release

0.0.8 This release

2 release files

0.0.7

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