Latest commit

History

43 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Code Interpreter API: A Stateful, Secure, and High-Performance Code Sandbox

ไธญๆ–‡็‰ˆ

This project provides a robust, API-driven code execution sandbox, engineered for high security, stateful session management, and strong performance. It utilizes a centralized API Gateway and a dynamic Worker Pool architecture, providing each user with a completely isolated and persistent execution session.

Now with dual-runtime support: Python 3.12 and Node.js 18 LTS, plus comprehensive document processing, browser automation, and 140+ pre-installed libraries.

A key technical feature of this project is its successful implementation of a "Virtual-Disk-per-Worker" architecture. This advanced model dynamically creates, formats, and mounts a dedicated virtual disk (.img file via losetup) for each worker container at runtime. This approach addresses the significant challenge of reliably managing dynamic block devices in a concurrent containerized environment, enabling superior I/O and filesystem isolation that is fundamental to the system's security posture.

Each worker is sandboxed within a multi-layered security model that includes strict resource limits, a zero-trust network policy, and runtime privilege reduction. By leveraging an internal Jupyter Kernel, it maintains the complete code execution context (variables, imports, functions) across multiple API calls, ensuring session continuity, security, and high performance.

Key Advantages

FeatureOur ApproachStandard Implementations (Common Trade-offs)
๐Ÿš€ PerformanceA pre-warmed pool of idle workers ensures instant session allocation. The fully asynchronous design (FastAPI, httpx) delivers high throughput (~32.8 RPS) and low latency.High latency due to on-demand container/environment startup for each new session. Often synchronous, leading to poor concurrency under load.
๐Ÿ”’ SecurityA multi-layered, zero-trust security model: no internet access (internal: true), inter-worker firewalls (iptables), gateway inaccessibility, and privilege drop (root to sandbox).Basic containerization often allows outbound internet access, lacks inter-worker firewalls (risk of lateral movement), and may run code with excessive privileges.
๐Ÿ”„ StatefulnessTrue session persistence. Each user is mapped to a dedicated worker with a persistent Jupyter Kernel, maintaining the full execution context across all API calls.Stateless (each call is a new environment) or emulated statefulness (e.g., saving/loading state via serialization), which is often slow and incomplete.
๐Ÿ› ๏ธ ReliabilityA "Cattle, not Pets" fault tolerance model. The gateway enforces hard timeouts and monitors worker health. Any failed, hung, or crashed worker is instantly destroyed and replaced.Workers are often treated as stateful "pets" that require complex recovery logic, increasing the risk of contaminated or inconsistent states persisting.
๐Ÿ’ก I/O IsolationVirtual-Disk-per-Worker Architecture. Each worker gets its own dynamically mounted block device, providing true filesystem and I/O isolation from the host and other workers.Often relies on shared host volumes (risk of cross-talk and security breaches) or has no persistent, isolated storage at all.

Built-in Capabilities

Each worker comes pre-loaded with a comprehensive set of tools and libraries. For a complete list, see worker/CAPABILITIES.md.

Runtime Environments

RuntimeVersionUse Case
Python3.12.12Primary execution environment with Jupyter Kernel
Node.js18 LTSJavaScript/TypeScript execution via subprocess

Pre-installed Libraries (140+)

CategoryKey LibrariesCapabilities
Scientific Computingnumpy, pandas, scipy, scikit-learn, statsmodelsData analysis, ML, statistics
Data Visualizationmatplotlib, seaborn, plotly, pyecharts, wordcloudCharts, graphs, interactive plots
Image ProcessingPIL, OpenCV, scikit-image, ImageMagick, rawpyImage editing, CV, RAW processing
Video Processingmoviepy, ffmpeg-python, PyAV, vidgearVideo editing, encoding, streaming
Audio Processingpydub, librosa, soundfile, pedalboardAudio editing, analysis, effects
Document Processingpython-docx, openpyxl, python-pptx, PyPDF2, pdfplumberOffice documents, PDF manipulation
Text & NLPjieba, pypinyin, thefuzz, fakerChinese NLP, fuzzy matching
Browser AutomationPlaywright + ChromiumWeb scraping, screenshots, testing

System Tools

ToolVersionCapabilities
LibreOfficeLatestDocument conversion (docx/xlsx/pptx โ†” PDF)
PandocLatestUniversal document converter (Markdown, LaTeX, etc.)
FFmpegLatestAudio/video encoding, transcoding, streaming
ImageMagickLatestImage conversion (200+ formats)
Tesseract OCRLatestText recognition (English + Chinese)
PopplerLatestPDF utilities (pdftotext, pdftoppm, etc.)
GhostscriptLatestPDF/PostScript processing

Node.js Packages (Global)

PackageUse Case
docxWord document creation
pptxgenjsPowerPoint generation
typescriptTypeScript compiler
ts-nodeDirect TypeScript execution

Performance Benchmarks

Stress-tested on a mid-range desktop to validate its performance and scalability under realistic conditions.

Test Configuration: Mid-Range Desktop (Intel i5-14400, 16GB RAM)

  • Test Scenario: 25 concurrent users, each sending 100 stateful requests (with result verification at each step).
  • Total Requests: 2,500
  • Throughput (RPS): ~32.8 req/s
  • Request Success Rate: 100%
  • State Verification Success Rate: 100%
  • P95 Latency: 496.50 ms
  • Test Parameters: The benchmark was conducted with the following runtime configuration:
    • MinIdleWorkers: 5
    • MaxTotalWorkers: 30
    • WorkerCPU: 1.0 core
    • WorkerRAM_MB: 1024 MB
    • WorkerDisk_MB: 500 MB

Result Charts

Test Summary Pie ChartLatency Distribution Chart

Architecture Overview

  1. API Gateway: The single, authenticated entry point. Its WorkerPool manages the entire lifecycle of worker instances, including the dynamic creation of their virtual disks. It acts as the trusted control plane.
  2. Worker Instance: An untrusted, disposable code execution unit. It runs a Supervisor that manages two processes (FastAPI service, Jupyter Kernel) as a non-root sandbox user. At startup, a script configures an iptables firewall to only accept traffic from the Gateway before dropping root privileges and mounting its dedicated virtual disk.

High-Level System ArchitectureRequest Flow Sequence Diagram

File Transfer Architecture

The system provides secure, high-performance file transfer capabilities via the Gateway's dual-mount architecture. This design allows the Gateway to directly access each worker's sandboxed filesystem without routing traffic through the untrusted worker container.

How It Works

 โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ Worker Container โ”‚
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚
โ”‚ Client โ”‚ โ”€โ”€โ”€ presigned URL โ”€โ”€โ”‚โ”€โ”€โ”‚ /sandbox (bind mount inside) โ”‚ โ”‚
โ”‚ (OSS) โ”‚ โ”‚ โ”‚ โ””โ”€โ”€ user_data.xlsx โ”‚ โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ โ”‚ โ””โ”€โ”€ output.png โ”‚ โ”‚
โ”‚ โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚
โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ”‚ โ”‚
โ”‚ โ”‚ (same block device)
โ”‚ โ–ผ
โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ HTTP PUT/GET โ”‚ Gateway Container โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚
โ”‚ โ”‚ /worker_mounts/{worker_id}/ โ”‚ โ”‚
โ”‚ โ”‚ โ””โ”€โ”€ user_data.xlsx โ”‚ โ”‚
โ”‚ โ”‚ โ””โ”€โ”€ output.png โ”‚ โ”‚
โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚
โ”‚ (host mount point) โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
  1. Upload: The Gateway downloads files from presigned URLs (e.g., OSS) and writes them directly to the worker's virtual disk via its own mount point (/worker_mounts/{worker_id}/).
  2. Export: The Gateway reads files from its mount point and uploads them to the presigned URL. Data never passes through the untrusted worker process.
  3. Delete: The Gateway directly removes files from the filesystem.

Security Features

FeatureImplementationThreat Mitigated
Path Traversal PreventionUses PurePosixPath.relative_to() to validate that all paths resolve within /sandbox. Rejects filenames containing / or \.Directory traversal attacks (e.g., ../../../etc/passwd)
SSRF ProtectionIntegrates ssrf-protect library to validate download URLs. Blocks requests to private IP ranges (10.x, 172.16.x, 192.168.x, 127.x) and internal hostnames.Server-Side Request Forgery
Redirect Bypass PreventionDisables HTTP redirects (allow_redirects=False) during file downloads.SSRF bypass via malicious redirects to internal services
Atomic WritesUploads use temp file + rename pattern to prevent partial/corrupted files on failure.Data corruption from interrupted transfers
File Size LimitsEnforces per-file size limit (default 100MB) with streaming validation. Aborts transfer immediately upon exceeding limit.Disk exhaustion attacks
Symlink Attack PreventionMounts virtual disk with nosymfollow option (Linux 5.10+). Verifies mount point is not a symlink before mounting.Symlink-based sandbox escapes
Concurrency ControlUses semaphore to limit concurrent file operations, preventing resource exhaustion.DoS via concurrent transfer floods

Quick Start

