−25%

sur Windows en paiement annuel, jusqu'au 31/10. Voir les offres

EQVPS
Commencer

SDK TypeScript pour sandboxes en 5 minutes : de npm i @eqvps/sdk au premier lancement

Installez @eqvps/sdk, démarrez une sandbox Firecracker depuis Node.js, Deno ou Bun, exécutez-y du code Python, Node et shell, transférez des fichiers et suivez une longue tâche en direct. Six étapes avec chaque ligne de code.

Ce guide fait tourner une sandbox depuis JavaScript ou TypeScript. Vous démarrerez une microVM Firecracker isolée, exécuterez du code dans trois langages, transférerez des fichiers et suivrez la sortie d'une longue tâche. Chaque étape est un court extrait.

Il vous faut Node.js 18+ (ou Deno, ou Bun) et un compte EQVPS.

1. Obtenir un token

Le SDK s'authentifie avec un token de compte ordinaire. Connecter votre compte montre comment en obtenir un depuis le tableau de bord, l'API ou le serveur MCP.

export EQVPS_API_KEY="your-token"

Un nouveau compte sans solde reçoit 1 $ de crédit sandbox la première fois qu'il crée une sandbox. Cela couvre ce guide de nombreuses fois.

2. Installer le SDK

npm i @eqvps/sdk

Les exemples utilisent des modules ES et await au niveau supérieur. Enregistrez-les en fichiers .mjs, ou en .ts et lancez-les avec npx tsx.

3. Démarrer une sandbox et exécuter du code

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

La sortie est l'identifiant de la sandbox (sb_ suivi de 24 caractères), puis 0 3.12.x. Sandbox.with supprime la sandbox quand le callback se termine, même s'il lève une exception.

Le langage par défaut est Python. Les deux autres sont à une option près :

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

Un script qui échoue ne lève rien. Vérifiez r.ok, qui vaut true quand exit_code est 0 et que la commande n'a pas expiré.

4. Commandes shell et paquets

exec accepte une chaîne shell ou un tableau argv. La sandbox a accès à Internet, les installations npm et pip fonctionnent donc :

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

Un appel synchrone dure au maximum 55 secondes. Au-delà, passez par une tâche de fond (étape 6).

5. Fichiers

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 accepte une chaîne ou un Uint8Array. download renvoie un Uint8Array, downloadText une chaîne. Un transfert est limité à 5 MB.

6. Longues tâches avec sortie en direct

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

La tâche rend la main immédiatement et n'a pas de limite de 55 secondes. wait interroge toutes les 2 secondes par défaut (pollIntervalMs le change). task.kill() l'arrête ; sb.task(id) s'y rattache depuis un autre processus.

Erreurs

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

Le SDK relance lui-même les 429 et 503, jusqu'à trois fois, quand le serveur envoie Retry-After. Le 429 le plus courant vient de plus de deux commandes simultanées sur un même compte. Toutes les classes sont dans la référence du SDK.

Coût de ce guide

Chaque exemple a vécu quelques secondes et a été facturé au minimum de 60 secondes : 0,00055 $ sur small, 0,0011 $ sur standard. La tâche de l'étape 6 a tourné environ 100 secondes sur standard, soit environ 0,002 $. Le tout reste bien en dessous d'un centime. La grille complète est dans limites et facturation des sandboxes.

Pour aller plus loin

FAQ

Quels environnements @eqvps/sdk prend-il en charge ?

Node.js 18 et plus récent, Deno et Bun. Il n'a aucune dépendance et utilise le fetch intégré, il fonctionne donc aussi dans un navigateur, mais ne mettez pas votre token de compte dans du code front-end.

La sandbox peut-elle exécuter du Python si mon application est en TypeScript ?

Oui. Le langage de votre application et celui du code de la sandbox sont indépendants. run accepte language python, node ou bash, et exec exécute n'importe quelle commande shell.

Comment être sûr que la sandbox est supprimée ?

Utilisez Sandbox.with(options, fn), qui supprime la sandbox quand fn se termine ou lève une exception. Avec TypeScript 5.2 ou plus récent, vous pouvez aussi écrire await using sb = await Sandbox.create().

Que renvoie run quand le code échoue ?

Un ExecResult avec un exit_code non nul et l'erreur dans stderr. Rien n'est levé. Les exceptions sont réservées aux erreurs d'API, comme un token invalide ou un solde vide.

Commentaires

Pas encore de commentaires. Soyez le premier.

Laisser un commentaire

Les commentaires sont modérés avant leur publication.