Python’s first mainstream package was the .egg file. Now there’s a new format in town called the Wheel (*.whl). A wheel “is designed to contain all the files for a PEP 376 compatible install in a way that is very close to the on-disk format”. In this article, we will learn how to create a wheel and then install our wheel in a virtualenv.
Getting Started
You will need pip to create wheel with. To learn how to install pip, I highly recommend reading pip’s installation page. If you already have pip, then you may need to upgrade it to the latest version. Here’s how: in a console window, type the following:
pip install --upgrade pip
Once you have that done, we’re ready to learn how to create wheels!
Creating a wheel
First of all, you will need to install the wheel package:
pip install wheel
That was easy! Next, we’ll be using the unidecode package for creating our first wheel as it doesn’t already have one made at the time of writing and I’ve used this package myself in several projects.
pip wheel --wheel-dir=my_wheels Unidecode
Now you should have a wheel named Unidecode-0.04.14-py26-none-any.whl in a folder named my_wheels. Let’s learn how to install our new wheel!
Install a Python wheel
Let’s create a virtualenv to test with. You can read more about virtualenv here. Once you have it installed, run the following command:
virtualenv test
This will create a virtual sandbox for us to play in that includes pip. Be sure to run the activate from its Scripts folder to enable the virtuanenv before continuing. Now virtualenv does not include wheel, so you’ll have to install wheel again:
pip install wheel
Once that is installed, we can install our wheel with the following command:
pip install --use-wheel --no-index --find-links=path/to/my_wheels Unidecode
To test that this worked, run Python from the Scripts folder in your virtualenv and try importing unidecode. If it imports, then you successfully installed your wheel!
Note: I originally had an old version of virtualenv installed that was quite troublesome. Be sure to upgrade yours or you’ll have to do a lot of futzing around to get it to work.
The *.whl file is similar to an *.egg in that it’s basically a *.zip file in disguise. If you rename the extension from *.whl to *.zip, you can open it up your zip application of choice and examine the files and folders inside at your leisure.
Wrapping Up
Now you should be ready to create your own wheels. They look like a nice way to create a local repository of dependencies for your project(s) that install quickly. You could create several different wheel repositories to easily switch between different version sets for testing purposes. When combined with virtualenv, you have a really easy way to see how newer versions of dependencies could affect your project without needing to download them multiple times.
Additional Information
- Wheel documentation
- Python Packaging User Guide
- virtualenv documentation
Do wheels have any practical advantage over eggs at this point? I understand that wheels implement the latest PEP’s etc. where eggs do not but for simple users like myself some practical incentive to switch might be useful.
Setuptools already provide the ability to create wheels,same as sdist or dist_egg, but what I’d like to know, if there’s a way to create a multiversion wheel/egg along with uploading it to PyPI?
Right now it seems as if I have to upload it from different version I python to get a wheel/egg for each python version it supports…
Add this to your setup.cfg:
[wheel]
universal = 1
They are supposedly faster to install, but I haven’t used them enough to be able to tell the difference.
Yeah, that’s true. Setuptools does support wheels. I was just expounding a bit on the documentation as it seems to recommend using pip.
They’re indeed notably faster to install, which can make a real difference if you’re doing a lot of installing.