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=}")
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=}")
Methods¶
use()(ref) — no API call; tag or UUID is resolved at execution timeuse()(ref, strict=True) — verifies the image exists via an API calloci()(ref) (aliases:docker(),podman(),pull_by_oci()) — likeuse(strict=True), but imports from the registry if not found locallyimport_from()(ref) — always imports from an external registry
use()(ref) — no API call; tag or UUID is resolved at execution timeuse()(ref, strict=True) — verifies the image exists via an API calloci()(ref) (aliases:docker(),podman(),pull_by_oci()) — likeuse(strict=True), but imports from the registry if not found locallyimport_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"orUUID(...)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=}")
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=}")
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.