Developer docs / AI Fabric SDK / Images & storage

Images

bladekit.Image: a chained, immutable image-definition DSL — catalog and registry bases, apt/pip/env/run layers, and the content hash that drives idempotent builds.

Image basics

bladekit.Image is an immutable image definition: a base plus an ordered list of layers. Every builder method (apt_install, pip_install, env, run_commands) returns a new Image with one extra layer appended — the receiver is never mutated, so a shared base can safely branch into several images.

Python
import bladekit

base = bladekit.Image.debian_slim(python_version="3.12").apt_install("git")
torch_image = base.pip_install("torch==2.3.0")
jax_image = base.pip_install("jax==0.4.28")   # `base` itself is unchanged

The image= parameter accepted by @app.function, @app.cls and bladekit.app(...) takes either of two things: a plain string — a catalog alias ("fabric/torch") or a raw registry ref — passed straight through to the run request, or a **bladekit.Image** DSL value. A DSL image is not built eagerly: the first .remote() / .spawn() call on a function using it resolves the definition to a build, idempotently by definition_hash (an unchanged definition triggers zero rebuild work server-side), streaming build logs to the terminal until the build succeeds or raising bladekit.ImageBuildError on failure.

Image.from_catalog

Signature
classmethod Image.from_catalog(alias: str) -> Image

alias str

Catalog alias, e.g. "fabric/torch" — the same string you could pass directly as image="fabric/torch".

Builds a base from an AI Fabric-maintained catalog image by alias. The alias is resolved server-side against the enabled catalogue at build time, so the underlying registry (and its host) never appears in your code and can move — including to an external registry — without changing anything downstream. An unknown or disabled alias fails the build with a clear error rather than silently pulling nothing.

Python
image = bladekit.Image.from_catalog("fabric/torch").pip_install("transformers==4.42.3")

@app.function(gpu="RTX-A4500", image=image)
def embed(texts: list[str]):
    ...

Image.from_registry

Signature
classmethod Image.from_registry(ref: str) -> Image

ref str

Registry image reference, carrying an explicit tag or digest.

Builds a base from a public registry image on the deployment's allowlist, for cases the catalog doesn't cover. Same rule as run refs elsewhere in AI Fabric: no implicit latest — ref must contain an explicit tag (:) or digest (@), or construction raises InvalidArgumentError immediately rather than failing the build later.

Python
image = bladekit.Image.from_registry(
    "nvcr.io/nvidia/pytorch:24.10-py3"
).pip_install("accelerate==0.31.0")

Image.debian_slim

Signature
classmethod Image.debian_slim(python_version: str = "3.12") -> Image

python_version strDefault: "3.12"

major.minor Python version, e.g. "3.12".

A platform-maintained Debian slim base with the given Python preinstalled — the usual starting point for a from-scratch image built up with apt_install / pip_install layers. The exact base image digest is a server-side config, not part of the definition hash, so a platform update to the underlying digest never changes your image's definition_hash.

Layer builders

apt_install

Signature
def apt_install(self, *packages: str) -> Image

*packages str

Debian package names, appended verbatim to an apt_install layer — no shell, no options.

pip_install

Signature
def pip_install(
    self,
    *packages: str,
    index_url: Optional[str] = None,
    extra_index_urls: Optional[Sequence[str]] = None,
) -> Image

*packages str

PEP 508 package specifiers.

index_url Optional[str]Default: None

Custom PyPI index URL for this layer.

extra_index_urls Optional[Sequence[str]]Default: None

Additional index URLs consulted alongside index_url.

env

Signature
def env(self, vars: Mapping[str, str]) -> Image

vars Mapping[str, str]

Non-empty mapping of environment variables baked into the layer.

run_commands

Signature
def run_commands(self, *commands: str) -> Image

*commands str

Shell command lines; each one becomes its own RUN / cache step, in order.

LimitValue
Layers per image64
Packages per apt_install / pip_install layer256
Commands per run_commands layer64
Vars per env layer64

Definition, hashing & caching

An Image is, in essence, a JSON document: to_definition() returns it as a dict (version, base, layers); canonical_json() renders it as canonical bytes (sorted keys, no spaces, UTF-8); definition_hash() is the lowercase-hex sha256 of those bytes. Layer order is always preserved — it is never sorted, since it changes build semantics.

Signature
def to_definition(self, *, sandbox: bool = False) -> Dict[str, Any]
def canonical_json(self, *, sandbox: bool = False) -> str
def definition_hash(self, *, sandbox: bool = False) -> str

sandbox boolDefault: False

Mark the definition as a sandbox image: the server injects forge-sandboxd as the entrypoint instead of the usual function runner. Part of the canonical JSON, so a sandbox build never collides with a function build of the identical base/layers.

Builds are idempotent by definition_hash: the control plane deduplicates on it, so re-running the exact same definition performs zero rebuild work, and the SDK additionally caches definition_hash → build_id per App instance to skip even the lookup for an image reused across functions in one process.

Reference from the Blade console · Updated .

Contact the team

Loading the form…