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
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.
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.
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
- 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:
When you install python3 using homebrew, it automatically installs pip3
You can verify that pip3 is installed by running
which pip3 or
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 installon 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
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
pipenv shell- to activate the environment
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.
lson 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 -rcommand 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
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
Check for Security vulnerabilities
To check for vulnerabilities in your packages, you can run
View package dependency graph
You can see all your project’s packages and their dependencies by running:
You can also add environment variables to your projects
- Create a .env file
- Add environment variables to it
pipenv run pythonYou 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)
A year later and this article still helped more than my last 15 google searches/stack overflow and several youtube videos. Thank you.
@mtaylor124 it is good to know that it was helpful. Thank you.
sorry for not related question, but what terminal app are you using?
I am using iterm2 - zsh - customized with Powerlevel9k
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.
Sweet. Didn't this. Thanks Roman.
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?
"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
This is by far the simplest and best tutorial on virtual env
Thank you @cnsp
Defenitely the easiest walk through ive run into on this subject after plenty of google searches, so thankk you!
Easy to follow. Thanks
Thank you @Ig543 I am glad you found this useful.