SDK е тънък слой над REST API на пясъчниците. Спестява ви три неща: да сглобявате заявки на ръка, да ги повтаряте, когато платформата е заета, и да забравяте да изтриете пясъчника, когато кодът хвърли изключение. Всичко тук отговаря на версия 0.2.0 на двата пакета.
Ако никога не сте създавали пясъчник, ръководството за свързване за 5 минути първо ще ви даде токен. Какво е пясъчник и какво има в него, е обяснено в Пясъчници.
Инсталиране и настройка
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) изпълнява команда на обвивката: низ минава през bash -lc, списък се изпълнява като argv без обвивка.
И двата връщат 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 | проверете токена |
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 директно; крайните точки са описани във файла OpenAPI на https://eqvps.com/openapi.json. Агентите в Claude, Cursor и други MCP клиенти изобщо нямат нужда от код: MCP сървърът има същите инструменти за пясъчници. А ако просто искате да видите как работи, на страницата за пясъчници са тарифите и пробният $1 за нови акаунти.
Коментари
Още няма коментари. Бъди първият.