TL;DR: Install BoxLite with pip install boxlite, then create a sandbox with async with boxlite.SimpleBox("python:slim") as box. Your code runs in a hardware-isolated micro-VM with its own kernel. No daemon, no root, no complex setup.
Before starting, make sure you have:
macOS (Apple Silicon):
Linux:
/dev/kvm accessible)kvm group: sudo usermod -aG kvm $USERpip install boxlite
That’s it. No daemon to start, no Docker to install, no root access needed.
Create a file called hello_sandbox.py:
import asyncio
import boxlite
async def main():
# Create a sandbox using the official Python image
async with boxlite.SimpleBox("python:slim") as box:
# Run a command inside the sandbox
result = await box.exec(
"python", "-c",
"print('Hello from inside the sandbox!')"
)
print(result.stdout)
asyncio.run(main())
Run it:
python hello_sandbox.py
The first run will pull the python:slim image (this takes a moment). Subsequent runs are fast thanks to layer caching.
When you ran that code:
The key point: your code ran in a hardware-isolated VM, not just a container. Even if the code tried to exploit a container escape vulnerability, it would still be trapped inside the VM.
Let’s run multi-line Python code:
import asyncio
import boxlite
code = '''
import os
import sys
print(f"Python version: {sys.version}")
print(f"Current directory: {os.getcwd()}")
print(f"User: {os.getenv('USER', 'unknown')}")
# This runs inside the sandbox - can't affect your host
with open('/tmp/sandbox_test.txt', 'w') as f:
f.write('Data stays inside the sandbox')
print("File written successfully!")
'''
async def main():
async with boxlite.SimpleBox("python:slim") as box:
result = await box.exec("python", "-c", code)
print("=== Output ===")
print(result.stdout)
if result.stderr:
print("=== Errors ===")
print(result.stderr)
print(f"=== Exit code: {result.exit_code} ===")
asyncio.run(main())
BoxLite provides a specialized CodeBox API for Python execution:
import asyncio
import boxlite
async def main():
async with boxlite.CodeBox() as box:
# CodeBox handles Python execution details
result = await box.run('''
import numpy as np
# NumPy is pre-installed in CodeBox
arr = np.array([1, 2, 3, 4, 5])
print(f"Array: {arr}")
print(f"Mean: {arr.mean()}")
print(f"Sum: {arr.sum()}")
''')
print(result.stdout)
asyncio.run(main())
CodeBox is optimized for Python code execution with:
Protect against runaway code:
async with boxlite.SimpleBox(
"python:slim",
memory_mb=256, # Limit memory to 256MB
cpus=1, # Limit to 1 CPU
) as box:
result = await box.exec("python", "-c", untrusted_code)
Always handle potential failures:
import asyncio
import boxlite
async def run_safely(code: str) -> str:
try:
async with boxlite.CodeBox() as box:
result = await box.run(code)
if result.exit_code != 0:
return f"Code failed with exit code {result.exit_code}:\n{result.stderr}"
return result.stdout
except Exception as e:
return f"Sandbox error: {e}"
# Example usage
async def main():
# This will fail gracefully
output = await run_safely("import nonexistent_module")
print(output)
# This will succeed
output = await run_safely("print('Hello!')")
print(output)
asyncio.run(main())
Make sure you have KVM access:
# Check if KVM is available
ls -la /dev/kvm
# Add yourself to the kvm group
sudo usermod -aG kvm $USER
# Log out and back in for the change to take effect
The first run downloads the OCI image. Subsequent runs reuse cached layers. You can pre-pull images:
import boxlite
# Pre-pull during setup
boxlite.pull_image("python:slim")
Increase the memory limit:
async with boxlite.SimpleBox("python:slim", memory_mb=1024) as box:
# 1GB of memory available
...
Now that you have BoxLite working:
Questions? Check out the complete examples or open an issue.