Skip to main content
Capture the disk state of a stopped sandbox as a reusable artifact, then boot fresh sandboxes from it. Snapshots are disk-only and require a sandbox that is not running. See Snapshots for concepts and walkthroughs.

Typical flow

from microsandbox import Sandbox, Snapshot

# Run setup work, then stop the sandbox
async with await Sandbox.create("baseline", image="python:3.12") as sb:
    await sb.exec("pip", ["install", "numpy"])
    await sb.stop()

# Capture its disk state under a name
snap = await Snapshot.create("baseline", name="after-pip-install")
print(snap.digest)

# Boot a fresh sandbox from the artifact
sb2 = await Sandbox.create("worker", snapshot="after-pip-install")

Take a snapshot

handle.snapshot()

async def snapshot(self, name: str) -> Snapshot
handle = await Sandbox.get("baseline")
snap = await handle.snapshot("after-pip-install")
print(snap.digest)
Snapshot this sandbox under a bare name in the default snapshots directory (~/.microsandbox/snapshots/<name>/). The sandbox must be stopped or crashed. For an explicit filesystem destination, see snapshot_to(). Called on a SandboxHandle, obtained from Sandbox.get().

Parameters

namestr
Snapshot name; resolved under the default snapshots directory.

Returns

The captured snapshot.

handle.snapshot_to()

async def snapshot_to(self, path: str | os.PathLike) -> Snapshot
handle = await Sandbox.get("baseline")
snap = await handle.snapshot_to("/data/snapshots/baseline")
Snapshot this sandbox to an explicit filesystem path. The sandbox must be stopped or crashed.

Parameters

pathstr | os.PathLike
Destination artifact directory.

Returns

The captured snapshot.

Snapshot.create()

@staticmethod
async def create(
    source_sandbox: str,
    *,
    name: str | None = None,
    path: str | os.PathLike | None = None,
    labels: dict[str, str] | None = None,
    force: bool = False,
    record_integrity: bool = False,
) -> Snapshot
snap = await Snapshot.create(
    "baseline",
    name="after-pip-install",
    labels={"stage": "post-deps"},
    record_integrity=True,
)
Create a snapshot from a stopped or crashed sandbox. Exactly one of name= (resolved under the default snapshots directory) or path= (explicit filesystem destination) is required.

Parameters

source_sandboxstr
Name of the stopped or crashed sandbox to capture.
namestr | None
Snapshot name under the default snapshots directory. Mutually exclusive with path.
pathstr | os.PathLike | None
Explicit destination directory. Mutually exclusive with name.
labelsdict[str, str] | None
User-supplied labels stored in the manifest.
forcebool
Overwrite an existing destination. Default False.
record_integritybool
Record an integrity hash in the manifest so the artifact can be verified later. Default False.

Returns

The captured snapshot.

Boot from a snapshot

Sandbox.create()

@staticmethod
async def create(name: str, *, snapshot: str | os.PathLike | None = None, **kwargs) -> Sandbox
# Boot from a snapshot
sb = await Sandbox.create("worker", snapshot="after-pip-install")

# Or from an image (existing flow, unchanged)
sb = await Sandbox.create("worker", image="python:3.12")
Boot a fresh sandbox from a snapshot artifact by passing snapshot= as a peer of image=. The two are mutually exclusive: pass exactly one. See Sandbox.create() for the full set of configuration kwargs.

Parameters

namestr
Sandbox name, up to 128 UTF-8 bytes.
snapshotstr | os.PathLike | None
Snapshot bare name or artifact path to boot from instead of image=.

Returns

Running sandbox.

Manage artifacts

Snapshot.open()

@staticmethod
async def open(path_or_name: str) -> Snapshot
snap = await Snapshot.open("after-pip-install")
print(snap.image_ref)
Open an existing artifact by bare name (resolved under the default snapshots directory) or path. Cheap metadata validation only; does not read the upper file. Use verify() for content checks.

Parameters

path_or_namestr
Bare snapshot name or artifact directory path.

Returns

The opened snapshot.

Snapshot.get()

@staticmethod
async def get(name_or_digest: str) -> SnapshotHandle
h = await Snapshot.get("after-pip-install")
print(h.digest)
Look up a handle in the local index by name, digest, or path.

Parameters

name_or_digeststr
Snapshot name, digest, or path.

Returns

Lightweight handle backed by an index row.

Snapshot.list()

@staticmethod
async def list() -> list[SnapshotHandle]
for h in await Snapshot.list():
    print(h.name, h.digest)
List indexed snapshots from the local DB cache.

Returns

Indexed snapshot handles.

Snapshot.list_dir()

@staticmethod
async def list_dir(dir: str | os.PathLike) -> list[Snapshot]
for snap in await Snapshot.list_dir("/mnt/artifacts"):
    print(snap.path, snap.digest)
Walk a directory and parse each subdirectory’s manifest. Does not touch the index, useful for inspecting external snapshot collections (e.g. a mounted volume of artifacts that were never imported). Skips entries that don’t look like snapshot artifacts.

Parameters

dirstr | os.PathLike
Directory to scan for artifacts.

Returns

One snapshot per valid artifact directory.

Snapshot.remove()

@staticmethod
async def remove(path_or_name: str, *, force: bool = False) -> None
await Snapshot.remove("after-pip-install", force=True)
Remove a snapshot artifact and its index row. Refuses if the snapshot has indexed children unless force=True.

