llm-python-sandbox 0.1.0
Secure Python code execution sandbox for LLM-generated code
Requires Python: >=3.9
Keywords: sandbox, security, code-execution, llm, ai

# LLM Python Sandbox

[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![Python 3.9+](https://img.shields.io/badge/python-3.9+-blue.svg)](https://www.python.org/downloads/)
[![Code Style: Black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)

A **secure, multi-layered Python sandbox** designed for executing code generated by Large Language Models (LLMs). It provides robust isolation mechanisms to ensure safe execution of untrusted code.

## 🚀 Features

- **🔒 Multi-layered Security**:
  - **AST Validation**: Blocks dangerous constructs (e.g., top-level code, `eval`, `exec`) before execution.
  - **Import Whitelisting**: Strictly controls which modules can be imported.
  - **Restricted Builtins**: Removes access to dangerous built-ins like `open`, `input`, etc.

- **🛡️ Process Isolation**:
  - **Subprocess Mode**: Executes code in a separate process for maximum isolation.
  - **Resource Limits**: Enforces memory usage and CPU time limits (on supported systems).
  - **Wall-clock Timeouts**: Prevents infinite loops and hanging processes.

- **🐼 Data Science Ready**:
  - Optimized for `pandas` DataFrame operations.
  - Supports passing DataFrames in and out of the sandbox.

- **🔌 Flexible Execution Modes**:
  - `safe_context`: Lightweight in-process isolation (faster, for trusted code).
  - `subprocess_sandbox`: Full process isolation (safer, for untrusted code).

## 📦 Installation

This project is configured as a Python package. You can install it using pip:

```bash
# Clone the repository
git clone https://github.com/yourusername/llm-python-sandbox.git
cd llm-python-sandbox

# Install in editable mode
pip install -e .

# Install development dependencies
pip install -e ".[dev]"
```

## 🛠️ Usage

### Basic Execution

The `CodeExecutor` provides a high-level API for running code.

```python
from src.executor import CodeExecutor

executor = CodeExecutor()

# Execute simple code
code = """
def greet(name):
    return f"Hello, {name}!"
"""

result = executor.execute_code(
    code=code,
    input_variables={"name": "World"},
    verification_code="assert result == 'Hello, World!'",
    execution_mode="subprocess_sandbox"
)

print(result["stdout"])
# Output: Hello, World!
```

### Working with DataFrames

The sandbox is designed to handle data transformations safely.

```python
import pandas as pd
from src.executor import CodeExecutor

executor = CodeExecutor()

# Input DataFrame
df = pd.DataFrame({"value": [1, 2, 3, 4, 5]})

# Code to execute
code = """
import pandas as pd

def transform_data(df):
    df['doubled'] = df['value'] * 2
    return df
"""

result = executor.execute_code(
    code=code,
    input_variables={"df": df},
    return_variables=["transform_data"], # Capture return value
    execution_mode="subprocess_sandbox"
)

# Access returned data
processed_df = result["returned_values"]["transform_data"]
print(processed_df)
```

### Execution Modes

| Mode | Description | Security Level | Performance | Use Case |
|------|-------------|----------------|-------------|----------|
| `default` | Standard `exec()` | 🔴 Low | ⚡ Very High | Trusted, local scripts only |
| `safe_context` | In-process sandbox | 🟡 Medium | 🚀 High | Trusted LLMs, internal tools |
| `subprocess_sandbox` | Separate process | 🟢 High | 🐢 Medium | **Untrusted LLM code**, public APIs |

## 🏗️ Architecture

The project consists of several core components:

- **`CodeExecutor`**: The main entry point that orchestrates execution.
- **`SubprocessSandbox`**: Handles process lifecycle, resource limits, and IPC.
- **`SafeFunctionContext`**: Manages the in-process execution environment.
- **`ASTValidator`**: Statically analyzes code structure to reject unsafe patterns.
- **`SafeImporter`**: Intercepts imports to enforce the whitelist.

## 🔒 Security Model

The sandbox uses a "defense in depth" strategy:

1.  **Static Analysis**: Code is first parsed into an AST. If it contains forbidden nodes (e.g., `exec`, `eval`) or disallowed top-level statements, it is rejected immediately.
2.  **Runtime Restrictions**: The execution environment has a stripped-down `__builtins__` dictionary.
3.  **Import Control**: A custom `__import__` hook verifies strictly against an allowlist (default: `math`, `json`, `pandas`, `numpy`, etc.).
4.  **Process Isolation**: Using the `subprocess` mode adds OS-level isolation, protecting the main application from crashes and memory exhaustion.

> ⚠️ **Note**: While robust, no sandbox is 100% impenetrable. Always run untrusted code in a highly restricted environment (e.g., Docker container, gVisor) in production.

## 🤝 Contributing

Contributions are welcome! Please follow these steps:

1.  install dev dependencies: `pip install -e ".[dev]"`
2.  Run tests: `pytest`
3.  Format code: `black .`
4.  Submit a Pull Request.

## 📄 License

MIT License