Sandboxes クイックスタート
このクイックスタートでは、Lizard SDK で sandbox を作成し、その中で Python を実行し、ファイルを書き込み、ポートを公開して、後片付けを行います。各ステップには TypeScript と Python のコードがあります。Pro またはトライアル中の Lizard (lizard.build) アカウント、API キー、プロジェクトが必要です。まず Sandboxes とは何かを知りたい場合は、概要 を読んでください。
インストールと認証
Lizard SDK をインストールし、Settings → API keys で、または lizard keys create <name> で API キーを作成します。LIZARD_API_KEY に保存してください。すべての sandbox はプロジェクトに属します。例ではその ID を projectId(Python では project_id)として渡しています。project には slug や名前も指定できます。
npm install @lizard-build/sdk
pip install lizard-sdk
export LIZARD_API_KEY="<your-api-key>"コマンドの実行
Sandbox.create はテンプレートから sandbox を起動します。ここでは、Python と一般的なデータ処理ライブラリを含む interpreter を使っています。timeoutMs は有効期間を設定します。SDK の既定は 5 分です。
import { Sandbox } from '@lizard-build/sdk';
const sandbox = await Sandbox.create('interpreter', {
projectId: 'proj_123', timeoutMs: 300_000,
});
try {
const result = await sandbox.process.exec("python -c 'print(2 ** 10)'");
console.log(result.stdout, result.stderr, result.exitCode);
} finally {
await sandbox.kill();
}from lizard import Sandbox
sandbox = Sandbox.create("interpreter", project_id="proj_123", timeout_ms=300_000)
try:
result = sandbox.process.exec_("python -c 'print(2 ** 10)'")
print(result.stdout, result.stderr, result.exit_code)
finally:
sandbox.kill()0 以外の終了コードはエラーではなく結果です: exitCode(Python では exit_code)を自分で確認してください。
ファイル
テキストまたはバイトは fs.write で書き込み、テキストは fs.read で、バイトは fs.readBytes(Python では read_bytes)で読み取ります。ディスク上のファイルはすべて一時停止後も残り、スナップショットにも含まれます。kill または期限切れでディスクは削除されるため、後で必要なファイルは /workspace の Persistent Volumes かスナップショットに残してください。
await sandbox.fs.write("/tmp/task.py", "print(42)\n");
const result = await sandbox.process.exec("python /tmp/task.py");
console.log(result.stdout);sandbox.fs.write("/tmp/task.py", "print(42)\n")
result = sandbox.process.exec_("python /tmp/task.py")
print(result.stdout)公開ポート
0.0.0.0 で待ち受けるサーバーを起動し、exposePort(port)(Python では expose_port)を呼び出します。url、hostname、accessToken が返されます。ポートは非公開です。ブラウザで url を開く(?lizard_token= が付いています)か、X-Lizard-Access-Token ヘッダーでトークンを送信してください。トークンのないリクエストには 401 が返されます。sandbox を停止するとポートは応答しなくなります。エージェントが作った 開発サーバーについては、プレビュー URL を参照してください。
await sandbox.process.exec(
"nohup python -m http.server 3000 --bind 0.0.0.0 --directory /tmp >/tmp/http.log 2>&1 </dev/null &",
);
const { url, hostname, accessToken } = await sandbox.exposePort(3000);
console.log(url); // open in a browser
const res = await fetch(`https://${hostname}/`, {
headers: { 'X-Lizard-Access-Token': accessToken },
});sandbox.process.exec_(
"nohup python -m http.server 3000 --bind 0.0.0.0 --directory /tmp >/tmp/http.log 2>&1 </dev/null &"
)
exposed = sandbox.expose_port(3000)
print(exposed.url) # open in a browser実行中の sandbox への再接続
sandbox ID(sandbox.sandboxId、Python では sandbox.sandbox_id)を保持しておき、別のプロセスや後のリクエストから Sandbox.connect(id) を呼び出すと、同じ sandbox のハンドルを取得できます。connect は sandbox が存在するかどうかを確認するだけです: 一時停止中の sandbox を再開せず、sandbox が停止するか期限切れになった後は NotFoundError を投げます。
const connected = await Sandbox.connect(sandbox.sandboxId);
console.log(await connected.getInfo());connected = Sandbox.connect(sandbox.sandbox_id)
print(connected.get_info())一時停止、再開、スナップショット
pause() は sandbox のメモリ、実行中のプロセス、ディスク上のすべてのファイルを保存します。一時停止が完了すると計算料金は止まりますが、Persistent Volumes のストレージ料金は引き続き発生します。resume() は同じ ID で sandbox を復元し、計算料金を再開します。どちらも処理をキューに入れてすぐに戻るため、成功を確認するには paused または running を待ってください。
await sandbox.pause();
await sandbox.waitForStatus('paused');
await sandbox.resume();
await sandbox.waitForStatus('running');- 一時停止すると、開いているネットワーク接続は閉じられます。再開後、sandbox 内のプログラムは再接続する必要があります。
- プロセスを保存できない場合、sandbox は実行を続け、
waitForStatusが理由付きのエラーを投げます。再開に失敗した場合、sandbox はチェックポイントを保持したまま一時停止状態に残ります。resume()を再度呼び出してください。 - 一時停止中は有効期間の期限が止まり、再開後に続きから進みます。一時停止中の sandbox は実行数の上限に数えられません。
高速一時停止。 pause({ fast: true })(Python: pause(fast=True)、CLI: lizard sandbox pause <id> --fast)はファイルだけを保持します。ディスク全体と /workspace です。メモリのサイズにかかわらず約 1 秒で完了します。通常の一時停止は、使用中のメモリが多いほど時間がかかります。実行中のプロセスは終了し、resume() は再起動と同じようにファイルを保ったままサンドボックスを新しく起動します。再開のレスポンスには memoryRestored: false が含まれます。実行中のものを残す必要がないときに使ってください。課金と有効期限の扱いは通常の一時停止と同じです。
await sandbox.pause({ fast: true });
await sandbox.waitForStatus('paused');スナップショットは、実行中の sandbox のメモリ、実行中のプロセス、ディスク上のすべてのファイルを保存します。スナップショットは、それ自身のプロジェクトとリージョンでのみ restore できます。restore できるのは、作成したユーザーとそのプロジェクトのメンバーです。ほかのプロジェクトを指定した Sandbox.restore(id, { projectId })(Python では project_id=)は HTTP 403 で失敗し、code は SNAPSHOT_SCOPE になります。取得前にクライアントとターミナルを閉じ、/workspace への書き込みを止めてください。
sandbox に Persistent Volume が接続されている場合、スナップショットには取得時点のボリュームのファイルのコピーが含まれます。どの restore も、現在のボリュームではなくそのコピーを受け取り、別のボリュームは接続できません。スナップショットを restore できる人は誰でもそのファイルを読めます。ボリュームのない sandbox のスナップショットは、restore 時に volumeId(Python では volume_id)で同じプロジェクトとリージョンのボリュームをマウントできます。
const saved = await sandbox.snapshot('my-app');
await Sandbox.waitForSnapshot(saved.id);
const copy = await Sandbox.restore(saved.id);スナップショットは、呼び出しが戻った時点で準備が完了し、ディスクから restore されるため、poolSize は適用されません。restore のたびに元の sandbox と同じサイズで実行され、そのサイズの時間単価で課金されます。restore には size は適用されません。CLI では lizard sandbox pause <id>、lizard sandbox resume <id>、lizard sandbox snapshot <id> --name my-app、lizard sandbox restore <snapshot-id> を使います。--volume については lizard sandbox を参照してください。
後片付けと次のステップ
タスクが終わったら、例の finally のように kill() を呼び出します。Python では、with Sandbox.create(...) as sandbox: を使うと、ブロックを抜けるときに sandbox が停止します。停止し忘れた sandbox は期限に達すると停止します。別の有効期間を設定しない限り、作成から 5 分後です。リソースと有効期間 を参照してください。
- すべての呼び出し、オプション、エラー: Sandbox API と SDK リファレンス。
- 呼び出し間で状態を保持する、LLM が書いたコード: コードインタープリター。
- sandbox の終了後も残るファイル: Persistent Volumes。
- sandbox 内のコーディングエージェント: Claude Code または OpenCode。
- ターミナルから同じ手順を実行:
lizard sandbox。ブラウザーでは: Sandboxes ダッシュボード。 - サイズ、料金、同時に実行できる sandbox の数: 制限。製品の概要と比較: Sandboxes。
更新日