docs/sdk/python/snapshots.mdx
Disk-only snapshots of a stopped sandbox. See Snapshots for concepts and walkthroughs; this page is the Python SDK reference.
from microsandbox import Sandbox, Snapshot, SnapshotHandle
snapshot= kwarg@staticmethod
async def create(name_or_config, *, snapshot: str | os.PathLike | None = None, **kwargs) -> Sandbox
Boot a fresh sandbox from a snapshot artifact by passing snapshot= as a peer of image=. The two are mutually exclusive — pass exactly one.
# 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")
Errors
ValueError — both image= and snapshot= were passed or neither, the snapshot artifact doesn't exist, or the artifact's manifest failed validationasync def snapshot(self, name: str) -> Snapshot
Snapshot this (stopped) sandbox under a bare name in the default snapshots directory (~/.microsandbox/snapshots/<name>/). For an explicit filesystem destination, see snapshot_to().
Errors
SnapshotSandboxRunning — the sandbox is not stoppedSnapshotAlreadyExists — destination exists (use Snapshot.create(..., force=True) to overwrite)async def snapshot_to(self, path: str | os.PathLike) -> Snapshot
Snapshot this (stopped) sandbox to an explicit filesystem path.
Properties are read-only attributes (not async).
| Property | Type | Description |
|---|---|---|
path | str | Path to the artifact directory |
digest | str | Canonical content digest (sha256:hex). The snapshot's identity. |
size_bytes | int | Apparent size of the captured upper layer in bytes (sparse on disk) |
image_ref | str | Image reference the snapshot was taken from |
image_manifest_digest | str | OCI manifest digest of the pinned image |
format | str | "raw" or "qcow2" (always "raw" today) |
fstype | str | Filesystem type inside the upper (e.g. "ext4") |
parent | str | None | Parent snapshot's digest, or None for a root |
created_at | str | RFC 3339 timestamp |
labels | dict[str, str] | User-supplied labels |
source_sandbox | str | None | Best-effort source-sandbox name |
async def verify(self) -> dict[str, Any]
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.
report = await snap.verify()
if report["upper"]["kind"] == "verified":
print(f"hash matches: {report['upper']['digest']}")
else:
print("no integrity hash recorded")
The report shape:
{
"digest": "sha256:...",
"path": "/path/to/artifact",
"upper": {"kind": "not_recorded"} # no integrity recorded
| {"kind": "verified", "algorithm": "...", "digest": "sha256:..."},
}
@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
Create a snapshot from a stopped sandbox. Exactly one of name= (resolved under the default snapshots directory) or path= (explicit filesystem destination) is required.
snap = await Snapshot.create(
"baseline",
name="after-pip-install",
labels={"stage": "post-deps"},
record_integrity=True,
)
@staticmethod
async def open(path_or_name: str) -> Snapshot
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.
@staticmethod
async def get(name_or_digest: str) -> SnapshotHandle
Look up a handle in the local index by name, digest, or path.
@staticmethod
async def list() -> list[SnapshotHandle]
List indexed snapshots from the local DB cache.
@staticmethod
async def list_dir(dir: str | os.PathLike) -> list[Snapshot]
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.
@staticmethod
async def remove(path_or_name: str, *, force: bool = False) -> None
Remove a snapshot artifact and its index row. Refuses if the snapshot has indexed children unless force=True.
@staticmethod
async def reindex(dir: str | os.PathLike | None = None) -> int
Walk dir (default: configured snapshots dir) and rebuild the local index. Returns the number of artifacts indexed.
@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
Bundle a snapshot into a .tar.zst archive. Computes and embeds the integrity hash in the bundled manifest if not already present.
@staticmethod
async def import_(
archive: str | os.PathLike,
*,
dest: str | os.PathLike | None = None,
) -> SnapshotHandle
Unpack a snapshot archive (.tar.zst or .tar) into the snapshots directory, verifying recorded integrity on the way in. Compression is detected from magic bytes.
The trailing underscore is intentional — import is a reserved Python keyword.
Lightweight handle backed by an index row. Returned by Snapshot.list() and Snapshot.get().
| Property | Type | Description |
|---|---|---|
digest | str | Manifest digest — canonical identity |
name | str | None | Convenience alias |
parent_digest | str | None | Parent snapshot digest (None today; populated when chains land) |
image_ref | str | Image the snapshot was taken from |
format | str | "raw" or "qcow2" |
size_bytes | int | None | Apparent upper size at index time |
created_at | float | ms since Unix epoch |
path | str | Local artifact directory path |
h = await Snapshot.get("after-pip-install")
snap = await h.open() # metadata-validated
await h.remove(force=False) # refuse if has children