Package: python-on-whales
A Docker client for Python, designed to be fun and intuitive!Works on Linux, macOS and Windows, for Python 3.8 and above.DocumentationGithub repositoryHow to install?pipinstallpython-on-whalesSome cool examplesStart by doingfrompython_on_whalesimportdockerand then:docker run hello-world->docker.run("hello-world")docker pull ubuntu->docker.pull("ubuntu")docker build ./->docker.build("./")docker compose up my_service->docker.compose.up(["my_service"])docker image ls->docker.image.list()docker ps->docker.ps()docker cp->docker.copy()You get the idea 🙂 it's the same as the CLI we all know and love.>>>frompython_on_whalesimportdocker>>>output=docker.run("hello-world")>>>print(output)HellofromDocker!Thismessageshowsthatyourinstallationappearstobeworkingcorrectly....>>>frompython_on_whalesimportdocker>>>print(docker.run("nvidia/cuda:11.0-base",["nvidia-smi"],gpus="all"))+-----------------------------------------------------------------------------+|NVIDIA-SMI450.51.06DriverVersion:450.51.06CUDAVersion:11.0||-------------------------------+----------------------+----------------------+|GPUNamePersistence-M|Bus-IdDisp.A|VolatileUncorr.ECC||FanTempPerfPwr:Usage/Cap|Memory-Usage|GPU-UtilComputeM.||||MIGM.||===============================+======================+======================||0TeslaT4On|00000000:00:1E.0Off|0||N/A34CP89W/70W|0MiB/15109MiB|0%Default||||N/A|+-------------------------------+----------------------+----------------------++-----------------------------------------------------------------------------+|Processes:||GPUGICIPIDTypeProcessnameGPUMemory||IDIDUsage||=============================================================================||Norunningprocessesfound|+-----------------------------------------------------------------------------+>>>frompython_on_whalesimportdocker>>>my_docker_image=docker.pull("ubuntu:20.04")20.04:Pullingfromlibrary/ubuntue6ca3592b144:Downloading[=============>]7.965MB/28.56MB534a5505201d:Downloadcomplete990916bd23bb:Downloadcomplete>>>print(my_docker_image.repo_tags)['ubuntu:20.04']>>>docker.image.list()[python_on_whales.Image(id='sha256:1a437e363abfa',tags=['ubuntu:20.04'])]>>>my_docker_image.remove()>>>frompython_on_whalesimportdocker>>>my_image=docker.build(".",tags="some_name")# uses Buildx/buildkit by default[+]Building1.6s(17/17)FINISHED=>[internal]loadbuilddefinitionfromDockerfile0.0s=>=>transferringdockerfile:32B0.0s=>[internal]load.dockerignore0.0s=>=>transferringcontext:2B0.0s=>[internal]loadmetadatafordocker.io/library/python:3.61.4s=>[python_dependencies1/5]FROMdocker.io/library/python:3.6@sha256:29328c59adb9ee6acc7bea8eb86d0cb14033c850.0s=>[internal]loadbuildcontext0.1s=>=>transferringcontext:72.86kB0.0s=>CACHED[python_dependencies2/5]RUNpipinstalltypeguardpydanticrequeststqdm0.0s=>CACHED[python_dependencies3/5]COPYtests/test-requirements.txt/tmp/0.0s=>CACHED[python_dependencies4/5]COPYrequirements.txt/tmp/0.0s=>CACHED[python_dependencies5/5]RUNpipinstall-r/tmp/test-requirements.txt-r/tmp/requirements.txt0.0s=>CACHED[tests_ubuntu_install_without_buildx1/7]RUNapt-getupdate&&apt-getinstall-yapt-tr0.0s=>CACHED[tests_ubuntu_install_without_buildx2/7]RUNcurl-fsSLhttps://download.docker.com/linux/ubuntu/g0.0s=>CACHED[tests_ubuntu_install_without_buildx3/7]RUNadd-apt-repository"deb [arch=amd64] https://downl  0.0s=>CACHED[tests_ubuntu_install_without_buildx4/7]RUNapt-getupdate&&apt-getinstall-ydocker-ce-0.0s=>CACHED[tests_ubuntu_install_without_buildx5/7]WORKDIR/python-on-whales0.0s=>CACHED[tests_ubuntu_install_without_buildx6/7]COPY..0.0s=>CACHED[tests_ubuntu_install_without_buildx7/7]RUNpipinstall-e.0.0s=>exportingtoimage0.1s=>=>exportinglayers0.0s=>=>writingimagesha256:e1c2382d515b097ebdac4ed189012ca3b34ab6be65ba0c650421ebcac8b70a4d0.0s=>=>namingtodocker.io/library/some_image_nameSome moredocker.run()advanced examples with postgresdockerrun--namesome-postgres-ePOSTGRES_PASSWORD=mysecretpassword-dpostgresbecomesfrompython_on_whalesimportdockerdocker.run("postgres:9.6",name="some-postgres",envs={"POSTGRES_PASSWORD":"mysecretpassword"},detach=True,)print(docker.ps())# [python_on_whales.Container(id='f5fb939c409d', name='some-postgres')]dockerrun-it--rm--networksome-networkpostgrespsql-hsome-postgres-Upostgresbecomesfrompython_on_whalesimportdocker# since it's interactive, you'll be dropped into the psql shell. The python code# will continue only after you exit the shell.docker.run("postgres:9.6",["psql","-h","some-postgres","-U","postgres"],networks=["some-network"],interactive=True,tty=True,remove=True,)dockerrun-d--namesome-postgres-ePOSTGRES_PASSWORD=mysecretpassword-ePGDATA=/var/lib/postgresql/data/pgdata-v/custom/mount:/var/lib/postgresql/data-vmyvolume:/tmp/myvolumepostgres-cshared_buffers=256MB-cmax_connections=200becomesfrompython_on_whalesimportdockerdocker.run("postgres:9.6",["-c","shared_buffers=256MB","-c","max_connections=200"],name="some-postgres",envs={"POSTGRES_PASSWORD":"mysecretpassword","PGDATA":"/var/lib/postgresql/data/pgdata"},volumes=[("/custom/mount","/var/lib/postgresql/data"),("myvolume","/tmp/myvolume")],detach=True,)Any Docker object can be used as a context manager to ensure it's removed even if an exception occurs:frompython_on_whalesimportdockerwithdocker.volume.create("random_name")assome_volume:docker.run("postgres:9.6",["-c","shared_buffers=256MB","-c","max_connections=200"],name="some-postgres",envs={"POSTGRES_PASSWORD":"mysecretpassword","PGDATA":"/var/lib/postgresql/data/pgdata"},volumes=[(some_volume,"/var/lib/postgresql/data"),("myvolume","/tmp/myvolume")],detach=True,)# so some stuff here# here we are out of the context manager, so the volume has been removed, even if there was an exception.Main features1 to 1 mapping between the CLI interface and the Python API. No need to look in the docs
what is the name of the function/argument you need.Support for the latest Docker features:Docker buildx/buildkit,docker run --gpu=all ...Support for Docker stack, services and Swarm (same API as the command line).Progress bars and progressive outputs when pulling, pushing, loading, building...Support for some other CLI commands that are not inDocker-py:docker cp,docker run --cpus ...and more.Nice SSH support for remote daemons.Docker object as Python objects: Container, Images, Volumes, Services... and their
attributes are updated in real-time!Each Docker object can be used as a context manager. When getting out of the
context, the Docker object is removed automatically, even if an exception occurs.A fully typed API (Mypy and IDE-friendly) compatible withpathlibandos.pathAll Docker objects and the Docker client are safe to use with multithreading and multiprocessing.Display the commands called and the environment variables used by setting the environment variablePYTHON_ON_WHALES_DEBUG=1.Why another project? Why not build on Docker-py?In a sense this project is built on top ofDocker-pybecause the implementation, the organisation and the API is inspired from the project, but the codebases
could not be the same.Two major differences do not permit that:The API is quite different. The aim of Python on Whales is to provide a 1-to-1
mapping between the Docker command line and Python, so that users don't even have
to open the docs to do write code.WhileDocker-pyis a complete re-implementation of the Docker client binary
(written in Go), Python on whales sits on top of the Docker client binary, which makes
implementing new features much easier and safer. For example, it'sunlikely that docker-py supports Buildx/buildkitanytime soon because rewriting a large Go codebase in Python is hard work.Should I use Docker-py or Python on Whales?Well, it's written in each project's description!Docker-py: A Python library for the Docker Engine APIPython on whales: An awesome Python wrapper for an awesome Docker CLIIf you need to talk to the Docker engine directly, you need to do low level operations,
use docker-py. Some good example would be writing the code to control docker from an IDE,
or if the speed of Docker calls is very important.
If you don't want to depend on the Docker CLI binary (~50MB), use docker-py.If you wanted to call the docker command line from Python,
do high level operations, use Python on Whales.
For example if you want to write your CI logic in Python rather than in bash (a very good choice 😉).
Some commands are only available in Python on whales
too:docker.buildx.build(...),docker.stack.deploy(...)...Use the right tool for the right job 🙂Alternatives to Docker: Podman, nerdctl...Support for Docker-compatible clients likePodmanandNerdctlwas introduced in Python-on-whales version 0.44.0.You can use an arbitrary binary to execute Docker commands by using the argumentclient_callofpython_on_whales.DockerCLient.
Here is an example:>>>frompython_on_whalesimportDockerClient>>>nerdctl=DockerClient(client_call=["nerdctl"])>>>nerdctl.pull("python:3.9")docker.io/library/python:3.9:resolved|++++++++++++++++++++++++++++++++++++++|index-sha256:a83c0aa6471527636d7331c30704d0f88e0ab3331bbc460d4ae2e53bbae64dca:done|++++++++++++++++++++++++++++++++++++++|manifest-sha256:8ccef93ff3c9e1bb9562d394526cdc6834033a0498073d41baa8b309f4fac20e:done|++++++++++++++++++++++++++++++++++++++|config-sha256:f033692e2c5abe1e0ee34bcca759a3e4432b10b0031174b08d48bcc90d14d68b:done|++++++++++++++++++++++++++++++++++++++|layer-sha256:9952b1051adaff513c99f86765361450af108b12b0073d0ba40255c4e419b481:done|++++++++++++++++++++++++++++++++++++++|layer-sha256:c766e27afb21eddf9ab3e4349700ebe697c32a4c6ada6af4f08282277a291a28:done|++++++++++++++++++++++++++++++++++++++|layer-sha256:1535e3c1181a81ea66d5bacb16564e4da2ba96304506598be39afe9c82b21c5c:done|++++++++++++++++++++++++++++++++++++++|layer-sha256:6de7cb7bdc8f9b4c4d6539233fe87304aa1a6427c3238183265c9f02d831eddb:done|++++++++++++++++++++++++++++++++++++++|layer-sha256:967757d5652770cfa81b6cc7577d65e06d336173da116d1fb5b2d349d5d44127:done|++++++++++++++++++++++++++++++++++++++|layer-sha256:c357e2c68cb3bf1e98dcb3eb6ceb16837253db71535921d6993c594588bffe04:done|++++++++++++++++++++++++++++++++++++++|layer-sha256:26787c68cf0c92a778db814d327e283fe1da4434a7fea1f0232dae8002e38f33:done|++++++++++++++++++++++++++++++++++++++|layer-sha256:6aefca2dc61dcbcd268b8a9861e552f9cdb69e57242faec64ac120d2355a9c1a:done|++++++++++++++++++++++++++++++++++++++|layer-sha256:32a180f5cf85702e7680719c40c39c07972b1176355df5a621de9eb87ad07ce2:done|++++++++++++++++++++++++++++++++++++++|elapsed:35.9stotal:333.5(9.3MiB/s)python_on_whales.Image(id='sha256:f033692e2c5ab',tags=['python:3.9'])You can do something similar with podman:frompython_on_whalesimportDockerClientpodman=DockerClient(client_call=["podman"])podman.pull("hello-world")podman.run("hello-world")print(podman.ps())...ContributingAny and all PRs are welcome. Please seethis documentation.What about the license?It's a MIT license, so quite permissive.The license can be foundin the git repository.