Skip to main content
from declaw import Template, TemplateBase, BuildInfo, TemplateBuildStatus, CopyItem
Templates let you pre-build sandbox images with specific packages, files, and environment variables installed. Once built, a template can be referenced by alias in Sandbox.create(template="my-template") to boot sandboxes that start from a known state.

TemplateBase

TemplateBase is a fluent builder for defining the contents of a template. Build up the definition by chaining methods, then pass it to Template.build().
from declaw import TemplateBase

template = (
    TemplateBase()
    .from_base_image("ubuntu:22.04")
    .apt_install("python3", "python3-pip", "curl")
    .run_cmd(["pip3", "install", "pandas", "numpy", "matplotlib"])
    .copy("./local_script.py", "/home/user/script.py")
    .set_envs({"PYTHONPATH": "/home/user"})
    .set_start_cmd("sleep infinity")
)

Methods

.from_base_image(image)

Set the base Docker image.
image
str
default:"'ubuntu:22.04'"
Docker image tag to use as the base.
Returns TemplateBase (for chaining)

.apt_install(*packages)

Install apt packages.
template.apt_install("git", "curl", "jq")
*packages
str
required
One or more package names to install via apt-get install.
Returns TemplateBase

.run_cmd(cmds)

Add a shell command to run during the build (equivalent to a Dockerfile RUN).
template.run_cmd(["pip3", "install", "torch", "--index-url", "https://download.pytorch.org/whl/cpu"])
cmds
list[str]
required
Command as a list of strings (the executable and its arguments).
Returns TemplateBase

.copy(src, dst, mode)

Copy a local file into the template image at build time.
template.copy("./requirements.txt", "/app/requirements.txt")
template.copy("./startup.sh", "/usr/local/bin/startup.sh", mode=0o755)
src
str
required
Local path to the file to copy.
dst
str
required
Destination path inside the image.
mode
int | None
default:"None"
Unix file permission bits (e.g. 0o755 for executable).
Returns TemplateBase

.set_envs(envs)

Set environment variables baked into the template.
template.set_envs({"APP_ENV": "production", "PORT": "8080"})
envs
dict[str, str]
required
Key-value pairs to set as environment variables.
Returns TemplateBase

.set_start_cmd(cmd, ready_check)

Set a command to run when the sandbox boots.
template.set_start_cmd("python3 /app/server.py")
cmd
str
required
Shell command to execute on sandbox start.
ready_check
Any | None
default:"None"
Optional readiness probe configuration. Reserved for future use.
Returns TemplateBase

.to_dict()

Serialize the template definition to a dict suitable for the API. Returns dict

Template

Template is a static class for building and querying templates via the API.

Template.build()

Submit a template build and wait for it to complete.
from declaw import Template, TemplateBase

template = (
    TemplateBase()
    .apt_install("python3-pip")
    .run_cmd(["pip3", "install", "pandas"])
)

build_info = Template.build(
    template=template,
    alias="data-analysis",
    cpu_count=2,
    memory_mb=2048,
    on_build_logs=print,
    api_key="your-api-key",
    domain="104.198.24.180:8080",
)
print("Template ID:", build_info.template_id)
template
TemplateBase
required
The template definition to build.
alias
str
required
Human-readable name for the template. Used as the template parameter in Sandbox.create().
cpu_count
int
default:"1"
Number of CPUs for the build worker.
memory_mb
int
default:"1024"
Memory in MB for the build worker.
on_build_logs
Callable[[str], None] | None
default:"None"
Callback invoked for each log line emitted during the build.
api_key
str | None
default:"$DECLAW_API_KEY"
API key override.
domain
str | None
default:"$DECLAW_DOMAIN"
Domain override.
request_timeout
float | None
default:"None"
Per-request HTTP timeout in seconds.
Returns BuildInfo

Template.build_in_background()

Submit a template build and return immediately without waiting for it to finish.
build_info = Template.build_in_background(
    template=template,
    alias="my-template",
    api_key="your-api-key",
    domain="104.198.24.180:8080",
)
print("Build started:", build_info.build_id)
Parameters are the same as Template.build() except on_build_logs is not accepted. Returns BuildInfo

Template.get_build_status()

Poll the status of a background build.
import time

build_info = Template.build_in_background(template, "my-template", api_key="key", domain="host:8080")

while True:
    status = Template.get_build_status(
        build_id=build_info.build_id,
        api_key="your-api-key",
        domain="104.198.24.180:8080",
    )
    print(status.status, status.logs[-1] if status.logs else "")
    if status.status in ("succeeded", "failed"):
        break
    time.sleep(3)
build_id
str
required
Build ID from a previous build() or build_in_background() call.
api_key
str | None
default:"$DECLAW_API_KEY"
API key override.
domain
str | None
default:"$DECLAW_DOMAIN"
Domain override.
request_timeout
float | None
default:"None"
Per-request HTTP timeout in seconds.
Returns TemplateBuildStatus

Data models

BuildInfo

@dataclass
class BuildInfo:
    build_id: str
    status: str
    template_id: str | None = None   # Set once build succeeds

TemplateBuildStatus

@dataclass
class TemplateBuildStatus:
    build_id: str
    status: str             # e.g. "pending", "running", "succeeded", "failed"
    logs: list[str]         # Build log lines accumulated so far

CopyItem

@dataclass
class CopyItem:
    src: str
    dst: str
    mode: int | None = None

AsyncTemplate

Use AsyncTemplate for async applications. It has the same static methods as Template but all are coroutines:
from declaw import AsyncTemplate, TemplateBase

template = TemplateBase().apt_install("nodejs", "npm")

build_info = await AsyncTemplate.build(
    template=template,
    alias="node-env",
    api_key="your-api-key",
    domain="104.198.24.180:8080",
)
Methods: await AsyncTemplate.build(...), await AsyncTemplate.build_in_background(...), await AsyncTemplate.get_build_status(...).

Using a template in Sandbox.create()

Once a template is built successfully, reference it by alias:
from declaw import Sandbox

sbx = Sandbox.create(
    template="data-analysis",   # alias set during build
    api_key="your-api-key",
    domain="104.198.24.180:8080",
)
# pandas is already installed — no pip install needed
result = sbx.commands.run("python3 -c \"import pandas; print(pandas.__version__)\"")
print(result.stdout)
sbx.kill()