−25%

na Windows przy płatności rocznej, do 31.10. Do planów

EQVPS
Zacznij

SDK TypeScript do sandboxów w 5 minut: od npm i @eqvps/sdk do pierwszego uruchomienia

Zainstaluj @eqvps/sdk, uruchom sandbox na Firecrackerze z Node.js, Deno lub Bun, wykonaj w nim kod w Pythonie, Node i powłoce, przenieś pliki i śledź długie zadanie na żywo. Sześć kroków z każdą linijką kodu.

Ten poradnik uruchamia sandbox z JavaScriptu lub TypeScriptu. Postawisz odizolowaną mikro-VM na Firecrackerze, wykonasz kod w trzech językach, przeniesiesz pliki i będziesz śledzić wyjście długiego zadania. Każdy krok to krótki fragment kodu.

Potrzebujesz Node.js 18+ (albo Deno, albo Bun) i konta EQVPS.

1. Zdobądź token

SDK uwierzytelnia się zwykłym tokenem konta. Strona łączenie konta pokazuje, jak go uzyskać z panelu, API lub serwera MCP.

export EQVPS_API_KEY="your-token"

Nowe konto bez salda dostaje 1 $ kredytu na sandboxy, gdy po raz pierwszy tworzy sandbox. To wystarczy na ten poradnik wiele razy.

2. Zainstaluj SDK

npm i @eqvps/sdk

Przykłady używają modułów ES i await na najwyższym poziomie. Zapisz je jako pliki .mjs albo jako .ts i uruchamiaj przez npx tsx.

3. Uruchom sandbox i wykonaj kod

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);
});

Na wyjściu będzie id sandboxa (sb_ i 24 kolejne znaki), potem 0 3.12.x. Sandbox.with usuwa sandbox, gdy callback się zakończy, także gdy rzuci wyjątek.

Domyślny język to Python. Dwa pozostałe to jedna opcja:

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);
});

Skrypt, który się wysypie, nie rzuca wyjątku. Sprawdzaj r.ok, które ma wartość true, gdy exit_code wynosi 0, a polecenie nie przekroczyło limitu czasu.

4. Polecenia powłoki i pakiety

exec przyjmuje napis dla powłoki albo tablicę argv. Sandbox ma dostęp do internetu, więc instalacje przez npm i pip działają:

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);
});

Wywołanie synchroniczne trwa najwyżej 55 sekund. Wszystko dłuższe idzie do zadania w tle (krok 6).

5. Pliki

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 przyjmuje napis albo Uint8Array. download zwraca Uint8Array, downloadText napis. Jeden transfer jest ograniczony do 5 MB.

6. Długie zadania z wyjściem na żywo

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
});

Zadanie wraca od razu i nie ma limitu 55 sekund. wait domyślnie odpytuje co 2 sekundy (zmienia to pollIntervalMs). task.kill() je zatrzymuje, sb.task(id) podłącza się do niego z innego procesu.

Błędy

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 sam ponawia 429 i 503 do trzech razy, gdy serwer wyśle Retry-After. Najczęstsze 429 bierze się z uruchamiania więcej niż dwóch poleceń naraz na jednym koncie. Wszystkie klasy są w dokumentacji SDK.

Koszt tego poradnika

Każdy przykład żył kilka sekund i został rozliczony za minimum 60 sekund: 0,00055 $ na small, 0,0011 $ na standard. Zadanie z kroku 6 działało około 100 sekund na standard, czyli około 0,002 $. Razem to znacznie mniej niż cent. Pełny cennik jest w limitach i rozliczeniach sandboxów.

Co dalej

FAQ

Jakie środowiska obsługuje @eqvps/sdk?

Node.js 18 i nowsze, Deno oraz Bun. Nie ma zależności i używa wbudowanego fetch, więc działa też w przeglądarce, ale nie umieszczaj tokenu konta w kodzie frontendu.

Czy sandbox może uruchamiać Pythona, jeśli moja aplikacja jest w TypeScript?

Tak. Język twojej aplikacji i język kodu w sandboxie są niezależne. run przyjmuje language python, node lub bash, a exec wykonuje dowolne polecenie powłoki.

Jak mieć pewność, że sandbox zostanie usunięty?

Użyj Sandbox.with(options, fn), które usuwa sandbox, gdy fn się zakończy lub rzuci wyjątek. W TypeScript 5.2 i nowszym możesz też napisać await using sb = await Sandbox.create().

Co zwraca run, gdy kod się wysypie?

ExecResult z niezerowym exit_code i błędem w stderr. Nic nie jest rzucane. Wyjątki są tylko dla błędów API, takich jak nieprawidłowy token albo puste saldo.

Komentarze

Brak komentarzy. Bądź pierwszy.

Zostaw komentarz

Komentarze są moderowane przed pojawieniem się.