Quickly spin up isolated Python sandboxes (virtualenv or Docker), install dependencies, execute code, and tear down.
Project description
sandboxr
Quickly spin up disposable Python sandboxes (virtualenv or Docker), install dependencies, execute code or scripts, capture output, and tear down—all with one simple API or CLI.
Table of Contents
- Why sandboxr?
- Features
- Installation
- Quickstart
- Backend Details
- Advanced Examples
- Testing
- CI Integration
- Contributing
- License
Why sandboxr?
When you need to:
- Test code snippets against different dependency versions
- Run untrusted or experimental code in isolation
- Provide "try-me" examples in documentation or tutorials
- Spin up throwaway environments for CI/CD smoke tests
…without polluting your global environment or managing virtualenvs by hand, sandboxr has you covered.
Features
- Dual backends:
virtualenv— uses the standard libraryvenv+pip.docker— builds and runs ephemeral Docker images.
- One-line CLI: install, run code or file, tear down.
- Python API: full control in your scripts or tools.
- Automatic teardown: sandbox directories and images are cleaned up by default.
- Flexible installs: pre-install on creation and add packages later.
- Timeouts: guard runaway code with execution time limits.
- Cross-platform: macOS, Linux, Windows (Docker backend requires Docker).
Installation
pip install sandboxr
Note: For editable installs (development), run:
pip install -e .
Quickstart
CLI Usage
# Run a one-off script in a virtualenv sandbox:
sandboxr \
--backend virtualenv \
--packages pandas,numpy \
--file demo_script.py
# Run inline code and keep the sandbox after execution:
sandboxr \
--backend docker \
--packages pytest \
--code "import pytest; print(pytest.__version__)" \
--keep
Options:
| Flag | Description |
|---|---|
| --backend | virtualenv or docker (required) |
| --packages | Comma-separated list of packages to pip-install before execution |
| --code | Inline Python code string (mutually exclusive with --file) |
| --file | Path to a .py file (mutually exclusive with --code) |
| --keep | Don't auto-teardown sandbox after execution (for debugging) |
Programmatic Usage
from sandboxr import SandboxManager
# 1) Create a sandbox with numpy + requests
mgr = SandboxManager(backend="virtualenv", packages=["numpy>=1.24", "requests"])
sandbox = mgr.create()
# 2) Run some code
stdout, stderr, exit_code = sandbox.exec("""
import numpy as np
print(np.array([1,2,3]) * 2)
""")
print("OUT:", stdout)
print("ERR:", stderr)
print("CODE:", exit_code)
# 3) Install more packages on the fly
sandbox.install(["pandas"])
out2, err2, code2 = sandbox.exec("import pandas as pd; print(pd.__version__)")
# 4) Tear down when done
sandbox.teardown()
Backend Details
VirtualenvSandbox
Creation: uses venv.create() to build an isolated env
- install(packages: List[str]): pip-install inside the sandbox
- exec(code: str, timeout: int = 30): run code string, capture stdout/stderr
- exec_file(path: str, timeout: int = 30): execute a script file
- teardown(): delete the sandbox directory
from sandboxr.backends.virtualenv import VirtualenvSandbox
DockerSandbox
Creation: writes a simple Dockerfile + docker build
- install(packages: List[str]): append RUN pip install layer, rebuild image
- exec(code: str, timeout: int = 30): docker run + capture output
- exec_file(path: str, timeout: int = 30): mount script into container, run
- teardown(): remove image + build context
from sandboxr.backends.docker import DockerSandbox
Advanced Examples
Test multiple dependency versions
versions = ["1.5.0", "2.0.1"]
for ver in versions:
sb = SandboxManager("virtualenv", [f"pandas=={ver}"]).create()
out, _, _ = sb.exec("import pandas as pd; print(pd.__version__)")
print("Pandas", ver, "→", out.strip())
sb.teardown()
Smoke-test a GitHub project
git clone https://github.com/psf/requests.git /tmp/requests-demo
sandboxr --backend virtualenv --packages pytest --code "import pytest; pytest.main(['/tmp/requests-demo'])"
Testing
We use pytest for our own test suite:
# ensure Docker is running if you want to test the docker backend
PYTHONPATH=$(pwd) pytest -q
CI Integration
Here's a minimal GitHub Actions snippet to run tests on push:
name: CI
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: 3.9
- name: Install dependencies
run: pip install -e . pytest
- name: Run tests
run: PYTHONPATH=$(pwd) pytest -q
Contributing
- Fork the repo
- Create a feature branch (git checkout -b feature/foo)
- Commit your changes (git commit -am 'Add foo')
- Push to the branch (git push origin feature/foo)
- Open a Pull Request
Please follow our Code of Conduct and Contributing Guidelines.
License
This project is licensed under the MIT License. See the LICENSE file for details.
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
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 sandboxr-0.1.3.tar.gz.
File metadata
- Download URL: sandboxr-0.1.3.tar.gz
- Upload date:
- Size: 6.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.8.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
da1d6775d692c9e0454c282875f5d7c9cfc8042f05f55964c0be768f67de49c6
|
|
| MD5 |
93be9b7023e1062548a36bc744012e55
|
|
| BLAKE2b-256 |
1a631cacd857223389f689294a7030651f1bd8f5c163a53c14f67eb7c87497ef
|
File details
Details for the file sandboxr-0.1.3-py3-none-any.whl.
File metadata
- Download URL: sandboxr-0.1.3-py3-none-any.whl
- Upload date:
- Size: 7.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.8.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
db8f1c66ade28af5be6ed3bf599643184197c0238d7ef975623617a2e39c55b2
|
|
| MD5 |
a9e152a68c7341fae0c94796f4fba9a5
|
|
| BLAKE2b-256 |
96e2271e7c5a036b1310f8f16e983acf77589afbc9c1db57163b6f9a29cfbffb
|