Skip to main content

Secure isolated code execution SDK for Python

Project description

fermion-sandbox

Secure isolated code execution SDK for Python. Run untrusted code, build projects, or host services in ephemeral containers.

Installation

pip install fermion-sandbox

Quick Start

import asyncio
import os
from fermion_sandbox import Sandbox

async def main():
    # Get API key from environment
    api_key = os.getenv('FERMION_API_KEY')
    if not api_key:
        raise ValueError("FERMION_API_KEY environment variable is required")

    # Create sandbox
    sandbox = Sandbox(api_key=api_key)
    await sandbox.create(should_backup_filesystem=False)

    # Execute commands
    result = await sandbox.run_command(cmd='node', args=['--version'])
    print(result.stdout)

    # Write and read files
    await sandbox.write_file(
        path='~/script.js',
        content='console.log("Hello World")'
    )

    response = await sandbox.get_file('~/script.js')
    content = response.text

    # Clean up
    await sandbox.disconnect()

asyncio.run(main())

Note: Set your API key as an environment variable: export FERMION_API_KEY='your-api-key'

Key Features

  • Isolated containers - Secure Linux environments for code execution
  • Real-time streaming - WebSocket-based command output streaming
  • File operations - Read/write files with binary support
  • Public URLs - Expose ports 3000, 1337, 1338 for web services
  • Git support - Clone repositories on container startup
  • Type safety - Full type hints with Pydantic models
  • Async/await - Built on asyncio for modern Python applications

Core API

Creating a Sandbox

sandbox = Sandbox(api_key='your-api-key')

# New container
await sandbox.create(
    should_backup_filesystem=False,  # Persist filesystem after shutdown
    git_repo_url='https://github.com/user/repo.git'  # Optional
)

# Or connect to existing
await sandbox.from_snippet('snippet-id')

Running Commands

# Quick commands (< 5 seconds)
result = await sandbox.run_command(
    cmd='ls',
    args=['-la']
)
print(result.stdout, result.stderr)

# Long-running with streaming
result = await sandbox.run_streaming_command(
    cmd='npm',
    args=['install'],
    on_stdout=lambda data: print(data),
    on_stderr=lambda data: print(data)
)
print(f"Exit code: {result.exit_code}")

File Operations

# Write file
await sandbox.write_file(
    path='~/app.js',
    content='console.log("Hello")'
)

# Read file
response = await sandbox.get_file('~/app.js')
text = response.text
binary_data = response.content

Web Services

# Start a server
asyncio.create_task(sandbox.run_streaming_command(
    cmd='node',
    args=['server.js']
))

# Get public URL
url = await sandbox.expose_port(3000)
print(f'Live at: {url}')
# https://abc123-3000.run-code.com

Quick Code Execution

from fermion_sandbox import decode_base64url

# Execute code without full sandbox
result = await sandbox.quick_run(
    runtime='Python',
    source_code='print("Hello, World!")'
)

if result.run_result and result.run_result.program_run_data:
    stdout = decode_base64url(result.run_result.program_run_data.stdout_base64_url_encoded)
    print(stdout)

Examples

Run a Node.js Project

import asyncio
from fermion_sandbox import Sandbox

async def main():
    sandbox = Sandbox(api_key='your-api-key')
    await sandbox.create(
        should_backup_filesystem=False,
        git_repo_url='https://github.com/user/node-app.git'
    )

    # Install dependencies
    await sandbox.run_streaming_command(
        cmd='npm',
        args=['install'],
        on_stdout=lambda data: print(data.strip())
    )

    # Build project
    await sandbox.run_command(cmd='npm', args=['run', 'build'])

    # Start server
    asyncio.create_task(sandbox.run_streaming_command(
        cmd='npm',
        args=['start']
    ))

    # Get public URL
    url = await sandbox.expose_port(3000)
    print(f'App running at: {url}')

    # Keep running
    await asyncio.sleep(60)
    await sandbox.disconnect()

asyncio.run(main())

Execute C++ Code

from fermion_sandbox import Sandbox, decode_base64url

