docs/sdk/python/images.mdx
Configure sandbox image sources and manage the local OCI image cache.
Factory for sandbox image sources.
@staticmethod
def oci(
reference: str,
*,
root_disk: RootDiskConfig | int | None = None,
upper_size_mib: int | None = None,
) -> ImageSource
from microsandbox import Image, RootDisk, Sandbox
sb = await Sandbox.create(
"api",
image=Image.oci("python:3.12", root_disk=RootDisk.managed(8192)),
)
Create an OCI image rootfs source. Use root_disk to configure its writable layer with a RootDisk factory result. An integer is shorthand for a managed disk of that size in MiB.
@staticmethod
def bind(path: str) -> ImageSource
sb = await Sandbox.create("api", image=Image.bind("/srv/rootfs"))
Create a rootfs source that binds a host directory as the guest root filesystem.
<p className="msb-label">Parameters</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><code>path</code><span className="msb-type">str</span></div> <div className="msb-param-desc">Host directory to use as the rootfs.</div> </div> </div> <p className="msb-label">Returns</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><a className="msb-type" href="#imagesource">ImageSource</a></div> <div className="msb-param-desc">Rootfs source for <code>image=</code>.</div> </div> </div>@staticmethod
def disk(path: str, *, fstype: str | None = None) -> ImageSource
sb = await Sandbox.create(
"api",
image=Image.disk("/data/root.qcow2", fstype="ext4"),
)
Create a rootfs source backed by a disk image. The format is inferred from the file extension. Pass fstype when the filesystem type cannot be auto-detected.
These static methods inspect and prune images already pulled into the local OCI cache. They require a local backend; on a cloud backend they raise UnsupportedError.
@staticmethod
async def get(reference: str) -> ImageHandle
handle = await Image.get("python:3.12")
print(handle.reference, handle.layer_count)
Fetch one cached image by reference. Raises ImageNotFoundError when the image is not present in the local cache.
@staticmethod
async def list() -> list[ImageHandle]
for image in await Image.list():
print(image.reference, image.size_bytes)
Return every cached image.
<p className="msb-label">Returns</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><a className="msb-type" href="#imagehandle">list[ImageHandle]</a></div> <div className="msb-param-desc">All cached image handles.</div> </div> </div>@staticmethod
async def inspect(reference: str) -> ImageDetail
detail = await Image.inspect("python:3.12")
print(detail.handle.reference)
for layer in detail.layers:
print(layer.position, layer.diff_id)
Return handle metadata plus the parsed OCI config and per-layer detail.
<p className="msb-label">Parameters</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><code>reference</code><span className="msb-type">str</span></div> <div className="msb-param-desc">Image reference to inspect.</div> </div> </div> <p className="msb-label">Returns</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><a className="msb-type" href="#imagedetail">ImageDetail</a></div> <div className="msb-param-desc">Handle, OCI config, and layers.</div> </div> </div>@staticmethod
async def remove(reference: str, *, force: bool = False) -> None
await Image.remove("python:3.12", force=True)
Delete a cached image. When force is False, an image still referenced by one or more sandboxes raises ImageInUseError; pass force=True to remove it anyway.
@staticmethod
async def prune() -> ImagePruneReport
report = await Image.prune()
print(f"{report.layers_removed} layers, {report.bytes_reclaimed} bytes")
Remove cached image data that is not used by any sandbox or indexed snapshot. The returned report counts the removed refs, manifests, layers, fsmeta files, and VMDK files, plus any measured bytes reclaimed.
<p className="msb-label">Returns</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><a className="msb-type" href="#imageprunereport">ImagePruneReport</a></div> <div className="msb-param-desc">Counts of removed data and bytes reclaimed.</div> </div> </div> <Accordion title="Example">report = await Image.prune()
print(f"{report.layers_removed} layers, {report.bytes_reclaimed} bytes")
@staticmethod
async def load(input_path: str, *, tag: str | None = None) -> list[ImageHandle]
Import images from a local archive into the cache. Accepts docker save tarballs and OCI Image Layout archives, so locally built images can be used without going through a registry.
# docker save my-image:latest -o my-image.tar
images = await Image.load(input_path="my-image.tar", tag="app:local")
for image in images:
print(image.reference, image.layer_count)
# Or pipe it in: docker save my-image:latest | python app.py
images = await Image.load(input_path="-")
@staticmethod
async def save(
reference: str | Sequence[str],
*,
output_path: str,
format: ImageArchiveFormat = ImageArchiveFormat.DOCKER,
) -> None
Export one or more cached images to an archive file. Raises ImageNotFoundError when any reference is not in the local cache, and ValueError for an empty reference list.
from microsandbox import ImageArchiveFormat
await Image.save("python:3.12", output_path="python.tar")
await Image.save(
"python:3.12",
output_path="python-oci.tar",
format=ImageArchiveFormat.OCI,
)
await Image.save(["python:3.12", "app:local"], output_path="bundle.tar")
A lightweight handle to a cached OCI image, returned by Image.get(), Image.list(), and Image.load(). Properties are read-only attributes; the two methods are async.
str
Image reference
int \| None
Total size in bytes, or None when unknown
str \| None
Content-addressable manifest digest
str \| None
Resolved architecture
str \| None
Resolved operating system
int
Number of layers
float \| None
Last referenced time, milliseconds since epoch
float \| None
First-pulled time, milliseconds since epoch
await inspect()
Fetch full detail for this image
<p className="msb-label">Returns</p>await remove(*, force=False)
Delete this image (raises ImageInUseError unless force)
Factory for writable OCI root disk configurations.
from microsandbox import DiskImageFormat, RootDisk
managed = RootDisk.managed(8192)
temporary = RootDisk.tmpfs(512)
existing = RootDisk.disk(
"/data/upper.raw",
format=DiskImageFormat.RAW,
fstype="ext4",
)
managed(size_mib=None)
Microsandbox-managed sparse ext4 disk
<p className="msb-label">Returns</p>tmpfs(size_mib=None)
Ephemeral RAM-backed upper layer
<p className="msb-label">Returns</p>disk(path, *, format=None, fstype=None)
User-supplied writable disk image
<p className="msb-label">Returns</p>Explicit rootfs image source. Build one with Image.oci(), Image.bind(), or Image.disk(), then pass it as the image= kwarg to Sandbox.create(). A frozen dataclass; treat its fields as opaque.
| Field | Type | Description |
|---|---|---|
_type | ImageSourceKind | Source kind |
_path | str | None | Host path for bind / disk sources |
_reference | str | None | OCI reference for oci sources |
_upper_size_mib | int | None | Writable overlay upper size in MiB (OCI only) |
_fstype | str | None | Filesystem type for disk sources |
_format | DiskImageFormat | None | Disk image format (inferred from extension) |
Frozen root disk configuration produced by RootDisk.
| Field | Type | Description |
|---|---|---|
kind | RootDiskKind | Root disk implementation |
size_mib | int | None | Managed disk or tmpfs size |
path | str | None | User-supplied disk image path |
format | DiskImageFormat | None | Disk image format |
fstype | str | None | Inner filesystem type |
Full detail for a cached image: the core handle, the parsed OCI config block, and per-layer metadata.
| Property | Type | Description |
|---|---|---|
handle | ImageHandle | Core cached image metadata |
config | ImageConfigDetail | None | Parsed OCI config block |
layers | list[ImageLayerDetail] | Layers in bottom-to-top order |
OCI image config fields extracted from the local cache.
| Property | Type | Description |
|---|---|---|
digest | str | Config blob digest |
env | list[str] | Environment variables (KEY=value) |
cmd | list[str] | None | Default command |
entrypoint | list[str] | None | Image entrypoint |
working_dir | str | None | Default working directory |
user | str | None | Default user |
labels | dict[str, Any] | None | OCI labels |
stop_signal | str | None | Configured stop signal |
Metadata for a single image layer.
| Property | Type | Description |
|---|---|---|
diff_id | str | Uncompressed layer diff id |
blob_digest | str | Compressed blob digest |
media_type | str | None | Layer media type |
compressed_size_bytes | int | None | Compressed size in bytes |
erofs_size_bytes | int | None | Size of the generated EROFS sidecar in bytes |
position | int | Layer position (bottom to top) |
Summary of cached image data removed by Image.prune().
| Property | Type | Description |
|---|---|---|
image_refs_removed | int | Number of image refs removed |
manifests_removed | int | Number of manifests removed |
layers_removed | int | Number of layer blobs removed |
fsmeta_removed | int | Number of fsmeta sidecar files removed |
vmdk_removed | int | Number of VMDK files removed |
bytes_reclaimed | int | None | Measured bytes reclaimed, or None when not measured |
Disk image container format.
| Member | Value | Description |
|---|---|---|
DiskImageFormat.QCOW2 | "qcow2" | QEMU copy-on-write v2 |
DiskImageFormat.RAW | "raw" | Raw block image |
DiskImageFormat.VMDK | "vmdk" | VMware disk image |
Archive layout used when exporting cached images.
| Member | Value | Description |
|---|---|---|
ImageArchiveFormat.DOCKER | "docker" | Docker archive compatible with docker load |
ImageArchiveFormat.OCI | "oci" | OCI Image Layout archive |
Root filesystem source kind.
| Member | Value | Description |
|---|---|---|
ImageSourceKind.OCI | "oci" | OCI image reference |
ImageSourceKind.BIND | "bind" | Host directory bind source |
ImageSourceKind.DISK | "disk" | Host disk-image source |
Writable OCI root disk implementation.
| Member | Value | Description |
|---|---|---|
RootDiskKind.MANAGED | "managed" | Microsandbox-managed sparse ext4 disk |
RootDiskKind.TMPFS | "tmpfs" | Ephemeral RAM-backed upper layer |
RootDiskKind.DISK_IMAGE | "disk-image" | User-supplied writable disk image |
Image operations raise these typed exceptions, all subclasses of MicrosandboxError.
| Exception | Raised when |
|---|---|
ImageNotFoundError | The image reference could not be resolved in the local cache |
ImageInUseError | The image is still referenced by one or more sandboxes (and force was not set) |
ImagePullFailedError | An image pull failed |
UnsupportedError | Cache operations were attempted on a backend that lacks a local cache |