这是本节的多页打印视图。
点击此处打印.
返回本页常规视图.
API
E2B API
e2b 官方 API 参考手册
https://e2b.dev/docs/api-reference/sandboxes/list-sandboxes
概念
-
Sandbox: e2b 称 code interpreter 为 Sandbox,本质上是一个轻量而安全隔离的MicroVM,基于 Firecracker 技术构建的。用于执行不可信的代码。
-
Template: 用户创建 code interpreter 的模板,和 sandbox 的关系类似 docker images 和 docker container,或者虚拟机和虚拟机镜像。
-
Tags: Tag 是附加在 Template 上的版本标识符,概念等同于 Docker 镜像的 Tag。用于对 Template 的版本管理。
-
Team: Team 是 E2B 中的组织架构和资源隔离边界。所有的 API Keys、构建的 Custom Templates(自定义模板)以及正在运行的 Sandboxes,都归属于一个具体的 Team。E2B 的免费额度、并发限制和账单都是以 Team 为维度进行计算的。类似租户的概念。
-
Evnd: 运行在 Sandbox 实例中的进程,用于外接和 Sandbox 实例通讯和交互。
-
Filesystem: Filesystem 代表沙箱内部隔离的虚拟“硬盘空间”,可以进行各种操作如读写文件,文件夹管理,上传与下载,以及最新提供的文件监听。
-
Process
API
Template API
标准的 CURD 生命周期管理API:
- Create template (v3): 创建 template,但 e2b 这里不用指定容器镜像,在 start build 时指定。
- Delete template: 删除指定 template-id 的 template
- Update template (v2): 更新指定 template-id 的 template 信息,仅限 public 参数(是否公用,还是仅仅在 team 内可用)
- Get template: 获取指定 template-id 的 template 信息,包括template的最后使用时间和使用次数,template的所有build
- Get template by alias: 获取指定 alias (name) 的 template 信息
- List templates: 获取指定 team-id 的所有 template 信息, Get template 方法的批量版本。
构建 build 相关的 API:
- Start build (v2): 开始构建 template,可以 fromImage / fromTemplate / fromImageRegistry。
- Get build status: 获取构建的信息包括日志,以及构建的状态如 building, waiting, ready, error, uploaded
- Get build logs: Get build status 的裁剪版本,只返回日志
- Get build upload link: 获取文件上传的地址,可以用来将构建所需的文件打包为tar之后传上去。开发者一般不需要调用,专门给 E2B 官方 CLI 或者高级自动化系统在底层使用。
E2b 使用 tag 来对 tamplate 进行管理,包括版本。在 create template 方法中可以初始设置 tag,包括使用 tags 参数和在 name 参数中使用"my-template:v1" 这样的格式。
- Assign tags: 分配 tag,不是简单的设置。因为同一个 template (template-id) 下同一个 tag 是唯一的。
- Delete tags: 从 template 上删除 tag
- List template tags: 列出指定 template-id 的 template 的所有tag
Sandbox API
标准的 CURD 生命周期管理API:
- Create Sandbox: 从指定 template 创建 Sandbox 实例
- Delete Sandbox: 删除指定 sandbox-id 的 Sandbox 实例
- Get Sandbox (v2): 查询指定 sandbox-id 的 Sandbox 实例信息
- List Sandbox(v2): 列出所有的运行中的 Sandbox 实例(仅限于当前 Team)
暂停和恢复的 API:
- Pause Sandbox: 暂停指定 sandbox-id 的 Sandbox 实例
- Resume sandbox: 废弃,被 Connect to Sandbox API 取代
- Connect to Sandbox: 等价于 Resume sandbox + Get Sandbox。如果 sandbox 实例被暂停则进行恢复,然后返回 Sandbox 实例的详细信息。
和超时/TTL相关的 API:
-
Set sandbox timeout: 设置 sandbox 实例的超时时间,每次调用后,超时的最大期限被设置为当前时间+传入的参数。在 Create Sandbox 时初始设置 timeout ,然后可以通过反复调用这个方法来持续延长 sandbox 的运行期限。比如将 timeout 时间从1分钟改成5分钟。关键词:修改 timeout 并重新计时
-
Refresh sandbox: 不改变沙箱原有的超时设定,只是单纯地把倒计时重置回最大值。比如当前 timeout 为1分钟,调用这个方法后将重新开始1分钟倒计时。关键词:重新计时但不修改 timeout。
和网络相关的 API:
- Put sandboxes network: 更新指定 sandbox-id 的 Sandbox 实例的网络配置。用提供的配置取代现有的 egress 规则。allowOut/denyOut 在 create sandbox 时进行初始设置。
和 Sandbox 可观测性相关的 API:
-
Get sandbox metrics: 通过 sandbox-id 查询指定 Sandbox 实例的 metrics 信息,如cpu,内存,磁盘
-
List sandbox metrics: Get sandbox metrics 的批量版本,支持指定多个 sandbox-id
-
Get sandbox logs (v2): 获取指定 sandbox-id 的 Sandbox 实例的日志内容
和快照相关的 API:
Evnd API
- Check the health of the service: 对 sandbox 实例进行健康检查(路径为/health)
- Get the stats of the service: 获取 sandbox 实例的状态,实际为 metrics信息(路径为/metrics),包括cpu,内存,磁盘的使用情况
- Get the environment variables: 获取 sandbox 实例的环境变量
Filesystem API
和目录/文件相关的 API:
- MakeDir
- ListDir
- Remove: 删除目录或者文件
- Move: 移动文件或者目录
- Stat: 查看文件或者目录状态
- Download a file: 下载文件
- Upload a file : 上传文件,会确保父目录存在。
- Compose multiple files: 将多个文件合并为一个文件,使用 zero copy
和文件夹监控相关的 API:
- WatchDir: 监控文件夹, Server-streaming 流式版本
- CreateWatcher: WatchDir 的非流式版本,只返回 watcherId
- GetWatcherEvents: 通过 watcherId 获取监控事件
- RemoveWatcher: 移除监控
Process API
- Start Process: 启动一个进程,Server-streaming RPC,流式。(但很奇怪不返回 pid)
- List: 列出所有进程,进程信息包含 pid 可以用于其他基于 pid 的操作
- Connect: 连接指定 pid 的进程,Server-streaming RPC,流式获取 ConnectResponse events
- CloseStdin: 关闭标准输入(stdin),向指定 pid 的进程发送 EOF 信号。此方法仅适用于非 PTY 进程。对于 PTY 进程,请改发 Ctrl+D(0x04)。
- SendInput: 向指定 pid 的进程发送 input 如 pty
- StreamInput: ??
- SendSignal: 向指定 pid 的进程发送信号如 SIGNAL_UNSPECIFIED, SIGNAL_SIGTERM, SIGNAL_SIGKILL
Team API
- List teams: 获取所有的 team 信息,包括 name / team-id / apiKey, 以及 isDefualt / 是不是默认 team。
- Get team metrics: 获取 team 的 metrics 信息,如 concurrentSandboxes,sandboxStartRate
- Get team metrics max: 获取指定间隔内的 metrics 的最大值, metrics 可以是 concurrent_sandboxes 或者 sandbox_start_rate
1.1 - Set Timeout API
E2B Sandbox Set Timeout API
测试代码
import os
import time
from datetime import datetime, timezone
from e2b import Sandbox
# 实验参数:
# t0 创建,timeout=60s
# t0+20s 调用 set_timeout(50)
# 判定:
# 若 end_at ≈ t0 + 70s → 以当前时刻重算(now + timeout)
# 若 end_at ≈ t0 + 110s → 在原超时上叠加(原 timeout + 新 timeout)
CREATE_TIMEOUT = 60
WAIT_SECONDS = 20
SET_TIMEOUT = 50
API_KEY = "e2b_4a9c76a966fcxxxxxxxxxxxxxxxx"
def utcnow() -> datetime:
return datetime.now(timezone.utc)
def fmt(dt: datetime | None) -> str:
if dt is None:
return "None"
return dt.astimezone(timezone.utc).isoformat()
def seconds_between(later: datetime, earlier: datetime) -> float:
return (later - earlier).total_seconds()
def print_info(label: str, info, *, t0: datetime, t_call: datetime | None = None) -> None:
print(f"\n=== {label} ===")
print(f"sandbox_id : {info.sandbox_id}")
print(f"started_at : {fmt(info.started_at)}")
print(f"end_at : {fmt(info.end_at)}")
print(f"end_at - started_at : {seconds_between(info.end_at, info.started_at):.1f}s")
print(f"end_at - t0 : {seconds_between(info.end_at, t0):.1f}s")
if t_call is not None:
print(f"end_at - 调用时刻 : {seconds_between(info.end_at, t_call):.1f}s")
def main() -> None:
os.environ["E2B_API_KEY"] = API_KEY
sbx = None
try:
t0 = utcnow()
sbx = Sandbox.create("code-interpreter-v1", timeout=CREATE_TIMEOUT)
info0 = sbx.get_info()
print(f"创建完成 t0={fmt(t0)}")
print_info("创建后", info0, t0=t0)
print(f"\n等待 {WAIT_SECONDS}s 后再调用 set_timeout ...")
time.sleep(WAIT_SECONDS)
t_call = utcnow()
print(f"调用 set_timeout 时刻 t_call={fmt(t_call)}")
print(f"距 t0 已过去 {seconds_between(t_call, t0):.1f}s")
print(f"set_timeout({SET_TIMEOUT})")
sbx.set_timeout(SET_TIMEOUT)
info1 = sbx.get_info()
print_info("set_timeout 后", info1, t0=t0, t_call=t_call)
from_now = seconds_between(info1.end_at, t_call)
from_create = seconds_between(info1.end_at, info0.started_at)
original_ttl = seconds_between(info0.end_at, info0.started_at)
print("\n=== 结论对照 ===")
print(f"原 end_at - started_at ≈ {original_ttl:.1f}s(期望 ~{CREATE_TIMEOUT}s)")
print(f"新 end_at - 调用时刻 ≈ {from_now:.1f}s")
print(f"新 end_at - started_at ≈ {from_create:.1f}s")
print(f"若以当前时刻重算,期望 end_at ≈ t_call + {SET_TIMEOUT}s,即 started_at 后约 {WAIT_SECONDS + SET_TIMEOUT}s")
print(f"若在原超时上叠加,期望 end_at ≈ started_at + {CREATE_TIMEOUT + SET_TIMEOUT}s")
finally:
if sbx is not None:
sbx.kill()
print("\n沙盒已关闭")
if __name__ == "__main__":
main()
测试结果
python ./settimeout.py
创建完成 t0=2026-08-17T11:06:27.911494+00:00
=== 创建后 ===
sandbox_id : ic0dtgk5ta2ili3e9t87l
started_at : 2026-08-17T11:06:33.440446+00:00
end_at : 2026-08-17T11:07:33.440446+00:00
end_at - started_at : 60.0s
end_at - t0 : 65.5s
等待 20s 后再调用 set_timeout ...
调用 set_timeout 时刻 t_call=2026-08-17T11:06:54.002638+00:00
距 t0 已过去 26.1s
set_timeout(50)
=== set_timeout 后 ===
sandbox_id : ic0dtgk5ta2ili3e9t87l
started_at : 2026-08-17T11:06:33.440446+00:00
end_at : 2026-08-17T11:07:44.259126+00:00
end_at - started_at : 70.8s
end_at - t0 : 76.3s
end_at - 调用时刻 : 50.3s
=== 结论对照 ===
原 end_at - started_at ≈ 60.0s(期望 ~60s)
新 end_at - 调用时刻 ≈ 50.3s
新 end_at - started_at ≈ 70.8s
若以当前时刻重算,期望 end_at ≈ t_call + 50s,即 started_at 后约 70s
若在原超时上叠加,期望 end_at ≈ started_at + 110s
沙盒已关闭
1.2 - Refresh Sandbox API
E2B Sandbox Refresh Sandbox API
测试代码
import json
import os
import time
import urllib.error
import urllib.request
from datetime import datetime, timezone
from e2b import Sandbox
# 实验参数:
# t0 创建,timeout=60s
# t0+20s 调用 refresh,duration=50s
# 判定:
# 若 end_at ≈ t0 + 70s → 以当前时刻重算(now + duration)
# 若 end_at ≈ t0 + 110s → 在原超时上叠加(原 timeout + duration)
# 若 end_at ≈ t0 + 60s → 没改到(refresh 不允许缩短时会出现)
CREATE_TIMEOUT = 60
WAIT_SECONDS = 20
REFRESH_DURATION = 50
API_KEY = "e2b_4a9c76a966fcxxxxxxxxxxxxxxxxxxxxxxxx"
E2B_API_URL = os.environ.get("E2B_API_URL", "https://api.e2b.app")
def utcnow() -> datetime:
return datetime.now(timezone.utc)
def fmt(dt: datetime | None) -> str:
if dt is None:
return "None"
return dt.astimezone(timezone.utc).isoformat()
def seconds_between(later: datetime, earlier: datetime) -> float:
return (later - earlier).total_seconds()
def print_info(label: str, info, *, t0: datetime, t_call: datetime | None = None) -> None:
print(f"\n=== {label} ===")
print(f"sandbox_id : {info.sandbox_id}")
print(f"started_at : {fmt(info.started_at)}")
print(f"end_at : {fmt(info.end_at)}")
print(f"end_at - started_at : {seconds_between(info.end_at, info.started_at):.1f}s")
print(f"end_at - t0 : {seconds_between(info.end_at, t0):.1f}s")
if t_call is not None:
print(f"end_at - 调用时刻 : {seconds_between(info.end_at, t_call):.1f}s")
def refresh_sandbox(sandbox_id: str, duration: int) -> None:
req = urllib.request.Request(
url=f"{E2B_API_URL}/sandboxes/{sandbox_id}/refreshes",
data=json.dumps({"duration": duration}).encode("utf-8"),
headers={
"X-API-Key": API_KEY,
"Content-Type": "application/json",
"Accept": "application/json",
},
method="POST",
)
try:
with urllib.request.urlopen(req) as resp:
print(f"\nrefresh API HTTP {resp.status}(204 表示成功)")
except urllib.error.HTTPError as e:
body = e.read().decode("utf-8", errors="replace")
raise RuntimeError(f"refresh API 失败: HTTP {e.code} {body}") from e
def main() -> None:
os.environ["E2B_API_KEY"] = API_KEY
sbx = None
try:
t0 = utcnow()
sbx = Sandbox.create("code-interpreter-v1", timeout=CREATE_TIMEOUT)
info0 = sbx.get_info()
print(f"创建完成 t0={fmt(t0)}")
print_info("创建后", info0, t0=t0)
print(f"\n等待 {WAIT_SECONDS}s 后再调用 refresh ...")
time.sleep(WAIT_SECONDS)
t_call = utcnow()
print(f"调用 refresh 时刻 t_call={fmt(t_call)}")
print(f"距 t0 已过去 {seconds_between(t_call, t0):.1f}s")
print(f"refresh duration = {REFRESH_DURATION}s")
refresh_sandbox(sbx.sandbox_id, REFRESH_DURATION)
info1 = sbx.get_info()
print_info("refresh 后", info1, t0=t0, t_call=t_call)
from_now = seconds_between(info1.end_at, t_call)
from_create = seconds_between(info1.end_at, info0.started_at)
original_ttl = seconds_between(info0.end_at, info0.started_at)
print("\n=== 结论对照 ===")
print(f"原 end_at - started_at ≈ {original_ttl:.1f}s(期望 ~{CREATE_TIMEOUT}s)")
print(f"新 end_at - 调用时刻 ≈ {from_now:.1f}s")
print(f"新 end_at - started_at ≈ {from_create:.1f}s")
print(f"若以当前时刻重算,期望 end_at ≈ t_call + {REFRESH_DURATION}s,即 started_at 后约 {WAIT_SECONDS + REFRESH_DURATION}s")
print(f"若在原超时上叠加,期望 end_at ≈ started_at + {CREATE_TIMEOUT + REFRESH_DURATION}s")
finally:
if sbx is not None:
sbx.kill()
print("\n沙盒已关闭")
if __name__ == "__main__":
main()
测试结果
python ./refresh-sandbox.py
创建完成 t0=2026-08-17T11:02:59.161667+00:00
=== 创建后 ===
sandbox_id : itokcnl2gvqzdvrczvalk
started_at : 2026-08-17T11:03:05.313013+00:00
end_at : 2026-08-17T11:04:05.313013+00:00
end_at - started_at : 60.0s
end_at - t0 : 66.2s
等待 20s 后再调用 refresh ...
调用 refresh 时刻 t_call=2026-08-17T11:03:25.730206+00:00
距 t0 已过去 26.6s
refresh duration = 50s
refresh API HTTP 204(204 表示成功)
=== refresh 后 ===
sandbox_id : itokcnl2gvqzdvrczvalk
started_at : 2026-08-17T11:03:05.313013+00:00
end_at : 2026-08-17T11:04:16.477246+00:00
end_at - started_at : 71.2s
end_at - t0 : 77.3s
end_at - 调用时刻 : 50.7s
=== 结论对照 ===
原 end_at - started_at ≈ 60.0s(期望 ~60s)
新 end_at - 调用时刻 ≈ 50.7s
新 end_at - started_at ≈ 71.2s
若以当前时刻重算,期望 end_at ≈ t_call + 50s,即 started_at 后约 70s
若在原超时上叠加,期望 end_at ≈ started_at + 110s
沙盒已关闭