−25%

Windows 年払い、10月31日まで。 プランを見る

EQVPS
始める

5 分で始めるサンドボックス用 TypeScript SDK:npm i @eqvps/sdk から最初の実行まで

@eqvps/sdk をインストールし、Node.js、Deno、Bun から Firecracker サンドボックスを起動して、Python、Node、シェルのコードを実行し、ファイルをやり取りし、長いジョブの出力をリアルタイムで追います。全コード付きの 6 ステップです。

このガイドでは JavaScript または TypeScript からサンドボックスを動かします。隔離された Firecracker の microVM を起動し、3 つの言語でコードを実行し、ファイルをやり取りし、長いジョブの出力を追います。各ステップは短いコード片です。

必要なのは 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 です。ほかの 2 つはオプション 1 つで切り替えられます。

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 を確認してください。exit_code が 0 でタイムアウトしていなければ true です。

4. シェルコマンドとパッケージ

exec はシェル文字列か 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 は文字列を返します。1 回の転送は 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;
}

サーバーが Retry-After を返した場合、SDK は 429 と 503 を最大 3 回まで自動で再試行します。最もよくある 429 は、1 つのアカウントで 3 つ以上のコマンドを同時に実行したときに起きます。すべてのクラスは SDK リファレンスにあります。

このガイドの費用

各例は数秒しか存在せず、最低料金の 60 秒分で課金されました。small で 0.00055 ドル、standard で 0.0011 ドルです。ステップ 6 のジョブは standard で約 100 秒動き、約 0.002 ドルでした。すべて合わせても 1 セントを大きく下回ります。料金表の全体はサンドボックスの制限と課金にあります。

次のステップ

よくある質問

@eqvps/sdk はどのランタイムに対応していますか?

Node.js 18 以降、Deno、Bun です。依存パッケージはなく組み込みの fetch を使うのでブラウザでも動きますが、アカウントトークンをフロントエンドのコードに置かないでください。

アプリが TypeScript でも、サンドボックスで Python を動かせますか?

動かせます。アプリの言語とサンドボックス内のコードの言語は無関係です。run の language には python、node、bash を指定でき、exec は任意のシェルコマンドを実行します。

サンドボックスが確実に削除されるようにするには?

Sandbox.with(options, fn) を使います。fn が終わったとき、または例外を投げたときにサンドボックスを削除します。TypeScript 5.2 以降なら await using sb = await Sandbox.create() とも書けます。

コードが失敗したとき run は何を返しますか?

0 以外の exit_code と、stderr にエラーが入った ExecResult を返します。例外は投げません。例外が出るのは、トークンが無効、残高がゼロといった API エラーの場合だけです。

コメント

まだコメントはありません。最初になりましょう。

コメントを残す

コメントは表示される前にモデレートされます。