5 Best Python Libraries for Interacting with Docker API

Rate this post

πŸ’‘ Problem Formulation: Managing Docker containers can be cumbersome when dealing with the command line interface or the RESTful API directly. Programmers often require a more efficient and programmatically stable method to interact with Docker. This article explores Python libraries that offer a high-level API to Docker, providing streamlined workflows for tasks like running containers, pulling images, and monitoring Docker environments. We’ll look at several libraries enriched with methods allowing Python scripts to communicate with Docker, taking input such as image names or container configurations, and providing outputs like container status or logs.

Method 1: Docker-Py

Docker-Py, now known as Docker SDK for Python, is an official Docker client library providing a more Pythonic way of controlling Docker. It allows for full-fledged Docker operations like managing containers, images, volumes, and networks through Python scripts. This library offers comprehensive functionality coupled with ease-of-use.

Here’s an example:

import docker

client = docker.from_env()
container = client.containers.run("alpine", ["echo", "hello world"])

print(container.logs())

Output:

'hello world\n'

This script initializes a Docker client connected to the default Docker daemon. It runs an Alpine container that executes the command ‘echo “hello world”‘, and then prints out the logs from the container, showcasing the output of the executed command.

Method 2: Docker-compose

Docker-compose is a tool for defining and running multi-container Docker applications. While not a direct API for using Docker itself, Docker Compose’s Python library allows you to define service stacks, network configurations, and volumes in a Pythonic way by leveraging the Compose file format.

Here’s an example:

from compose.cli.main import TopLevelCommand, project_from_options

project = project_from_options('.', {'--file': 'docker-compose.yml'})
command = TopLevelCommand(project)

command.up({'--detach': True})

Output:

Creating network "myapp_default" with the default driver Creating volume "myapp_data" with default driver Creating myapp_web_1 ... done

This code snippet uses the Docker Compose Python library to read a ‘docker-compose.yml’ file, create a project, and then start all services defined in the Docker Compose file in detached mode. It programmatically launches the services just as if ‘docker-compose up’ were run from the command line.

Method 3: Podman-py

Podman-py is a library for interacting with Podman, which is a daemonless container runtime that is compatible with Docker. Podman-py uses a similar approach to Docker’s libraries, enabling manipulation of containers, images, and pods programmatically via Python, appealing for those using Podman for its rootless capabilities.

Here’s an example:

import podman

with podman.Client() as client:
    print(client.images.pull('alpine', 'latest'))
    print(client.containers.run('alpine', 'echo hello world'))

Output:

Trying to pull alpine:latest... Getting image source signatures... Copying blob sha256:4fe2ade4980c2... Successfully pulled alpine:latest hello world

This example demonstrates how to use podman-py to pull the latest ‘alpine’ image and then run a new container with that image, executing ‘echo hello world’. The outputs show the pulling process of the image and then output the result of the ‘echo’ command from the container.

Method 4: aiocker

aiocker is an asynchronous Python library that interfaces with Docker’s APIs. It is designed for applications that require non-blocking interactions with Docker, enabling you to perform Docker operations without stalling an application’s main event loop, making it ideal for use within asynchronous Python web frameworks like FastAPI or aiohttp.

Here’s an example:

import asyncio
from aiocker import Docker

async def run_container():
    async with Docker() as docker:
        container = await docker.containers.run("alpine", ["echo", "hello world"], detach=True)
        logs = await container.logs(stdout=True)
        print(logs)

asyncio.run(run_container())

Output:

b'hello world\n'

This asynchronous code snippet creates an aiocker Docker client, runs an Alpine container, and fetches the logs, printing out ‘hello world’. It is carried out without blocking the main event loop, which is essential for concurrency in Python programs.

Bonus One-Liner Method 5: sh

The ‘sh’ library allows you to call any program as if it were a function, and this includes Docker. This method is not explicitly designed for Docker engagement but offers a quick and straightforward way to execute Docker commands within Python.

Here’s an example:

from sh import docker

print(docker('run', 'alpine', 'echo hello world'))

Output:

hello world

This one-liner uses ‘sh’ to execute a Docker run command as if it were a shell command, pulling an Alpine image and echoing ‘hello world’. It’s a crisp approach suitable for simple commands but doesn’t provide comprehensive error handling or advanced Docker interactions.

Summary/Discussion

  • Method 1: Docker SDK for Python. Provides a full-featured and supported method to interact with Docker. Offers both low-level and high-level APIs. However, it requires understanding the Docker SDK and its structure.
  • Method 2: Docker Compose. Useful for orchestrating multi-container setups. Pythonic handling of compose files and service scaling. Not suitable for simple container tasks or fine-grained Docker object control.
  • Method 3: Podman-py. An excellent Docker alternative allowing for daemonless and rootless interactions. However, it presumes a switch from Docker to Podman which might not be desirable for all.
  • Method 4: aiocker. Offers asynchronous Docker operations, critical for modern async applications. However, the library might be less mature, and proper exception handling in async code can be complex.
  • Bonus Method 5: sh. Quick and easy for command-line-based Docker interactions with minimal code. It lacks direct Docker API benefits and isn’t intended for complex or programmatic interactions.