Skip to main content

PyContainers

pycontainers is a wrapper to communicate with the docker/container(MacOs)/podman cli. Alternative to docker-py and python-on-whales

🚀 Quick Start

Installation

pip install pycontainers

Or with uv:

uv add pycontainers

Basic Usage

from pycontainers import docker, podman

if __name__ == "__main__":
    containers = docker.ps(all=False)
    for container in containers:
        print(container)

    # Or use Podman explicitly
    podman_containers = podman.ps(all=False)

You can also auto-detect the first available runtime (docker, then podman):

from pycontainers import PyContainers

runtime = PyContainers()
print(runtime.backend)

Async Usage

Use the aio namespace inside coroutines to avoid nested asyncio.run calls:

import asyncio

from pycontainers import docker


async def main():
    await docker.aio.pull("ubuntu:20.04")
    containers = await docker.aio.ps(all=False)
    for container in containers:
        print(container)

    container = await docker.aio.run(
        "alpine",
        detach=True,
        entrypoint="/bin/sh",
        command=["-c", "sleep 60"],
    )
    output = await container.aio.execute("echo hello")
    print(output)
    await container.aio.rm()


if __name__ == "__main__":
    asyncio.run(main())

Streaming Output

Long-running or verbose commands can stream stdout/stderr instead of buffering the full response:

import asyncio

from pycontainers import docker


async def main():
    async for chunk in docker.aio.stream("pull", "ubuntu:20.04"):
        print(chunk, end="")

    container = await docker.aio.run("alpine", detach=True, command=["echo", "hello"])
    async for line in container.aio.stream_lines("logs"):
        print(line)

    # Follow logs until the stream ends (Ctrl+C in scripts)
    async for line in container.aio.follow_logs(tail=10):
        print(line)


if __name__ == "__main__":
    asyncio.run(main())

Sync callers can use docker.stream(...), container.stream_lines(...), or container.logs(follow=True).

Synchronous callers can keep using docker.ps(), docker.run(), and container.execute() as before. These commands expose typed kwargs for common options (name, detach, envs, volumes, filter, and more).

Failed CLI commands raise CommandError with subcommand, exit_code, and output attributes:

from pycontainers import CommandError, docker

try:
    docker.run("bad-image")
except CommandError as error:
    print(error.subcommand, error.exit_code, error.output)

Compose Usage

Manage multi-container projects through docker.compose (or podman.compose):

from pycontainers import docker

project = docker.compose(file="docker-compose.yml", project_name="demo")
project.up(detach=True, build=True)

for service in project.ps():
    print(service)

web = project.service("web")
print(web.exec("echo hello from compose"))

project.down(volumes=True)

Documentation

Development

This project uses Just as its task runner. Install it with brew install just or see the installation guide.

just --list                              # List available commands
just install                             # Install dependencies
just test                                # Run all tests
just test-cov                            # Run unit tests with coverage enforcement
just test-docker                         # Docker CLI integration tests (CI job: docker)
just test-container                      # Apple container CLI tests (CI job: container, macOS)
just test-podman                         # Podman CLI integration tests (CI job: podman)
just test tests/unit-tests/test_model.py  # Run specific tests
just lint                                # Run linter and verify formatting
just format                              # Apply code formatting
just check                               # Run pyright type checker
just update                              # Update dependencies
just check-deps                          # Check for outdated dependencies
VERSION=2.0.0 just build                 # Build the package (VERSION is required)
just install-local                       # Install the local wheel build
just deploy                              # Deploy to PyPI

📄 License

MIT

Metadata

Release files for pycontainers 1.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pycontainers 1.0.0
File Size Uploaded
pycontainers-1.0.0.tar.gz 105.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for pycontainers 1.0.0
File Interpreter ABI Platform
pycontainers-1.0.0-py3-none-any.whl Python 3 none any Details

Total release size: 133.9 kB

Release files / pycontainers-1.0.0.tar.gz

Download URL pycontainers-1.0.0.tar.gz
Size 105.2 kB
Tags Source
SHA-256 checksum
How to use checksums
af705d5812bd2157addbab873b5aa8f74ccc0381093916f5d7c2bf6055df6b2b
BLAKE2b-256 checksum
How to use checksums
b1d7aaa3cdb5bd90ac5e22547a96c61df463018c48891134abeb0010bd8f94b4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Release files / pycontainers-1.0.0-py3-none-any.whl

Download URL pycontainers-1.0.0-py3-none-any.whl
Size 28.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
77779535b53af0256f9302543da58d2e61dba299846ef7d01be63546bd2aa121
BLAKE2b-256 checksum
How to use checksums
9876d6a84e9f94bac7fc1c5b65221030b5099b090838ab3fab1fbce3ecc331d0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Release history Release notifications | RSS feed

This release

1.0.0 This release

2 release 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