core
Sandboxes
A machine you keep. Sandbox() creates one and it
stays up until you destroy it, so state survives between commands — installed packages, files
you wrote, a process still running. It bills for as long as it exists, so delete() is what ends the meter.
create one
Every argument is a keyword and every one has a default, so you name only what you are changing. The two you will name most are the same two words the CLI prompts with — machine and environment. This is the full signature, with the value each argument takes when you leave it out:
from boltzlabs import Sandbox
# every value below IS the default — Sandbox() alone is exactly this call
Sandbox(
machine="small", # nano | small | medium | large
environment="base", # runtimes: base | python | node | pytorch
# agents: opencode | claude-code | codex | deepagents | aider
name=None, # None -> the id the platform assigns
internet=False,
idle_timeout=None, # seconds; None -> the platform's own
max_lifetime=None, # seconds; None -> the platform's own
)So the common calls are short, and each one says what it is asking for:
sb = Sandbox() # all defaults: small / base
sb = Sandbox(environment="python") # machine stays small
sb = Sandbox(machine="medium", environment="pytorch", name="trainer")
sb.run("print(1)") # language follows the environment
sb.exec("pip install requests") # a shell command
print(sb.url(8080)) # public URL for a port inside
sb.delete() # stops the meterAn id is assigned by the platform, never chosen by you, so it is not a constructor argument —
reach an existing sandbox with boltzlabs.sandbox(id) or by name. Use internet=True when you need ports.
sb = Sandbox(internet=True, name="web")
sb.exec("python -m http.server 8000")
print(sb.url(8000))
# or from the CLI: bzlabs forward web 8000 (Ctrl-C to stop)not forgetting to delete
A with block is the same three steps with the delete() written for you — including when line two raises,
which is the case that otherwise leaves a machine billing until you notice.
with Sandbox() as sb:
print(sb.run("print(sum(range(101)))"))
# destroyed here, however the block endedresults
run and exec return the same result. Print it and you get
the output; test it and you get success.
print(sb.exec("ls")) # prints stdout
if sb.exec("test -f /app/x"): # True when the exit code was 0
...
sb.exec("make").check() # raises if it failed
# .stdout .stderr .exit_code .duration_ms when you want them.
# A non-zero exit is data, not an exception: your program failed, not the call.terminal
sb.terminal() is bzlabs connect: a real PTY, with the remote shell owning
echo, arrow keys, tab completion and ^C. Pass a script instead and you get the transcript back —
for commands that only behave correctly with a terminal attached.
sb.terminal() # interactive
print(sb.terminal("tty; echo from-a-real-tty")) # scriptedwhat you have
import boltzlabs
boltzlabs.me() # who your key belongs to (bzlabs auth status)
boltzlabs.sandboxes() # everything you have running (bzlabs ls)
boltzlabs.sandbox(id) # one of them, by id (bzlabs status <id>)
boltzlabs.environments() # runtimes and coding agents (bzlabs environments)
boltzlabs.machines() # machines and prices (bzlabs machines)