Sandboxes-Schnellstart
In diesem Schnellstart erstellen Sie mit Lizard SDK eine Sandbox, führen darin Python aus, schreiben eine Datei, öffnen einen Port und beenden die Sandbox. Jeder Schritt hat Code für TypeScript und Python. Sie brauchen ein Konto bei Lizard (lizard.build) mit Pro oder der Testphase, einen API-Schlüssel und ein Projekt. Was Sandboxes sind, erfahren Sie zuerst im Überblick.
Installation und Anmeldung
Installieren Sie das Lizard SDK und erstellen Sie unter Settings → API keys oder mit lizard keys create <name> einen API-Schlüssel. Speichern Sie ihn in LIZARD_API_KEY. Jede Sandbox gehört zu einem Projekt; die Beispiele übergeben dessen ID als projectId (Python: project_id), und project akzeptiert auch einen Slug oder Namen.
npm install @lizard-build/sdk
pip install lizard-sdk
export LIZARD_API_KEY="<your-api-key>"Befehl ausführen
Sandbox.create startet eine Sandbox aus einer Vorlage, hier interpreter, die Python und gängige Datenbibliotheken enthält. timeoutMs legt ihre Laufzeit fest; der Standard im SDK sind fünf Minuten.
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()Ein Exit-Code ungleich null steht im Ergebnis und löst keine Exception aus: Prüfen Sie exitCode (Python: exit_code) selbst.
Dateien
Schreiben Sie Text oder Bytes mit fs.write, lesen Sie Text mit fs.read und Bytes mit fs.readBytes (Python: read_bytes). Dateien bleiben nur so lange erhalten wie die Sandbox, es sei denn, Sie schreiben sie auf ein Volume aus Persistent Volumes unter /workspace.
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)Öffentliche Ports
Starten Sie einen Server auf 0.0.0.0 und rufen Sie dann exposePort(port) auf (Python: expose_port). Der Aufruf gibt url, hostname und accessToken zurück. Der Port ist privat: Öffnen Sie url im Browser (sie enthält ?lizard_token=) oder senden Sie das Token im Header X-Lizard-Access-Token. Anfragen ohne Token erhalten 401. Nach dem Stopp bedient die Sandbox den Port nicht mehr. Für einen Dev-Server, den ein Agent gebaut hat, siehe Vorschau-URLs.
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 browserMit einer laufenden Sandbox verbinden
Merken Sie sich die Sandbox-ID (sandbox.sandboxId, Python: sandbox.sandbox_id) und rufen Sie Sandbox.connect(id) aus einem anderen Prozess oder einer späteren Anfrage auf, um ein Handle auf dieselbe Sandbox zu erhalten. connect prüft nur, ob die Sandbox existiert: Eine pausierte Sandbox wird dadurch nicht fortgesetzt, und sobald die Sandbox beendet oder abgelaufen ist, löst der Aufruf NotFoundError aus.
const connected = await Sandbox.connect(sandbox.sandboxId);
console.log(await connected.getInfo());connected = Sandbox.connect(sandbox.sandbox_id)
print(connected.get_info())Pause, Fortsetzen und Snapshots
pause() speichert Arbeitsspeicher und laufende Prozesse der Sandbox, behält /workspace auf ihrem Node und beendet die Abrechnung. resume() stellt die Sandbox mit derselben ID wieder her. Beide Aufrufe reihen die Arbeit ein und kehren sofort zurück; warten Sie auf den neuen Status.
await sandbox.pause();
await sandbox.waitForStatus('paused');
await sandbox.resume();
await sandbox.waitForStatus('running');- Eine Pause schließt offene Netzwerkverbindungen. Programme in der Sandbox müssen sich nach dem Fortsetzen neu verbinden.
- Lassen sich die Prozesse nicht speichern, läuft die Sandbox weiter, und
waitForStatuslöst einen Fehler mit dem Grund aus. Schlägt das Fortsetzen fehl, bleibt die Sandbox mit ihrem Checkpoint pausiert; rufen Sieresume()erneut auf. - Während der Pause bleibt die restliche Laufzeit unverändert. Nach dem Fortsetzen zählt sie weiter herunter. Eine pausierte Sandbox zählt nicht zum Limit laufender Sandboxes.
- Eine pausierte Sandbox wird auf demselben Node fortgesetzt. Fällt dieser Node aus, geht der pausierte Zustand verloren; exportieren Sie benötigte Dateien.
Ein Snapshot speichert Arbeitsspeicher und /workspace-Dateien einer laufenden Sandbox als private Vorlage im Projekt. Jedes Restore startet eine neue Sandbox in der Region des Snapshots. Schließen Sie vor der Aufnahme Clients und Terminals und stoppen Sie Schreibvorgänge in /workspace. Angehängte Persistent Volumes werden nicht erfasst.
const saved = await sandbox.snapshot('my-app', { poolSize: 5 });
await Sandbox.waitForSnapshot(saved.id);
const copy = await Sandbox.restore(saved.id);Ein Snapshot einer Firecracker-Sandbox ist bereit, sobald der Aufruf zurückkehrt, und wird von der Festplatte wiederhergestellt; daher gilt poolSize nicht. Jede Wiederherstellung startet eine Sandbox in der Größe der Quelle. Für sie gilt der Stundenpreis dieser Größe. Ein Snapshot einer Pod-Sandbox hält warme Kopien bereit, standardmäßig fünf (eine bis zehn); ist keine bereit, kann Restore HTTP 503 zurückgeben, bis der Pool nachgefüllt ist, und die wiederhergestellte Sandbox wird nach gemessener Nutzung abgerechnet. In beiden Fällen gilt size nicht für ein Restore. In der CLI nutzen Sie lizard sandbox pause <id>, lizard sandbox resume <id>, lizard sandbox snapshot <id> --name my-app und lizard sandbox restore <snapshot-id>.
Aufräumen und nächste Schritte
Rufen Sie kill() auf, wenn die Aufgabe erledigt ist, wie es die Beispiele in finally tun. In Python beendet with Sandbox.create(...) as sandbox: die Sandbox, wenn der Block endet. Eine nicht beendete Sandbox stoppt nach Ablauf ihrer Laufzeit, fünf Minuten nach der Erstellung, sofern Sie keine andere Laufzeit setzen; siehe Ressourcen und Laufzeit.
- Jeder Aufruf, jede Option und jeder Fehler: Sandbox-API- und SDK-Referenz.
- Code von einem LLM mit Zustand zwischen Aufrufen: Code Interpreter.
- Dateien, die eine Sandbox überdauern: Persistent Volumes.
- Ein Coding-Agent in einer Sandbox: Claude Code oder OpenCode.
- Dieselben Schritte aus einem Terminal:
lizard sandbox. Im Browser: das Sandboxes-Dashboard. - Größen, Preise und wie viele Sandboxes gleichzeitig laufen können: Limits. Produktüberblick und Vergleich: Sandboxes.
Aktualisiert