DEV Community

Cover image for Setting up a Python development environment with pipenv
David Itam Essien
David Itam Essien

Posted on • Updated on

Setting up a Python development environment with pipenv

What is pipenv?

Photo credit:Make a Mem.org

According to the official documentation, “Pipenv is a tool that aims to bring the best of all packaging worlds (bundler, composer, npm, cargo, yarn, etc.) to the Python world.” “It harnesses Pipfile, pip, and virtualenv into one single command."

What does this mean?

Photo credit:Make a Mem.org

First, we need to understand what a package manager is. A package manager is a tool that helps in the process of managing (installing, uninstalling, and upgrading) software packages or modules. If you have worked with node.js before, you would have worked with NPM (Node Package Manager) which is used for managing the JavaScript modules you work with on node. What pipenv does is help with the management of the python packages used for building projects in the same way that NPM does.

Pipenv works by creating a virtual environment for isolating the different software packages that you install for your projects. Before pipenv, they were other python package managers for creating virtual environments like virtualenv, but they have their issues.

Why virtual environments?

Hi! My name is Pip. I am the standard package manager for python. I can help you install and uninstall python packages. However, I install them in the global scope of your system’s environment.

Why is this a problem?

Imagine that you have about 5 Django projects on your computer and each of them uses its own version of Django, each of these versions of Django has their different versions of dependencies. If you are actually doing the imagination with me, you will soon realize that there is bound to be conflict among the dependencies. Perhaps, a lower version of a dependency will be overridden, causing one of your apps to break and this is not what you want.

A simple solution to this is to create a form of isolation for each of these projects so that they do not interfere with each other hence avoiding a Django civil-war. This is where virtual environments come in.
It is a common practice among software development teams working on a single project to share a file containing a description of all the packages required to run the application. Pip uses a requirement.txt file. However, some problems arise with this.

The requirements.txt file does not take note of the specific versions of the packages being installed. This can cause problems in the future because running “pip install” will get the most recent versions of the packages which may cause the app to break. Although this problem can be solved by pinning(manually specifying) the versions, this will not work for the dependencies of the packages, since they are recorded in the requirements.txt file.

Let me make it clearer - supposing you have two packages you installed with pip (p1 v.0.01 and p2 v.0.02). These packages each have their own dependencies. Only the above-mentioned packages will be recorded in the requirements.txt file. So even if they are not upgraded to the most recent versions, their dependencies are not pinned and can be upgraded, causing the app to break.

Why pipenv

  • Pipenv solves the above problems by creating virtual environments for running each individual project, so their packages and dependencies do not clash.

  • Secondly, pipenv manages the records of the installed packages and their dependencies using a pipfile, and pipfile.lock files. The pipfile keeps track of all the installed packages which the pipfile.lock file keeps track of their dependencies. The fun part about this whole thing is that you can easily generate a requirements.txt file for people who are not using pipenv yet.

  • In the past, we had other packages for creating virtual environments that helped solve this problem, one of them is the virtualenv package, but it is a bit tedious to set up and use. Pipenv makes it easier for you to manage your packages. It combines pip and virtualenv to create virtual environments for your project.

Image Source: https://docs.pipenv.org/en/latest/

Enough talk, let’s get to work.

Photo credit: imgflip

Setting up pipenv

For the sake of demonstrating how pipenv works, we will be setting up a basic Django project. But for this to happen, we need to have python and pip installed.

Install python3

We will be installing python3 which is the latest version of python. The easiest approach is to visit: https://www.python.org/downloads/, download the package that is suitable for your operating system and install it. For this article, I will be working on the Mac OSX environment. So alternatively you can install python via terminal, in the following steps:

After the installation process has finished running, you can type which brew to see the location of the installed homebrew. Homebrew is a package manager for mac your output should look similar to this

  • Install python 3. To install python3, run brew install python3

On my computer, it shows that I have already installed python3, it also shows the version of python3 that I have installed.

To verify that you have python3 installed, on the terminal, type: which python3

When you install python3 using homebrew, it automatically installs pip3
You can verify that pip3 is installed by running which pip3 or pip3 --version

Install pipenv

To install pipenv, run Pip3 install pipenv

If you look at my output in the screenshot, you will see some places where it states “Requirement already satisfied” - That is because I already had virtualenv installed, and remember I told you that pipenv works with both virtualenv and pip.

Which environment are we in currently?

When I run “pip3 freeze”, you will see that it displays all the packages that I have in my current environment which is the global environment. You will soon see the difference when we run the same command in our virtual environment when we have not installed any packages.

Launch virtual environment

To create our virtual environment, we have to create a directory for our project and run the commands in that directory.

Looking at the screenshot above, you will realize that I ran the following commands:

  • mkdir project_1 - to create a new project directory
  • cd project_1 - to change my current working directory to the new directory I just created
  • pipenv shell - to create a new virtual environment, and you will notice that the environment has been successfully created.

Verify which environment we are in

To verify that we have changed environments, run pip3 freeze again:

Unlike the previous output, you will notice that there is no result. This is because we are no longer in the global scope, and in this new environment, we have not installed any apps. Also, if you check the project directory, you will notice that a new Pipfile has been created.

The pipfile is written in a configuration language call TOML(Tom’s Obvious Minimal Language). It is meant for writing easy to read configuration files. We will not bother ourselves with the first four lines.

  • Line 6 indicates where packages that will be used for development purposes only will be listed. These packages will not be installed in production environments, only in testing and development environments.
  • Line 8 indicates the section where production based packages will be listed
  • Line 11 indicates the version of python used or required.
  • Note that you can manually add the packages to this file, and run pipenv install on your terminal to install them.

Now, let us install a new package, and see what happens. We will be installing Django

You will notice that I did not specify the version of Django to install. You will also notice that it searched for a Pipfile.lock file and created one when it could not find any.

In our code editor, you will also find out that Django has been added to the list of packages. And the version is specified with an asterisk. What this means is that it will always install the latest version whenever someone runs pipenv install. We can also change the asterisk to the version we want. You will also notice that a piplefile.lock file was generated. This keeps track of all the installed packages and their dependencies.

One more thing we can do is to run the pip3 freeze command again. You will notice that only the packages listed in the pipfile.lock file are listed here.

Check the current environment

You can type the following commands to verify which environment you are in:

  • Python - this should start the python shell, as seen in the image below.
  • Import sys - import the sys module
  • Sys.excutable - this should print out the path to the current python environment you are running in
  • Type exit() - to quit the python shell Type exit - to quit the environment.
  • Repeat the first 3 commands, you will notice that the output is different. This is because as of now, mac comes with python 2.7 preinstalled. Since you are no longer in the virtual environment you created, you will get a different output. You can also run pip3 freeze

Testing our Django installation

  • Make sure you are in the directory you created your environment
  • Type pipenv shell - to activate the environment
  • Run django-admin startproject bookstore . - The period (.) at the end indicates that it should install it in the current directory and call the project bookstore. You may not see any output after the command is executed.
  • Type ls on the terminal, and you will see that a new directory called bookstore has been created. You will also notice another file called manage.py.

Run the Django app

To run the Django app, on the terminal, type the following command:

  • python manage.py runserver
  • Copy the URL provided in the terminal as highlighted, pasted it on your browser address bar and press enter to run it.

Now you have your Django app

The requirements.txt file

As earlier mentioned, the requirements.txt file was used to keep records of installed packages when using pip. In case you need to work with someone who uses pip instead of pipenv, you can share a requirements.txt file with them:

Create a requirements.txt file

  • run the pipenv lock -r command to display the list of installed packages.
  • Copy the output of the above-executed command and paste it in the requirements.txt file and push it to your project repository. The other developer, just needs to run pip install, and all the packages and their dependencies will be installed.

Generate your own pipfile.lock

In case you have a requirements.txt file, you can generate your pipfile.lock

  • Put the requirements.txt file in your project directory
  • Run pipenv lock
  • Run pipenv install --ignore-pipfile - this will install all packages and their dependencies using the pipfile.lock and will ignore the pipfile.

Other useful pipenv commands

List packages installed in the current environment

  • Pipenv lock -r

  • Pipenv uninstall package to uninstall the package

  • Install packages for development environments

  • Check for Security vulnerabilities
    To check for vulnerabilities in your packages, you can run pipenv check

  • View package dependency graph
    You can see all your project’s packages and their dependencies by running: pipenv graph

  • Environment variables
    You can also add environment variables to your projects

    • Create a .env file
    • Add environment variables to it
    • PASSWORD=’mysecretpassword’
    • pipenv run python You will see the environment variables loading Import os os.environ[‘PASSWORD’]
  • Delete a virtual environment

    You can also remove the environment. Note that this does not delete the resources or files created in your project. It simply deactivates the environment.

I hope you enjoyed my tutorial. Please leave your feedback so that I can share better. Remember to like and share so that others will learn from it.

Top comments (14)

Collapse
 
mtaylor124 profile image
MTaylor124

A year later and this article still helped more than my last 15 google searches/stack overflow and several youtube videos. Thank you.

Collapse
 
davidshare profile image
David Itam Essien

@mtaylor124 it is good to know that it was helpful. Thank you.

Collapse
 
ndrini profile image
Andrea Alessandrini

"The requirements.txt file does not take note of the specific versions of the packages being installed"
As far I know into requirements.txt file it is possible to specify the versions of the packages

Collapse
 
affinage profile image
affinage

sorry for not related question, but what terminal app are you using?

Collapse
 
davidshare profile image
David Itam Essien

I am using iterm2 - zsh - customized with Powerlevel9k

Collapse
 
romkatv profile image
Roman Perepelitsa

There is powerlevel10k now. It takes only a minute to switch over and you get 10 times faster prompt. All your configuration options will work as before.

Thread Thread
 
larrywachira profile image
Larry • Edited

Sweet. Didn't this. Thanks Roman.

Collapse
 
philsorenson profile image
Phil Sorenson

I was going to ask the same exact question! Super slick looking.
Is it possible to show me/us how to go about that? or just show us a screenshot of the edit?

Collapse
 
cnsp profile image
cnsp

This is by far the simplest and best tutorial on virtual env

Collapse
 
davidshare profile image
David Itam Essien

Thank you @cnsp

Collapse
 
lg543 profile image
lg543

Easy to follow. Thanks

Collapse
 
davidshare profile image
David Itam Essien

Thank you @Ig543 I am glad you found this useful.

Collapse
 
3jacksonsmith profile image
Jackson Smith

thanks :)

Collapse
 
philsorenson profile image
Phil Sorenson

Defenitely the easiest walk through ive run into on this subject after plenty of google searches, so thankk you!