Parameters

path_or_namestr
Bare snapshot name or artifact path.
forcebool
Remove even if the snapshot has indexed children. Default False.

Snapshot.reindex()

@staticmethod
async def reindex(dir: str | os.PathLike | None = None) -> int
count = await Snapshot.reindex()
print(f"indexed {count} snapshots")
Walk dir (default: configured snapshots dir) and rebuild the local index. Returns the number of artifacts indexed.

Parameters

dirstr | os.PathLike | None
Directory to scan. Default: the configured snapshots directory.

Returns

int
Number of artifacts indexed.

Snapshot.export()

@staticmethod
async def export(
    name_or_path: str,
    out: str | os.PathLike,
    *,
    with_parents: bool = False,
    with_image: bool = False,
    plain_tar: bool = False,
) -> None
await Snapshot.export(
    "after-pip-install",
    "/tmp/after-pip-install.tar.zst",
    with_parents=True,
)
Bundle a snapshot into a .tar.zst archive. The existing snapshot manifest is archived as-is; create the snapshot with recorded integrity when the archive will cross a trust boundary.

Parameters

name_or_pathstr
Snapshot bare name or artifact path to export.
outstr | os.PathLike
Output archive path.
with_parentsbool
Include the snapshot’s parent chain. Default False.
with_imagebool
Include the pinned base image. Default False.
plain_tarbool
Write an uncompressed .tar instead of .tar.zst. Default False.

Move artifacts

Snapshot.import_()

@staticmethod
async def import_(
    archive: str | os.PathLike,
    *,
    dest: str | os.PathLike | None = None,
) -> SnapshotHandle
h = await Snapshot.import_("/tmp/after-pip-install.tar.zst")
print(h.path)
Unpack a snapshot archive (.tar.zst or .tar) into the snapshots directory, verifying recorded integrity when present. Compression is detected from magic bytes. The trailing underscore is intentional: import is a reserved Python keyword.

Parameters

archivestr | os.PathLike
Archive path (.tar.zst or .tar).
deststr | os.PathLike | None
Destination directory. Default: the configured snapshots directory.

Returns

Handle to the imported snapshot.

Inspect

snap.verify()

async def verify(self) -> dict[str, Any]
report = await snap.verify()
if report["upper"]["kind"] == "verified":
    print(f"hash matches: {report['upper']['digest']}")
else:
    print("no integrity hash recorded")
Recompute the upper layer’s content hash and compare against the manifest. Walks data extents only, so a 4 GiB sparse file with a few MB of data verifies in milliseconds.

Returns

dict[str, Any]
Verification report. The upper.kind field is “not_recorded” when no integrity hash was stored, or “verified” with the recomputed digest.
The report shape:
{
    "digest": "sha256:...",
    "path": "/path/to/artifact",
    "upper": {"kind": "not_recorded"}                            # no integrity recorded
        | {"kind": "verified", "algorithm": "...", "digest": "sha256:..."},
}

handle.open()

async def open(self) -> Snapshot
h = await Snapshot.get("after-pip-install")
snap = await h.open()
print(snap.fstype)
Load the full Snapshot metadata for this handle. Metadata-validated only; does not read the upper file.

Returns

The opened snapshot.

handle.remove()

async def remove(self, *, force: bool = False) -> None
h = await Snapshot.get("after-pip-install")
await h.remove(force=False)
Remove this snapshot artifact and its index row. Refuses if the snapshot has indexed children unless force=True.

Parameters

forcebool
Remove even if the snapshot has indexed children. Default False.

Types

Snapshot

Returned by snapshot() · snapshot_to() · Snapshot.create() · Snapshot.open() · Snapshot.list_dir() · handle.open()

A fully-parsed snapshot artifact. Properties are read-only attributes (not async).
Property / MethodTypeDescription
pathstrPath to the artifact directory
digeststrCanonical content digest (sha256:hex). The snapshot’s identity
size_bytesintApparent size of the captured upper layer in bytes (sparse on disk)
image_refstrImage reference the snapshot was taken from
image_manifest_digeststrOCI manifest digest of the pinned image
formatstr"raw" or "qcow2" (always "raw" today)
fstypestrFilesystem type inside the upper (e.g. "ext4")
parentstr | NoneParent snapshot’s digest, or None for a root
created_atstrRFC 3339 timestamp
labelsdict[str, str]User-supplied labels
source_sandboxstr | NoneBest-effort source-sandbox name
verify()Awaitable[dict[str, Any]]Recompute and check the upper-layer integrity hash. See verify()

SnapshotHandle

Returned by Snapshot.get() · Snapshot.list() · Snapshot.import_()

Lightweight handle backed by an index row. Properties are read-only attributes (not async).
Property / MethodTypeDescription
digeststrManifest digest, canonical identity
namestr | NoneConvenience alias
parent_digeststr | NoneParent snapshot digest, or None for a root
image_refstrImage the snapshot was taken from
formatstr"raw" or "qcow2"
size_bytesint | NoneApparent upper size at index time
created_atfloatms since Unix epoch
pathstrLocal artifact directory path
open()Awaitable[Snapshot]Load full metadata. See open()
remove(force=False)Awaitable[None]Delete the artifact and its index row. See remove()