SDK 是沙箱 REST API 之上的一層薄封裝。它替您省掉三件事:手工拼請求、平台繁忙時重試、程式碼拋異常後忘記刪除沙箱。本頁內容對應兩個包的 0.2.0 版本。
如果您從沒建立過沙箱,先看 5 分鐘連線指南 拿到 token。沙箱是什麼、裡面有什麼,見 沙箱。
安裝與設定
pip install eqvps # Python 3.8+
npm i @eqvps/sdk # Node.js 18+, Deno, Bun
export EQVPS_API_KEY=... # your EQVPS account token
兩種語言寫的同一個程式:建立沙箱、執行程式碼、刪除沙箱。
from eqvps import Sandbox
with Sandbox.create(tariff="small") as sb:
r = sb.run("print(2 + 2)")
print(r.exit_code, r.stdout) # 0 4
import { Sandbox } from "@eqvps/sdk";
await Sandbox.with({ tariff: "small" }, async (sb) => {
const r = await sb.run("print(2 + 2)");
console.log(r.exit_code, r.stdout); // 0 4
});
建立與查詢沙箱
Sandbox.create(...) 啟動一個沙箱,通常約一秒。Python 使用關鍵字參數,TypeScript 使用一個選項物件。
| Python | TypeScript | 預設值 | 含義 |
|---|---|---|---|
mode | mode | "ephemeral" | "ephemeral"(按秒)或 "persistent"(按已開始的小時計費,保留磁碟) |
tariff | tariff | "small" | micro、small、standard、plus、pro、max |
idle_timeout | idleTimeout | 300 | 臨時沙箱無活動多少秒後被刪除,最長 3600 |
ttl | ttl | — | 最長存活時間(秒):臨時沙箱最多 86400,持久沙箱最多 2592000 |
env | env | — | 所有指令可用的環境變數,加密儲存 |
api_key、base_url | apiKey、baseUrl | 環境變數 | 覆蓋 EQVPS_API_KEY / EQVPS_API_URL |
timeout | timeoutMs | 70 秒 | 每個請求的 HTTP 超時 |
max_retries | maxRetries | 3 | 遇到 429/503 時的重試次數 |
Sandbox.connect(id) 連線到已有沙箱,通常是您昨天建立的持久沙箱。Sandbox.list() 返回帳戶下的全部沙箱,包括執行中和已暫停的。
屬性:id(sb_ + 24 位十六進位制字元)、mode、tariff、state(running、starting、paused、pausing、resuming、deleting、deleted)、env_keys / envKeys(只有名稱,值永遠不會返回)以及 info(原始物件)。refresh() 會重新載入這些屬性。
kill() 刪除沙箱並停止計費。對已經不存在的沙箱呼叫它不算錯誤。
執行程式碼
run(code, language="python", timeout=30) 透過 stdin 把程式碼交給 Python 3.12、Node.js 22 或 bash("python"、"node"、"bash")。exec(command, cwd=None, stdin=None, timeout=30) 執行 shell 指令:字串經 bash -lc 執行,列表則作為 argv 直接執行、不經過 shell。
兩者都返回 ExecResult:
| 欄位 | 含義 |
|---|---|
exit_code | 程式結束代碼 |
stdout、stderr | 輸出,每個流最多 1 MiB |
timed_out | 指令觸發了超時 |
truncated | 輸出被截斷 |
duration_ms | 執行時長 |
ok | exit_code == 0 且沒有超時 |
一次同步呼叫 最長 55 秒。兩個方法都接受只作用於本次呼叫的 env,它會覆蓋建立時設定的值。
長任務:背景任務
傳入 background=True(TypeScript:{ background: true }),立即得到一個 Task。它沒有 55 秒限制,可以一直執行到沙箱生命週期結束。每個沙箱最多 8 個任務。
task = sb.exec("cd /root/app && python3 -m pytest -q", background=True)
result = task.wait(on_output=lambda out, err: print(out, end=""))
print(result.state, result.exit_code) # done 0
const task = await sb.exec("cd /root/app && npm test", { background: true });
const result = await task.wait({ onOutput: (out) => process.stdout.write(out) });
| 方法 | 作用 |
|---|---|
task.logs() | 自上次呼叫以來新增的 stdout 和 stderr |
task.status() | 檢視狀態而不消費輸出:running、done、failed、killed、timeout |
task.wait(timeout, poll_interval=2, on_output) | 輪詢直到任務結束,返回 TaskResult |
task.kill() | 停止任務及其程式 |
sb.task(id) / sb.tasks() | 重新連線某個任務 / 列出任務 |
如果 wait 自身超時,會丟擲 SandboxTimeoutError,但任務仍在執行。執行中的任務還會阻止臨時沙箱因空閒被刪除。
檔案與用量
upload(path, content, mode=None) 把檔案寫到絕對路徑並返回其大小。download(path) 返回位元組,download_text(path) / downloadText(path) 返回字串。單次傳輸上限 5 MB。
usage() 返回執行秒數、已用 CPU 秒數、對外位元組、每小時價格、billed_usd 和 estimated_total_usd。tariffs() 是一個無需金鑰的普通函式,返回目前價格和限制。計費規則見 沙箱限制與計費。
錯誤
所有 API 錯誤都是 EqvpsError 的子類,帶有 status(HTTP 狀態)、code(穩定的字串)和 body。伺服器返回時會填充 retry_after / retryAfter。
| 類 | HTTP | 典型 code | 處理方式 |
|---|---|---|---|
AuthenticationError | 401 | unauthenticated | 檢查 token |
InsufficientBalanceError | 402 | insufficient_balance | 儲值餘額 |
NotFoundError | 404 | not_found | id 錯誤或檔案不存在 |
SandboxPausedError | 409 | sandbox_paused | 因餘額耗盡而暫停,儲值後恢復 |
SandboxDeletedError | 410 | sandbox_deleted | 已被永久刪除 |
FileTooLargeError | 413 | file_too_large | 單次傳輸保持在 5 MB 以下 |
ValidationError | 422 | invalid_request | 修正參數 |
RateLimitError | 429 | too_many_concurrent、too_many_tasks、rate_limited | 等待後重試 |
BudgetExceededError | 429 | budget_exceeded | 達到沙箱的每日或每月支出上限 |
CapacityError | 503 | capacity | 稍後重試或改用更小的方案 |
SandboxTimeoutError | — | request_timeout、wait_timeout | 超時的是 HTTP 請求(或 wait),不是指令 |
大多數 429 來自兩個限制:一個帳戶 同時最多執行 2 條指令,最多持有 20 個沙箱。伺服器告知等待時間時 SDK 會自動重試,三次之後丟擲異常。
什麼時候不需要 SDK
任何有 HTTP 用戶端的語言都可以直接呼叫 API,介面定義在 https://eqvps.com/openapi.json 的 OpenAPI 檔案裡。在 Claude、Cursor 或其他 MCP 用戶端裡執行的代理完全不需要寫程式碼:MCP 伺服器 提供同樣的沙箱工具。如果只是想看看效果,沙箱頁面 列出了方案以及新帳戶的 $1 試用。
評論
目前還沒有評論。歡迎成為第一位。