−25%

su Windows con pagamento annuale, fino al 31/10. Vai ai piani

EQVPS
Inizia

SDK TypeScript per sandbox in 5 minuti: da npm i @eqvps/sdk alla prima esecuzione

Installa @eqvps/sdk, avvia una sandbox Firecracker da Node.js, Deno o Bun, esegui codice Python, Node e shell, sposta file e segui un lavoro lungo in diretta. Sei passi con ogni riga di codice.

Questa guida fa partire una sandbox da JavaScript o TypeScript. Avvierai una microVM Firecracker isolata, eseguirai codice in tre linguaggi, sposterai file e seguirai l'output di un lavoro lungo. Ogni passo è un breve snippet.

Ti servono Node.js 18+ (oppure Deno, o Bun) e un account EQVPS.

1. Ottieni un token

L'SDK si autentica con un normale token dell'account. Collegare l'account mostra come ottenerlo da dashboard, API o server MCP.

export EQVPS_API_KEY="your-token"

Un nuovo account senza saldo riceve 1 $ di credito per sandbox la prima volta che ne crea una. Basta per questa guida molte volte.

2. Installa l'SDK

npm i @eqvps/sdk

Gli esempi usano moduli ES e await di primo livello. Salvali come file .mjs, oppure come .ts ed eseguili con npx tsx.

3. Avvia una sandbox ed esegui codice

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

L'output è l'id della sandbox (sb_ più altri 24 caratteri), poi 0 3.12.x. Sandbox.with elimina la sandbox quando il callback termina, anche se lancia un'eccezione.

Il linguaggio predefinito è Python. Gli altri due sono a un'opzione di distanza:

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

Uno script che fallisce non lancia nulla. Controlla r.ok, che è true quando exit_code è 0 e il comando non è andato in timeout.

4. Comandi shell e pacchetti

exec accetta una stringa shell o un array argv. La sandbox ha accesso a Internet, quindi le installazioni con npm e pip funzionano:

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

Una chiamata sincrona dura al massimo 55 secondi. Tutto ciò che dura di più va in un task in background (passo 6).

5. File

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 accetta una stringa o un Uint8Array. download restituisce un Uint8Array, downloadText una stringa. Un trasferimento è limitato a 5 MB.

6. Lavori lunghi con output in diretta

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

Il task ritorna subito e non ha il limite di 55 secondi. wait interroga ogni 2 secondi per impostazione predefinita (pollIntervalMs lo cambia). task.kill() lo ferma; sb.task(id) si ricollega da un altro processo.

Errori

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

L'SDK ripete da solo 429 e 503, fino a tre volte, quando il server invia Retry-After. Il 429 più comune nasce dall'eseguire più di due comandi contemporaneamente su un account. Tutte le classi sono nel riferimento dell'SDK.

Costo di questa guida

Ogni esempio è vissuto pochi secondi ed è stato fatturato al minimo di 60 secondi: 0,00055 $ su small, 0,0011 $ su standard. Il lavoro del passo 6 è durato circa 100 secondi su standard, circa 0,002 $. Tutto insieme resta ben sotto un centesimo. Il listino completo è in limiti e fatturazione delle sandbox.

Prossimi passi

FAQ

Quali runtime supporta @eqvps/sdk?

Node.js 18 e successivi, Deno e Bun. Non ha dipendenze e usa il fetch integrato, quindi funziona anche nel browser, ma non mettere il token dell'account nel codice front-end.

La sandbox può eseguire Python se la mia app è in TypeScript?

Sì. Il linguaggio della tua app e quello del codice nella sandbox sono indipendenti. run accetta language python, node o bash, ed exec esegue qualsiasi comando shell.

Come mi assicuro che la sandbox venga eliminata?

Usa Sandbox.with(options, fn), che elimina la sandbox quando fn termina o lancia un'eccezione. Con TypeScript 5.2 o successivo puoi anche scrivere await using sb = await Sandbox.create().

Cosa restituisce run quando il codice fallisce?

Un ExecResult con exit_code diverso da zero e l'errore in stderr. Non lancia nulla. Le eccezioni sono solo per errori dell'API, come un token non valido o un saldo vuoto.

Commenti

Ancora nessun commento. Sii il primo.

Lascia un commento

I commenti sono moderati prima di comparire.