Skip to main content

What You’ll Learn

  • Creating a tar.gz from a local directory
  • Uploading it with Volumes.create()
  • Attaching it to a new sandbox via Sandbox.create(volumes=[...])
  • Confirming the files materialize at the mount path before the first command runs

Prerequisites

export DECLAW_API_KEY="your-api-key"
export DECLAW_DOMAIN="your-declaw-instance.example.com:8080"

Code Walkthrough

Build a tarball in memory and upload it, then attach to a sandbox.
import io
import tarfile
import time
from declaw import Sandbox, Volumes, VolumeAttachment


def build_sample_tarball() -> bytes:
    buf = io.BytesIO()
    with tarfile.open(fileobj=buf, mode="w:gz") as tar:
        for name, body in (
            ("config.json", b'{"env":"prod"}\n'),
            ("data/rows.csv", b"id,name\n1,alice\n2,bob\n"),
        ):
            info = tarfile.TarInfo(name=name)
            info.size = len(body)
            info.mtime = int(time.time())
            tar.addfile(info, io.BytesIO(body))
    return buf.getvalue()


vol = Volumes.create(name="demo-dataset", data=build_sample_tarball())
print(vol.volume_id)          # vol-...
print(vol.size_bytes)

sbx = Sandbox.create(
    template="base",
    timeout=120,
    volumes=[VolumeAttachment(volume_id=vol.volume_id, mount_path="/data")],
)
try:
    result = sbx.commands.run("ls -la /data && cat /data/config.json")
    print(result.stdout)
finally:
    sbx.kill()
mount_path / mountPath must be an absolute directory inside the sandbox and cannot be a system directory (/, /etc, /usr, /proc, /sys, /dev, /bin, /sbin, /lib, /lib64, /var, /run, /boot). The tarball’s regular-file entries are materialized there. Expected output:
total 12
drwxr-xr-x 3 root root 4096 … .
drwxr-xr-x 1 root root 4096 … ..
-rw-r--r-- 1 root root   15 … config.json
drwxr-xr-x 2 root root 4096 … data
{"env":"prod"}
Clean up when you’re done. The blob + metadata row are removed; the volume is no longer attachable.
Volumes.delete(vol.volume_id)

Full Example

Runnable versions live in the repo:
  • Python: cookbook/volumes_quickstart.py
  • TypeScript: cookbook-ts/volumes_quickstart.ts
Both upload a sample tarball, spin up two sandboxes with the same volume attached, and confirm both see identical contents.

Phase 1 Limits

  • Body must be application/gzip (a tar archive gzipped).
  • 4 GiB upload cap.
  • Files materialize once, at sandbox boot. Sandbox writes to files under mount_path stay private to that sandbox — they do not flow back to the volume.