Setting up a Python development environment with pipenv
Tags: python, pipenv, frontend, backend
Published: 2019-07-31 15:40:31

## What is pipenv?
![](https://thepracticaldev.s3.amazonaws.com/i/2se0w0ljrntu91te9335.jpg)Photo credit:[Make a Mem.org](https://makeameme.org/meme/you-have-a-h86fi4)

According to the official documentation, “[Pipenv](https://docs.pipenv.org/en/latest/) 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?
![](https://thepracticaldev.s3.amazonaws.com/i/g9ixav1ev13r2uzxuwi4.jpg)Photo credit:[Make a Mem.org](https://makeameme.org/meme/what-do-you-5c1659)

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.

![](https://thepracticaldev.s3.amazonaws.com/i/epdxe11gnoglo79ltx9c.gif)`Image Source: https://docs.pipenv.org/en/latest/ `


Enough talk, let’s get to work.
![](https://thepracticaldev.s3.amazonaws.com/i/t9pxaoc608vhggmhvlf3.jpg)
Photo credit: [imgflip](https://imgflip.com/i/kv4si)

## 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:

* Install Xcode if you don’t already have it installed by visiting the app store: https://apps.apple.com/us/app/xcode/id497799835. Once it has been installed, open your terminal and type the following code: xcode-select --install

* Install homebrew if it is not already installed by running the following code on your terminal: /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

   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
![](https://thepracticaldev.s3.amazonaws.com/i/rmb0gqi273eoh8ky2g9q.png)


* Install python 3.
To install python3, run brew install python3
![](https://thepracticaldev.s3.amazonaws.com/i/ao40erczuq9o5vkjonwa.png)

   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`
![](https://thepracticaldev.s3.amazonaws.com/i/9warcnhv786i2n0zus92.png)

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

![](https://thepracticaldev.s3.amazonaws.com/i/4aui9icvvoodt0h787sk.png)

### Install pipenv
To install pipenv, run Pip3 install pipenv
![](https://thepracticaldev.s3.amazonaws.com/i/nukyhxweyq126lxg7f3q.png)

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.
![](https://thepracticaldev.s3.amazonaws.com/i/2whv2b7hoq7kz50ohjuz.png)

### Launch virtual environment
To create our virtual environment, we have to create a directory for our project and run the commands in that directory.
![](https://thepracticaldev.s3.amazonaws.com/i/z43lmdxjao13ypq4pxa9.png)

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`:
![](https://thepracticaldev.s3.amazonaws.com/i/3g85xffdhs2eu38v31tz.png)
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.
![](https://thepracticaldev.s3.amazonaws.com/i/0pgkhgle6h6ecte87hr0.png)

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
![](https://thepracticaldev.s3.amazonaws.com/i/tco3hp0blyqu8528q3xr.png)

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.
![](https://thepracticaldev.s3.amazonaws.com/i/i8ky59w8bi07kwo14ujl.png)

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.
![](https://thepracticaldev.s3.amazonaws.com/i/nzm2c06rue54k0eao57i.png)

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.
![](https://thepracticaldev.s3.amazonaws.com/i/bokkkzm6q1u3uh8l1hw4.png)

### 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
![](https://thepracticaldev.s3.amazonaws.com/i/aaszj3rzy6gy4o3wzylb.png)

### 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.
![](https://thepracticaldev.s3.amazonaws.com/i/hxjweedwso1lf406st5u.png)

### 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.
![](https://thepracticaldev.s3.amazonaws.com/i/otloxn6zqyfvp8vu22pa.png)

### Now you have your Django app
![](https://thepracticaldev.s3.amazonaws.com/i/syfvhg88wx9lrz8ziyn4.png)


## 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
![](https://thepracticaldev.s3.amazonaws.com/i/7qbp6qy6tu95slb2jr9r.png)

* Pipenv uninstall package to uninstall the package
![](https://thepracticaldev.s3.amazonaws.com/i/fap3pavtyn7c2k7wp2zm.png)

* Install packages for development environments
![](https://thepracticaldev.s3.amazonaws.com/i/mkiyp4cbnmn363tymogz.png)

* Check for Security vulnerabilities
To check for vulnerabilities in your packages, you can run `pipenv check`
![](https://thepracticaldev.s3.amazonaws.com/i/td7dvn88b3n0k3r17d6e.png)

* View package dependency graph
You can see all your project’s packages and their dependencies by running:  `pipenv graph`
![](https://thepracticaldev.s3.amazonaws.com/i/7n65ft3xoxcf7ryesatj.png)

* 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’]
![](https://thepracticaldev.s3.amazonaws.com/i/i9gqv2z1ksi0pm0u9mil.png)
![](https://thepracticaldev.s3.amazonaws.com/i/5rwoum59g3zafki525kz.png)

* 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. 
![](https://thepracticaldev.s3.amazonaws.com/i/bz2ct1u93epuw49oscmh.png)


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.