Working with Images

ConTree SDK provides several ways to reference and import container images. For full API documentation, see ImagesManager and ImagesManagerSync.

Using Images by Tag

The simplest way to get an image is images.use(tag). This creates an image object immediately without any API call — the tag is resolved at execution time when you run a command:

image = await contree.images.use("ubuntu:latest")
result = await image.run(shell="echo hello")
image = contree.images.use("ubuntu:latest")
result = image.run(shell="echo hello").wait()

Pulling Images

For resolving a tag/UUID to an image upfront, use images.use(strict=True). For importing images from external registries, use images.oci():

 1print(f"Selected {image_uuid=}")
 2print(f"Selected {image_tag=}")
 3
 4print("\nPulling by UUID (strict):")
 5result = await client.images.use(image_uuid, strict=True)
 6print(f"Pulled by UUID: {result.uuid=}, {result.tag=}, {result.state=}")
 7
 8print("\nPulling by tag (strict):")
 9result = await client.images.use(image_tag, strict=True)
10print(f"Pulled by tag: {result.uuid=}, {result.tag=}, {result.state=}")
11
12print("\nImporting public image using oci:")
13result = await client.images.oci("docker://ghcr.io/linuxserver/code-server:latest")
14print(f"Pulled public: {result.uuid=}, {result.tag=}, {result.state=}")

See use() and oci() for all parameters.

 1print(f"Selected {image_uuid=}")
 2print(f"Selected {image_tag=}")
 3
 4print("\nPulling by UUID (strict):")
 5result = client.images.use(image_uuid, strict=True)
 6print(f"Pull by UUID: {result.uuid=}, {result.tag=}, {result.state=}")
 7
 8print("\nPulling by tag (strict):")
 9result = client.images.use(image_tag, strict=True)
10print(f"Pull by tag: {result.uuid=}, {result.tag=}, {result.state=}")
11
12print("\nImporting public image using oci:")
13result = client.images.oci("docker://ghcr.io/linuxserver/code-server:latest")
14print(f"Import public: {result.uuid=}, {result.tag=}, {result.state=}")

See use() and oci() for all parameters.

Methods

  • use()(ref) — no API call; tag or UUID is resolved at execution time

  • use()(ref, strict=True) — verifies the image exists via an API call

  • oci()(ref) (aliases: docker(), podman(), pull_by_oci()) — like use(strict=True), but imports from the registry if not found locally

  • import_from()(ref) — always imports from an external registry

  • use()(ref) — no API call; tag or UUID is resolved at execution time

  • use()(ref, strict=True) — verifies the image exists via an API call

  • oci()(ref) (aliases: docker(), podman(), pull_by_oci()) — like use(strict=True), but imports from the registry if not found locally

  • import_from()(ref) — always imports from an external registry

Danger

import_from always triggers a new import operation and should only be used when you explicitly need to re-import. In most cases, prefer images.oci(), which returns an existing image if already imported. If no import is needed at all, use images.use().

What ref can be

  • UUID — reference an existing image by its UUID, e.g. "550e8400-e29b-41d4-a716-446655440000" or UUID(...)

  • OCI tag — reference by image tag, e.g. "ubuntu:latest"

  • OCI full URL — full reference including registry host, e.g. "docker://ghcr.io/owner/image:tag"

  • OCIReference — programmatic OCI reference object

Tagging Images

You can assign or remove a tag on any image using tag_as() and untag(). Tags are unique across all images — assigning an existing tag to a new image moves it automatically.

 1image = await client.images.use(image_tag, strict=True)
 2print(f"Original: {image.uuid=}, {image.tag=}")
 3
 4tagged = await image.tag_as("my-custom-tag:v1")
 5print(f"After tag_as: {tagged.uuid=}, {tagged.tag=}")
 6
 7untagged = await tagged.untag()
 8print(f"After untag: {untagged.uuid=}, {untagged.tag=}")
 9
10result = await image.run(shell="echo hello", tag="my-result:v1", disposable=False)
11print(f"Run result: {result.uuid=}, {result.tag=}")

See tag_as() and untag() for details.

 1image = client.images.use(image_tag, strict=True)
 2print(f"Original: {image.uuid=}, {image.tag=}")
 3
 4tagged = image.tag_as("my-custom-tag:v1")
 5print(f"After tag_as: {tagged.uuid=}, {tagged.tag=}")
 6
 7untagged = tagged.untag()
 8print(f"After untag: {untagged.uuid=}, {untagged.tag=}")
 9
10result = image.run(shell="echo hello", tag="my-result:v1", disposable=False).wait()
11print(f"Run result: {result.uuid=}, {result.tag=}")

See tag_as() and untag() for details.

You can also tag the result of a run() directly by passing tag= to the call — the resulting image will be tagged after execution completes:

result = await image.run(shell="pip install mylib && python setup.py", tag="myapp:ready", disposable=False)
print(result.tag)  # "myapp:ready"
result = image.run(shell="pip install mylib && python setup.py", tag="myapp:ready", disposable=False).wait()
print(result.tag)  # "myapp:ready"

Listing Images

View all available images in your ConTree instance:

 1all_images = await client.images()
 2print(f"Loaded {all_images=}")
 3
 4limited_images = await client.images(number=3)
 5print(f"Found {len(limited_images)=}")
 6
 7tagged_images = await client.images(tagged=True)
 8print(f"Found {len(tagged_images)=}")
 9
10imported_images = await client.images(kind=ImageKind.IMPORTED)
11print(f"Found {len(imported_images)=}")
12
13recent_images = await client.images(since=datetime.now() - timedelta(days=7), number=5)
14print(f"Found {len(recent_images)=}")

See ImagesManager for filtering and iteration options.

 1all_images = client.images()
 2print(f"Loaded {all_images=}")
 3
 4limited_images = client.images(number=3)
 5print(f"Found {len(limited_images)=}")
 6
 7tagged_images = client.images(tagged=True)
 8print(f"Found {len(tagged_images)=}")
 9
10imported_images = client.images(kind=ImageKind.IMPORTED)
11print(f"Found {len(imported_images)=}")
12
13recent_images = client.images(since=datetime.now() - timedelta(days=7), number=5)
14print(f"Found {len(recent_images)=}")

See ImagesManagerSync for filtering and iteration options.