Skip to content

Add File System Support via pyodide.FS #37

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 32 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
12009a0
feat(filesystem): add MEMFS filesystem support
fullzer4 May 26, 2025
d008190
Merge branch 'main' of github.com:fullzer4/langchain-sandbox into ful…
fullzer4 May 26, 2025
033c044
feat(sandbox): file attachment operations
fullzer4 May 26, 2025
c7d1896
fix: improve file system implementation and file handling
fullzer4 May 26, 2025
214ebf7
Merge pull request #1 from fullzer4/fullzer4/add_fyle_system
fullzer4 May 26, 2025
b5038cb
fix: conventions
fullzer4 May 26, 2025
3822ac9
Merge pull request #2 from fullzer4/fullzer4/add_fyle_system
fullzer4 May 26, 2025
bb115d3
fix: _build_command place convention
fullzer4 May 26, 2025
4262f83
Merge pull request #3 from fullzer4/fullzer4/add_fyle_system
fullzer4 May 26, 2025
f4584dc
fix: better filesystem operations and file handling
fullzer4 May 27, 2025
5b7b91d
feat: implement dynamic filesystem support with flexible tool archite…
fullzer4 May 28, 2025
bb23978
fix: follow python conventions
fullzer4 May 28, 2025
867b674
fix: typescript conventions
fullzer4 May 28, 2025
0bac09a
fix: rollback some tests
fullzer4 May 28, 2025
2511119
fix: permissions
fullzer4 May 28, 2025
6e9c104
feat: README changes
fullzer4 May 28, 2025
13f3057
fix: unified PyodideSandboxTool with complete backward compatibility
fullzer4 May 28, 2025
0d27435
fix: clean README
fullzer4 May 28, 2025
672eeb1
fix: lint
fullzer4 May 28, 2025
fd0285c
fix: Remove PyodideSandboxStructuredTool and fix unintentional README…
fullzer4 May 29, 2025
f03e6a0
fix: return file output limitation | remove local test functions
fullzer4 May 29, 2025
95e0f96
fixes
fullzer4 May 31, 2025
3d7317c
fixes
fullzer4 May 31, 2025
a042fd2
fix: improve filesystem operations and dynamic tool descriptions
fullzer4 Jun 1, 2025
ee4c4a2
Merge pull request #4 from fullzer4/fix/conventions-and-patterns
fullzer4 Jun 1, 2025
5cd6849
fix(pyodide): unrestrict file system access to ensure Pyodide can loa…
fullzer4 Jun 1, 2025
7665c23
fix: configure Deno permissions for reliable Pyodide execution
fullzer4 Jun 2, 2025
86f36c2
fix: restore uv.lock
fullzer4 Jun 2, 2025
db086a2
fix: restore uv.lock
fullzer4 Jun 2, 2025
d4267f7
fix: ensure custom descriptions are preserved in PyodideSandboxTool
fullzer4 Jun 2, 2025
37362fd
refactor: remove unnecessary filesystem operations (exists, remove, c…
fullzer4 Jun 5, 2025
5652d5c
revert: restore previous permission model and add allow_read to tests
fullzer4 Jun 5, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 45 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ LangChain Sandbox provides a secure environment for executing untrusted Python c
## 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
Expand All @@ -35,9 +34,6 @@ LangChain Sandbox provides a secure environment for executing untrusted Python c
## 💡 Example Usage


> [!warning]
> Use `alllow_net` to limit the network requests that can be made by the sandboxed code to avoid SSRF attacks
> https://docs.deno.com/runtime/fundamentals/security/#network-access

```python
from langchain_sandbox import PyodideSandbox
Expand Down Expand Up @@ -141,6 +137,49 @@ result = await agent.ainvoke(
)
```

### File System Support

You can now attach files to the sandbox environment and perform data analysis:

```python
import asyncio

from langchain_sandbox import PyodideSandboxTool
from langgraph.prebuilt import create_react_agent

# Define the sandbox tool with filesystem support
sandbox_tool = PyodideSandboxTool(
enable_filesystem=True,
allow_net=True,
)

sales_data = """...csv_data"""

sandbox_tool.attach_file("sales.csv", sales_data)

# Create an agent with the sandbox tool
agent = create_react_agent(
"anthropic:claude-3-7-sonnet-latest", [sandbox_tool]
)

query = """Please analyze the sales data and tell me:
1. What is the total revenue by category?
2. Which region has the highest sales?
3. What are the top 3 best-selling products by revenue?

Use pandas to read the CSV file and perform the analysis."""

async def run_agent(query: str):
# Stream agent outputs
async for chunk in agent.astream({"messages": query}):
print(chunk)
print("\n")

if __name__ == "__main__":
# Run the agent
asyncio.run(run_agent(query))
```

#### Stateful Tool

> [!important]
Expand Down Expand Up @@ -192,16 +231,15 @@ second_result = await agent.ainvoke(
)
```



See full examples here:

* [ReAct agent](examples/react_agent.py)
* [CodeAct agent](examples/codeact_agent.py)
* [ReAct agent with csv](examples/react_agent_with_csv.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.
- **`sandbox-py`**: Contains `PyodideSandbox` which just wraps the JavaScript/TypeScript module and executes it as a subprocess.
48 changes: 48 additions & 0 deletions examples/react_agent_with_csv.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# pip install langgraph-codeact "langchain[anthropic]"
import asyncio

from langchain_sandbox import PyodideSandboxTool
from langgraph.prebuilt import create_react_agent


# Define the sandbox tool with filesystem support
sandbox_tool = PyodideSandboxTool(
enable_filesystem=True,
allow_net=True,
)

sales_data = """date,product,category,quantity,price,region
2024-01-15,Laptop,Electronics,2,1299.99,North
2024-01-16,Chair,Furniture,1,249.50,South
2024-01-16,T-shirt,Clothing,5,29.99,East
2024-01-17,Laptop,Electronics,1,1299.99,West
2024-01-18,Phone,Electronics,3,799.99,North
2024-01-19,Desk,Furniture,2,399.99,South
2024-01-20,Jeans,Clothing,4,79.99,East
2024-01-21,Tablet,Electronics,2,499.99,West
2024-01-22,Sofa,Furniture,1,899.99,North
2024-01-23,Shoes,Clothing,3,129.99,South"""

sandbox_tool.attach_file("sales.csv", sales_data)

# Create an agent with the sandbox tool
agent = create_react_agent(
"anthropic:claude-3-7-sonnet-latest", [sandbox_tool]
)

query = """Please analyze the sales data and tell me:
1. What is the total revenue by category?
2. Which region has the highest sales?
3. What are the top 3 best-selling products by revenue?

Use pandas to read the CSV file and perform the analysis."""

async def run_agent(query: str):
# Stream agent outputs
async for chunk in agent.astream({"messages": query}):
print(chunk)
print("\n")

if __name__ == "__main__":
# Run the agent
asyncio.run(run_agent(query))
Loading
Loading