1. Prerequisites

  • Docker and Docker Compose installed and running.
  • An HTTP client (e.g., cURL, Postman, or Python's httpx).

2. Start the Service

Convenience scripts are provided to start the environment. You can customize the resource allocation and pool size via command-line arguments.

  • Linux / macOS:sh start.sh [options]
  • Windows (PowerShell):.\start.ps1 [options]

The gateway will listen on http://127.0.0.1:3874.

Customizing the Environment

You can pass the following parameters to the startup scripts to configure the system's behavior.

ParameterShell (.sh)PowerShell (.ps1)DefaultDescription
Min Idle Workers--min-idle-workers-MinIdleWorkers10The minimum number of idle, pre-warmed workers to keep ready in the pool.
Max Total Workers--max-total-workers-MaxTotalWorkers50The absolute maximum number of concurrent worker containers the system is allowed to create.
Worker CPU Limit--worker-cpu-WorkerCPU1.5The number of CPU cores to allocate to each worker container (e.g., 1.5 for one and a half cores).
Worker RAM Limit--worker-ram-mb-WorkerRAM_MB1536The amount of RAM in megabytes to allocate to each worker container.
Worker Disk Size--worker-disk-mb-WorkerDisk_MB500The size of the virtual disk in megabytes to create for each worker's sandboxed filesystem.

Note: Default resource limits have been increased to support Node.js, LibreOffice, and Playwright. For lightweight deployments without these features, you can reduce the limits.

Example (Linux/macOS):

# Start with a larger pool and more powerful workers
sh start.sh --min-idle-workers 10 --worker-cpu 2.0 --worker-ram-mb 2048

Example (Windows PowerShell):

# Start with a lightweight configuration for a low-resource environment
.\start.ps1 -MinIdleWorkers 2-MaxTotalWorkers 10-WorkerCPU 0.5-WorkerRAM_MB 512

3. Get the Auth Token

Retrieve the auto-generated token from the running gateway container:

docker exec code-interpreter_gateway cat /gateway/auth_token.txt

For a quick UI test, open the included test.html file in your browser, paste the token, and click "New Session".

4. Stop the Service

  • Linux / macOS:sh stop.sh
  • Windows (PowerShell):.\stop.ps1

API Documentation

All endpoints are prefixed with /api/v1. All requests require the X-Auth-Token: <your-token> header.

1. Execute Code POST /api/v1/execute?user_uuid={uuid}

Executes Python code within a user's stateful session.

  • Query Parameter: user_uuid (required) - UUID identifying the user session
  • Request Body: { "code": "string" }
  • Success Response (200 OK): { "worker_id": "string", "result_text": "string | null", "result_base64": "string | null" }
  • Timeout/Crash Response (503/504): Indicates a fatal error. The environment has been destroyed and recycled.

2. Release Session POST /api/v1/release?user_uuid={uuid}

Proactively terminates a user's session and destroys its worker.

  • Query Parameter: user_uuid (required) - UUID identifying the user session
  • Success Response (204 No Content)

3. Get System Status GET /api/v1/status (Admin)

Returns a summary of the worker pool's status for monitoring.

  • Success Response (200 OK):
    {
    "total_workers": 10,
    "busy_workers": 3,
    "is_initializing": false
    }

4. Batch Upload Files to Sandbox POST /api/v1/files?user_uuid={uuid}

Downloads files from presigned URLs and saves them to the user's worker sandbox. Supports batch operations with concurrent processing.

  • Query Parameter: user_uuid (required) - UUID identifying the user session
  • Limits: Max 100 files per request, max 100MB per file
  • Request Body:
    {
    "files": [
    {"download_url": "https://...", "path": "/sandbox/", "name": "data.xlsx"},
    {"download_url": "https://...", "path": "/sandbox/", "name": "image.png"}
    ]
    }
  • Success Response (201 Created):
    {
    "success": true,
    "results": [
    {"full_path": "/sandbox/data.xlsx", "size": 12345},
    {"full_path": "/sandbox/image.png", "size": 67890}
    ]
    }

5. Batch Export Files from Sandbox POST /api/v1/files/export?user_uuid={uuid}

Reads files from sandbox and uploads them to OSS via presigned URLs. Supports batch operations with concurrent processing.

  • Query Parameter: user_uuid (required) - UUID identifying the user session
  • Limits: Max 100 files per request
  • Request Body:
    {
    "files": [
    {"path": "/sandbox/", "name": "result.xlsx", "upload_url": "https://..."},
    {"path": "/sandbox/", "name": "chart.png", "upload_url": "https://..."}
    ]
    }
  • Success Response (200 OK):
    {
    "success": true,
    "results": [
    {"path": "/sandbox/", "name": "result.xlsx", "size": 8192},
    {"path": "/sandbox/", "name": "chart.png", "size": 54321}
    ]
    }

6. Batch Delete Files from Sandbox DELETE /api/v1/files?user_uuid={uuid}

Deletes files from the user's worker sandbox. Supports batch operations.

  • Query Parameter: user_uuid (required) - UUID identifying the user session
  • Limits: Max 100 files per request
  • Request Body:
    {
    "files": [
    {"path": "/sandbox/", "name": "temp.xlsx"},
    {"path": "/sandbox/", "name": "old.png"}
    ]
    }
  • Success Response (204 No Content)

Usage Example (Python)

importhttpximportasyncioimportuuidimportbase64importsubprocessGATEWAY_URL="http://127.0.0.1:3874"USER_ID=str(uuid.uuid4())
defget_auth_token():
try:
returnsubprocess.check_output(
["docker", "exec", "code-interpreter_gateway", "cat", "/gateway/auth_token.txt"],
text=True
).strip()
exceptException:
print("โŒ Could not fetch Auth Token. Is the service running?")
returnNoneasyncdefexecute_code(client: httpx.AsyncClient, code: str):
print(f"\n--- Executing ---\n{code.strip()}")
try:
response=awaitclient.post(
f"{GATEWAY_URL}/api/v1/execute",
params={"user_uuid": USER_ID},
json={"code": code},
timeout=30.0
)
response.raise_for_status()
data=response.json()
ifdata.get("result_text"):
print(">>> Text Result:\n"+data["result_text"])
ifdata.get("result_base64"):
print(">>> Image generated! (output.png saved)")
withopen("output.png", "wb") asf:
f.write(base64.b64decode(data["result_base64"]))
excepthttpx.HTTPStatusErrorase:
print(f"Execution failed: {e.response.status_code} - {e.response.text}")
asyncdefmain():
token=get_auth_token()
ifnottoken: returnheaders= {"X-Auth-Token": token}
asyncwithhttpx.AsyncClient(headers=headers) asclient:
# Step 1: Define a variableawaitexecute_code(client, "a = 100")
# Step 2: Use the variable from the previous step (state is maintained)awaitexecute_code(client, "print(f'The value of a is {a}')")
if__name__=="__main__":
asyncio.run(main())

License

This project is licensed under the MIT License.

About

๐Ÿš€ A stateful, secure, and scalable Python code sandbox via API. Built with a Gateway-Worker architecture using Docker for ultimate isolation and Jupyter Kernels for session persistence. / ๐Ÿš€ ไธ€ไธชๆœ‰็Šถๆ€ใ€้ซ˜ๅฎ‰ๅ…จๆ€ง็š„ๅฏไผธ็ผฉ Python ไปฃ็ ๆฒ™็ฎฑ๏ผŒ้€š่ฟ‡ API ๆไพ›ๆœๅŠกใ€‚้‡‡็”จโ€œ็ฝ‘ๅ…ณ-ๅทฅไฝœๅฎžไพ‹โ€ๆžถๆž„๏ผŒๅˆฉ็”จ Docker ๅฎž็Žฐๆž่‡ด้š”็ฆป๏ผŒๅนถ้€š่ฟ‡ Jupyter ๅ†…ๆ ธไฟๆŒไผš่ฏ็š„ๆŒไน…ๅŒ–ใ€‚

Resources

Stars

4 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Latest commit

History

43 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Code Interpreter API: A Stateful, Secure, and High-Performance Code Sandbox

ไธญๆ–‡็‰ˆ

This project provides a robust, API-driven code execution sandbox, engineered for high security, stateful session management, and strong performance. It utilizes a centralized API Gateway and a dynamic Worker Pool architecture, providing each user with a completely isolated and persistent execution session.

Now with dual-runtime support: Python 3.12 and Node.js 18 LTS, plus comprehensive document processing, browser automation, and 140+ pre-installed libraries.

A key technical feature of this project is its successful implementation of a "Virtual-Disk-per-Worker" architecture. This advanced model dynamically creates, formats, and mounts a dedicated virtual disk (.img file via losetup) for each worker container at runtime. This approach addresses the significant challenge of reliably managing dynamic block devices in a concurrent containerized environment, enabling superior I/O and filesystem isolation that is fundamental to the system's security posture.

Each worker is sandboxed within a multi-layered security model that includes strict resource limits, a zero-trust network policy, and runtime privilege reduction. By leveraging an internal Jupyter Kernel, it maintains the complete code execution context (variables, imports, functions) across multiple API calls, ensuring session continuity, security, and high performance.

Key Advantages

FeatureOur ApproachStandard Implementations (Common Trade-offs)
๐Ÿš€ PerformanceA pre-warmed pool of idle workers ensures instant session allocation. The fully asynchronous design (FastAPI, httpx) delivers high throughput (~32.8 RPS) and low latency.High latency due to on-demand container/environment startup for each new session. Often synchronous, leading to poor concurrency under load.
๐Ÿ”’ SecurityA multi-layered, zero-trust security model: no internet access (internal: true), inter-worker firewalls (iptables), gateway inaccessibility, and privilege drop (root to sandbox).Basic containerization often allows outbound internet access, lacks inter-worker firewalls (risk of lateral movement), and may run code with excessive privileges.
๐Ÿ”„ StatefulnessTrue session persistence. Each user is mapped to a dedicated worker with a persistent Jupyter Kernel, maintaining the full execution context across all API calls.Stateless (each call is a new environment) or emulated statefulness (e.g., saving/loading state via serialization), which is often slow and incomplete.
๐Ÿ› ๏ธ ReliabilityA "Cattle, not Pets" fault tolerance model. The gateway enforces hard timeouts and monitors worker health. Any failed, hung, or crashed worker is instantly destroyed and replaced.Workers are often treated as stateful "pets" that require complex recovery logic, increasing the risk of contaminated or inconsistent states persisting.
๐Ÿ’ก I/O IsolationVirtual-Disk-per-Worker Architecture. Each worker gets its own dynamically mounted block device, providing true filesystem and I/O isolation from the host and other workers.Often relies on shared host volumes (risk of cross-talk and security breaches) or has no persistent, isolated storage at all.

Built-in Capabilities

Each worker comes pre-loaded with a comprehensive set of tools and libraries. For a complete list, see worker/CAPABILITIES.md.

Runtime Environments

RuntimeVersionUse Case
Python3.12.12Primary execution environment with Jupyter Kernel
Node.js18 LTSJavaScript/TypeScript execution via subprocess

Pre-installed Libraries (140+)

CategoryKey LibrariesCapabilities
Scientific Computingnumpy, pandas, scipy, scikit-learn, statsmodelsData analysis, ML, statistics
Data Visualizationmatplotlib, seaborn, plotly, pyecharts, wordcloudCharts, graphs, interactive plots
Image ProcessingPIL, OpenCV, scikit-image, ImageMagick, rawpyImage editing, CV, RAW processing
Video Processingmoviepy, ffmpeg-python, PyAV, vidgearVideo editing, encoding, streaming
Audio Processingpydub, librosa, soundfile, pedalboardAudio editing, analysis, effects
Document Processingpython-docx, openpyxl, python-pptx, PyPDF2, pdfplumberOffice documents, PDF manipulation
Text & NLPjieba, pypinyin, thefuzz, fakerChinese NLP, fuzzy matching
Browser AutomationPlaywright + ChromiumWeb scraping, screenshots, testing

System Tools

ToolVersionCapabilities
LibreOfficeLatestDocument conversion (docx/xlsx/pptx โ†” PDF)
PandocLatestUniversal document converter (Markdown, LaTeX, etc.)
FFmpegLatestAudio/video encoding, transcoding, streaming
ImageMagickLatestImage conversion (200+ formats)
Tesseract OCRLatestText recognition (English + Chinese)
PopplerLatestPDF utilities (pdftotext, pdftoppm, etc.)
GhostscriptLatestPDF/PostScript processing

Node.js Packages (Global)

PackageUse Case
docxWord document creation
pptxgenjsPowerPoint generation
typescriptTypeScript compiler
ts-nodeDirect TypeScript execution

Performance Benchmarks

Stress-tested on a mid-range desktop to validate its performance and scalability under realistic conditions.

Test Configuration: Mid-Range Desktop (Intel i5-14400, 16GB RAM)

  • Test Scenario: 25 concurrent users, each sending 100 stateful requests (with result verification at each step).
  • Total Requests: 2,500
  • Throughput (RPS): ~32.8 req/s
  • Request Success Rate: 100%
  • State Verification Success Rate: 100%
  • P95 Latency: 496.50 ms
  • Test Parameters: The benchmark was conducted with the following runtime configuration:
    • MinIdleWorkers: 5
    • MaxTotalWorkers: 30
    • WorkerCPU: 1.0 core
    • WorkerRAM_MB: 1024 MB
    • WorkerDisk_MB: 500 MB

Result Charts

Test Summary Pie ChartLatency Distribution Chart

Architecture Overview

  1. API Gateway: The single, authenticated entry point. Its WorkerPool manages the entire lifecycle of worker instances, including the dynamic creation of their virtual disks. It acts as the trusted control plane.
  2. Worker Instance: An untrusted, disposable code execution unit. It runs a Supervisor that manages two processes (FastAPI service, Jupyter Kernel) as a non-root sandbox user. At startup, a script configures an iptables firewall to only accept traffic from the Gateway before dropping root privileges and mounting its dedicated virtual disk.

High-Level System ArchitectureRequest Flow Sequence Diagram

File Transfer Architecture

The system provides secure, high-performance file transfer capabilities via the Gateway's dual-mount architecture. This design allows the Gateway to directly access each worker's sandboxed filesystem without routing traffic through the untrusted worker container.

How It Works

 โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ Worker Container โ”‚
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚
โ”‚ Client โ”‚ โ”€โ”€โ”€ presigned URL โ”€โ”€โ”‚โ”€โ”€โ”‚ /sandbox (bind mount inside) โ”‚ โ”‚
โ”‚ (OSS) โ”‚ โ”‚ โ”‚ โ””โ”€โ”€ user_data.xlsx โ”‚ โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ โ”‚ โ””โ”€โ”€ output.png โ”‚ โ”‚
โ”‚ โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚
โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ”‚ โ”‚
โ”‚ โ”‚ (same block device)
โ”‚ โ–ผ
โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ HTTP PUT/GET โ”‚ Gateway Container โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚
โ”‚ โ”‚ /worker_mounts/{worker_id}/ โ”‚ โ”‚
โ”‚ โ”‚ โ””โ”€โ”€ user_data.xlsx โ”‚ โ”‚
โ”‚ โ”‚ โ””โ”€โ”€ output.png โ”‚ โ”‚
โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚
โ”‚ (host mount point) โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
  1. Upload: The Gateway downloads files from presigned URLs (e.g., OSS) and writes them directly to the worker's virtual disk via its own mount point (/worker_mounts/{worker_id}/).
  2. Export: The Gateway reads files from its mount point and uploads them to the presigned URL. Data never passes through the untrusted worker process.
  3. Delete: The Gateway directly removes files from the filesystem.

Security Features

FeatureImplementationThreat Mitigated
Path Traversal PreventionUses PurePosixPath.relative_to() to validate that all paths resolve within /sandbox. Rejects filenames containing / or \.Directory traversal attacks (e.g., ../../../etc/passwd)
SSRF ProtectionIntegrates ssrf-protect library to validate download URLs. Blocks requests to private IP ranges (10.x, 172.16.x, 192.168.x, 127.x) and internal hostnames.Server-Side Request Forgery
Redirect Bypass PreventionDisables HTTP redirects (allow_redirects=False) during file downloads.SSRF bypass via malicious redirects to internal services
Atomic WritesUploads use temp file + rename pattern to prevent partial/corrupted files on failure.Data corruption from interrupted transfers
File Size LimitsEnforces per-file size limit (default 100MB) with streaming validation. Aborts transfer immediately upon exceeding limit.Disk exhaustion attacks
Symlink Attack PreventionMounts virtual disk with nosymfollow option (Linux 5.10+). Verifies mount point is not a symlink before mounting.Symlink-based sandbox escapes
Concurrency ControlUses semaphore to limit concurrent file operations, preventing resource exhaustion.DoS via concurrent transfer floods

Quick Start

1. Prerequisites

  • Docker and Docker Compose installed and running.
  • An HTTP client (e.g., cURL, Postman, or Python's httpx).

2. Start the Service

Convenience scripts are provided to start the environment. You can customize the resource allocation and pool size via command-line arguments.

  • Linux / macOS:sh start.sh [options]
  • Windows (PowerShell):.\start.ps1 [options]

The gateway will listen on http://127.0.0.1:3874.

Customizing the Environment

You can pass the following parameters to the startup scripts to configure the system's behavior.

ParameterShell (.sh)PowerShell (.ps1)DefaultDescription
Min Idle Workers--min-idle-workers-MinIdleWorkers10The minimum number of idle, pre-warmed workers to keep ready in the pool.
Max Total Workers--max-total-workers-MaxTotalWorkers50The absolute maximum number of concurrent worker containers the system is allowed to create.
Worker CPU Limit--worker-cpu-WorkerCPU1.5The number of CPU cores to allocate to each worker container (e.g., 1.5 for one and a half cores).
Worker RAM Limit--worker-ram-mb-WorkerRAM_MB1536The amount of RAM in megabytes to allocate to each worker container.
Worker Disk Size--worker-disk-mb-WorkerDisk_MB500The size of the virtual disk in megabytes to create for each worker's sandboxed filesystem.

Note: Default resource limits have been increased to support Node.js, LibreOffice, and Playwright. For lightweight deployments without these features, you can reduce the limits.

Example (Linux/macOS):

# Start with a larger pool and more powerful workers
sh start.sh --min-idle-workers 10 --worker-cpu 2.0 --worker-ram-mb 2048

Example (Windows PowerShell):

# Start with a lightweight configuration for a low-resource environment
.\start.ps1 -MinIdleWorkers 2-MaxTotalWorkers 10-WorkerCPU 0.5-WorkerRAM_MB 512

3. Get the Auth Token

Retrieve the auto-generated token from the running gateway container:

docker exec code-interpreter_gateway cat /gateway/auth_token.txt

For a quick UI test, open the included test.html file in your browser, paste the token, and click "New Session".

4. Stop the Service

  • Linux / macOS:sh stop.sh
  • Windows (PowerShell):.\stop.ps1

API Documentation

All endpoints are prefixed with /api/v1. All requests require the X-Auth-Token: <your-token> header.

1. Execute Code POST /api/v1/execute?user_uuid={uuid}

Executes Python code within a user's stateful session.

  • Query Parameter: user_uuid (required) - UUID identifying the user session
  • Request Body: { "code": "string" }
  • Success Response (200 OK): { "worker_id": "string", "result_text": "string | null", "result_base64": "string | null" }
  • Timeout/Crash Response (503/504): Indicates a fatal error. The environment has been destroyed and recycled.

2. Release Session POST /api/v1/release?user_uuid={uuid}

Proactively terminates a user's session and destroys its worker.

  • Query Parameter: user_uuid (required) - UUID identifying the user session
  • Success Response (204 No Content)

3. Get System Status GET /api/v1/status (Admin)

Returns a summary of the worker pool's status for monitoring.

  • Success Response (200 OK):
    {
    "total_workers": 10,
    "busy_workers": 3,
    "is_initializing": false
    }

4. Batch Upload Files to Sandbox POST /api/v1/files?user_uuid={uuid}

Downloads files from presigned URLs and saves them to the user's worker sandbox. Supports batch operations with concurrent processing.

  • Query Parameter: user_uuid (required) - UUID identifying the user session
  • Limits: Max 100 files per request, max 100MB per file
  • Request Body:
    {
    "files": [
    {"download_url": "https://...", "path": "/sandbox/", "name": "data.xlsx"},
    {"download_url": "https://...", "path": "/sandbox/", "name": "image.png"}
    ]
    }
  • Success Response (201 Created):
    {
    "success": true,
    "results": [
    {"full_path": "/sandbox/data.xlsx", "size": 12345},
    {"full_path": "/sandbox/image.png", "size": 67890}
    ]
    }

5. Batch Export Files from Sandbox POST /api/v1/files/export?user_uuid={uuid}

Reads files from sandbox and uploads them to OSS via presigned URLs. Supports batch operations with concurrent processing.

  • Query Parameter: user_uuid (required) - UUID identifying the user session
  • Limits: Max 100 files per request
  • Request Body:
    {
    "files": [
    {"path": "/sandbox/", "name": "result.xlsx", "upload_url": "https://..."},
    {"path": "/sandbox/", "name": "chart.png", "upload_url": "https://..."}
    ]
    }
  • Success Response (200 OK):
    {
    "success": true,
    "results": [
    {"path": "/sandbox/", "name": "result.xlsx", "size": 8192},
    {"path": "/sandbox/", "name": "chart.png", "size": 54321}
    ]
    }

6. Batch Delete Files from Sandbox DELETE /api/v1/files?user_uuid={uuid}

Deletes files from the user's worker sandbox. Supports batch operations.

  • Query Parameter: user_uuid (required) - UUID identifying the user session
  • Limits: Max 100 files per request
  • Request Body:
    {
    "files": [
    {"path": "/sandbox/", "name": "temp.xlsx"},
    {"path": "/sandbox/", "name": "old.png"}
    ]
    }
  • Success Response (204 No Content)

Usage Example (Python)

importhttpximportasyncioimportuuidimportbase64importsubprocessGATEWAY_URL="http://127.0.0.1:3874"USER_ID=str(uuid.uuid4())
defget_auth_token():
try:
returnsubprocess.check_output(
["docker", "exec", "code-interpreter_gateway", "cat", "/gateway/auth_token.txt"],
text=True
).strip()
exceptException:
print("โŒ Could not fetch Auth Token. Is the service running?")
returnNoneasyncdefexecute_code(client: httpx.AsyncClient, code: str):
print(f"\n--- Executing ---\n{code.strip()}")
try:
response=awaitclient.post(
f"{GATEWAY_URL}/api/v1/execute",
params={"user_uuid": USER_ID},
json={"code": code},
timeout=30.0
)
response.raise_for_status()
data=response.json()
ifdata.get("result_text"):
print(">>> Text Result:\n"+data["result_text"])
ifdata.get("result_base64"):
print(">>> Image generated! (output.png saved)")
withopen("output.png", "wb") asf:
f.write(base64.b64decode(data["result_base64"]))
excepthttpx.HTTPStatusErrorase:
print(f"Execution failed: {e.response.status_code} - {e.response.text}")
asyncdefmain():
token=get_auth_token()
ifnottoken: returnheaders= {"X-Auth-Token": token}
asyncwithhttpx.AsyncClient(headers=headers) asclient:
# Step 1: Define a variableawaitexecute_code(client, "a = 100")
# Step 2: Use the variable from the previous step (state is maintained)awaitexecute_code(client, "print(f'The value of a is {a}')")
if__name__=="__main__":
asyncio.run(main())

License

This project is licensed under the MIT License.

About

๐Ÿš€ A stateful, secure, and scalable Python code sandbox via API. Built with a Gateway-Worker architecture using Docker for ultimate isolation and Jupyter Kernels for session persistence. / ๐Ÿš€ ไธ€ไธชๆœ‰็Šถๆ€ใ€้ซ˜ๅฎ‰ๅ…จๆ€ง็š„ๅฏไผธ็ผฉ Python ไปฃ็ ๆฒ™็ฎฑ๏ผŒ้€š่ฟ‡ API ๆไพ›ๆœๅŠกใ€‚้‡‡็”จโ€œ็ฝ‘ๅ…ณ-ๅทฅไฝœๅฎžไพ‹โ€ๆžถๆž„๏ผŒๅˆฉ็”จ Docker ๅฎž็Žฐๆž่‡ด้š”็ฆป๏ผŒๅนถ้€š่ฟ‡ Jupyter ๅ†…ๆ ธไฟๆŒไผš่ฏ็š„ๆŒไน…ๅŒ–ใ€‚

Resources

Stars

4 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Latest commit

History

43 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Code Interpreter API: A Stateful, Secure, and High-Performance Code Sandbox

ไธญๆ–‡็‰ˆ

This project provides a robust, API-driven code execution sandbox, engineered for high security, stateful session management, and strong performance. It utilizes a centralized API Gateway and a dynamic Worker Pool architecture, providing each user with a completely isolated and persistent execution session.

Now with dual-runtime support: Python 3.12 and Node.js 18 LTS, plus comprehensive document processing, browser automation, and 140+ pre-installed libraries.

A key technical feature of this project is its successful implementation of a "Virtual-Disk-per-Worker" architecture. This advanced model dynamically creates, formats, and mounts a dedicated virtual disk (.img file via losetup) for each worker container at runtime. This approach addresses the significant challenge of reliably managing dynamic block devices in a concurrent containerized environment, enabling superior I/O and filesystem isolation that is fundamental to the system's security posture.

Each worker is sandboxed within a multi-layered security model that includes strict resource limits, a zero-trust network policy, and runtime privilege reduction. By leveraging an internal Jupyter Kernel, it maintains the complete code execution context (variables, imports, functions) across multiple API calls, ensuring session continuity, security, and high performance.

Key Advantages

FeatureOur ApproachStandard Implementations (Common Trade-offs)
๐Ÿš€ PerformanceA pre-warmed pool of idle workers ensures instant session allocation. The fully asynchronous design (FastAPI, httpx) delivers high throughput (~32.8 RPS) and low latency.High latency due to on-demand container/environment startup for each new session. Often synchronous, leading to poor concurrency under load.
๐Ÿ”’ SecurityA multi-layered, zero-trust security model: no internet access (internal: true), inter-worker firewalls (iptables), gateway inaccessibility, and privilege drop (root to sandbox).Basic containerization often allows outbound internet access, lacks inter-worker firewalls (risk of lateral movement), and may run code with excessive privileges.
๐Ÿ”„ StatefulnessTrue session persistence. Each user is mapped to a dedicated worker with a persistent Jupyter Kernel, maintaining the full execution context across all API calls.Stateless (each call is a new environment) or emulated statefulness (e.g., saving/loading state via serialization), which is often slow and incomplete.
๐Ÿ› ๏ธ ReliabilityA "Cattle, not Pets" fault tolerance model. The gateway enforces hard timeouts and monitors worker health. Any failed, hung, or crashed worker is instantly destroyed and replaced.Workers are often treated as stateful "pets" that require complex recovery logic, increasing the risk of contaminated or inconsistent states persisting.
๐Ÿ’ก I/O IsolationVirtual-Disk-per-Worker Architecture. Each worker gets its own dynamically mounted block device, providing true filesystem and I/O isolation from the host and other workers.Often relies on shared host volumes (risk of cross-talk and security breaches) or has no persistent, isolated storage at all.

Built-in Capabilities

Each worker comes pre-loaded with a comprehensive set of tools and libraries. For a complete list, see worker/CAPABILITIES.md.

Runtime Environments

RuntimeVersionUse Case
Python3.12.12Primary execution environment with Jupyter Kernel
Node.js18 LTSJavaScript/TypeScript execution via subprocess

Pre-installed Libraries (140+)

CategoryKey LibrariesCapabilities
Scientific Computingnumpy, pandas, scipy, scikit-learn, statsmodelsData analysis, ML, statistics
Data Visualizationmatplotlib, seaborn, plotly, pyecharts, wordcloudCharts, graphs, interactive plots
Image ProcessingPIL, OpenCV, scikit-image, ImageMagick, rawpyImage editing, CV, RAW processing
Video Processingmoviepy, ffmpeg-python, PyAV, vidgearVideo editing, encoding, streaming
Audio Processingpydub, librosa, soundfile, pedalboardAudio editing, analysis, effects
Document Processingpython-docx, openpyxl, python-pptx, PyPDF2, pdfplumberOffice documents, PDF manipulation
Text & NLPjieba, pypinyin, thefuzz, fakerChinese NLP, fuzzy matching
Browser AutomationPlaywright + ChromiumWeb scraping, screenshots, testing

System Tools

ToolVersionCapabilities
LibreOfficeLatestDocument conversion (docx/xlsx/pptx โ†” PDF)
PandocLatestUniversal document converter (Markdown, LaTeX, etc.)
FFmpegLatestAudio/video encoding, transcoding, streaming
ImageMagickLatestImage conversion (200+ formats)
Tesseract OCRLatestText recognition (English + Chinese)
PopplerLatestPDF utilities (pdftotext, pdftoppm, etc.)
GhostscriptLatestPDF/PostScript processing

Node.js Packages (Global)

PackageUse Case
docxWord document creation
pptxgenjsPowerPoint generation
typescriptTypeScript compiler
ts-nodeDirect TypeScript execution

Performance Benchmarks

Stress-tested on a mid-range desktop to validate its performance and scalability under realistic conditions.

Test Configuration: Mid-Range Desktop (Intel i5-14400, 16GB RAM)

  • Test Scenario: 25 concurrent users, each sending 100 stateful requests (with result verification at each step).
  • Total Requests: 2,500
  • Throughput (RPS): ~32.8 req/s
  • Request Success Rate: 100%
  • State Verification Success Rate: 100%
  • P95 Latency: 496.50 ms
  • Test Parameters: The benchmark was conducted with the following runtime configuration:
    • MinIdleWorkers: 5
    • MaxTotalWorkers: 30
    • WorkerCPU: 1.0 core
    • WorkerRAM_MB: 1024 MB
    • WorkerDisk_MB: 500 MB

Result Charts

Test Summary Pie ChartLatency Distribution Chart

Architecture Overview

  1. API Gateway: The single, authenticated entry point. Its WorkerPool manages the entire lifecycle of worker instances, including the dynamic creation of their virtual disks. It acts as the trusted control plane.
  2. Worker Instance: An untrusted, disposable code execution unit. It runs a Supervisor that manages two processes (FastAPI service, Jupyter Kernel) as a non-root sandbox user. At startup, a script configures an iptables firewall to only accept traffic from the Gateway before dropping root privileges and mounting its dedicated virtual disk.

High-Level System ArchitectureRequest Flow Sequence Diagram

File Transfer Architecture

The system provides secure, high-performance file transfer capabilities via the Gateway's dual-mount architecture. This design allows the Gateway to directly access each worker's sandboxed filesystem without routing traffic through the untrusted worker container.

How It Works

 โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ Worker Container โ”‚
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚
โ”‚ Client โ”‚ โ”€โ”€โ”€ presigned URL โ”€โ”€โ”‚โ”€โ”€โ”‚ /sandbox (bind mount inside) โ”‚ โ”‚
โ”‚ (OSS) โ”‚ โ”‚ โ”‚ โ””โ”€โ”€ user_data.xlsx โ”‚ โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ โ”‚ โ””โ”€โ”€ output.png โ”‚ โ”‚
โ”‚ โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚
โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ”‚ โ”‚
โ”‚ โ”‚ (same block device)
โ”‚ โ–ผ
โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ HTTP PUT/GET โ”‚ Gateway Container โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚
โ”‚ โ”‚ /worker_mounts/{worker_id}/ โ”‚ โ”‚
โ”‚ โ”‚ โ””โ”€โ”€ user_data.xlsx โ”‚ โ”‚
โ”‚ โ”‚ โ””โ”€โ”€ output.png โ”‚ โ”‚
โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚
โ”‚ (host mount point) โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
  1. Upload: The Gateway downloads files from presigned URLs (e.g., OSS) and writes them directly to the worker's virtual disk via its own mount point (/worker_mounts/{worker_id}/).
  2. Export: The Gateway reads files from its mount point and uploads them to the presigned URL. Data never passes through the untrusted worker process.
  3. Delete: The Gateway directly removes files from the filesystem.

Security Features

FeatureImplementationThreat Mitigated
Path Traversal PreventionUses PurePosixPath.relative_to() to validate that all paths resolve within /sandbox. Rejects filenames containing / or \.Directory traversal attacks (e.g., ../../../etc/passwd)
SSRF ProtectionIntegrates ssrf-protect library to validate download URLs. Blocks requests to private IP ranges (10.x, 172.16.x, 192.168.x, 127.x) and internal hostnames.Server-Side Request Forgery
Redirect Bypass PreventionDisables HTTP redirects (allow_redirects=False) during file downloads.SSRF bypass via malicious redirects to internal services
Atomic WritesUploads use temp file + rename pattern to prevent partial/corrupted files on failure.Data corruption from interrupted transfers
File Size LimitsEnforces per-file size limit (default 100MB) with streaming validation. Aborts transfer immediately upon exceeding limit.Disk exhaustion attacks
Symlink Attack PreventionMounts virtual disk with nosymfollow option (Linux 5.10+). Verifies mount point is not a symlink before mounting.Symlink-based sandbox escapes
Concurrency ControlUses semaphore to limit concurrent file operations, preventing resource exhaustion.DoS via concurrent transfer floods

Quick Start

1. Prerequisites

  • Docker and Docker Compose installed and running.
  • An HTTP client (e.g., cURL, Postman, or Python's httpx).

2. Start the Service

Convenience scripts are provided to start the environment. You can customize the resource allocation and pool size via command-line arguments.

  • Linux / macOS:sh start.sh [options]
  • Windows (PowerShell):.\start.ps1 [options]

The gateway will listen on http://127.0.0.1:3874.

Customizing the Environment

You can pass the following parameters to the startup scripts to configure the system's behavior.

ParameterShell (.sh)PowerShell (.ps1)DefaultDescription
Min Idle Workers--min-idle-workers-MinIdleWorkers10The minimum number of idle, pre-warmed workers to keep ready in the pool.
Max Total Workers--max-total-workers-MaxTotalWorkers50The absolute maximum number of concurrent worker containers the system is allowed to create.
Worker CPU Limit--worker-cpu-WorkerCPU1.5The number of CPU cores to allocate to each worker container (e.g., 1.5 for one and a half cores).
Worker RAM Limit--worker-ram-mb-WorkerRAM_MB1536The amount of RAM in megabytes to allocate to each worker container.
Worker Disk Size--worker-disk-mb-WorkerDisk_MB500The size of the virtual disk in megabytes to create for each worker's sandboxed filesystem.

Note: Default resource limits have been increased to support Node.js, LibreOffice, and Playwright. For lightweight deployments without these features, you can reduce the limits.

Example (Linux/macOS):

# Start with a larger pool and more powerful workers
sh start.sh --min-idle-workers 10 --worker-cpu 2.0 --worker-ram-mb 2048

Example (Windows PowerShell):

# Start with a lightweight configuration for a low-resource environment
.\start.ps1 -MinIdleWorkers 2-MaxTotalWorkers 10-WorkerCPU 0.5-WorkerRAM_MB 512

3. Get the Auth Token

Retrieve the auto-generated token from the running gateway container:

docker exec code-interpreter_gateway cat /gateway/auth_token.txt

For a quick UI test, open the included test.html file in your browser, paste the token, and click "New Session".

4. Stop the Service

  • Linux / macOS:sh stop.sh
  • Windows (PowerShell):.\stop.ps1

API Documentation

All endpoints are prefixed with /api/v1. All requests require the X-Auth-Token: <your-token> header.

1. Execute Code POST /api/v1/execute?user_uuid={uuid}

Executes Python code within a user's stateful session.

  • Query Parameter: user_uuid (required) - UUID identifying the user session
  • Request Body: { "code": "string" }
  • Success Response (200 OK): { "worker_id": "string", "result_text": "string | null", "result_base64": "string | null" }
  • Timeout/Crash Response (503/504): Indicates a fatal error. The environment has been destroyed and recycled.

2. Release Session POST /api/v1/release?user_uuid={uuid}

Proactively terminates a user's session and destroys its worker.

  • Query Parameter: user_uuid (required) - UUID identifying the user session
  • Success Response (204 No Content)

3. Get System Status GET /api/v1/status (Admin)

Returns a summary of the worker pool's status for monitoring.

  • Success Response (200 OK):
    {
    "total_workers": 10,
    "busy_workers": 3,
    "is_initializing": false
    }

4. Batch Upload Files to Sandbox POST /api/v1/files?user_uuid={uuid}

Downloads files from presigned URLs and saves them to the user's worker sandbox. Supports batch operations with concurrent processing.

  • Query Parameter: user_uuid (required) - UUID identifying the user session
  • Limits: Max 100 files per request, max 100MB per file
  • Request Body:
    {
    "files": [
    {"download_url": "https://...", "path": "/sandbox/", "name": "data.xlsx"},
    {"download_url": "https://...", "path": "/sandbox/", "name": "image.png"}
    ]
    }
  • Success Response (201 Created):
    {
    "success": true,
    "results": [
    {"full_path": "/sandbox/data.xlsx", "size": 12345},
    {"full_path": "/sandbox/image.png", "size": 67890}
    ]
    }

5. Batch Export Files from Sandbox POST /api/v1/files/export?user_uuid={uuid}

Reads files from sandbox and uploads them to OSS via presigned URLs. Supports batch operations with concurrent processing.

  • Query Parameter: user_uuid (required) - UUID identifying the user session
  • Limits: Max 100 files per request
  • Request Body:
    {
    "files": [
    {"path": "/sandbox/", "name": "result.xlsx", "upload_url": "https://..."},
    {"path": "/sandbox/", "name": "chart.png", "upload_url": "https://..."}
    ]
    }
  • Success Response (200 OK):
    {
    "success": true,
    "results": [
    {"path": "/sandbox/", "name": "result.xlsx", "size": 8192},
    {"path": "/sandbox/", "name": "chart.png", "size": 54321}
    ]
    }

6. Batch Delete Files from Sandbox DELETE /api/v1/files?user_uuid={uuid}

Deletes files from the user's worker sandbox. Supports batch operations.

  • Query Parameter: user_uuid (required) - UUID identifying the user session
  • Limits: Max 100 files per request
  • Request Body:
    {
    "files": [
    {"path": "/sandbox/", "name": "temp.xlsx"},
    {"path": "/sandbox/", "name": "old.png"}
    ]
    }
  • Success Response (204 No Content)

Usage Example (Python)

importhttpximportasyncioimportuuidimportbase64importsubprocessGATEWAY_URL="http://127.0.0.1:3874"USER_ID=str(uuid.uuid4())
defget_auth_token():
try:
returnsubprocess.check_output(
["docker", "exec", "code-interpreter_gateway", "cat", "/gateway/auth_token.txt"],
text=True
).strip()
exceptException:
print("โŒ Could not fetch Auth Token. Is the service running?")
returnNoneasyncdefexecute_code(client: httpx.AsyncClient, code: str):
print(f"\n--- Executing ---\n{code.strip()}")
try:
response=awaitclient.post(
f"{GATEWAY_URL}/api/v1/execute",
params={"user_uuid": USER_ID},
json={"code": code},
timeout=30.0
)
response.raise_for_status()
data=response.json()
ifdata.get("result_text"):
print(">>> Text Result:\n"+data["result_text"])
ifdata.get("result_base64"):
print(">>> Image generated! (output.png saved)")
withopen("output.png", "wb") asf:
f.write(base64.b64decode(data["result_base64"]))
excepthttpx.HTTPStatusErrorase:
print(f"Execution failed: {e.response.status_code} - {e.response.text}")
asyncdefmain():
token=get_auth_token()
ifnottoken: returnheaders= {"X-Auth-Token": token}
asyncwithhttpx.AsyncClient(headers=headers) asclient:
# Step 1: Define a variableawaitexecute_code(client, "a = 100")
# Step 2: Use the variable from the previous step (state is maintained)awaitexecute_code(client, "print(f'The value of a is {a}')")
if__name__=="__main__":
asyncio.run(main())

License

This project is licensed under the MIT License.

About

๐Ÿš€ A stateful, secure, and scalable Python code sandbox via API. Built with a Gateway-Worker architecture using Docker for ultimate isolation and Jupyter Kernels for session persistence. / ๐Ÿš€ ไธ€ไธชๆœ‰็Šถๆ€ใ€้ซ˜ๅฎ‰ๅ…จๆ€ง็š„ๅฏไผธ็ผฉ Python ไปฃ็ ๆฒ™็ฎฑ๏ผŒ้€š่ฟ‡ API ๆไพ›ๆœๅŠกใ€‚้‡‡็”จโ€œ็ฝ‘ๅ…ณ-ๅทฅไฝœๅฎžไพ‹โ€ๆžถๆž„๏ผŒๅˆฉ็”จ Docker ๅฎž็Žฐๆž่‡ด้š”็ฆป๏ผŒๅนถ้€š่ฟ‡ Jupyter ๅ†…ๆ ธไฟๆŒไผš่ฏ็š„ๆŒไน…ๅŒ–ใ€‚

Resources

Stars

4 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Latest commit

History

43 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Code Interpreter API: A Stateful, Secure, and High-Performance Code Sandbox

ไธญๆ–‡็‰ˆ

This project provides a robust, API-driven code execution sandbox, engineered for high security, stateful session management, and strong performance. It utilizes a centralized API Gateway and a dynamic Worker Pool architecture, providing each user with a completely isolated and persistent execution session.

Now with dual-runtime support: Python 3.12 and Node.js 18 LTS, plus comprehensive document processing, browser automation, and 140+ pre-installed libraries.

A key technical feature of this project is its successful implementation of a "Virtual-Disk-per-Worker" architecture. This advanced model dynamically creates, formats, and mounts a dedicated virtual disk (.img file via losetup) for each worker container at runtime. This approach addresses the significant challenge of reliably managing dynamic block devices in a concurrent containerized environment, enabling superior I/O and filesystem isolation that is fundamental to the system's security posture.

Each worker is sandboxed within a multi-layered security model that includes strict resource limits, a zero-trust network policy, and runtime privilege reduction. By leveraging an internal Jupyter Kernel, it maintains the complete code execution context (variables, imports, functions) across multiple API calls, ensuring session continuity, security, and high performance.

Key Advantages

FeatureOur ApproachStandard Implementations (Common Trade-offs)
๐Ÿš€ PerformanceA pre-warmed pool of idle workers ensures instant session allocation. The fully asynchronous design (FastAPI, httpx) delivers high throughput (~32.8 RPS) and low latency.High latency due to on-demand container/environment startup for each new session. Often synchronous, leading to poor concurrency under load.
๐Ÿ”’ SecurityA multi-layered, zero-trust security model: no internet access (internal: true), inter-worker firewalls (iptables), gateway inaccessibility, and privilege drop (root to sandbox).Basic containerization often allows outbound internet access, lacks inter-worker firewalls (risk of lateral movement), and may run code with excessive privileges.
๐Ÿ”„ StatefulnessTrue session persistence. Each user is mapped to a dedicated worker with a persistent Jupyter Kernel, maintaining the full execution context across all API calls.Stateless (each call is a new environment) or emulated statefulness (e.g., saving/loading state via serialization), which is often slow and incomplete.
๐Ÿ› ๏ธ ReliabilityA "Cattle, not Pets" fault tolerance model. The gateway enforces hard timeouts and monitors worker health. Any failed, hung, or crashed worker is instantly destroyed and replaced.Workers are often treated as stateful "pets" that require complex recovery logic, increasing the risk of contaminated or inconsistent states persisting.
๐Ÿ’ก I/O IsolationVirtual-Disk-per-Worker Architecture. Each worker gets its own dynamically mounted block device, providing true filesystem and I/O isolation from the host and other workers.Often relies on shared host volumes (risk of cross-talk and security breaches) or has no persistent, isolated storage at all.

Built-in Capabilities

Each worker comes pre-loaded with a comprehensive set of tools and libraries. For a complete list, see worker/CAPABILITIES.md.

Runtime Environments

RuntimeVersionUse Case
Python3.12.12Primary execution environment with Jupyter Kernel
Node.js18 LTSJavaScript/TypeScript execution via subprocess

Pre-installed Libraries (140+)

CategoryKey LibrariesCapabilities
Scientific Computingnumpy, pandas, scipy, scikit-learn, statsmodelsData analysis, ML, statistics
Data Visualizationmatplotlib, seaborn, plotly, pyecharts, wordcloudCharts, graphs, interactive plots
Image ProcessingPIL, OpenCV, scikit-image, ImageMagick, rawpyImage editing, CV, RAW processing
Video Processingmoviepy, ffmpeg-python, PyAV, vidgearVideo editing, encoding, streaming
Audio Processingpydub, librosa, soundfile, pedalboardAudio editing, analysis, effects
Document Processingpython-docx, openpyxl, python-pptx, PyPDF2, pdfplumberOffice documents, PDF manipulation
Text & NLPjieba, pypinyin, thefuzz, fakerChinese NLP, fuzzy matching
Browser AutomationPlaywright + ChromiumWeb scraping, screenshots, testing

System Tools

ToolVersionCapabilities
LibreOfficeLatestDocument conversion (docx/xlsx/pptx โ†” PDF)
PandocLatestUniversal document converter (Markdown, LaTeX, etc.)
FFmpegLatestAudio/video encoding, transcoding, streaming
ImageMagickLatestImage conversion (200+ formats)
Tesseract OCRLatestText recognition (English + Chinese)
PopplerLatestPDF utilities (pdftotext, pdftoppm, etc.)
GhostscriptLatestPDF/PostScript processing

Node.js Packages (Global)

PackageUse Case
docxWord document creation
pptxgenjsPowerPoint generation
typescriptTypeScript compiler
ts-nodeDirect TypeScript execution

Performance Benchmarks

Stress-tested on a mid-range desktop to validate its performance and scalability under realistic conditions.

Test Configuration: Mid-Range Desktop (Intel i5-14400, 16GB RAM)

  • Test Scenario: 25 concurrent users, each sending 100 stateful requests (with result verification at each step).
  • Total Requests: 2,500
  • Throughput (RPS): ~32.8 req/s
  • Request Success Rate: 100%
  • State Verification Success Rate: 100%
  • P95 Latency: 496.50 ms
  • Test Parameters: The benchmark was conducted with the following runtime configuration:
    • MinIdleWorkers: 5
    • MaxTotalWorkers: 30
    • WorkerCPU: 1.0 core
    • WorkerRAM_MB: 1024 MB
    • WorkerDisk_MB: 500 MB

Result Charts

Test Summary Pie ChartLatency Distribution Chart

Architecture Overview

  1. API Gateway: The single, authenticated entry point. Its WorkerPool manages the entire lifecycle of worker instances, including the dynamic creation of their virtual disks. It acts as the trusted control plane.
  2. Worker Instance: An untrusted, disposable code execution unit. It runs a Supervisor that manages two processes (FastAPI service, Jupyter Kernel) as a non-root sandbox user. At startup, a script configures an iptables firewall to only accept traffic from the Gateway before dropping root privileges and mounting its dedicated virtual disk.

High-Level System ArchitectureRequest Flow Sequence Diagram

File Transfer Architecture

The system provides secure, high-performance file transfer capabilities via the Gateway's dual-mount architecture. This design allows the Gateway to directly access each worker's sandboxed filesystem without routing traffic through the untrusted worker container.

How It Works

 โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ Worker Container โ”‚
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚
โ”‚ Client โ”‚ โ”€โ”€โ”€ presigned URL โ”€โ”€โ”‚โ”€โ”€โ”‚ /sandbox (bind mount inside) โ”‚ โ”‚
โ”‚ (OSS) โ”‚ โ”‚ โ”‚ โ””โ”€โ”€ user_data.xlsx โ”‚ โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ โ”‚ โ””โ”€โ”€ output.png โ”‚ โ”‚
โ”‚ โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚
โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ”‚ โ”‚
โ”‚ โ”‚ (same block device)
โ”‚ โ–ผ
โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ HTTP PUT/GET โ”‚ Gateway Container โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚
โ”‚ โ”‚ /worker_mounts/{worker_id}/ โ”‚ โ”‚
โ”‚ โ”‚ โ””โ”€โ”€ user_data.xlsx โ”‚ โ”‚
โ”‚ โ”‚ โ””โ”€โ”€ output.png โ”‚ โ”‚
โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚
โ”‚ (host mount point) โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
  1. Upload: The Gateway downloads files from presigned URLs (e.g., OSS) and writes them directly to the worker's virtual disk via its own mount point (/worker_mounts/{worker_id}/).
  2. Export: The Gateway reads files from its mount point and uploads them to the presigned URL. Data never passes through the untrusted worker process.
  3. Delete: The Gateway directly removes files from the filesystem.

Security Features

FeatureImplementationThreat Mitigated
Path Traversal PreventionUses PurePosixPath.relative_to() to validate that all paths resolve within /sandbox. Rejects filenames containing / or \.Directory traversal attacks (e.g., ../../../etc/passwd)
SSRF ProtectionIntegrates ssrf-protect library to validate download URLs. Blocks requests to private IP ranges (10.x, 172.16.x, 192.168.x, 127.x) and internal hostnames.Server-Side Request Forgery
Redirect Bypass PreventionDisables HTTP redirects (allow_redirects=False) during file downloads.SSRF bypass via malicious redirects to internal services
Atomic WritesUploads use temp file + rename pattern to prevent partial/corrupted files on failure.Data corruption from interrupted transfers
File Size LimitsEnforces per-file size limit (default 100MB) with streaming validation. Aborts transfer immediately upon exceeding limit.Disk exhaustion attacks
Symlink Attack PreventionMounts virtual disk with nosymfollow option (Linux 5.10+). Verifies mount point is not a symlink before mounting.Symlink-based sandbox escapes
Concurrency ControlUses semaphore to limit concurrent file operations, preventing resource exhaustion.DoS via concurrent transfer floods

Quick Start

1. Prerequisites

  • Docker and Docker Compose installed and running.
  • An HTTP client (e.g., cURL, Postman, or Python's httpx).

2. Start the Service

Convenience scripts are provided to start the environment. You can customize the resource allocation and pool size via command-line arguments.

  • Linux / macOS:sh start.sh [options]
  • Windows (PowerShell):.\start.ps1 [options]

The gateway will listen on http://127.0.0.1:3874.

Customizing the Environment

You can pass the following parameters to the startup scripts to configure the system's behavior.

ParameterShell (.sh)PowerShell (.ps1)DefaultDescription
Min Idle Workers--min-idle-workers-MinIdleWorkers10The minimum number of idle, pre-warmed workers to keep ready in the pool.
Max Total Workers--max-total-workers-MaxTotalWorkers50The absolute maximum number of concurrent worker containers the system is allowed to create.
Worker CPU Limit--worker-cpu-WorkerCPU1.5The number of CPU cores to allocate to each worker container (e.g., 1.5 for one and a half cores).
Worker RAM Limit--worker-ram-mb-WorkerRAM_MB1536The amount of RAM in megabytes to allocate to each worker container.
Worker Disk Size--worker-disk-mb-WorkerDisk_MB500The size of the virtual disk in megabytes to create for each worker's sandboxed filesystem.

Note: Default resource limits have been increased to support Node.js, LibreOffice, and Playwright. For lightweight deployments without these features, you can reduce the limits.

Example (Linux/macOS):

# Start with a larger pool and more powerful workers
sh start.sh --min-idle-workers 10 --worker-cpu 2.0 --worker-ram-mb 2048

Example (Windows PowerShell):

# Start with a lightweight configuration for a low-resource environment
.\start.ps1 -MinIdleWorkers 2-MaxTotalWorkers 10-WorkerCPU 0.5-WorkerRAM_MB 512

3. Get the Auth Token

Retrieve the auto-generated token from the running gateway container:

docker exec code-interpreter_gateway cat /gateway/auth_token.txt

For a quick UI test, open the included test.html file in your browser, paste the token, and click "New Session".

4. Stop the Service

  • Linux / macOS:sh stop.sh
  • Windows (PowerShell):.\stop.ps1

API Documentation

All endpoints are prefixed with /api/v1. All requests require the X-Auth-Token: <your-token> header.

1. Execute Code POST /api/v1/execute?user_uuid={uuid}

Executes Python code within a user's stateful session.

  • Query Parameter: user_uuid (required) - UUID identifying the user session
  • Request Body: { "code": "string" }
  • Success Response (200 OK): { "worker_id": "string", "result_text": "string | null", "result_base64": "string | null" }
  • Timeout/Crash Response (503/504): Indicates a fatal error. The environment has been destroyed and recycled.

2. Release Session POST /api/v1/release?user_uuid={uuid}

Proactively terminates a user's session and destroys its worker.

  • Query Parameter: user_uuid (required) - UUID identifying the user session
  • Success Response (204 No Content)

3. Get System Status GET /api/v1/status (Admin)

Returns a summary of the worker pool's status for monitoring.

  • Success Response (200 OK):
    {
    "total_workers": 10,
    "busy_workers": 3,
    "is_initializing": false
    }

4. Batch Upload Files to Sandbox POST /api/v1/files?user_uuid={uuid}

Downloads files from presigned URLs and saves them to the user's worker sandbox. Supports batch operations with concurrent processing.

  • Query Parameter: user_uuid (required) - UUID identifying the user session
  • Limits: Max 100 files per request, max 100MB per file
  • Request Body:
    {
    "files": [
    {"download_url": "https://...", "path": "/sandbox/", "name": "data.xlsx"},
    {"download_url": "https://...", "path": "/sandbox/", "name": "image.png"}
    ]
    }
  • Success Response (201 Created):
    {
    "success": true,
    "results": [
    {"full_path": "/sandbox/data.xlsx", "size": 12345},
    {"full_path": "/sandbox/image.png", "size": 67890}
    ]
    }

5. Batch Export Files from Sandbox POST /api/v1/files/export?user_uuid={uuid}

Reads files from sandbox and uploads them to OSS via presigned URLs. Supports batch operations with concurrent processing.

  • Query Parameter: user_uuid (required) - UUID identifying the user session
  • Limits: Max 100 files per request
  • Request Body:
    {
    "files": [
    {"path": "/sandbox/", "name": "result.xlsx", "upload_url": "https://..."},
    {"path": "/sandbox/", "name": "chart.png", "upload_url": "https://..."}
    ]
    }
  • Success Response (200 OK):
    {
    "success": true,
    "results": [
    {"path": "/sandbox/", "name": "result.xlsx", "size": 8192},
    {"path": "/sandbox/", "name": "chart.png", "size": 54321}
    ]
    }

6. Batch Delete Files from Sandbox DELETE /api/v1/files?user_uuid={uuid}

Deletes files from the user's worker sandbox. Supports batch operations.

  • Query Parameter: user_uuid (required) - UUID identifying the user session
  • Limits: Max 100 files per request
  • Request Body:
    {
    "files": [
    {"path": "/sandbox/", "name": "temp.xlsx"},
    {"path": "/sandbox/", "name": "old.png"}
    ]
    }
  • Success Response (204 No Content)

Usage Example (Python)

importhttpximportasyncioimportuuidimportbase64importsubprocessGATEWAY_URL="http://127.0.0.1:3874"USER_ID=str(uuid.uuid4())
defget_auth_token():
try:
returnsubprocess.check_output(
["docker", "exec", "code-interpreter_gateway", "cat", "/gateway/auth_token.txt"],
text=True
).strip()
exceptException:
print("โŒ Could not fetch Auth Token. Is the service running?")
returnNoneasyncdefexecute_code(client: httpx.AsyncClient, code: str):
print(f"\n--- Executing ---\n{code.strip()}")
try:
response=awaitclient.post(
f"{GATEWAY_URL}/api/v1/execute",
params={"user_uuid": USER_ID},
json={"code": code},
timeout=30.0
)
response.raise_for_status()
data=response.json()
ifdata.get("result_text"):
print(">>> Text Result:\n"+data["result_text"])
ifdata.get("result_base64"):
print(">>> Image generated! (output.png saved)")
withopen("output.png", "wb") asf:
f.write(base64.b64decode(data["result_base64"]))
excepthttpx.HTTPStatusErrorase:
print(f"Execution failed: {e.response.status_code} - {e.response.text}")
asyncdefmain():
token=get_auth_token()
ifnottoken: returnheaders= {"X-Auth-Token": token}
asyncwithhttpx.AsyncClient(headers=headers) asclient:
# Step 1: Define a variableawaitexecute_code(client, "a = 100")
# Step 2: Use the variable from the previous step (state is maintained)awaitexecute_code(client, "print(f'The value of a is {a}')")
if__name__=="__main__":
asyncio.run(main())

License

This project is licensed under the MIT License.

About

๐Ÿš€ A stateful, secure, and scalable Python code sandbox via API. Built with a Gateway-Worker architecture using Docker for ultimate isolation and Jupyter Kernels for session persistence. / ๐Ÿš€ ไธ€ไธชๆœ‰็Šถๆ€ใ€้ซ˜ๅฎ‰ๅ…จๆ€ง็š„ๅฏไผธ็ผฉ Python ไปฃ็ ๆฒ™็ฎฑ๏ผŒ้€š่ฟ‡ API ๆไพ›ๆœๅŠกใ€‚้‡‡็”จโ€œ็ฝ‘ๅ…ณ-ๅทฅไฝœๅฎžไพ‹โ€ๆžถๆž„๏ผŒๅˆฉ็”จ Docker ๅฎž็Žฐๆž่‡ด้š”็ฆป๏ผŒๅนถ้€š่ฟ‡ Jupyter ๅ†…ๆ ธไฟๆŒไผš่ฏ็š„ๆŒไน…ๅŒ–ใ€‚

Resources

Stars

4 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Latest commit

History

43 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Code Interpreter API: A Stateful, Secure, and High-Performance Code Sandbox

ไธญๆ–‡็‰ˆ

This project provides a robust, API-driven code execution sandbox, engineered for high security, stateful session management, and strong performance. It utilizes a centralized API Gateway and a dynamic Worker Pool architecture, providing each user with a completely isolated and persistent execution session.

Now with dual-runtime support: Python 3.12 and Node.js 18 LTS, plus comprehensive document processing, browser automation, and 140+ pre-installed libraries.

A key technical feature of this project is its successful implementation of a "Virtual-Disk-per-Worker" architecture. This advanced model dynamically creates, formats, and mounts a dedicated virtual disk (.img file via losetup) for each worker container at runtime. This approach addresses the significant challenge of reliably managing dynamic block devices in a concurrent containerized environment, enabling superior I/O and filesystem isolation that is fundamental to the system's security posture.

Each worker is sandboxed within a multi-layered security model that includes strict resource limits, a zero-trust network policy, and runtime privilege reduction. By leveraging an internal Jupyter Kernel, it maintains the complete code execution context (variables, imports, functions) across multiple API calls, ensuring session continuity, security, and high performance.

Key Advantages

FeatureOur ApproachStandard Implementations (Common Trade-offs)
๐Ÿš€ PerformanceA pre-warmed pool of idle workers ensures instant session allocation. The fully asynchronous design (FastAPI, httpx) delivers high throughput (~32.8 RPS) and low latency.High latency due to on-demand container/environment startup for each new session. Often synchronous, leading to poor concurrency under load.
๐Ÿ”’ SecurityA multi-layered, zero-trust security model: no internet access (internal: true), inter-worker firewalls (iptables), gateway inaccessibility, and privilege drop (root to sandbox).Basic containerization often allows outbound internet access, lacks inter-worker firewalls (risk of lateral movement), and may run code with excessive privileges.
๐Ÿ”„ StatefulnessTrue session persistence. Each user is mapped to a dedicated worker with a persistent Jupyter Kernel, maintaining the full execution context across all API calls.Stateless (each call is a new environment) or emulated statefulness (e.g., saving/loading state via serialization), which is often slow and incomplete.
๐Ÿ› ๏ธ ReliabilityA "Cattle, not Pets" fault tolerance model. The gateway enforces hard timeouts and monitors worker health. Any failed, hung, or crashed worker is instantly destroyed and replaced.Workers are often treated as stateful "pets" that require complex recovery logic, increasing the risk of contaminated or inconsistent states persisting.
๐Ÿ’ก I/O IsolationVirtual-Disk-per-Worker Architecture. Each worker gets its own dynamically mounted block device, providing true filesystem and I/O isolation from the host and other workers.Often relies on shared host volumes (risk of cross-talk and security breaches) or has no persistent, isolated storage at all.

Built-in Capabilities

Each worker comes pre-loaded with a comprehensive set of tools and libraries. For a complete list, see worker/CAPABILITIES.md.

Runtime Environments

RuntimeVersionUse Case
Python3.12.12Primary execution environment with Jupyter Kernel
Node.js18 LTSJavaScript/TypeScript execution via subprocess

Pre-installed Libraries (140+)

CategoryKey LibrariesCapabilities
Scientific Computingnumpy, pandas, scipy, scikit-learn, statsmodelsData analysis, ML, statistics
Data Visualizationmatplotlib, seaborn, plotly, pyecharts, wordcloudCharts, graphs, interactive plots
Image ProcessingPIL, OpenCV, scikit-image, ImageMagick, rawpyImage editing, CV, RAW processing
Video Processingmoviepy, ffmpeg-python, PyAV, vidgearVideo editing, encoding, streaming
Audio Processingpydub, librosa, soundfile, pedalboardAudio editing, analysis, effects
Document Processingpython-docx, openpyxl, python-pptx, PyPDF2, pdfplumberOffice documents, PDF manipulation
Text & NLPjieba, pypinyin, thefuzz, fakerChinese NLP, fuzzy matching
Browser AutomationPlaywright + ChromiumWeb scraping, screenshots, testing

System Tools

ToolVersionCapabilities
LibreOfficeLatestDocument conversion (docx/xlsx/pptx โ†” PDF)
PandocLatestUniversal document converter (Markdown, LaTeX, etc.)
FFmpegLatestAudio/video encoding, transcoding, streaming
ImageMagickLatestImage conversion (200+ formats)
Tesseract OCRLatestText recognition (English + Chinese)
PopplerLatestPDF utilities (pdftotext, pdftoppm, etc.)
GhostscriptLatestPDF/PostScript processing

Node.js Packages (Global)

PackageUse Case
docxWord document creation
pptxgenjsPowerPoint generation
typescriptTypeScript compiler
ts-nodeDirect TypeScript execution

Performance Benchmarks

Stress-tested on a mid-range desktop to validate its performance and scalability under realistic conditions.

Test Configuration: Mid-Range Desktop (Intel i5-14400, 16GB RAM)

  • Test Scenario: 25 concurrent users, each sending 100 stateful requests (with result verification at each step).
  • Total Requests: 2,500
  • Throughput (RPS): ~32.8 req/s
  • Request Success Rate: 100%
  • State Verification Success Rate: 100%
  • P95 Latency: 496.50 ms
  • Test Parameters: The benchmark was conducted with the following runtime configuration:
    • MinIdleWorkers: 5
    • MaxTotalWorkers: 30
    • WorkerCPU: 1.0 core
    • WorkerRAM_MB: 1024 MB
    • WorkerDisk_MB: 500 MB

Result Charts

Test Summary Pie ChartLatency Distribution Chart

Architecture Overview

  1. API Gateway: The single, authenticated entry point. Its WorkerPool manages the entire lifecycle of worker instances, including the dynamic creation of their virtual disks. It acts as the trusted control plane.
  2. Worker Instance: An untrusted, disposable code execution unit. It runs a Supervisor that manages two processes (FastAPI service, Jupyter Kernel) as a non-root sandbox user. At startup, a script configures an iptables firewall to only accept traffic from the Gateway before dropping root privileges and mounting its dedicated virtual disk.

High-Level System ArchitectureRequest Flow Sequence Diagram

File Transfer Architecture

The system provides secure, high-performance file transfer capabilities via the Gateway's dual-mount architecture. This design allows the Gateway to directly access each worker's sandboxed filesystem without routing traffic through the untrusted worker container.

How It Works

 โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ Worker Container โ”‚
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚
โ”‚ Client โ”‚ โ”€โ”€โ”€ presigned URL โ”€โ”€โ”‚โ”€โ”€โ”‚ /sandbox (bind mount inside) โ”‚ โ”‚
โ”‚ (OSS) โ”‚ โ”‚ โ”‚ โ””โ”€โ”€ user_data.xlsx โ”‚ โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ โ”‚ โ””โ”€โ”€ output.png โ”‚ โ”‚
โ”‚ โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚
โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ”‚ โ”‚
โ”‚ โ”‚ (same block device)
โ”‚ โ–ผ
โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ HTTP PUT/GET โ”‚ Gateway Container โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚
โ”‚ โ”‚ /worker_mounts/{worker_id}/ โ”‚ โ”‚
โ”‚ โ”‚ โ””โ”€โ”€ user_data.xlsx โ”‚ โ”‚
โ”‚ โ”‚ โ””โ”€โ”€ output.png โ”‚ โ”‚
โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚
โ”‚ (host mount point) โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
  1. Upload: The Gateway downloads files from presigned URLs (e.g., OSS) and writes them directly to the worker's virtual disk via its own mount point (/worker_mounts/{worker_id}/).
  2. Export: The Gateway reads files from its mount point and uploads them to the presigned URL. Data never passes through the untrusted worker process.
  3. Delete: The Gateway directly removes files from the filesystem.

Security Features

FeatureImplementationThreat Mitigated
Path Traversal PreventionUses PurePosixPath.relative_to() to validate that all paths resolve within /sandbox. Rejects filenames containing / or \.Directory traversal attacks (e.g., ../../../etc/passwd)
SSRF ProtectionIntegrates ssrf-protect library to validate download URLs. Blocks requests to private IP ranges (10.x, 172.16.x, 192.168.x, 127.x) and internal hostnames.Server-Side Request Forgery
Redirect Bypass PreventionDisables HTTP redirects (allow_redirects=False) during file downloads.SSRF bypass via malicious redirects to internal services
Atomic WritesUploads use temp file + rename pattern to prevent partial/corrupted files on failure.Data corruption from interrupted transfers
File Size LimitsEnforces per-file size limit (default 100MB) with streaming validation. Aborts transfer immediately upon exceeding limit.Disk exhaustion attacks
Symlink Attack PreventionMounts virtual disk with nosymfollow option (Linux 5.10+). Verifies mount point is not a symlink before mounting.Symlink-based sandbox escapes
Concurrency ControlUses semaphore to limit concurrent file operations, preventing resource exhaustion.DoS via concurrent transfer floods

Quick Start

1. Prerequisites

  • Docker and Docker Compose installed and running.
  • An HTTP client (e.g., cURL, Postman, or Python's httpx).

2. Start the Service

Convenience scripts are provided to start the environment. You can customize the resource allocation and pool size via command-line arguments.

  • Linux / macOS:sh start.sh [options]
  • Windows (PowerShell):.\start.ps1 [options]

The gateway will listen on http://127.0.0.1:3874.

Customizing the Environment

You can pass the following parameters to the startup scripts to configure the system's behavior.

ParameterShell (.sh)PowerShell (.ps1)DefaultDescription
Min Idle Workers--min-idle-workers-MinIdleWorkers10The minimum number of idle, pre-warmed workers to keep ready in the pool.
Max Total Workers--max-total-workers-MaxTotalWorkers50The absolute maximum number of concurrent worker containers the system is allowed to create.
Worker CPU Limit--worker-cpu-WorkerCPU1.5The number of CPU cores to allocate to each worker container (e.g., 1.5 for one and a half cores).
Worker RAM Limit--worker-ram-mb-WorkerRAM_MB1536The amount of RAM in megabytes to allocate to each worker container.
Worker Disk Size--worker-disk-mb-WorkerDisk_MB500The size of the virtual disk in megabytes to create for each worker's sandboxed filesystem.

Note: Default resource limits have been increased to support Node.js, LibreOffice, and Playwright. For lightweight deployments without these features, you can reduce the limits.

Example (Linux/macOS):

# Start with a larger pool and more powerful workers
sh start.sh --min-idle-workers 10 --worker-cpu 2.0 --worker-ram-mb 2048

Example (Windows PowerShell):

# Start with a lightweight configuration for a low-resource environment
.\start.ps1 -MinIdleWorkers 2-MaxTotalWorkers 10-WorkerCPU 0.5-WorkerRAM_MB 512

3. Get the Auth Token

Retrieve the auto-generated token from the running gateway container:

docker exec code-interpreter_gateway cat /gateway/auth_token.txt

For a quick UI test, open the included test.html file in your browser, paste the token, and click "New Session".

4. Stop the Service

  • Linux / macOS:sh stop.sh
  • Windows (PowerShell):.\stop.ps1

API Documentation

All endpoints are prefixed with /api/v1. All requests require the X-Auth-Token: <your-token> header.

1. Execute Code POST /api/v1/execute?user_uuid={uuid}

Executes Python code within a user's stateful session.

  • Query Parameter: user_uuid (required) - UUID identifying the user session
  • Request Body: { "code": "string" }
  • Success Response (200 OK): { "worker_id": "string", "result_text": "string | null", "result_base64": "string | null" }
  • Timeout/Crash Response (503/504): Indicates a fatal error. The environment has been destroyed and recycled.

2. Release Session POST /api/v1/release?user_uuid={uuid}

Proactively terminates a user's session and destroys its worker.

  • Query Parameter: user_uuid (required) - UUID identifying the user session
  • Success Response (204 No Content)

3. Get System Status GET /api/v1/status (Admin)

Returns a summary of the worker pool's status for monitoring.

  • Success Response (200 OK):
    {
    "total_workers": 10,
    "busy_workers": 3,
    "is_initializing": false
    }

4. Batch Upload Files to Sandbox POST /api/v1/files?user_uuid={uuid}

Downloads files from presigned URLs and saves them to the user's worker sandbox. Supports batch operations with concurrent processing.

  • Query Parameter: user_uuid (required) - UUID identifying the user session
  • Limits: Max 100 files per request, max 100MB per file
  • Request Body:
    {
    "files": [
    {"download_url": "https://...", "path": "/sandbox/", "name": "data.xlsx"},
    {"download_url": "https://...", "path": "/sandbox/", "name": "image.png"}
    ]
    }
  • Success Response (201 Created):
    {
    "success": true,
    "results": [
    {"full_path": "/sandbox/data.xlsx", "size": 12345},
    {"full_path": "/sandbox/image.png", "size": 67890}
    ]
    }

5. Batch Export Files from Sandbox POST /api/v1/files/export?user_uuid={uuid}

Reads files from sandbox and uploads them to OSS via presigned URLs. Supports batch operations with concurrent processing.

  • Query Parameter: user_uuid (required) - UUID identifying the user session
  • Limits: Max 100 files per request
  • Request Body:
    {
    "files": [
    {"path": "/sandbox/", "name": "result.xlsx", "upload_url": "https://..."},
    {"path": "/sandbox/", "name": "chart.png", "upload_url": "https://..."}
    ]
    }
  • Success Response (200 OK):
    {
    "success": true,
    "results": [
    {"path": "/sandbox/", "name": "result.xlsx", "size": 8192},
    {"path": "/sandbox/", "name": "chart.png", "size": 54321}
    ]
    }

6. Batch Delete Files from Sandbox DELETE /api/v1/files?user_uuid={uuid}

Deletes files from the user's worker sandbox. Supports batch operations.

  • Query Parameter: user_uuid (required) - UUID identifying the user session
  • Limits: Max 100 files per request
  • Request Body:
    {
    "files": [
    {"path": "/sandbox/", "name": "temp.xlsx"},
    {"path": "/sandbox/", "name": "old.png"}
    ]
    }
  • Success Response (204 No Content)

Usage Example (Python)

importhttpximportasyncioimportuuidimportbase64importsubprocessGATEWAY_URL="http://127.0.0.1:3874"USER_ID=str(uuid.uuid4())
defget_auth_token():
try:
returnsubprocess.check_output(
["docker", "exec", "code-interpreter_gateway", "cat", "/gateway/auth_token.txt"],
text=True
).strip()
exceptException:
print("โŒ Could not fetch Auth Token. Is the service running?")
returnNoneasyncdefexecute_code(client: httpx.AsyncClient, code: str):
print(f"\n--- Executing ---\n{code.strip()}")
try:
response=awaitclient.post(
f"{GATEWAY_URL}/api/v1/execute",
params={"user_uuid": USER_ID},
json={"code": code},
timeout=30.0
)
response.raise_for_status()
data=response.json()
ifdata.get("result_text"):
print(">>> Text Result:\n"+data["result_text"])
ifdata.get("result_base64"):
print(">>> Image generated! (output.png saved)")
withopen("output.png", "wb") asf:
f.write(base64.b64decode(data["result_base64"]))
excepthttpx.HTTPStatusErrorase:
print(f"Execution failed: {e.response.status_code} - {e.response.text}")
asyncdefmain():
token=get_auth_token()
ifnottoken: returnheaders= {"X-Auth-Token": token}
asyncwithhttpx.AsyncClient(headers=headers) asclient:
# Step 1: Define a variableawaitexecute_code(client, "a = 100")
# Step 2: Use the variable from the previous step (state is maintained)awaitexecute_code(client, "print(f'The value of a is {a}')")
if__name__=="__main__":
asyncio.run(main())

License

This project is licensed under the MIT License.

About

๐Ÿš€ A stateful, secure, and scalable Python code sandbox via API. Built with a Gateway-Worker architecture using Docker for ultimate isolation and Jupyter Kernels for session persistence. / ๐Ÿš€ ไธ€ไธชๆœ‰็Šถๆ€ใ€้ซ˜ๅฎ‰ๅ…จๆ€ง็š„ๅฏไผธ็ผฉ Python ไปฃ็ ๆฒ™็ฎฑ๏ผŒ้€š่ฟ‡ API ๆไพ›ๆœๅŠกใ€‚้‡‡็”จโ€œ็ฝ‘ๅ…ณ-ๅทฅไฝœๅฎžไพ‹โ€ๆžถๆž„๏ผŒๅˆฉ็”จ Docker ๅฎž็Žฐๆž่‡ด้š”็ฆป๏ผŒๅนถ้€š่ฟ‡ Jupyter ๅ†…ๆ ธไฟๆŒไผš่ฏ็š„ๆŒไน…ๅŒ–ใ€‚

Resources

Stars

4 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Latest commit

History

43 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Code Interpreter API: A Stateful, Secure, and High-Performance Code Sandbox

ไธญๆ–‡็‰ˆ

This project provides a robust, API-driven code execution sandbox, engineered for high security, stateful session management, and strong performance. It utilizes a centralized API Gateway and a dynamic Worker Pool architecture, providing each user with a completely isolated and persistent execution session.

Now with dual-runtime support: Python 3.12 and Node.js 18 LTS, plus comprehensive document processing, browser automation, and 140+ pre-installed libraries.

A key technical feature of this project is its successful implementation of a "Virtual-Disk-per-Worker" architecture. This advanced model dynamically creates, formats, and mounts a dedicated virtual disk (.img file via losetup) for each worker container at runtime. This approach addresses the significant challenge of reliably managing dynamic block devices in a concurrent containerized environment, enabling superior I/O and filesystem isolation that is fundamental to the system's security posture.

Each worker is sandboxed within a multi-layered security model that includes strict resource limits, a zero-trust network policy, and runtime privilege reduction. By leveraging an internal Jupyter Kernel, it maintains the complete code execution context (variables, imports, functions) across multiple API calls, ensuring session continuity, security, and high performance.

Key Advantages

FeatureOur ApproachStandard Implementations (Common Trade-offs)
๐Ÿš€ PerformanceA pre-warmed pool of idle workers ensures instant session allocation. The fully asynchronous design (FastAPI, httpx) delivers high throughput (~32.8 RPS) and low latency.High latency due to on-demand container/environment startup for each new session. Often synchronous, leading to poor concurrency under load.
๐Ÿ”’ SecurityA multi-layered, zero-trust security model: no internet access (internal: true), inter-worker firewalls (iptables), gateway inaccessibility, and privilege drop (root to sandbox).Basic containerization often allows outbound internet access, lacks inter-worker firewalls (risk of lateral movement), and may run code with excessive privileges.
๐Ÿ”„ StatefulnessTrue session persistence. Each user is mapped to a dedicated worker with a persistent Jupyter Kernel, maintaining the full execution context across all API calls.Stateless (each call is a new environment) or emulated statefulness (e.g., saving/loading state via serialization), which is often slow and incomplete.
๐Ÿ› ๏ธ ReliabilityA "Cattle, not Pets" fault tolerance model. The gateway enforces hard timeouts and monitors worker health. Any failed, hung, or crashed worker is instantly destroyed and replaced.Workers are often treated as stateful "pets" that require complex recovery logic, increasing the risk of contaminated or inconsistent states persisting.
๐Ÿ’ก I/O IsolationVirtual-Disk-per-Worker Architecture. Each worker gets its own dynamically mounted block device, providing true filesystem and I/O isolation from the host and other workers.Often relies on shared host volumes (risk of cross-talk and security breaches) or has no persistent, isolated storage at all.

Built-in Capabilities

Each worker comes pre-loaded with a comprehensive set of tools and libraries. For a complete list, see worker/CAPABILITIES.md.

Runtime Environments

RuntimeVersionUse Case
Python3.12.12Primary execution environment with Jupyter Kernel
Node.js18 LTSJavaScript/TypeScript execution via subprocess

Pre-installed Libraries (140+)

CategoryKey LibrariesCapabilities
Scientific Computingnumpy, pandas, scipy, scikit-learn, statsmodelsData analysis, ML, statistics
Data Visualizationmatplotlib, seaborn, plotly, pyecharts, wordcloudCharts, graphs, interactive plots
Image ProcessingPIL, OpenCV, scikit-image, ImageMagick, rawpyImage editing, CV, RAW processing
Video Processingmoviepy, ffmpeg-python, PyAV, vidgearVideo editing, encoding, streaming
Audio Processingpydub, librosa, soundfile, pedalboardAudio editing, analysis, effects
Document Processingpython-docx, openpyxl, python-pptx, PyPDF2, pdfplumberOffice documents, PDF manipulation
Text & NLPjieba, pypinyin, thefuzz, fakerChinese NLP, fuzzy matching
Browser AutomationPlaywright + ChromiumWeb scraping, screenshots, testing

System Tools

ToolVersionCapabilities
LibreOfficeLatestDocument conversion (docx/xlsx/pptx โ†” PDF)
PandocLatestUniversal document converter (Markdown, LaTeX, etc.)
FFmpegLatestAudio/video encoding, transcoding, streaming
ImageMagickLatestImage conversion (200+ formats)
Tesseract OCRLatestText recognition (English + Chinese)
PopplerLatestPDF utilities (pdftotext, pdftoppm, etc.)
GhostscriptLatestPDF/PostScript processing

Node.js Packages (Global)

PackageUse Case
docxWord document creation
pptxgenjsPowerPoint generation
typescriptTypeScript compiler
ts-nodeDirect TypeScript execution

Performance Benchmarks

Stress-tested on a mid-range desktop to validate its performance and scalability under realistic conditions.

Test Configuration: Mid-Range Desktop (Intel i5-14400, 16GB RAM)

  • Test Scenario: 25 concurrent users, each sending 100 stateful requests (with result verification at each step).
  • Total Requests: 2,500
  • Throughput (RPS): ~32.8 req/s
  • Request Success Rate: 100%
  • State Verification Success Rate: 100%
  • P95 Latency: 496.50 ms
  • Test Parameters: The benchmark was conducted with the following runtime configuration:
    • MinIdleWorkers: 5
    • MaxTotalWorkers: 30
    • WorkerCPU: 1.0 core
    • WorkerRAM_MB: 1024 MB
    • WorkerDisk_MB: 500 MB

Result Charts

Test Summary Pie ChartLatency Distribution Chart

Architecture Overview

  1. API Gateway: The single, authenticated entry point. Its WorkerPool manages the entire lifecycle of worker instances, including the dynamic creation of their virtual disks. It acts as the trusted control plane.
  2. Worker Instance: An untrusted, disposable code execution unit. It runs a Supervisor that manages two processes (FastAPI service, Jupyter Kernel) as a non-root sandbox user. At startup, a script configures an iptables firewall to only accept traffic from the Gateway before dropping root privileges and mounting its dedicated virtual disk.

High-Level System ArchitectureRequest Flow Sequence Diagram

File Transfer Architecture

The system provides secure, high-performance file transfer capabilities via the Gateway's dual-mount architecture. This design allows the Gateway to directly access each worker's sandboxed filesystem without routing traffic through the untrusted worker container.

How It Works

 โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ Worker Container โ”‚
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚
โ”‚ Client โ”‚ โ”€โ”€โ”€ presigned URL โ”€โ”€โ”‚โ”€โ”€โ”‚ /sandbox (bind mount inside) โ”‚ โ”‚
โ”‚ (OSS) โ”‚ โ”‚ โ”‚ โ””โ”€โ”€ user_data.xlsx โ”‚ โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ โ”‚ โ””โ”€โ”€ output.png โ”‚ โ”‚
โ”‚ โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚
โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ”‚ โ”‚
โ”‚ โ”‚ (same block device)
โ”‚ โ–ผ
โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ HTTP PUT/GET โ”‚ Gateway Container โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚
โ”‚ โ”‚ /worker_mounts/{worker_id}/ โ”‚ โ”‚
โ”‚ โ”‚ โ””โ”€โ”€ user_data.xlsx โ”‚ โ”‚
โ”‚ โ”‚ โ””โ”€โ”€ output.png โ”‚ โ”‚
โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚
โ”‚ (host mount point) โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
  1. Upload: The Gateway downloads files from presigned URLs (e.g., OSS) and writes them directly to the worker's virtual disk via its own mount point (/worker_mounts/{worker_id}/).
  2. Export: The Gateway reads files from its mount point and uploads them to the presigned URL. Data never passes through the untrusted worker process.
  3. Delete: The Gateway directly removes files from the filesystem.

Security Features

FeatureImplementationThreat Mitigated
Path Traversal PreventionUses PurePosixPath.relative_to() to validate that all paths resolve within /sandbox. Rejects filenames containing / or \.Directory traversal attacks (e.g., ../../../etc/passwd)
SSRF ProtectionIntegrates ssrf-protect library to validate download URLs. Blocks requests to private IP ranges (10.x, 172.16.x, 192.168.x, 127.x) and internal hostnames.Server-Side Request Forgery
Redirect Bypass PreventionDisables HTTP redirects (allow_redirects=False) during file downloads.SSRF bypass via malicious redirects to internal services
Atomic WritesUploads use temp file + rename pattern to prevent partial/corrupted files on failure.Data corruption from interrupted transfers
File Size LimitsEnforces per-file size limit (default 100MB) with streaming validation. Aborts transfer immediately upon exceeding limit.Disk exhaustion attacks
Symlink Attack PreventionMounts virtual disk with nosymfollow option (Linux 5.10+). Verifies mount point is not a symlink before mounting.Symlink-based sandbox escapes
Concurrency ControlUses semaphore to limit concurrent file operations, preventing resource exhaustion.DoS via concurrent transfer floods

Quick Start

1. Prerequisites

  • Docker and Docker Compose installed and running.
  • An HTTP client (e.g., cURL, Postman, or Python's httpx).

2. Start the Service

Convenience scripts are provided to start the environment. You can customize the resource allocation and pool size via command-line arguments.

  • Linux / macOS:sh start.sh [options]
  • Windows (PowerShell):.\start.ps1 [options]

The gateway will listen on http://127.0.0.1:3874.

Customizing the Environment

You can pass the following parameters to the startup scripts to configure the system's behavior.

ParameterShell (.sh)PowerShell (.ps1)DefaultDescription
Min Idle Workers--min-idle-workers-MinIdleWorkers10The minimum number of idle, pre-warmed workers to keep ready in the pool.
Max Total Workers--max-total-workers-MaxTotalWorkers50The absolute maximum number of concurrent worker containers the system is allowed to create.
Worker CPU Limit--worker-cpu-WorkerCPU1.5The number of CPU cores to allocate to each worker container (e.g., 1.5 for one and a half cores).
Worker RAM Limit--worker-ram-mb-WorkerRAM_MB1536The amount of RAM in megabytes to allocate to each worker container.
Worker Disk Size--worker-disk-mb-WorkerDisk_MB500The size of the virtual disk in megabytes to create for each worker's sandboxed filesystem.

Note: Default resource limits have been increased to support Node.js, LibreOffice, and Playwright. For lightweight deployments without these features, you can reduce the limits.

Example (Linux/macOS):

# Start with a larger pool and more powerful workers
sh start.sh --min-idle-workers 10 --worker-cpu 2.0 --worker-ram-mb 2048

Example (Windows PowerShell):

# Start with a lightweight configuration for a low-resource environment
.\start.ps1 -MinIdleWorkers 2-MaxTotalWorkers 10-WorkerCPU 0.5-WorkerRAM_MB 512

3. Get the Auth Token

Retrieve the auto-generated token from the running gateway container:

docker exec code-interpreter_gateway cat /gateway/auth_token.txt

For a quick UI test, open the included test.html file in your browser, paste the token, and click "New Session".

4. Stop the Service

  • Linux / macOS:sh stop.sh
  • Windows (PowerShell):.\stop.ps1

API Documentation

All endpoints are prefixed with /api/v1. All requests require the X-Auth-Token: <your-token> header.

1. Execute Code POST /api/v1/execute?user_uuid={uuid}

Executes Python code within a user's stateful session.

  • Query Parameter: user_uuid (required) - UUID identifying the user session
  • Request Body: { "code": "string" }
  • Success Response (200 OK): { "worker_id": "string", "result_text": "string | null", "result_base64": "string | null" }
  • Timeout/Crash Response (503/504): Indicates a fatal error. The environment has been destroyed and recycled.

2. Release Session POST /api/v1/release?user_uuid={uuid}

Proactively terminates a user's session and destroys its worker.

  • Query Parameter: user_uuid (required) - UUID identifying the user session
  • Success Response (204 No Content)

3. Get System Status GET /api/v1/status (Admin)

Returns a summary of the worker pool's status for monitoring.

  • Success Response (200 OK):
    {
    "total_workers": 10,
    "busy_workers": 3,
    "is_initializing": false
    }

4. Batch Upload Files to Sandbox POST /api/v1/files?user_uuid={uuid}

Downloads files from presigned URLs and saves them to the user's worker sandbox. Supports batch operations with concurrent processing.

  • Query Parameter: user_uuid (required) - UUID identifying the user session
  • Limits: Max 100 files per request, max 100MB per file
  • Request Body:
    {
    "files": [
    {"download_url": "https://...", "path": "/sandbox/", "name": "data.xlsx"},
    {"download_url": "https://...", "path": "/sandbox/", "name": "image.png"}
    ]
    }
  • Success Response (201 Created):
    {
    "success": true,
    "results": [
    {"full_path": "/sandbox/data.xlsx", "size": 12345},
    {"full_path": "/sandbox/image.png", "size": 67890}
    ]
    }

5. Batch Export Files from Sandbox POST /api/v1/files/export?user_uuid={uuid}

Reads files from sandbox and uploads them to OSS via presigned URLs. Supports batch operations with concurrent processing.

  • Query Parameter: user_uuid (required) - UUID identifying the user session
  • Limits: Max 100 files per request
  • Request Body:
    {
    "files": [
    {"path": "/sandbox/", "name": "result.xlsx", "upload_url": "https://..."},
    {"path": "/sandbox/", "name": "chart.png", "upload_url": "https://..."}
    ]
    }
  • Success Response (200 OK):
    {
    "success": true,
    "results": [
    {"path": "/sandbox/", "name": "result.xlsx", "size": 8192},
    {"path": "/sandbox/", "name": "chart.png", "size": 54321}
    ]
    }

6. Batch Delete Files from Sandbox DELETE /api/v1/files?user_uuid={uuid}

Deletes files from the user's worker sandbox. Supports batch operations.

  • Query Parameter: user_uuid (required) - UUID identifying the user session
  • Limits: Max 100 files per request
  • Request Body:
    {
    "files": [
    {"path": "/sandbox/", "name": "temp.xlsx"},
    {"path": "/sandbox/", "name": "old.png"}
    ]
    }
  • Success Response (204 No Content)

Usage Example (Python)

importhttpximportasyncioimportuuidimportbase64importsubprocessGATEWAY_URL="http://127.0.0.1:3874"USER_ID=str(uuid.uuid4())
defget_auth_token():
try:
returnsubprocess.check_output(
["docker", "exec", "code-interpreter_gateway", "cat", "/gateway/auth_token.txt"],
text=True
).strip()
exceptException:
print("โŒ Could not fetch Auth Token. Is the service running?")
returnNoneasyncdefexecute_code(client: httpx.AsyncClient, code: str):
print(f"\n--- Executing ---\n{code.strip()}")
try:
response=awaitclient.post(
f"{GATEWAY_URL}/api/v1/execute",
params={"user_uuid": USER_ID},
json={"code": code},
timeout=30.0
)
response.raise_for_status()
data=response.json()
ifdata.get("result_text"):
print(">>> Text Result:\n"+data["result_text"])
ifdata.get("result_base64"):
print(">>> Image generated! (output.png saved)")
withopen("output.png", "wb") asf:
f.write(base64.b64decode(data["result_base64"]))
excepthttpx.HTTPStatusErrorase:
print(f"Execution failed: {e.response.status_code} - {e.response.text}")
asyncdefmain():
token=get_auth_token()
ifnottoken: returnheaders= {"X-Auth-Token": token}
asyncwithhttpx.AsyncClient(headers=headers) asclient:
# Step 1: Define a variableawaitexecute_code(client, "a = 100")
# Step 2: Use the variable from the previous step (state is maintained)awaitexecute_code(client, "print(f'The value of a is {a}')")
if__name__=="__main__":
asyncio.run(main())

License

This project is licensed under the MIT License.

About

๐Ÿš€ A stateful, secure, and scalable Python code sandbox via API. Built with a Gateway-Worker architecture using Docker for ultimate isolation and Jupyter Kernels for session persistence. / ๐Ÿš€ ไธ€ไธชๆœ‰็Šถๆ€ใ€้ซ˜ๅฎ‰ๅ…จๆ€ง็š„ๅฏไผธ็ผฉ Python ไปฃ็ ๆฒ™็ฎฑ๏ผŒ้€š่ฟ‡ API ๆไพ›ๆœๅŠกใ€‚้‡‡็”จโ€œ็ฝ‘ๅ…ณ-ๅทฅไฝœๅฎžไพ‹โ€ๆžถๆž„๏ผŒๅˆฉ็”จ Docker ๅฎž็Žฐๆž่‡ด้š”็ฆป๏ผŒๅนถ้€š่ฟ‡ Jupyter ๅ†…ๆ ธไฟๆŒไผš่ฏ็š„ๆŒไน…ๅŒ–ใ€‚

Resources

Stars

4 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Latest commit

History

43 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Code Interpreter API: A Stateful, Secure, and High-Performance Code Sandbox

ไธญๆ–‡็‰ˆ

This project provides a robust, API-driven code execution sandbox, engineered for high security, stateful session management, and strong performance. It utilizes a centralized API Gateway and a dynamic Worker Pool architecture, providing each user with a completely isolated and persistent execution session.

Now with dual-runtime support: Python 3.12 and Node.js 18 LTS, plus comprehensive document processing, browser automation, and 140+ pre-installed libraries.

A key technical feature of this project is its successful implementation of a "Virtual-Disk-per-Worker" architecture. This advanced model dynamically creates, formats, and mounts a dedicated virtual disk (.img file via losetup) for each worker container at runtime. This approach addresses the significant challenge of reliably managing dynamic block devices in a concurrent containerized environment, enabling superior I/O and filesystem isolation that is fundamental to the system's security posture.

Each worker is sandboxed within a multi-layered security model that includes strict resource limits, a zero-trust network policy, and runtime privilege reduction. By leveraging an internal Jupyter Kernel, it maintains the complete code execution context (variables, imports, functions) across multiple API calls, ensuring session continuity, security, and high performance.

Key Advantages

FeatureOur ApproachStandard Implementations (Common Trade-offs)
๐Ÿš€ PerformanceA pre-warmed pool of idle workers ensures instant session allocation. The fully asynchronous design (FastAPI, httpx) delivers high throughput (~32.8 RPS) and low latency.High latency due to on-demand container/environment startup for each new session. Often synchronous, leading to poor concurrency under load.
๐Ÿ”’ SecurityA multi-layered, zero-trust security model: no internet access (internal: true), inter-worker firewalls (iptables), gateway inaccessibility, and privilege drop (root to sandbox).Basic containerization often allows outbound internet access, lacks inter-worker firewalls (risk of lateral movement), and may run code with excessive privileges.
๐Ÿ”„ StatefulnessTrue session persistence. Each user is mapped to a dedicated worker with a persistent Jupyter Kernel, maintaining the full execution context across all API calls.Stateless (each call is a new environment) or emulated statefulness (e.g., saving/loading state via serialization), which is often slow and incomplete.
๐Ÿ› ๏ธ ReliabilityA "Cattle, not Pets" fault tolerance model. The gateway enforces hard timeouts and monitors worker health. Any failed, hung, or crashed worker is instantly destroyed and replaced.Workers are often treated as stateful "pets" that require complex recovery logic, increasing the risk of contaminated or inconsistent states persisting.
๐Ÿ’ก I/O IsolationVirtual-Disk-per-Worker Architecture. Each worker gets its own dynamically mounted block device, providing true filesystem and I/O isolation from the host and other workers.Often relies on shared host volumes (risk of cross-talk and security breaches) or has no persistent, isolated storage at all.

Built-in Capabilities

Each worker comes pre-loaded with a comprehensive set of tools and libraries. For a complete list, see worker/CAPABILITIES.md.

Runtime Environments

RuntimeVersionUse Case
Python3.12.12Primary execution environment with Jupyter Kernel
Node.js18 LTSJavaScript/TypeScript execution via subprocess

Pre-installed Libraries (140+)

CategoryKey LibrariesCapabilities
Scientific Computingnumpy, pandas, scipy, scikit-learn, statsmodelsData analysis, ML, statistics
Data Visualizationmatplotlib, seaborn, plotly, pyecharts, wordcloudCharts, graphs, interactive plots
Image ProcessingPIL, OpenCV, scikit-image, ImageMagick, rawpyImage editing, CV, RAW processing
Video Processingmoviepy, ffmpeg-python, PyAV, vidgearVideo editing, encoding, streaming
Audio Processingpydub, librosa, soundfile, pedalboardAudio editing, analysis, effects
Document Processingpython-docx, openpyxl, python-pptx, PyPDF2, pdfplumberOffice documents, PDF manipulation
Text & NLPjieba, pypinyin, thefuzz, fakerChinese NLP, fuzzy matching
Browser AutomationPlaywright + ChromiumWeb scraping, screenshots, testing

System Tools

ToolVersionCapabilities
LibreOfficeLatestDocument conversion (docx/xlsx/pptx โ†” PDF)
PandocLatestUniversal document converter (Markdown, LaTeX, etc.)
FFmpegLatestAudio/video encoding, transcoding, streaming
ImageMagickLatestImage conversion (200+ formats)
Tesseract OCRLatestText recognition (English + Chinese)
PopplerLatestPDF utilities (pdftotext, pdftoppm, etc.)
GhostscriptLatestPDF/PostScript processing

Node.js Packages (Global)

PackageUse Case
docxWord document creation
pptxgenjsPowerPoint generation
typescriptTypeScript compiler
ts-nodeDirect TypeScript execution

Performance Benchmarks

Stress-tested on a mid-range desktop to validate its performance and scalability under realistic conditions.

Test Configuration: Mid-Range Desktop (Intel i5-14400, 16GB RAM)

  • Test Scenario: 25 concurrent users, each sending 100 stateful requests (with result verification at each step).
  • Total Requests: 2,500
  • Throughput (RPS): ~32.8 req/s
  • Request Success Rate: 100%
  • State Verification Success Rate: 100%
  • P95 Latency: 496.50 ms
  • Test Parameters: The benchmark was conducted with the following runtime configuration:
    • MinIdleWorkers: 5
    • MaxTotalWorkers: 30
    • WorkerCPU: 1.0 core
    • WorkerRAM_MB: 1024 MB
    • WorkerDisk_MB: 500 MB

Result Charts

Test Summary Pie ChartLatency Distribution Chart

Architecture Overview

  1. API Gateway: The single, authenticated entry point. Its WorkerPool manages the entire lifecycle of worker instances, including the dynamic creation of their virtual disks. It acts as the trusted control plane.
  2. Worker Instance: An untrusted, disposable code execution unit. It runs a Supervisor that manages two processes (FastAPI service, Jupyter Kernel) as a non-root sandbox user. At startup, a script configures an iptables firewall to only accept traffic from the Gateway before dropping root privileges and mounting its dedicated virtual disk.

High-Level System ArchitectureRequest Flow Sequence Diagram

File Transfer Architecture

The system provides secure, high-performance file transfer capabilities via the Gateway's dual-mount architecture. This design allows the Gateway to directly access each worker's sandboxed filesystem without routing traffic through the untrusted worker container.

How It Works

 โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ Worker Container โ”‚
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚
โ”‚ Client โ”‚ โ”€โ”€โ”€ presigned URL โ”€โ”€โ”‚โ”€โ”€โ”‚ /sandbox (bind mount inside) โ”‚ โ”‚
โ”‚ (OSS) โ”‚ โ”‚ โ”‚ โ””โ”€โ”€ user_data.xlsx โ”‚ โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ โ”‚ โ””โ”€โ”€ output.png โ”‚ โ”‚
โ”‚ โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚
โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ”‚ โ”‚
โ”‚ โ”‚ (same block device)
โ”‚ โ–ผ
โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ HTTP PUT/GET โ”‚ Gateway Container โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚
โ”‚ โ”‚ /worker_mounts/{worker_id}/ โ”‚ โ”‚
โ”‚ โ”‚ โ””โ”€โ”€ user_data.xlsx โ”‚ โ”‚
โ”‚ โ”‚ โ””โ”€โ”€ output.png โ”‚ โ”‚
โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚
โ”‚ (host mount point) โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
  1. Upload: The Gateway downloads files from presigned URLs (e.g., OSS) and writes them directly to the worker's virtual disk via its own mount point (/worker_mounts/{worker_id}/).
  2. Export: The Gateway reads files from its mount point and uploads them to the presigned URL. Data never passes through the untrusted worker process.
  3. Delete: The Gateway directly removes files from the filesystem.

Security Features

FeatureImplementationThreat Mitigated
Path Traversal PreventionUses PurePosixPath.relative_to() to validate that all paths resolve within /sandbox. Rejects filenames containing / or \.Directory traversal attacks (e.g., ../../../etc/passwd)
SSRF ProtectionIntegrates ssrf-protect library to validate download URLs. Blocks requests to private IP ranges (10.x, 172.16.x, 192.168.x, 127.x) and internal hostnames.Server-Side Request Forgery
Redirect Bypass PreventionDisables HTTP redirects (allow_redirects=False) during file downloads.SSRF bypass via malicious redirects to internal services
Atomic WritesUploads use temp file + rename pattern to prevent partial/corrupted files on failure.Data corruption from interrupted transfers
File Size LimitsEnforces per-file size limit (default 100MB) with streaming validation. Aborts transfer immediately upon exceeding limit.Disk exhaustion attacks
Symlink Attack PreventionMounts virtual disk with nosymfollow option (Linux 5.10+). Verifies mount point is not a symlink before mounting.Symlink-based sandbox escapes
Concurrency ControlUses semaphore to limit concurrent file operations, preventing resource exhaustion.DoS via concurrent transfer floods

Quick Start

1. Prerequisites

  • Docker and Docker Compose installed and running.
  • An HTTP client (e.g., cURL, Postman, or Python's httpx).

2. Start the Service

Convenience scripts are provided to start the environment. You can customize the resource allocation and pool size via command-line arguments.

  • Linux / macOS:sh start.sh [options]
  • Windows (PowerShell):.\start.ps1 [options]

The gateway will listen on http://127.0.0.1:3874.

Customizing the Environment

You can pass the following parameters to the startup scripts to configure the system's behavior.

ParameterShell (.sh)PowerShell (.ps1)DefaultDescription
Min Idle Workers--min-idle-workers-MinIdleWorkers10The minimum number of idle, pre-warmed workers to keep ready in the pool.
Max Total Workers--max-total-workers-MaxTotalWorkers50The absolute maximum number of concurrent worker containers the system is allowed to create.
Worker CPU Limit--worker-cpu-WorkerCPU1.5The number of CPU cores to allocate to each worker container (e.g., 1.5 for one and a half cores).
Worker RAM Limit--worker-ram-mb-WorkerRAM_MB1536The amount of RAM in megabytes to allocate to each worker container.
Worker Disk Size--worker-disk-mb-WorkerDisk_MB500The size of the virtual disk in megabytes to create for each worker's sandboxed filesystem.

Note: Default resource limits have been increased to support Node.js, LibreOffice, and Playwright. For lightweight deployments without these features, you can reduce the limits.

Example (Linux/macOS):

# Start with a larger pool and more powerful workers
sh start.sh --min-idle-workers 10 --worker-cpu 2.0 --worker-ram-mb 2048

Example (Windows PowerShell):

# Start with a lightweight configuration for a low-resource environment
.\start.ps1 -MinIdleWorkers 2-MaxTotalWorkers 10-WorkerCPU 0.5-WorkerRAM_MB 512

3. Get the Auth Token

Retrieve the auto-generated token from the running gateway container:

docker exec code-interpreter_gateway cat /gateway/auth_token.txt

For a quick UI test, open the included test.html file in your browser, paste the token, and click "New Session".

4. Stop the Service

  • Linux / macOS:sh stop.sh
  • Windows (PowerShell):.\stop.ps1

API Documentation

All endpoints are prefixed with /api/v1. All requests require the X-Auth-Token: <your-token> header.

1. Execute Code POST /api/v1/execute?user_uuid={uuid}

Executes Python code within a user's stateful session.

  • Query Parameter: user_uuid (required) - UUID identifying the user session
  • Request Body: { "code": "string" }
  • Success Response (200 OK): { "worker_id": "string", "result_text": "string | null", "result_base64": "string | null" }
  • Timeout/Crash Response (503/504): Indicates a fatal error. The environment has been destroyed and recycled.

2. Release Session POST /api/v1/release?user_uuid={uuid}

Proactively terminates a user's session and destroys its worker.

  • Query Parameter: user_uuid (required) - UUID identifying the user session
  • Success Response (204 No Content)

3. Get System Status GET /api/v1/status (Admin)

Returns a summary of the worker pool's status for monitoring.

  • Success Response (200 OK):
    {
    "total_workers": 10,
    "busy_workers": 3,
    "is_initializing": false
    }

4. Batch Upload Files to Sandbox POST /api/v1/files?user_uuid={uuid}

Downloads files from presigned URLs and saves them to the user's worker sandbox. Supports batch operations with concurrent processing.

  • Query Parameter: user_uuid (required) - UUID identifying the user session
  • Limits: Max 100 files per request, max 100MB per file
  • Request Body:
    {
    "files": [
    {"download_url": "https://...", "path": "/sandbox/", "name": "data.xlsx"},
    {"download_url": "https://...", "path": "/sandbox/", "name": "image.png"}
    ]
    }
  • Success Response (201 Created):
    {
    "success": true,
    "results": [
    {"full_path": "/sandbox/data.xlsx", "size": 12345},
    {"full_path": "/sandbox/image.png", "size": 67890}
    ]
    }

5. Batch Export Files from Sandbox POST /api/v1/files/export?user_uuid={uuid}

Reads files from sandbox and uploads them to OSS via presigned URLs. Supports batch operations with concurrent processing.

  • Query Parameter: user_uuid (required) - UUID identifying the user session
  • Limits: Max 100 files per request
  • Request Body:
    {
    "files": [
    {"path": "/sandbox/", "name": "result.xlsx", "upload_url": "https://..."},
    {"path": "/sandbox/", "name": "chart.png", "upload_url": "https://..."}
    ]
    }
  • Success Response (200 OK):
    {
    "success": true,
    "results": [
    {"path": "/sandbox/", "name": "result.xlsx", "size": 8192},
    {"path": "/sandbox/", "name": "chart.png", "size": 54321}
    ]
    }

6. Batch Delete Files from Sandbox DELETE /api/v1/files?user_uuid={uuid}

Deletes files from the user's worker sandbox. Supports batch operations.

  • Query Parameter: user_uuid (required) - UUID identifying the user session
  • Limits: Max 100 files per request
  • Request Body:
    {
    "files": [
    {"path": "/sandbox/", "name": "temp.xlsx"},
    {"path": "/sandbox/", "name": "old.png"}
    ]
    }
  • Success Response (204 No Content)

Usage Example (Python)

importhttpximportasyncioimportuuidimportbase64importsubprocessGATEWAY_URL="http://127.0.0.1:3874"USER_ID=str(uuid.uuid4())
defget_auth_token():
try:
returnsubprocess.check_output(
["docker", "exec", "code-interpreter_gateway", "cat", "/gateway/auth_token.txt"],
text=True
).strip()
exceptException:
print("โŒ Could not fetch Auth Token. Is the service running?")
returnNoneasyncdefexecute_code(client: httpx.AsyncClient, code: str):
print(f"\n--- Executing ---\n{code.strip()}")
try:
response=awaitclient.post(
f"{GATEWAY_URL}/api/v1/execute",
params={"user_uuid": USER_ID},
json={"code": code},
timeout=30.0
)
response.raise_for_status()
data=response.json()
ifdata.get("result_text"):
print(">>> Text Result:\n"+data["result_text"])
ifdata.get("result_base64"):
print(">>> Image generated! (output.png saved)")
withopen("output.png", "wb") asf:
f.write(base64.b64decode(data["result_base64"]))
excepthttpx.HTTPStatusErrorase:
print(f"Execution failed: {e.response.status_code} - {e.response.text}")
asyncdefmain():
token=get_auth_token()
ifnottoken: returnheaders= {"X-Auth-Token": token}
asyncwithhttpx.AsyncClient(headers=headers) asclient:
# Step 1: Define a variableawaitexecute_code(client, "a = 100")
# Step 2: Use the variable from the previous step (state is maintained)awaitexecute_code(client, "print(f'The value of a is {a}')")
if__name__=="__main__":
asyncio.run(main())

License

This project is licensed under the MIT License.

About

๐Ÿš€ A stateful, secure, and scalable Python code sandbox via API. Built with a Gateway-Worker architecture using Docker for ultimate isolation and Jupyter Kernels for session persistence. / ๐Ÿš€ ไธ€ไธชๆœ‰็Šถๆ€ใ€้ซ˜ๅฎ‰ๅ…จๆ€ง็š„ๅฏไผธ็ผฉ Python ไปฃ็ ๆฒ™็ฎฑ๏ผŒ้€š่ฟ‡ API ๆไพ›ๆœๅŠกใ€‚้‡‡็”จโ€œ็ฝ‘ๅ…ณ-ๅทฅไฝœๅฎžไพ‹โ€ๆžถๆž„๏ผŒๅˆฉ็”จ Docker ๅฎž็Žฐๆž่‡ด้š”็ฆป๏ผŒๅนถ้€š่ฟ‡ Jupyter ๅ†…ๆ ธไฟๆŒไผš่ฏ็š„ๆŒไน…ๅŒ–ใ€‚

Resources

Stars

4 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Latest commit

History

43 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Code Interpreter API: A Stateful, Secure, and High-Performance Code Sandbox

ไธญๆ–‡็‰ˆ

This project provides a robust, API-driven code execution sandbox, engineered for high security, stateful session management, and strong performance. It utilizes a centralized API Gateway and a dynamic Worker Pool architecture, providing each user with a completely isolated and persistent execution session.

Now with dual-runtime support: Python 3.12 and Node.js 18 LTS, plus comprehensive document processing, browser automation, and 140+ pre-installed libraries.

A key technical feature of this project is its successful implementation of a "Virtual-Disk-per-Worker" architecture. This advanced model dynamically creates, formats, and mounts a dedicated virtual disk (.img file via losetup) for each worker container at runtime. This approach addresses the significant challenge of reliably managing dynamic block devices in a concurrent containerized environment, enabling superior I/O and filesystem isolation that is fundamental to the system's security posture.

Each worker is sandboxed within a multi-layered security model that includes strict resource limits, a zero-trust network policy, and runtime privilege reduction. By leveraging an internal Jupyter Kernel, it maintains the complete code execution context (variables, imports, functions) across multiple API calls, ensuring session continuity, security, and high performance.

Key Advantages

FeatureOur ApproachStandard Implementations (Common Trade-offs)
๐Ÿš€ PerformanceA pre-warmed pool of idle workers ensures instant session allocation. The fully asynchronous design (FastAPI, httpx) delivers high throughput (~32.8 RPS) and low latency.High latency due to on-demand container/environment startup for each new session. Often synchronous, leading to poor concurrency under load.
๐Ÿ”’ SecurityA multi-layered, zero-trust security model: no internet access (internal: true), inter-worker firewalls (iptables), gateway inaccessibility, and privilege drop (root to sandbox).Basic containerization often allows outbound internet access, lacks inter-worker firewalls (risk of lateral movement), and may run code with excessive privileges.
๐Ÿ”„ StatefulnessTrue session persistence. Each user is mapped to a dedicated worker with a persistent Jupyter Kernel, maintaining the full execution context across all API calls.Stateless (each call is a new environment) or emulated statefulness (e.g., saving/loading state via serialization), which is often slow and incomplete.
๐Ÿ› ๏ธ ReliabilityA "Cattle, not Pets" fault tolerance model. The gateway enforces hard timeouts and monitors worker health. Any failed, hung, or crashed worker is instantly destroyed and replaced.Workers are often treated as stateful "pets" that require complex recovery logic, increasing the risk of contaminated or inconsistent states persisting.
๐Ÿ’ก I/O IsolationVirtual-Disk-per-Worker Architecture. Each worker gets its own dynamically mounted block device, providing true filesystem and I/O isolation from the host and other workers.Often relies on shared host volumes (risk of cross-talk and security breaches) or has no persistent, isolated storage at all.

Built-in Capabilities

Each worker comes pre-loaded with a comprehensive set of tools and libraries. For a complete list, see worker/CAPABILITIES.md.

Runtime Environments

RuntimeVersionUse Case
Python3.12.12Primary execution environment with Jupyter Kernel
Node.js18 LTSJavaScript/TypeScript execution via subprocess

Pre-installed Libraries (140+)

CategoryKey LibrariesCapabilities
Scientific Computingnumpy, pandas, scipy, scikit-learn, statsmodelsData analysis, ML, statistics
Data Visualizationmatplotlib, seaborn, plotly, pyecharts, wordcloudCharts, graphs, interactive plots
Image ProcessingPIL, OpenCV, scikit-image, ImageMagick, rawpyImage editing, CV, RAW processing
Video Processingmoviepy, ffmpeg-python, PyAV, vidgearVideo editing, encoding, streaming
Audio Processingpydub, librosa, soundfile, pedalboardAudio editing, analysis, effects
Document Processingpython-docx, openpyxl, python-pptx, PyPDF2, pdfplumberOffice documents, PDF manipulation
Text & NLPjieba, pypinyin, thefuzz, fakerChinese NLP, fuzzy matching
Browser AutomationPlaywright + ChromiumWeb scraping, screenshots, testing

System Tools

ToolVersionCapabilities
LibreOfficeLatestDocument conversion (docx/xlsx/pptx โ†” PDF)
PandocLatestUniversal document converter (Markdown, LaTeX, etc.)
FFmpegLatestAudio/video encoding, transcoding, streaming
ImageMagickLatestImage conversion (200+ formats)
Tesseract OCRLatestText recognition (English + Chinese)
PopplerLatestPDF utilities (pdftotext, pdftoppm, etc.)
GhostscriptLatestPDF/PostScript processing

Node.js Packages (Global)

PackageUse Case
docxWord document creation
pptxgenjsPowerPoint generation
typescriptTypeScript compiler
ts-nodeDirect TypeScript execution

Performance Benchmarks

Stress-tested on a mid-range desktop to validate its performance and scalability under realistic conditions.

Test Configuration: Mid-Range Desktop (Intel i5-14400, 16GB RAM)

  • Test Scenario: 25 concurrent users, each sending 100 stateful requests (with result verification at each step).
  • Total Requests: 2,500
  • Throughput (RPS): ~32.8 req/s
  • Request Success Rate: 100%
  • State Verification Success Rate: 100%
  • P95 Latency: 496.50 ms
  • Test Parameters: The benchmark was conducted with the following runtime configuration:
    • MinIdleWorkers: 5
    • MaxTotalWorkers: 30
    • WorkerCPU: 1.0 core
    • WorkerRAM_MB: 1024 MB
    • WorkerDisk_MB: 500 MB

Result Charts

Test Summary Pie ChartLatency Distribution Chart

Architecture Overview

  1. API Gateway: The single, authenticated entry point. Its WorkerPool manages the entire lifecycle of worker instances, including the dynamic creation of their virtual disks. It acts as the trusted control plane.
  2. Worker Instance: An untrusted, disposable code execution unit. It runs a Supervisor that manages two processes (FastAPI service, Jupyter Kernel) as a non-root sandbox user. At startup, a script configures an iptables firewall to only accept traffic from the Gateway before dropping root privileges and mounting its dedicated virtual disk.

High-Level System ArchitectureRequest Flow Sequence Diagram

File Transfer Architecture

The system provides secure, high-performance file transfer capabilities via the Gateway's dual-mount architecture. This design allows the Gateway to directly access each worker's sandboxed filesystem without routing traffic through the untrusted worker container.

How It Works

 โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ Worker Container โ”‚
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚
โ”‚ Client โ”‚ โ”€โ”€โ”€ presigned URL โ”€โ”€โ”‚โ”€โ”€โ”‚ /sandbox (bind mount inside) โ”‚ โ”‚
โ”‚ (OSS) โ”‚ โ”‚ โ”‚ โ””โ”€โ”€ user_data.xlsx โ”‚ โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ โ”‚ โ””โ”€โ”€ output.png โ”‚ โ”‚
โ”‚ โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚
โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ”‚ โ”‚
โ”‚ โ”‚ (same block device)
โ”‚ โ–ผ
โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ HTTP PUT/GET โ”‚ Gateway Container โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚
โ”‚ โ”‚ /worker_mounts/{worker_id}/ โ”‚ โ”‚
โ”‚ โ”‚ โ””โ”€โ”€ user_data.xlsx โ”‚ โ”‚
โ”‚ โ”‚ โ””โ”€โ”€ output.png โ”‚ โ”‚
โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚
โ”‚ (host mount point) โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
  1. Upload: The Gateway downloads files from presigned URLs (e.g., OSS) and writes them directly to the worker's virtual disk via its own mount point (/worker_mounts/{worker_id}/).
  2. Export: The Gateway reads files from its mount point and uploads them to the presigned URL. Data never passes through the untrusted worker process.
  3. Delete: The Gateway directly removes files from the filesystem.

Security Features

FeatureImplementationThreat Mitigated
Path Traversal PreventionUses PurePosixPath.relative_to() to validate that all paths resolve within /sandbox. Rejects filenames containing / or \.Directory traversal attacks (e.g., ../../../etc/passwd)
SSRF ProtectionIntegrates ssrf-protect library to validate download URLs. Blocks requests to private IP ranges (10.x, 172.16.x, 192.168.x, 127.x) and internal hostnames.Server-Side Request Forgery
Redirect Bypass PreventionDisables HTTP redirects (allow_redirects=False) during file downloads.SSRF bypass via malicious redirects to internal services
Atomic WritesUploads use temp file + rename pattern to prevent partial/corrupted files on failure.Data corruption from interrupted transfers
File Size LimitsEnforces per-file size limit (default 100MB) with streaming validation. Aborts transfer immediately upon exceeding limit.Disk exhaustion attacks
Symlink Attack PreventionMounts virtual disk with nosymfollow option (Linux 5.10+). Verifies mount point is not a symlink before mounting.Symlink-based sandbox escapes
Concurrency ControlUses semaphore to limit concurrent file operations, preventing resource exhaustion.DoS via concurrent transfer floods

Quick Start

1. Prerequisites

  • Docker and Docker Compose installed and running.
  • An HTTP client (e.g., cURL, Postman, or Python's httpx).

2. Start the Service

Convenience scripts are provided to start the environment. You can customize the resource allocation and pool size via command-line arguments.

  • Linux / macOS:sh start.sh [options]
  • Windows (PowerShell):.\start.ps1 [options]

The gateway will listen on http://127.0.0.1:3874.

Customizing the Environment

You can pass the following parameters to the startup scripts to configure the system's behavior.

ParameterShell (.sh)PowerShell (.ps1)DefaultDescription
Min Idle Workers--min-idle-workers-MinIdleWorkers10The minimum number of idle, pre-warmed workers to keep ready in the pool.
Max Total Workers--max-total-workers-MaxTotalWorkers50The absolute maximum number of concurrent worker containers the system is allowed to create.
Worker CPU Limit--worker-cpu-WorkerCPU1.5The number of CPU cores to allocate to each worker container (e.g., 1.5 for one and a half cores).
Worker RAM Limit--worker-ram-mb-WorkerRAM_MB1536The amount of RAM in megabytes to allocate to each worker container.
Worker Disk Size--worker-disk-mb-WorkerDisk_MB500The size of the virtual disk in megabytes to create for each worker's sandboxed filesystem.

Note: Default resource limits have been increased to support Node.js, LibreOffice, and Playwright. For lightweight deployments without these features, you can reduce the limits.

Example (Linux/macOS):

# Start with a larger pool and more powerful workers
sh start.sh --min-idle-workers 10 --worker-cpu 2.0 --worker-ram-mb 2048

Example (Windows PowerShell):

# Start with a lightweight configuration for a low-resource environment
.\start.ps1 -MinIdleWorkers 2-MaxTotalWorkers 10-WorkerCPU 0.5-WorkerRAM_MB 512

3. Get the Auth Token

Retrieve the auto-generated token from the running gateway container:

docker exec code-interpreter_gateway cat /gateway/auth_token.txt

For a quick UI test, open the included test.html file in your browser, paste the token, and click "New Session".

4. Stop the Service

  • Linux / macOS:sh stop.sh
  • Windows (PowerShell):.\stop.ps1

API Documentation

All endpoints are prefixed with /api/v1. All requests require the X-Auth-Token: <your-token> header.

1. Execute Code POST /api/v1/execute?user_uuid={uuid}

Executes Python code within a user's stateful session.

  • Query Parameter: user_uuid (required) - UUID identifying the user session
  • Request Body: { "code": "string" }
  • Success Response (200 OK): { "worker_id": "string", "result_text": "string | null", "result_base64": "string | null" }
  • Timeout/Crash Response (503/504): Indicates a fatal error. The environment has been destroyed and recycled.

2. Release Session POST /api/v1/release?user_uuid={uuid}

Proactively terminates a user's session and destroys its worker.

  • Query Parameter: user_uuid (required) - UUID identifying the user session
  • Success Response (204 No Content)

3. Get System Status GET /api/v1/status (Admin)

Returns a summary of the worker pool's status for monitoring.

  • Success Response (200 OK):
    {
    "total_workers": 10,
    "busy_workers": 3,
    "is_initializing": false
    }

4. Batch Upload Files to Sandbox POST /api/v1/files?user_uuid={uuid}

Downloads files from presigned URLs and saves them to the user's worker sandbox. Supports batch operations with concurrent processing.

  • Query Parameter: user_uuid (required) - UUID identifying the user session
  • Limits: Max 100 files per request, max 100MB per file
  • Request Body:
    {
    "files": [
    {"download_url": "https://...", "path": "/sandbox/", "name": "data.xlsx"},
    {"download_url": "https://...", "path": "/sandbox/", "name": "image.png"}
    ]
    }
  • Success Response (201 Created):
    {
    "success": true,
    "results": [
    {"full_path": "/sandbox/data.xlsx", "size": 12345},
    {"full_path": "/sandbox/image.png", "size": 67890}
    ]
    }

5. Batch Export Files from Sandbox POST /api/v1/files/export?user_uuid={uuid}

Reads files from sandbox and uploads them to OSS via presigned URLs. Supports batch operations with concurrent processing.

  • Query Parameter: user_uuid (required) - UUID identifying the user session
  • Limits: Max 100 files per request
  • Request Body:
    {
    "files": [
    {"path": "/sandbox/", "name": "result.xlsx", "upload_url": "https://..."},
    {"path": "/sandbox/", "name": "chart.png", "upload_url": "https://..."}
    ]
    }
  • Success Response (200 OK):
    {
    "success": true,
    "results": [
    {"path": "/sandbox/", "name": "result.xlsx", "size": 8192},
    {"path": "/sandbox/", "name": "chart.png", "size": 54321}
    ]
    }

6. Batch Delete Files from Sandbox DELETE /api/v1/files?user_uuid={uuid}

Deletes files from the user's worker sandbox. Supports batch operations.

  • Query Parameter: user_uuid (required) - UUID identifying the user session
  • Limits: Max 100 files per request
  • Request Body:
    {
    "files": [
    {"path": "/sandbox/", "name": "temp.xlsx"},
    {"path": "/sandbox/", "name": "old.png"}
    ]
    }
  • Success Response (204 No Content)

Usage Example (Python)

importhttpximportasyncioimportuuidimportbase64importsubprocessGATEWAY_URL="http://127.0.0.1:3874"USER_ID=str(uuid.uuid4())
defget_auth_token():
try:
returnsubprocess.check_output(
["docker", "exec", "code-interpreter_gateway", "cat", "/gateway/auth_token.txt"],
text=True
).strip()
exceptException:
print("โŒ Could not fetch Auth Token. Is the service running?")
returnNoneasyncdefexecute_code(client: httpx.AsyncClient, code: str):
print(f"\n--- Executing ---\n{code.strip()}")
try:
response=awaitclient.post(
f"{GATEWAY_URL}/api/v1/execute",
params={"user_uuid": USER_ID},
json={"code": code},
timeout=30.0
)
response.raise_for_status()
data=response.json()
ifdata.get("result_text"):
print(">>> Text Result:\n"+data["result_text"])
ifdata.get("result_base64"):
print(">>> Image generated! (output.png saved)")
withopen("output.png", "wb") asf:
f.write(base64.b64decode(data["result_base64"]))
excepthttpx.HTTPStatusErrorase:
print(f"Execution failed: {e.response.status_code} - {e.response.text}")
asyncdefmain():
token=get_auth_token()
ifnottoken: returnheaders= {"X-Auth-Token": token}
asyncwithhttpx.AsyncClient(headers=headers) asclient:
# Step 1: Define a variableawaitexecute_code(client, "a = 100")
# Step 2: Use the variable from the previous step (state is maintained)awaitexecute_code(client, "print(f'The value of a is {a}')")
if__name__=="__main__":
asyncio.run(main())

License

This project is licensed under the MIT License.

About

๐Ÿš€ A stateful, secure, and scalable Python code sandbox via API. Built with a Gateway-Worker architecture using Docker for ultimate isolation and Jupyter Kernels for session persistence. / ๐Ÿš€ ไธ€ไธชๆœ‰็Šถๆ€ใ€้ซ˜ๅฎ‰ๅ…จๆ€ง็š„ๅฏไผธ็ผฉ Python ไปฃ็ ๆฒ™็ฎฑ๏ผŒ้€š่ฟ‡ API ๆไพ›ๆœๅŠกใ€‚้‡‡็”จโ€œ็ฝ‘ๅ…ณ-ๅทฅไฝœๅฎžไพ‹โ€ๆžถๆž„๏ผŒๅˆฉ็”จ Docker ๅฎž็Žฐๆž่‡ด้š”็ฆป๏ผŒๅนถ้€š่ฟ‡ Jupyter ๅ†…ๆ ธไฟๆŒไผš่ฏ็š„ๆŒไน…ๅŒ–ใ€‚

Resources

Stars

4 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages