−25%

на річну оплату Windows, до 31.10. До тарифів

EQVPS
Почати

SDK для пісочниць на TypeScript за 5 хвилин: від npm i @eqvps/sdk до першого запуску

Встановіть @eqvps/sdk, запустіть пісочницю на Firecracker із Node.js, Deno або Bun, виконайте в ній код на Python, Node і shell, передайте файли й стежте за довгим завданням наживо. Шість кроків, увесь код на місці.

Цей посібник запускає пісочницю з JavaScript або TypeScript. Ви піднімете ізольовану мікро-VM на Firecracker, виконаєте код трьома мовами, передасте файли й отримуватимете вивід довгого завдання. Кожен крок — короткий фрагмент коду.

Потрібні Node.js 18+ (або Deno, або Bun) і акаунт EQVPS.

1. Отримайте токен

SDK авторизується звичайним токеном акаунта. Як отримати його в кабінеті, через API або MCP-сервер, показано на сторінці підключення акаунта.

export EQVPS_API_KEY="your-token"

Новий акаунт без балансу отримує $1 кредиту на пісочниці, коли вперше створює пісочницю. Цього з запасом вистачить на весь посібник багато разів.

2. Встановіть SDK

npm i @eqvps/sdk

Приклади використовують ES-модулі й await на верхньому рівні. Зберігайте їх як файли .mjs або як .ts і запускайте через npx tsx.

3. Запустіть пісочницю й виконайте код

import { Sandbox } from "@eqvps/sdk";

await Sandbox.with({ tariff: "small" }, async (sb) => {
  console.log(sb.id);
  const r = await sb.run("import platform; print(platform.python_version())");
  console.log(r.exit_code, r.stdout);
});

У виводі буде id пісочниці (sb_ і ще 24 символи), потім 0 3.12.x. Sandbox.with видаляє пісочницю, коли колбек завершився, зокрема якщо він кинув виняток.

За замовчуванням мова — Python. Дві інші — одна опція:

await Sandbox.with({}, async (sb) => {
  const js = await sb.run("console.log(process.version)", { language: "node" });
  const sh = await sb.run("uname -r && nproc", { language: "bash" });
  console.log(js.stdout, sh.stdout);
});

Скрипт, що впав, винятку не кидає. Перевіряйте r.ok: він дорівнює true, коли exit_code дорівнює 0 і команда не вперлася в таймаут.

4. Команди shell і пакети

exec приймає рядок для shell або масив argv. Пісочниця має доступ в інтернет, тож встановлення через npm і pip працює:

await Sandbox.with({ tariff: "small" }, async (sb) => {
  await sb.exec("mkdir -p /root/app && cd /root/app && npm init -y && npm i lodash", { timeout: 55 });
  const r = await sb.exec(["node", "-e", "console.log(require('/root/app/node_modules/lodash').VERSION)"]);
  console.log(r.stdout);
});

Синхронний виклик триває не більше 55 секунд. Усе, що довше, іде у фонове завдання (крок 6).

5. Файли

await Sandbox.with({}, async (sb) => {
  await sb.upload("/root/input.json", JSON.stringify({ values: [3, 5, 8] }));
  await sb.run("import json; d = json.load(open('/root/input.json')); open('/root/out.txt', 'w').write(str(sum(d['values'])))");
  console.log(await sb.downloadText("/root/out.txt"));   // 16
});

upload приймає рядок або Uint8Array. download повертає Uint8Array, downloadText — рядок. Одна передача обмежена 5 MB.

6. Довгі завдання з живим виводом

await Sandbox.with({ tariff: "standard" }, async (sb) => {
  const task = await sb.exec("for i in 1 2 3 4 5; do echo step $i; sleep 20; done", { background: true });
  const res = await task.wait({ onOutput: (out) => process.stdout.write(out) });
  console.log(res.state, res.exit_code);   // done 0
});

Завдання повертається одразу, і обмеження в 55 секунд у нього немає. wait за замовчуванням опитує кожні 2 секунди (це змінює pollIntervalMs). task.kill() зупиняє завдання, sb.task(id) під'єднується до нього з іншого процесу.

Помилки

import { Sandbox, InsufficientBalanceError, RateLimitError } from "@eqvps/sdk";

try {
  await Sandbox.with({}, async (sb) => console.log((await sb.run("print(1)")).stdout));
} catch (e) {
  if (e instanceof InsufficientBalanceError) console.log("Top up the balance");
  else if (e instanceof RateLimitError) console.log("Busy, retry in", e.retryAfter);
  else throw e;
}

SDK сам повторює 429 і 503 до трьох разів, якщо сервер надіслав Retry-After. Найчастіший 429 — більше двох одночасних команд на одному акаунті. Усі класи є в довіднику SDK.

Скільки коштує цей посібник

Кожен приклад жив кілька секунд, і за нього списано мінімум у 60 секунд: $0.00055 на small, $0.0011 на standard. Завдання з кроку 6 працювало близько 100 секунд на standard, це приблизно $0.002. Усе разом — помітно менше цента. Повний прайс — у розділі ліміти й оплата пісочниць.

Що далі

Часті питання

Які середовища підтримує @eqvps/sdk?

Node.js 18 і новіший, Deno і Bun. Залежностей немає, використовується вбудований fetch, тож SDK працює й у браузері, але токен акаунта у фронтенд-код не кладіть.

Чи може пісочниця виконувати Python, якщо мій застосунок на TypeScript?

Так. Мова вашого застосунку й мова коду в пісочниці не пов'язані. run приймає language python, node або bash, а exec виконує будь-яку команду shell.

Як гарантувати, що пісочниця видалиться?

Використовуйте Sandbox.with(options, fn): пісочниця видаляється, коли fn завершилася або кинула виняток. У TypeScript 5.2 і новішому можна писати await using sb = await Sandbox.create().

Що повертає run, якщо код упав?

ExecResult із ненульовим exit_code і помилкою в stderr. Винятку немає. Винятки бувають лише при помилках API, наприклад при неправильному токені або порожньому балансі.

Коментарі

Поки немає коментарів. Будьте першим.

Залишити коментар

Коментарі проходять модерацію перед публікацією.