Skip to main content
CodeBox is BoxLite’s purpose-built sandbox for running untrusted Python code. It auto-installs missing packages, captures output, and keeps your host system completely safe. This tutorial walks through the core workflow.

What you’ll build

A script that:
  1. Creates an isolated CodeBox
  2. Runs untrusted Python code inside it
  3. Auto-installs required packages
  4. Returns the output to your application

Prerequisites

pip install boxlite
Requires Python 3.10+.

Step 1: Run simple code

Start with a basic example — execute a Python snippet and print the result.
run_code.py
import asyncio
import boxlite


async def main():
    async with boxlite.CodeBox() as codebox:
        result = await codebox.run("""
x = sum(range(100))
print(f"Sum of 0-99: {x}")
""")
        print(result)


if __name__ == "__main__":
    asyncio.run(main())
python run_code.py
# Output: Sum of 0-99: 4950
What’s happening:
  • CodeBox creates a lightweight VM with a Python runtime pre-installed
  • Your code runs inside the VM — completely isolated from the host
  • Output is captured and returned as a string
  • The VM is cleaned up automatically when the context exits

Step 2: Auto-install packages

CodeBox detects missing imports and installs them automatically. No manual pip install needed.
auto_install.py
import asyncio
import boxlite


async def main():
    async with boxlite.CodeBox() as codebox:
        # requests is not pre-installed — CodeBox installs it for you
        result = await codebox.run("""
import requests
response = requests.get('https://api.github.com/zen')
print(response.text)
""")
        print(result)


if __name__ == "__main__":
    asyncio.run(main())

Step 3: Install packages explicitly

When you need specific versions or want to pre-install packages before running code, use install_package().
explicit_install.py
import asyncio
import boxlite


async def main():
    async with boxlite.CodeBox() as codebox:
        # Pre-install specific packages
        await codebox.install_package("pandas")
        await codebox.install_package("matplotlib")

        result = await codebox.run("""
import pandas as pd
import matplotlib
print(f"pandas {pd.__version__}, matplotlib {matplotlib.__version__}")

df = pd.DataFrame({"x": [1, 2, 3], "y": [4, 5, 6]})
print(df.describe())
""")
        print(result)


if __name__ == "__main__":
    asyncio.run(main())
For data-heavy workloads (pandas, numpy, matplotlib), increase memory to 4096 MiB or more. The default 2048 MiB is enough for most code execution.

Step 4: Run a script file

Use run_script() to execute a Python script from your host filesystem inside the box.
run_script() reads the script from your host machine and executes it inside the box. It does not look for files already inside the guest.
analysis.py
# This file lives on the HOST at ./analysis.py
import json
data = {"status": "success", "items": [1, 2, 3]}
print(json.dumps(data, indent=2))
run_script.py
import asyncio
import boxlite


async def main():
    async with boxlite.CodeBox() as codebox:
        # run_script() reads ./analysis.py from the HOST filesystem
        # and executes it inside the box
        result = await codebox.run_script("./analysis.py")
        print(result)


if __name__ == "__main__":
    asyncio.run(main())
python run_script.py
# Output:
# {
#   "status": "success",
#   "items": [1, 2, 3]
# }

Step 5: Run multiple snippets in the same box

A single CodeBox can run many snippets sequentially. Filesystem state persists between calls — installed packages and written files remain available. However, in-memory state (variables, functions) does not persist.
Each run() call spawns a separate Python process. Variables and functions defined in one run() call are not available in the next. Use the filesystem to share data between calls.
multi_run.py
import asyncio
import boxlite


async def main():
    async with boxlite.CodeBox() as codebox:
        # First run: compute results and write to a file
        await codebox.run("""
import json

data = {"a": 1, "b": 2, "c": 3}
output = {k: v * 2 for k, v in data.items()}

with open('/tmp/results.json', 'w') as f:
    json.dump(output, f)
print("Saved results to /tmp/results.json")
""")

        # Second run: read the file from the previous run
        result = await codebox.run("""
import json

with open('/tmp/results.json') as f:
    data = json.load(f)
print(json.dumps(data))
""")
        print(result)  # {"a": 2, "b": 4, "c": 6}


if __name__ == "__main__":
    asyncio.run(main())

What’s next?