- Python wheel – Don’t reinvent it, just use it. - July 18, 2022
The Python wheel is a standard way to package code and make it available to users by uploading the wheel to a PyPI registry. This article summarises the Python wheel, why it was invented, and what it is good for. You will find a list of references at the end.
Starting with why…
Why should we package our code at all?
- To make it easy for people to access and use our code
How Should we package it?
- Who are our software’s users?
- Who will install our software? Tech people? Business people?
- Where will our software run? On servers, desktop, mobile clients, or embedded?
- Is our software installed individually, or in large deployment batches?
How to package a Python app?
There are lots of options as you can see below. In this article, we will highlight the Python wheel which is roughly on the same level as PEX (Python EXecutable).
Let’s start with the Python module…
If our code consists of a single module, i.e. a single Python file, we could simply send this around. However, the documentation we can provide inside this one code file is limited. Would it not be nice to have a README file?
If we have several modules and an __init__.py file we got ourselves an import package. It is, however, difficult to share because it consists of several files. Thus, we bundle it together into an archive. Our import package then becomes a distribution package. There are two types of distribution packages: source distributions (sdist) and built distributions (bdist). You can read more about the differences below.
- Module (a simple .py file)
- Import package (Directory containing __init__.py file)
- Distribution package (Archive of zero or more import packages)
- sdist (source distribution)
- Compressed source code (requires a build step)
- Even if the sdist is pure Python, the installation metadata from setup.py and/or setup.cfg still needs to be built out when installed by pip.
- A sdist allows almost anyone to build your code on their platform.
- bdist (built distribution)
- Binary file (wheel is standard)
- A bdist is a binary file. The current standard for bdists is what’s known as a wheel, a file with a .whl extension.
- A bdist is prebuilt (for a given platform) and saves users the work of building it themselves.
- sdist (source distribution)
Why use a Python wheel instead of a sdist?
Here is what the Python Packaging Authority (PyPA) has to say about it:
Apart from the reason that one may not have the right tools or experience to compile code of other languages, wheels also significantly speed up the installation process of packages. You will find a list of more advantages at the end of the article.
What is inside a Python distribution?
In the graphic above you can see an example of files that could go into a distribution package. Apart from source code, there could be compiled artifacts, test data, documentation, metadata, and so forth.
What type of Python wheels are there?
There are three types of python wheels with different levels of constraints: universal, pure Python, and platform wheels.
When you go to pypi.org, look for a package and click on Download files, you will see that you can download the source distribution, and normally one or more built distributions. Below you can see a screenshot of the well-known pandas package.
Platform wheels are usually a bit larger in size than the source distribution because they contain compiled artifacts from other languages than Python. However, the installation process with wheels compared to sdists is much quicker as there is no build step required.
How to read a Python platform wheel filename?
How to read a Python universal wheel filename?
The Python wheel in a nutshell…
- wheels install faster than source distributions for both pure-Python packages and extension modules
- wheels are smaller than source distributions (if not platform specific)
- there’s no need for a compiler to install wheels that contain compiled extension modules
- pip automatically generates .pyc files in the wheel that match the right Python interpreter
- pip will always choose a wheel over a sdist if available
- wheels provide consistency by removing many of the variables involved in installing a package out of the equation
One important security concern of (platform) wheels is that they are potentially subject to version rot as they contain a binary dependency that is not updated automatically by your system package manager. So be sure to check the wheel’s creation date. Right below the download link on pypi.org, you will see when the wheel was last updated.