Overview
The sandbox module provides secure code execution through isolated Docker containers with gVisor sandboxing. Agents can execute Python code and shell commands while maintaining session state across multiple executions.
Quick Start
import ray
from rayai.sandbox import execute_code, execute_shell
# Initialize Ray
ray.init()
# Execute Python code
result = ray.get(execute_code.remote("print('Hello, World!')"))
print(result["stdout"]) # Hello, World!
# Execute shell commands
result = ray.get(execute_shell.remote("ls -la"))
print(result["stdout"])
Session Persistence
Variables persist across executions within the same session:
# Create a variable
ray.get(execute_code.remote("x = 42", session_id="my-session"))
# Use it later
result = ray.get(execute_code.remote("print(x * 2)", session_id="my-session"))
print(result["stdout"]) # 84
# Shell and code share the same container
ray.get(execute_shell.remote("echo 'data' > /tmp/file.txt", session_id="my-session"))
result = ray.get(execute_code.remote(
"print(open('/tmp/file.txt').read())",
session_id="my-session"
))
Custom Environments
Use custom Docker images or Dockerfiles:
# Using a pre-built image
result = ray.get(execute_code.remote(
"import pandas; print(pandas.__version__)",
image="python:3.12-slim",
session_id="pandas-session"
))
# Using a custom Dockerfile
dockerfile = """
FROM python:3.12-slim
RUN pip install pandas numpy scikit-learn
"""
result = ray.get(execute_code.remote(
"import sklearn; print(sklearn.__version__)",
dockerfile=dockerfile,
session_id="ml-session"
))
Volume Mounts
Mount host directories into the container:
# Mount a dataset directory (read-only)
volumes = {
"/path/to/data": {"bind": "/mnt/data", "mode": "ro"}
}
result = ray.get(execute_code.remote(
"import os; print(os.listdir('/mnt/data'))",
session_id="data-session",
volumes=volumes
))
File Upload
Upload files directly to a session container:
from rayai.sandbox import upload_file
# First create the session
ray.get(execute_code.remote("x = 1", session_id="upload-session"))
# Upload a CSV file
data = b"name,value\nAlice,100\nBob,200"
ray.get(upload_file.remote("/tmp/data.csv", data, session_id="upload-session"))
# Read the uploaded file
result = ray.get(execute_code.remote(
"import pandas as pd; print(pd.read_csv('/tmp/data.csv'))",
session_id="upload-session"
))
Session Management
from rayai.sandbox import get_session_stats, cleanup_session
# Get session statistics
stats = ray.get(get_session_stats.remote("my-session"))
print(f"Executions: {stats['execution_count']}")
print(f"Uptime: {stats['uptime']:.1f}s")
print(f"Container: {stats['container_status']}")
# Cleanup when done
result = ray.get(cleanup_session.remote("my-session"))
print(result["status"]) # success
API Reference
execute_code
Execute Python code in an isolated container.
| Parameter | Type | Default | Description |
|---|
code | str | required | Python code to execute |
session_id | str | None | None | Session ID (auto-generated if not provided) |
image | str | python:3.12-slim | Docker image |
dockerfile | str | None | None | Custom Dockerfile (overrides image) |
environment | dict[str, str] | None | None | Environment variables |
volumes | dict | None | Volume mounts |
mcp_allowlist | list[str] | None | None | Allowed MCP server URLs |
timeout | int | 30 | Timeout in seconds |
execute_shell
Execute shell commands in an isolated container.
| Parameter | Type | Default | Description |
|---|
command | str | required | Shell command to execute |
session_id | str | None | None | Session ID (auto-generated if not provided) |
image | str | python:3.12-slim | Docker image |
dockerfile | str | None | None | Custom Dockerfile (overrides image) |
environment | dict[str, str] | None | None | Environment variables |
volumes | dict | None | Volume mounts |
mcp_allowlist | list[str] | None | None | Allowed MCP server URLs |
timeout | int | 30 | Timeout in seconds |
upload_file
Upload a file to a session container.
| Parameter | Type | Description |
|---|
path | str | Destination path in container |
content | bytes | File content |
session_id | str | Session ID (must exist) |
get_session_stats
Get statistics for a session.
| Parameter | Type | Description |
|---|
session_id | str | Session ID |
cleanup_session
Cleanup session and remove container.
| Parameter | Type | Description |
|---|
session_id | str | Session ID |
Return Types
ExecutionResult
| Field | Type | Description |
|---|
status | "success" | "error" | Execution status |
stdout | str | Standard output |
stderr | str | Standard error |
exit_code | int | Exit code (0 = success) |
execution_id | str | Unique execution ID |
SessionStats
| Field | Type | Description |
|---|
session_id | str | Session identifier |
execution_count | int | Number of executions |
created_at | float | Creation timestamp |
uptime | float | Uptime in seconds |
container_status | str | Docker container status |
Security
Network access is disabled by default. Containers cannot make HTTP requests, run pip install, or access external services.
The sandbox uses multiple security layers:
- gVisor sandboxing: Kernel-level isolation via
runsc runtime
- Network isolation:
network_mode=none by default
- Resource limits: 512MB memory, 1 CPU, 30s timeout
- No persistent storage: Containers are ephemeral
MCP Allowlist
For controlled external access, use the MCP allowlist:
# Allow access to specific MCP servers
result = ray.get(execute_code.remote(
code="# Code can access allowed MCP servers",
session_id="mcp-session",
mcp_allowlist=["http://localhost:8265/mcp"]
))
Installation
The sandbox requires Docker and the optional sandbox dependencies:
# Install dependencies
pip install rayai[sandbox]
# Ensure Docker is running
docker info
# (Optional) Install gVisor for enhanced security
# See: https://gvisor.dev/docs/user_guide/install/
If gVisor is not available, the sandbox falls back to standard Docker (runc) unless STRICT_GVISOR=True is set in the config.