Official Python client for Runbox - secure code execution API
Project description
Runbox Python Client
Official Python client for Runbox - a fast, secure API for running code in isolated containers.
Installation
pip install runbox-py
Quick Start
from runbox_client import Client
# Create a client
client = Client(
url="http://localhost:8080",
api_key="your-api-key"
)
# Step 1: Set up a container and get environment info
setup = client.setup(
identifier="my-session",
language="python"
)
print(setup.container_id) # => "runbox-my-session-python"
print(setup.environment_snapshot.runtime_version) # => "3.11.6"
print(setup.environment_snapshot.packages["requests"]) # => "2.31.0"
# Step 2: Run code in the container
result = client.run(
container_id=setup.container_id,
files=[{"path": "main.py", "content": "print('Hello!')"}],
run_command="python main.py"
)
print(result.stdout) # => "Hello!\n"
print(result.success) # => True
Configuration
Using Environment Variables
export RUNBOX_URL=http://localhost:8080
export RUNBOX_API_KEY=your-api-key
from runbox_client import Client
# Will use environment variables
client = Client()
Explicit Configuration
client = Client(
url="http://localhost:8080",
api_key="your-api-key",
timeout=120 # HTTP timeout in seconds
)
Usage
Setting Up a Container
setup = client.setup(
identifier="session-123",
language="python",
env={"API_KEY": "secret"}, # Optional: environment variables
memory="512m", # Optional: memory limit
network_allow=["api.stripe.com"] # Optional: allowed network destinations
)
# Access environment information
print(setup.container_id) # => "runbox-session-123-python"
print(setup.cached) # => False (True if container was reused)
env = setup.environment_snapshot
print(env.os_name) # => "debian"
print(env.os_version) # => "12"
print(env.runtime_name) # => "python"
print(env.runtime_version) # => "3.11.6"
print(env.packages) # => {"pip": "23.0.1", "requests": "2.31.0", ...}
Running Code
result = client.run(
container_id="runbox-session-123-python",
files=[{"path": "main.py", "content": "print('Hello!')"}],
run_command="python main.py",
env={"DEBUG": "true"}, # Optional: runtime environment variables
timeout=30 # Optional: execution timeout in seconds
)
print(result.success) # => True
print(result.exit_code) # => 0
print(result.stdout) # => "Hello!\n"
print(result.stderr) # => ""
print(result.execution_time_ms) # => 42
print(result.timed_out) # => False
Installing Dependencies On-The-Fly
Install new dependencies before running code:
# Python example
result = client.run(
container_id=container_id,
files=[{"path": "main.py", "content": "import requests; print(requests.__version__)"}],
run_command="python main.py",
new_dependencies=["requests==2.31.0", "pytest"]
)
print(result.packages) # => {"pip": "23.0.1", "requests": "2.31.0", "pytest": "7.4.0", ...}
# Ruby example
result = client.run(
container_id=container_id,
files=[{"path": "main.rb", "content": "require 'rake'; puts Rake::VERSION"}],
run_command="ruby main.rb",
new_dependencies=["rake", "rspec"]
)
# Shell example (uses apk)
result = client.run(
container_id=container_id,
files=[{"path": "script.sh", "content": "#!/bin/sh\ncurl --version"}],
run_command="sh script.sh",
new_dependencies=["curl", "jq", "git"]
)
Note: The packages field is only included in the result when new_dependencies are provided.
Async Support
import asyncio
from runbox_client import AsyncClient
async def main():
async with AsyncClient(url="http://localhost:8080", api_key="your-api-key") as client:
# Setup container
setup = await client.setup(
identifier="session-123",
language="python"
)
# Run code
result = await client.run(
container_id=setup.container_id,
files=[{"path": "main.py", "content": "print('Hello!')"}],
run_command="python main.py"
)
print(result.stdout)
asyncio.run(main())
Cleanup Containers
deleted = client.delete_containers("session-123")
print(deleted) # => ["runbox-session-123-python"]
Check Health
health = client.health()
print(health.status) # => "healthy"
print(health.version) # => "1.0.0"
API Reference
client.setup(identifier, language, **options)
Set up a container and get environment information.
Parameters:
identifier(str, required): Unique identifier for container reuselanguage(str, required): Programming language ("python","ruby","shell")env(dict, optional): Environment variables to settimeout(int, optional): Default timeout in secondsmemory(str, optional): Memory limit (e.g.,"256m","1g")network_allow(list[str], optional): Allowed network destinations
Returns: SetupResult with:
container_id: Container ID to use inrun()callscached: Whether container was reusedenvironment_snapshot: Environment information (OS, runtime, packages)
client.run(container_id, files, run_command, **options)
Run code in a container that was set up via setup().
Parameters:
container_id(str, required): Container ID fromsetup()responsefiles(list[dict], required): Files to write before runningrun_command(str, required): Command to runenv(dict, optional): Runtime environment variablestimeout(int, optional): Execution timeout in seconds
Returns: RunResult with:
success: Whether run succeeded (exit code 0)exit_code: Process exit codestdout: Standard outputstderr: Standard errorexecution_time_ms: Execution time in millisecondstimed_out: Whether run timed out
Error Handling
from runbox_client import (
Client,
AuthenticationError,
NotFoundError,
ValidationError,
RunError,
ConnectionError,
)
try:
setup = client.setup(identifier="test", language="python")
result = client.run(
container_id=setup.container_id,
files=[{"path": "main.py", "content": "print('hi')"}],
run_command="python main.py"
)
except AuthenticationError:
print("Invalid API key")
except NotFoundError:
print("Container not found (did you call setup first?)")
except ValidationError as e:
print(f"Invalid request: {e}")
except RunError as e:
print(f"Run failed: {e}")
except ConnectionError as e:
print(f"Could not connect: {e}")
Development
Setup
python3 -m venv venv
source venv/bin/activate
pip install -e ".[dev]"
Running Tests
pytest
Running Integration Tests
Integration tests require a running Runbox server:
# Start Runbox server (in another terminal)
cd ../runbox
docker-compose up
# Run integration tests
export RUNBOX_URL=http://localhost:8080
export RUNBOX_API_KEY=your-api-key
python examples/integration_test.py
Linting & Typing
ruff check .
mypy src
CI/CD
-
CI: Runs on every push and PR
- Tests on Python 3.9, 3.10, 3.11, 3.12
- Linting with Ruff
- Type checking with MyPy
- Integration tests against live Runbox server
-
CD: Publishes to PyPI on version tags
- Create a tag:
git tag v1.0.0 && git push --tags - Uses Trusted Publishing
- Create a tag:
License
MIT License - see LICENSE for details.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file runbox_py-1.1.1.tar.gz.
File metadata
- Download URL: runbox_py-1.1.1.tar.gz
- Upload date:
- Size: 11.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
50793a9ec82ce550941b313dffd590e072492a8be0e0b30518616fd0107d40f9
|
|
| MD5 |
0a78d6530f5bdf9ea7d8cc63fc7bf1a3
|
|
| BLAKE2b-256 |
b0ccaa239a4a70878341201f131a28494828a5e1a86c92f64d92d406a324db89
|
Provenance
The following attestation bundles were made for runbox_py-1.1.1.tar.gz:
Publisher:
cd.yml on kaka-ruto/runbox-py
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
runbox_py-1.1.1.tar.gz -
Subject digest:
50793a9ec82ce550941b313dffd590e072492a8be0e0b30518616fd0107d40f9 - Sigstore transparency entry: 1164195980
- Sigstore integration time:
-
Permalink:
kaka-ruto/runbox-py@a4603846a10a3937251110812201ae7731b4bc6a -
Branch / Tag:
refs/tags/v1.1.1 - Owner: https://github.com/kaka-ruto
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
cd.yml@a4603846a10a3937251110812201ae7731b4bc6a -
Trigger Event:
push
-
Statement type:
File details
Details for the file runbox_py-1.1.1-py3-none-any.whl.
File metadata
- Download URL: runbox_py-1.1.1-py3-none-any.whl
- Upload date:
- Size: 7.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1e0fb4724c5f901a58907d3918f9775947f070ae4e8e90a6a2aeeb9715a378aa
|
|
| MD5 |
6c2e9bad6b8943951ef979f40d52b470
|
|
| BLAKE2b-256 |
dc1cc0a38a28c1ac1b6b0c513fb171c7fb2372eda165d150d28be7af65331cb2
|
Provenance
The following attestation bundles were made for runbox_py-1.1.1-py3-none-any.whl:
Publisher:
cd.yml on kaka-ruto/runbox-py
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
runbox_py-1.1.1-py3-none-any.whl -
Subject digest:
1e0fb4724c5f901a58907d3918f9775947f070ae4e8e90a6a2aeeb9715a378aa - Sigstore transparency entry: 1164196070
- Sigstore integration time:
-
Permalink:
kaka-ruto/runbox-py@a4603846a10a3937251110812201ae7731b4bc6a -
Branch / Tag:
refs/tags/v1.1.1 - Owner: https://github.com/kaka-ruto
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
cd.yml@a4603846a10a3937251110812201ae7731b4bc6a -
Trigger Event:
push
-
Statement type: