Reading Time: 6 minutes
pypi logo

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
 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!

If you are a Fully Managed VPS server, Cloud Dedicated, VMWare Private Cloud, Private Parent server, Managed Cloud Servers, or a Dedicated server owner, and you are uncomfortable with performing any of the steps outlined, we can assist you with more information.

Avatar for Isaac Noboa

About the Author: Isaac Noboa

Former support technician, budding software developer, and general tinkerer. If there's one thing Isaac enjoys more than understanding how systems work, it's helping others do the same.

Latest Articles

How to install Puppet Server on Linux (AlmaLinux)

Read Article

Deploying web applications with NGINX HTTP Server

Read Article

Email security best practices for using SPF, DKIM, and DMARC

Read Article

Linux dos2unix command syntax — removing hidden Windows characters from files

Read Article

Change cPanel password from WebHost Manager (WHM)

Read Article