One of the most significant advantages of Python is how easy it is to reuse existing code.
- Need to talk to servers? Just import requests!
- Need to talk to a MySQL database? Import the mysql.connector software!
- Need to fly? Just import antigravity!
Of course, these packages need to exist somewhere in your server, and installing them can be problematic without the right tools. Fortunately, that is a problem the Python developers have invested significant time investigating and correcting.
The solution to this problem first arrived in 2004 in the form of a suite of tools called setuptools. It is a collection of Python enhancements that make it easy to package and disseminate Python distributions, especially those that depend on other packages. The original format used by setuptools was an “egg”; This is a ZIP file with additional information added to help the system locate and sort it out correctly.
To manage these packages, setuptools includes easy_install, which can automatically download, build, install, and manage Python eggs.
Sadly, Python eggs have several disadvantages:
- Only a single version of a package can be installed in a given directory. This is especially troublesome if different parts of your application require different versions of the same package.
- It provides no support for clean uninstallation or upgrades. Removing files is the most common method, but it can get messy if any listed files are missing. Mainly, the issue lies in that the .egg_info files do not have a way to list the installed files that document the package metadata.
- Using an egg often requires modifying the sys.path variable to add the location of this egg. This modification, in turn, slows down the search whenever a command is issued. It is only noticeable when you have many entries (a hundred or so), which, while improbable, is certainly possible in complicated setups.
To overcome those disadvantages, the Python community agreed on a new package standard called Wheels, which is similar to Egg files. However, there are a few notable differences that make this a better option:
- Wheels are used for installation, not for importing code directly. This means that the code itself does not need to be compiled before it is packaged. This way, it is not tied to a specific Python version of the implementation. In other words, you can install packages built with previous versions of Python in your current install. This way, we do not have to wait for the developers of the package to create a new release.
- Related to this, Wheels keeps the version of the wheel specification used for packaging. This makes the format more future-proof since newer versions can determine which packages should be treated as older ones.
- The naming convention for Wheels makes it possible to see where a package comes from and what version it is. This information quickly determines what data to keep when two packages conflict. For example, distribution-1.0-1-py27-none-any.whl is the first build of a package called ‘distribution’ and is compatible with any Python 2.7 implementation. There is no need for a specific Application Binary Interface, on any CPU architecture.
- Lastly, Python wheels contain all the same information as eggs. It is possible to convert existing eggs without losing any info and extracting an egg from any given wheel.
The Introduction of Pip
To take advantage of all these benefits, the Pip installer was released in 2008. This package also replaced easy_install (while still being mainly built on top of setuptools). Besides all the advantages that wheels have, Pip has many other desirable features:
- The ability to override your package’s dependencies on specific versions of different packages it needs, using Requirements files — another major win towards forward compatibility. This makes it easy to replicate environments when deploying an application.
- The ability to uninstall packages using the Pip uninstall command. Also, listing installed packages using the Pip list command. Or using Pip freeze if you need them listed in the Requirements format.
- Pip can also install packages from PyPI (Python Package Index), a central repository for Python software. This is a handy tool in keeping all our packages up-to-date and synchronized.
- Another significant advantage of Pip is that it can install files as a regular user by default without escalating to root. This is both a security improvement in general and a convenience when installing packages in shared hosting, where root access may not be available.
So, Which Installer Should I Use?
In most cases, unless you know exactly what you are doing and why, you will want to use Pip. The specific situations where easy_install is the better option are few and far between. You will most likely already know if you need to use easy_install, but those cases certainly exist.
In the first place, when you need to install a package that is only available as an egg, you have no choice but to use easy_install.
Another use-case of easy_install is using an external launcher (such as pylauncher) to launch scripts. When configured with the SETUPTOOLS_LAUNCHER environment variable, easy_install will install scripts with the .pya extension appended so that they can be launched by double-clicking similar to any other executable.
Easy_install also allows us to exclude individual scripts during installation using the --exclude-scripts flag. This flag is useful if you need to install multiple versions of a package while preserving the earlier script versions.
It used to be the norm that we would have to install Pip using setuptools. Nowadays, that is not the case—most environments where Python is installed already come with a copy of Pip. But, if it does not (and your system package manager also does not offer a copy), you can run a simple script to set it up.
Setuptools (which includes install) are also generally installed through Pip, via downloadable packages, if you need to install them manually.
Installing a Package Using Pip
Let’s quickly go over how to use each of these package distribution tools. Using Pip is remarkably easy once you know the name of the package you want to install. Simply running pip install package_name will make the package available for importing. In this case, we are going to be installing Pillow, a popular Python imaging library.
[user@host ~]$ pip install Pillow Defaulting to user installation because normal site-packages is not writeable Collecting Pillow Downloading Pillow-8.0.1-cp38-cp38-manylinux1_x86_64.whl (2.2 MB) |████████████████████████████████| 2.2 MB 1.5 MB/s Installing collected packages: Pillow Successfully installed Pillow-8.0.1
Note how Pip automatically locates the wheel file appropriate for our system, in this case, Pillow-8.0.1-cp38-cp38-manylinux1_x86_64.whl. It also detected that we ran it as a regular user instead of as root and installed Pillow for this user only.
Installing a Package Using Easy_Install
To install easy_install packages as a user, we first need to set up a configuration file at /home/user/.pydistutils.cfg. We can skip this step if we are installing a program as root for every user on the machine:
[user@host ~]$ cat > $HOME/.pydistutils.cfg <<EOF > [install] > user=1 > EOF Once that is set up, just run easy_install as normal. [user@host ~]$ easy_install Pillow WARNING: The easy_install command is deprecated and will be removed in a future version. Searching for Pillow Reading https://pypi.org/simple/Pillow/ Downloading https://files.pythonhosted.org/packages/[...] Best match: Pillow 8.0.1 Processing Pillow-8.0.1-cp38-cp38-manylinux1_x86_64.whl Installing Pillow-8.0.1-cp38-cp38-manylinux1_x86_64.whl to /home/user/.local/lib/python3.8/site-packages Adding Pillow 8.0.1 to easy-install.pth file Installed /home/user/.local/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg Processing dependencies for Pillow Finished processing dependencies for Pillow
The output is more verbose, but it tells us a couple of essential things. First, that easy_install has already been deprecated, favoring Pip, so we should be using Pip when possible. Second, we can see how, although only a Wheel (.whl) package is available, it still contains all the necessary information to create the .egg format package that easy_install needs.
While the choice used to be more difficult in the past, the idea is obvious now; Pip should be our go-to solution whenever possible. It is explicitly designed to take as much of the setup effort out of your hands as possible. However, in the rare cases where your setup explicitly requires it, or when the only available option for installing a package is an .egg file, easy_install is still there to help.
Should you have any questions regarding this information, we are always available to answer any inquiries with issues related to this article, 24 hours a day, 7 days a week 365 days a year.
Give us a call at 800.580.4985, or open a chat or ticket with us to speak with one of our knowledgeable Solutions or Experienced Hosting advisors to learn how you can take advantage of these techniques today!
Our Sales and Support teams are available 24 hours by phone or e-mail to assist.