Быстрый старт Sandboxes
В этом руководстве вы создадите sandbox с помощью Lizard SDK, запустите в нём Python, запишете файл, откроете порт и освободите ресурсы. У каждого шага есть код на TypeScript и Python. Вам нужны аккаунт Lizard (lizard.build) на Pro или в пробном периоде, API-ключ и проект. Чтобы сначала узнать, что такое Sandboxes, прочитайте обзор.
Установка и вход
Установите Lizard SDK и создайте API-ключ в Settings → API keys или командой lizard keys create <name>. Сохраните его в 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 из шаблона, здесь это interpreter с Python и основными библиотеками для работы с данными. timeoutMs задаёт срок жизни; в SDK по умолчанию это пять минут.
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()Ненулевой код завершения возвращается в результате, а не вызывает исключение: проверяйте exitCode (в Python: exit_code) сами.
Файлы
fs.write записывает текст или байты, fs.read читает текст, а fs.readBytes (в Python: read_bytes) читает байты. Файлы доступны, только пока работает sandbox, если не записать их на том Persistent Volumes в /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)Публичные порты
Запустите сервер на 0.0.0.0, затем вызовите exposePort(port) (в Python: expose_port). Он возвращает url, hostname и accessToken. Порт закрыт: откройте url в браузере (в нём есть ?lizard_token=) или передайте токен в заголовке X-Lizard-Access-Token. Запросы без токена получают 401. После остановки sandbox порт больше не обслуживается. Про dev-сервер, который собрал агент, см. 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
Сохраните ID sandbox (sandbox.sandboxId, в Python: sandbox.sandbox_id) и вызовите Sandbox.connect(id) из другого процесса или в более позднем запросе, чтобы получить объект для того же sandbox. connect только проверяет, что sandbox существует: он не возобновляет приостановленный sandbox и выбрасывает NotFoundError, если sandbox уже остановлен через kill или его срок истёк.
const connected = await Sandbox.connect(sandbox.sandboxId);
console.log(await connected.getInfo());connected = Sandbox.connect(sandbox.sandbox_id)
print(connected.get_info())Пауза, возобновление и снимки
pause() сохраняет память и запущенные процессы sandbox и оставляет /workspace на его узле. Успешная пауза останавливает оплату вычислений; хранение в Persistent Volumes оплачивается дальше. resume() восстанавливает sandbox с тем же ID и возобновляет оплату вычислений. Оба вызова ставят задачу в очередь и сразу возвращают ответ; дождитесь статуса paused или running, чтобы подтвердить успех.
await sandbox.pause();
await sandbox.waitForStatus('paused');
await sandbox.resume();
await sandbox.waitForStatus('running');- Пауза закрывает открытые сетевые соединения. После возобновления программы в sandbox должны подключиться заново.
- Если процессы не удаётся сохранить, sandbox продолжает работать, а
waitForStatusвыбрасывает ошибку с причиной. Если возобновление не удалось, sandbox остаётся на паузе с сохранённым состоянием; вызовитеresume()ещё раз. - Пока sandbox на паузе, срок жизни не расходуется; после возобновления отсчёт продолжается. Приостановленный sandbox не учитывается в лимите запущенных.
- Приостановленный sandbox возобновляется на том же узле. Если узел выйдет из строя, сохранённое состояние пропадёт; выгрузите нужные файлы заранее.
Снимок (snapshot) сохраняет память и файлы /workspace работающего sandbox как приватный шаблон проекта. Каждый restore запускает новый sandbox в регионе снимка. Перед снимком закройте клиенты и терминалы и остановите запись в /workspace. Подключённые Persistent Volumes в снимок не входят.
const saved = await sandbox.snapshot('my-app', { poolSize: 5 });
await Sandbox.waitForSnapshot(saved.id);
const copy = await Sandbox.restore(saved.id);Снимок sandbox на Firecracker готов сразу после возврата вызова и восстанавливается с диска, поэтому poolSize к нему не применяется. Каждый restore запускается с размером источника и оплачивается по почасовой цене этого размера. Снимок sandbox, работающего как pod, держит готовые копии, по умолчанию пять (от одной до десяти); если готовых копий нет, restore может вернуть HTTP 503, пока пул не пополнится, а восстановленный sandbox оплачивается по измеренному расходу. В обоих случаях size к restore не применяется. В CLI используйте lizard sandbox pause <id>, lizard sandbox resume <id>, lizard sandbox snapshot <id> --name my-app и lizard sandbox restore <snapshot-id>.
Очистка и дальнейшие шаги
Вызывайте kill(), когда задача завершена, как это делают примеры в блоке finally. В Python with Sandbox.create(...) as sandbox: останавливает sandbox при выходе из блока. Если вы не остановите sandbox, он завершит работу через пять минут после создания либо по истечении заданного вами срока; см. ресурсы и сроки жизни.
- Все вызовы, параметры и ошибки: справочник по Sandbox API и SDK.
- Код от LLM с сохранением состояния между вызовами: интерпретатор кода.
- Файлы, которые переживают sandbox: Persistent Volumes.
- Агент для разработки в sandbox: Claude Code или OpenCode.
- Те же шаги из терминала:
lizard sandbox. В браузере: кабинет Sandboxes. - Размеры, цены и сколько sandbox может работать одновременно: лимиты. Обзор продукта и сравнение: Sandboxes.
Обновлено