async def main():
    sandbox = Sandbox(api_key='your-api-key')

    result = await sandbox.quick_run(
        runtime='C++',
        source_code='''
            #include <iostream>
            using namespace std;
            int main() {
                int a, b;
                cin >> a >> b;
                cout << a + b << endl;
                return 0;
            }
        ''',
        stdin='5 3',
        expected_output='8'
    )

    print(f"Status: {result.run_result.run_status}")
    stdout = decode_base64url(result.run_result.program_run_data.stdout_base64_url_encoded)
    print(f"Output: {stdout}")

asyncio.run(main())

API Reference

Sandbox Class

Constructor

Sandbox(api_key: str)

Initialize sandbox client with API key.

Methods

async create(should_backup_filesystem: bool, git_repo_url: Optional[str] = None) -> str

  • Create new container
  • Returns: snippet ID

async from_snippet(playground_snippet_id: str) -> None

  • Connect to existing container

async run_command(cmd: str, args: Optional[list[str]] = None) -> CommandResult

  • Execute command (< 5s timeout)
  • Returns: CommandResult with stdout, stderr

async run_streaming_command(...) -> CommandResult

  • Execute with streaming output
  • Callbacks: on_stdout, on_stderr
  • Returns: CommandResult with stdout, stderr, exit_code

async write_file(path: str, content: Union[str, bytes]) -> None

  • Write file to container

async get_file(path: str) -> httpx.Response

  • Read file from container
  • Returns: Response object (use .text or .content)

async expose_port(port: Literal[3000, 1337, 1338]) -> str

  • Get public URL for port

get_public_urls() -> Dict[int, str]

  • Get all available public URLs

async disconnect() -> None

  • Clean up resources

is_connected() -> bool

  • Check connection status

async quick_run(...) -> DsaExecutionResult

  • Execute code without full sandbox
  • Supported runtimes: C, C++, Java, Python, Node.js, SQLite, MySQL, Go, Rust, .NET

File Paths

All paths must start with ~ (home) or /home/damner:

  • ~/file.js/home/damner/file.js
  • /home/damner/app/index.js → absolute path
  • /home/damner/code/app/index.js → also supported (nested under home)

Supported Ports

Public URLs available for:

  • Port 3000
  • Port 1337
  • Port 1338

Requirements

  • Python 3.8+
  • httpx
  • websockets
  • pydantic

Development

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

# Run tests
pytest

# Format code
black fermion_sandbox/

# Type checking
mypy fermion_sandbox/

Examples Directory

Check the examples/ directory for more usage examples:

  • basic_usage.py - Basic commands and file operations
  • streaming_command.py - Real-time streaming output
  • quick_run.py - Quick code execution
  • web_server.py - Running web servers with public URLs

Running Examples

Set your API key and run any example:

# Set API key inline (recommended)
FERMION_API_KEY='your-api-key' python examples/basic_usage.py

# Or export for current terminal session
export FERMION_API_KEY='your-api-key'
python examples/basic_usage.py

Running Tests

# Unit tests (no API key needed)
pytest tests/test_utils.py tests/test_types.py

# Integration tests (API key required)
FERMION_API_KEY='your-api-key' pytest tests/test_integration.py

# All tests
FERMION_API_KEY='your-api-key' pytest tests/

License

MIT

Support

For issues and questions, visit GitHub Issues.

Related

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

fermion_sandbox-0.1.0.tar.gz (29.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

fermion_sandbox-0.1.0-py3-none-any.whl (23.5 kB view details)

Uploaded Python 3

File details

Details for the file fermion_sandbox-0.1.0.tar.gz.

File metadata

  • Download URL: fermion_sandbox-0.1.0.tar.gz
  • Upload date:
  • Size: 29.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.4

File hashes

Hashes for fermion_sandbox-0.1.0.tar.gz
Algorithm Hash digest
SHA256 c662477384e9c07c2c56a3db2e8575f3899feba109a2628e0ee8abc9e29382ae
MD5 7193878c3cdffeb4e0f169fb28398dba
BLAKE2b-256 7c0b77905966b2900c1fe8d14c518dce524b8e0ca5985c9adeab42df4bfba501

See more details on using hashes here.

File details

Details for the file fermion_sandbox-0.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for fermion_sandbox-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 aed9a93d720219cadfb67a705699b13487cca27ce6bc462c59ca7b94347c0ad3
MD5 35abe443c03be705ca70d26d75a641b0
BLAKE2b-256 676688af6de8b9b3d6434ca5fca0641723d90b51f192be8e0de31c2ac43d7bd4

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page