isolated-sandbox / README.md
ChefAdorous's picture
Configure for Hugging Face Spaces with Docker SDK and add limitations notice
6ae3186
metadata
title: Code Execution Sandbox API
emoji: ๐Ÿ”’
colorFrom: blue
colorTo: purple
sdk: docker
pinned: false
license: mit

Code Execution Sandbox API - Enhanced

Secure, isolated code execution environment with persistent VM-like sessions and file system operations.

๐Ÿš€ Features

Dual Execution Modes

  1. Stateless Execution - Quick, ephemeral code execution (backward compatible)
  2. Persistent Sessions - Long-running containers with file storage and state persistence

Capabilities

  • โœ… Multi-Language Support: Python, JavaScript, Bash (+ Go, Java, Rust in sessions)
  • โœ… Secure Isolation: Docker-based containerization with resource limits
  • โœ… File Operations: Upload, download, list, execute files
  • โœ… Persistent State: Files and data persist across executions within a session
  • โœ… Auto-Cleanup: Idle sessions automatically destroyed after timeout
  • โœ… Resource Limits: CPU, memory, timeout enforcement
  • โœ… Network Isolation: Disabled by default (configurable)

๐Ÿ“ฆ Installation

Prerequisites

  • Python 3.8+
  • Docker (must be running)
  • 4GB+ RAM recommended

Setup

# Clone repository
git clone <repo-url>
cd isolated-sandbox

# Create virtual environment
python -m venv .venv
.venv\\Scripts\\activate  # Windows
# source .venv/bin/activate  # Linux/Mac

# Install dependencies
pip install -r requirements.txt
pip install -r requirements-dev.txt  # For testing

# Build development environment image (takes 10-15 minutes)
pwsh build_devenv.ps1
# OR manually:
# docker build -f sandbox/images/devenv.Dockerfile -t sandbox-devenv:latest sandbox/images/

Environment Configuration

Copy .env.example to .env and customize:

MAX_EXECUTION_TIME=30
MAX_MEMORY_MB=512
ENABLE_NETWORK=false
LOG_LEVEL=INFO

๐Ÿƒ Quick Start

Start the API Server

python app.py
# Or with uvicorn:
# uvicorn app:app --host 0.0.0.0 --port 7860

API will be available at http://localhost:7860

API Documentation

Interactive docs: http://localhost:7860/docs

๐Ÿ“š Usage Examples

1. Stateless Execution (Quick & Simple)

import requests

# Execute Python code
response = requests.post("http://localhost:7860/execute", json={
    "code": "print('Hello, World!')",
    "language": "python",
    "timeout": 10
})

print(response.json())
# {
#   "stdout": "Hello, World!\\n",
#   "stderr": "",
#   "exit_code": 0,
#   "execution_time": 0.123
# }

2. Persistent Session Workflow

import requests
import time

# Step 1: Create a session
session_resp = requests.post("http://localhost:7860/sessions", json={
    "metadata": {"user": "john", "project": "demo"},
    "timeout_minutes": 30
})
session_id = session_resp.json()["session_id"]
print(f"Session created: {session_id}")

# Wait for session to be ready
time.sleep(2)

# Step 2: Upload a file
with open("script.py", "rb") as f:
    files_resp = requests.post(
        f"http://localhost:7860/sessions/{session_id}/files",
        files={"file": ("script.py", f)}
    )
print(f"Uploaded: {files_resp.json()}")

# Step 3: Execute code in session
exec_resp = requests.post(
    f"http://localhost:7860/sessions/{session_id}/execute",
    json={
        "code": "with open('/workspace/data.txt', 'w') as f: f.write('persistent')",
        "language": "python"
    }
)
print(f"Execution: {exec_resp.json()}")

# Step 4: Execute uploaded file
file_exec_resp = requests.post(
    f"http://localhost:7860/sessions/{session_id}/execute-file",
    json={
        "filepath": "/workspace/script.py",
        "language": "python",
        "args": ["--verbose"]
    }
)
print(f"File execution: {file_exec_resp.json()}")

# Step 5: List files
files = requests.get(f"http://localhost:7860/sessions/{session_id}/files")
print(f"Files: {files.json()}")

# Step 6: Download file
download = requests.get(f"http://localhost:7860/sessions/{session_id}/files/data.txt")
print(f"Downloaded content: {download.content}")

# Step 7: Destroy session (cleanup)
requests.delete(f"http://localhost:7860/sessions/{session_id}")

3. Test State Persistence

# First execution: create file
exec1 = requests.post(f"http://localhost:7860/sessions/{session_id}/execute", json={
    "code": "import json; data = {'count': 1}; json.dump(data, open('/workspace/state.json', 'w'))",
    "language": "python"
})

# Second execution: read and modify (file persists!)
exec2 = requests.post(f"http://localhost:7860/sessions/{session_id}/execute", json={
    "code": """
import json
data = json.load(open('/workspace/state.json'))
data['count'] += 1
print(f'Count: {data["count"]}')
""",
    "language": "python"
})

print(exec2.json()["stdout"])  # Output: Count: 2

๐Ÿ”Œ API Endpoints

Session Management

Method Endpoint Description
POST /sessions Create new session
GET /sessions List all sessions
GET /sessions/{id} Get session details
DELETE /sessions/{id} Destroy session

File Operations

Method Endpoint Description
POST /sessions/{id}/files Upload file (multipart)
GET /sessions/{id}/files List files in workspace
GET /sessions/{id}/files/{path} Download file

Code Execution

Method Endpoint Description
POST /execute Stateless execution (ephemeral)
POST /sessions/{id}/execute Execute code in session
POST /sessions/{id}/execute-file Execute uploaded file

Information

Method Endpoint Description
GET / API information
GET /health Health check
GET /languages List supported languages

๐Ÿ”’ Security Features

Container Isolation

  • Read-only root filesystem
  • Non-root user execution
  • Network isolation (default: disabled)
  • PID limits (prevent fork bombs)
  • No new privileges flag

Resource Limits

  • CPU: 1 core (configurable)
  • Memory: 512MB default (configurable)
  • Execution timeout: 30s default
  • Container auto-cleanup

File Security

  • File size limit: 10MB per file
  • Session limit: 100MB total
  • Allowed extensions only
  • Path traversal prevention
  • Sandboxed to /workspace directory

Session Management

  • Auto-timeout after idle period (30 min default)
  • Background cleanup thread
  • Volume isolation per session

๐Ÿ› ๏ธ Development Environment (Sessions)

The sandbox-devenv:latest image includes:

Languages & Runtimes

  • Python: 3.12 (pyenv, poetry, uv, pip, black, mypy, pytest, ruff)
  • Node.js: 22, 20, 18 (nvm, npm, yarn, pnpm, eslint, prettier)
  • Java: OpenJDK 21 (Maven, Gradle)
  • Go: 1.24
  • Rust: 1.87 (rustc, cargo)
  • C/C++: gcc, clang, cmake, ninja, conan

Tools & Utilities

  • Version Control: git
  • Editors: vim, nano
  • Utilities: curl, wget, jq, yq, ripgrep, tmux
  • Docker: Docker-in-Docker support

Workspace

  • Default directory: /workspace
  • Persistent across executions
  • Mounted via Docker volume

๐Ÿงช Testing

# Run all tests
pytest

# Run specific test suites
pytest tests/test_api.py          # API integration tests
pytest tests/test_executor.py     # Executor unit tests
pytest tests/test_session_manager.py  # Session management tests
pytest tests/test_file_operations.py  # File operation tests

# Run with coverage
pytest --cov=sandbox --cov-report=html

๐Ÿšข Deployment

Docker Deployment

FROM python:3.11-slim

WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt

COPY . .

# Build devenv image (or pull from registry)
RUN docker build -f sandbox/images/devenv.Dockerfile -t sandbox-devenv:latest sandbox/images/

EXPOSE 7860
CMD ["python", "app.py"]

Requirements

  • Docker-in-Docker capable host
  • 4GB+ RAM (for concurrent sessions)
  • Persistent volume for session data (optional)

Recommended Platforms

  • Self-hosted VPS with Docker
  • AWS ECS, GCP Cloud Run, Azure Container Instances
  • Railway, Render (with Docker support)

Not Recommended

  • โŒ Hugging Face Spaces (no Docker-in-Docker)
  • โŒ Vercel, Netlify (serverless, stateless)

๐Ÿ“Š Configuration

Session Limits

Edit sandbox/session_manager.py:

MAX_CONCURRENT_SESSIONS = 10  # Limit concurrent sessions
SESSION_TIMEOUT_MINUTES = 30  # Auto-cleanup timeout

File Limits

Edit sandbox/file_manager.py:

MAX_FILE_SIZE = 10 * 1024 * 1024  # 10MB per file
MAX_SESSION_SIZE = 100 * 1024 * 1024  # 100MB per session

Resource Limits

Edit .env:

MAX_EXECUTION_TIME=30
MAX_MEMORY_MB=512
ENABLE_NETWORK=false

๐Ÿ”„ Architecture

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                    FastAPI Application                   โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚  Executor     โ”‚  Session Manager  โ”‚   File Manager       โ”‚
โ”‚  (stateless)  โ”‚  (persistent)     โ”‚   (file ops)         โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
        โ”‚                 โ”‚                    โ”‚
        โ–ผ                 โ–ผ                    โ–ผ
   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”      โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
   โ”‚Ephemeralโ”‚      โ”‚Long-Running  โ”‚    โ”‚ Docker   โ”‚
   โ”‚Containerโ”‚      โ”‚Container     โ”‚    โ”‚ Volumes  โ”‚
   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜      โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
        โ”‚                 โ”‚                    โ”‚
        โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                          โ”‚
                    Docker Engine

๐Ÿ“ License

MIT License - See LICENSE file for details

๐Ÿค Contributing

  1. Fork the repository
  2. Create feature branch
  3. Add tests for new features
  4. Ensure all tests pass
  5. Submit pull request

๐Ÿ“ฎ Support

For issues, questions, or contributions, please open an issue on GitHub.