Skip to main content

literegistry-podman-client

literegistry-podman-client is a small, standalone async Python client for running commands in rootless Podman containers through a LiteRegistry gateway. The person using it needs only a gateway URL; they do not need Redis, Podman, Docker, or the full literegistry package.

The same gateway may also expose a Docker Hub pull-through mirror. Mirror use is configured on the Podman servers by the operator, so client code still only passes a normal image such as docker.io/library/ubuntu:24.04.

Install

From PyPI after publication:

pip install literegistry-podman-client

From this repository:

pip install ./literegistry_podman_client

The distribution name uses hyphens. Python imports use underscores:

from literegistry_podman_client import PodmanClient

Its only runtime dependency is aiohttp.

Give a deployment to someone

The operator gives the user one value:

export PODMAN_GATEWAY_URL=http://gateway.example:8080

The user can verify both gateway features:

curl -fsS "$PODMAN_GATEWAY_URL/health"
curl -fsS "$PODMAN_GATEWAY_URL/v2/"

/health checks the LiteRegistry gateway. /v2/ checks its Docker Registry V2 mirror route. No Redis URL or Podman replica address is exposed to users.

Small async example

This creates one container, writes a file, reads it in a separate command, and always deletes the container at the end:

import asyncio

from literegistry_podman_client import PodmanClient


async def main() -> None:
    gateway_url = "http://gateway.example:8080"

    async with PodmanClient(gateway_url, workdir="/tmp") as client:
        async with client.session(
            image="docker.io/library/ubuntu:24.04",
            client_id="rollout-17",
        ) as podman:
            print(podman.container_id)

            await podman.execute(
                "printf 'ai2 hello\\n' > hello.txt",
                check=True,
            )
            result = await podman.execute("cat hello.txt", check=True)
            print(result.stdout, end="")


asyncio.run(main())

The image pull happens on the selected Podman replica. If the operator wired those replicas to the gateway's mirror, the pull is transparently cached; the user does not change the image reference or client configuration.

The runnable version is examples/ai2_hello.py:

python literegistry_podman_client/examples/ai2_hello.py \
  --gateway "$PODMAN_GATEWAY_URL"

Explicit lifecycle

Handshake, execute, and close are all async. The affinity ID returned by the handshake keeps every command on the replica that owns its container.

client = PodmanClient(gateway_url, workdir="/home/user")
await client.open()
session = None
try:
    session = await client.handshake(image=container_image)
    first = await client.execute(
        session.affinity_id,
        "python -c 'print(6 * 7)'",
        timeout=60,
    )
    first.check_returncode()
finally:
    try:
        if session is not None:
            await session.close()
    finally:
        await client.aclose()
  • client.close(affinity_id) or session.close() deletes the container and its gateway affinity binding.
  • client.aclose() only closes the local HTTP connection pool. It cannot guess which concurrent sessions should be deleted.
  • check=True or result.check_returncode() raises PodmanCommandError for a non-zero command exit. Without it, stdout, stderr, and the exit code remain available on CommandResult.

Concurrent trajectories

One PodmanClient is intentionally shareable. It does not store a private "current container". Each handshake returns a separate session:

async def rollout(client: PodmanClient, number: int) -> str:
    async with client.session(client_id=f"rollout-{number}") as podman:
        result = await podman.execute("echo $((20 + 22))", check=True)
        return result.stdout.strip()


async with PodmanClient(gateway_url) as client:
    outputs = await asyncio.gather(
        *(rollout(client, i) for i in range(128))
    )

The HTTP pool is shared, while every request carries its explicit affinity ID. As soon as one trajectory completes, application code may start another.

Mirror behavior

There are two distinct flows behind the gateway URL:

Python client -> /affinity/* -> Podman replica -> rootless container
Podman pull   -> /v2/*       -> Docker mirror -> Docker Hub

The client exposes await client.mirror_health() as a convenience probe, but it does not configure the mirror. The deployment operator configures each Podman replica's containers-registries.conf to use the gateway URL. This is what ensures all users of the gateway benefit from the cache.

Build and publish

cd literegistry_podman_client
python -m build
python -m twine check dist/*
python -m twine upload dist/*

Publishing requires a PyPI account and token. Verify that the distribution name literegistry-podman-client is available before the first upload.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

literegistry_podman_client-0.1.1.tar.gz (11.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

literegistry_podman_client-0.1.1-py3-none-any.whl (8.6 kB view details)

Uploaded Python 3

File details

Details for the file literegistry_podman_client-0.1.1.tar.gz.

File metadata

File hashes

Hashes for literegistry_podman_client-0.1.1.tar.gz
Algorithm Hash digest
SHA256 9d0c703d2aa9427acf4c9ebf925fcb04b4e66a34dbe65b049cafac8534625df2
MD5 dbaf8ed4515a9a4cbad867d6e2c56825
BLAKE2b-256 a95f6195803a31b3a1d1d3af05ddfaccca855dbe5dc3daf2b78e98d3ab58b1d6

See more details on using hashes here.

File details

Details for the file literegistry_podman_client-0.1.1-py3-none-any.whl.

File metadata

File hashes

Hashes for literegistry_podman_client-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 0ae440faeeb7417b98a4b29911987c1fd4b503eb0a7ae84bf9c2954f21a93728
MD5 d714f2c89651c1953a5fef5a31cd6c59
BLAKE2b-256 52616d1ce53a302923933f09265504c0e7bafc7a36f7db0558128f7e8ebcad6c

See more details on using hashes here.

Release history Release notifications | RSS feed

0.1.3

2 files

0.1.2

2 files

This release

0.1.1 This release

2 files

0.1.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page