面向 zerobox 的 Python SDK。可通过文件、网络和凭据控制来对任意命令进行沙箱化。
pip install zerobox
安装 wheel 会将 zerobox CLI 放入你环境的 bin/ 中,并提供一个 Python SDK。
有关 CLI 用法、secrets 概念、完整标志参考、性能数据和平台支持,请参阅 主 README。
from zerobox import Sandbox
sandbox = Sandbox.create({"allow_write": ["/tmp"]})
print(sandbox.sh("echo hello").text())
有三种运行命令的方式。每种都会返回一个 ShellCommand,你可以通过 .text()、.json() 或 .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='')
在异步应用中使用 AsyncSandbox,这样等待沙箱子进程时不会阻塞事件循环。命令结构与 Sandbox 相同,但创建和终止操作都需要 await。
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()
异步命令支持相同的 timeout 选项:
import subprocess
try:
await sandbox.sh("sleep 60").text(timeout=1.0)
except subprocess.TimeoutExpired:
print("cancelled")
退出码非零会抛出 SandboxCommandError:
from zerobox import Sandbox, SandboxCommandError
sandbox = Sandbox.create()
try:
sandbox.sh("exit 1").text()
except SandboxCommandError as e:
print(e.code, e.stderr)
传入沙箱进程永远看不到的 API 密钥。代理仅会为受信任的主机替换为真实值。
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()
有关占位符替换的工作原理,请参阅 主 README。
记录文件系统更改并自动回滚:
sandbox = Sandbox.create({
"allow_write": ["."],
"restore": True,
})
sandbox.sh("npm install").text()
记录但不回滚:
sandbox = Sandbox.create({
"allow_write": ["."],
"snapshot": True,
"snapshot_exclude": ["node_modules"],
})
sandbox.sh("npm install").text()
向任意终止操作传入 timeout(秒):
import subprocess
try:
sandbox.sh("sleep 60").text(timeout=1.0)
except subprocess.TimeoutExpired:
print("cancelled")
sandbox = Sandbox.create({
"env": {"NODE_ENV": "production"},
"allow_env": ["PATH", "HOME"],
"deny_env": ["AWS_SECRET_ACCESS_KEY"],
})
有关默认继承的内容以及对应的 CLI 选项,请参阅 主 README。
Sandbox.create(options) 接受一个 SandboxOptions dataclass 或普通字典。所有字段均为可选。
未知的字典键(例如误将 allow_write 写成 allowWrite)会在构造时抛出 TypeError。
Sandbox.py(code) 会运行沙箱内 PATH 中的任意 python3。如果你当前使用的解释器位于沙箱可读根目录之外(例如 ~/.local/share/uv/ 下由 uv 管理的 Python),请改用以下方式:
import sys
sandbox = Sandbox.create({"allow_read": [sys.prefix]})
sandbox.exec(sys.executable, ["-c", "print('hi')"]).text()
zerobox)zerobox)Apache-2.0
| 方法 | 成功时 | 退出码非零时 |
|---|
.text() | 将 stdout 作为字符串返回 | 抛出 SandboxCommandError |
.json() | 将 stdout 解析为 JSON | 抛出 SandboxCommandError |
.output() | 返回 CommandOutput(code, stdout, stderr) | 返回相同的结构,绝不抛出异常 |
| 字段 | 类型 | 描述 |
|---|
profile | str | list[str] | 命名配置文件。列表按从左到右的顺序合并。默认值为 "workspace"。 |
allow_read / deny_read | list[str] | 可读取 / 被阻止的路径。 |
allow_write / deny_write | list[str] | 可写入 / 被阻止的路径。 |
allow_net | bool | list[str] | True 允许全部。列表则限制为这些域名。 |
deny_net | list[str] | 被阻止的域名。 |
allow_all | bool | 完整的文件系统和网络访问权限。 |
no_sandbox | bool | 完全禁用沙箱。 |
strict_sandbox | bool | 失败而不是回退到较弱的隔离。 |
cwd | str | 工作目录。 |
env | dict[str, str] | 显式设置的环境变量。 |
allow_env | bool | list[str] | 继承父进程的环境变量。 |
deny_env | list[str] | 被阻止的环境变量。 |
snapshot | bool | 记录文件系统更改。 |
restore | bool | 记录并在退出后回滚。隐含 snapshot。 |
snapshot_paths / snapshot_exclude | list[str] | 需要跟踪的路径 / 排除的模式。 |
secrets | dict[str, SecretConfig] | 具有按主机作用域的机密。 |
debug | bool | 将沙箱配置打印到 stderr。 |