
Aislamiento de procesos ligero y multiplataforma, impulsado por el runtime de OpenAI Codex. Aísle cualquier comando con controles de archivos, red y credenciales.
SDK de Python para zerobox. Aísla en un sandbox cualquier comando con controles de archivos, red y credenciales.
pip install zerobox
Al instalar la rueda, se coloca la CLI de zerobox en el bin/ de tu entorno y expone un SDK de Python.
Para el uso de la CLI, conceptos de secretos, la referencia completa de banderas, números de rendimiento y soporte de plataforma, consulta el README principal.
from zerobox import Sandbox
sandbox = Sandbox.create({"allow_write": ["/tmp"]})
print(sandbox.sh("echo hello").text())
Tres formas de ejecutar un comando. Cada una devuelve un ShellCommand que puedes terminar con .text(), .json() o .output().
name = "world"
sandbox.sh(f"echo hello {name}").text()
data = sandbox.py("import json; print(json.dumps({'sum': 1 + 2}))").json()
sandbox.exec("python3", ["-c", "print('hi')"]).text()
data = sandbox.sh("cat data.json").json()
result = sandbox.sh("exit 42").output()
# CommandOutput(code=42, stdout='', stderr='')
Usa AsyncSandbox en aplicaciones asíncronas para que la espera del subproceso en sandbox no bloquee el bucle de eventos. La forma del comando es la misma que Sandbox, pero la creación y los terminadores se esperan.
from zerobox import AsyncSandbox
sandbox = await AsyncSandbox.create({"allow_write": ["/tmp"]})
text = await sandbox.sh("echo hello").text()
data = await sandbox.sh("printf '{\"ok\": true}'").json()
result = await sandbox.exec("python3", ["-c", "print('hi')"]).output()
Los comandos asíncronos aceptan la misma opción timeout:
import subprocess
try:
await sandbox.sh("sleep 60").text(timeout=1.0)
except subprocess.TimeoutExpired:
print("cancelado")
La salida no cero lanza SandboxCommandError:
from zerobox import Sandbox, SandboxCommandError
sandbox = Sandbox.create()
try:
sandbox.sh("exit 1").text()
except SandboxCommandError as e:
print(e.code, e.stderr)
Pasa claves API que el proceso en sandbox nunca ve. El proxy sustituye el valor real solo para hosts aprobados.
import os
from zerobox import Sandbox
sandbox = Sandbox.create({
"secrets": {
"OPENAI_API_KEY": {
"value": os.environ["OPENAI_API_KEY"],
"hosts": ["api.openai.com"],
},
"GITHUB_TOKEN": {
"value": os.environ["GITHUB_TOKEN"],
"hosts": ["api.github.com"],
},
},
})
sandbox.sh('curl -H "Authorization: Bearer $OPENAI_API_KEY" https://api.openai.com/v1/models').text()
Consulta el README principal para saber cómo funciona la sustitución de marcadores de posición.
Graba los cambios del sistema de archivos y los revierte automáticamente:
sandbox = Sandbox.create({
"allow_write": ["."],
"restore": True,
})
sandbox.sh("npm install").text()
Graba sin revertir:
sandbox = Sandbox.create({
"allow_write": ["."],
"snapshot": True,
"snapshot_exclude": ["node_modules"],
})
sandbox.sh("npm install").text()
Pasa un timeout (segundos) a cualquier terminador:
import subprocess
try:
sandbox.sh("sleep 60").text(timeout=1.0)
except subprocess.TimeoutExpired:
print("cancelado")
sandbox = Sandbox.create({
"env": {"NODE_ENV": "production"},
"allow_env": ["PATH", "HOME"],
"deny_env": ["AWS_SECRET_ACCESS_KEY"],
})
Consulta el README principal para ver qué se hereda por defecto y los equivalentes de CLI.
Sandbox.create(options) acepta una dataclass SandboxOptions o un dict simple. Todos los campos son opcionales.
Claves de dict desconocidas (por ejemplo, allowWrite accidental en lugar de allow_write) lanzan TypeError en el momento de la construcción.
Sandbox.py(code) ejecuta el python3 que esté en PATH dentro del sandbox. Si tu intérprete activo se encuentra fuera de las raíces legibles del sandbox (por ejemplo, Pythons gestionados por uv en ~/.local/share/uv/), recurre a:
import sys
sandbox = Sandbox.create({"allow_read": [sys.prefix]})
sandbox.exec(sys.executable, ["-c", "print('hi')"]).text()
zerobox)zerobox)Apache-2.0
| Método | En éxito | En salida no cero |
|---|
.text() | Devuelve stdout como cadena | Lanza SandboxCommandError |
.json() | Analiza stdout como JSON | Lanza SandboxCommandError |
.output() | Devuelve CommandOutput(code, stdout, stderr) | Devuelve la misma estructura, nunca lanza |
| Campo | Tipo | Descripción |
|---|
profile | str | list[str] | Perfil(es) con nombre. Una lista se fusiona de izquierda a derecha. Por defecto "workspace". |
allow_read / deny_read | list[str] | Rutas legibles / bloqueadas. |
allow_write / deny_write | list[str] | Rutas escribibles / bloqueadas. |
allow_net | bool | list[str] | True permite todo. Una lista lo restringe a esos dominios. |
deny_net | list[str] | Dominios bloqueados. |
allow_all | bool | Acceso completo al sistema de archivos y la red. |
no_sandbox | bool | Desactivar el sandbox por completo. |
strict_sandbox | bool | Fallar en lugar de recurrir a un aislamiento más débil. |
cwd | str | Directorio de trabajo. |
env | dict[str, str] | Variables de entorno explícitas. |
allow_env | bool | list[str] | Heredar variables de entorno del proceso padre. |
deny_env | list[str] | Variables de entorno bloqueadas. |
snapshot | bool | Grabar los cambios del sistema de archivos. |
restore | bool | Grabar y revertir después de la salida. Implica snapshot. |
snapshot_paths / snapshot_exclude | list[str] | Rutas rastreadas / patrones excluidos. |
secrets | dict[str, SecretConfig] | Secretos con alcances por host. |
debug | bool | Imprimir la configuración del sandbox en stderr. |