Pipenv is another tool for installing python packages.

It does the same as pip: just installs the packages. But the main difference - it creates a virtual environment for your new project, so it guarantees versions of packages and dependencies will not clash between different projects.

Also, pipenv's environment tiered to one python version, you can simply create one project for python 3.3, and another for python 3.6. Then when you will run python, it will use the right version from pipenv's environment.

Another great advantage: pipenv freezes version numbers of all packages: Major+minor+patch. When native pip's requirments.txt can hold unpredictive version and it is easy to forget to modify the file before pushing when you install or update something.

This means:

  • If you work with colleagues on a project when you install a new package your college will be able get absolutely the same versions of all packages, so if code works for you it works for them also
  • On the deployed server versions will same for you

Why pipenv and not alternatives?

There are quite a several tools that do pretty the same and have the same benefits. One of them is pyenv (23.8k GitHub stars) and another is poetry (15.4 GitHub stars). When pipenv is 22k Stars so far.

Here the thing: pipenv is maintained by the same organization which works on native python's pip, native virtualenv, and much more: Python Packaging Authority.

It is official. It is stable. It is comfortable. Well, integrated. Pretty simple. Long living.

How to install pipenv

Just run:

sudo pip install pipenv

If the pip command is not found, you might have the only pip3.

After this, pipenv the command should start working in the terminal.

How to work with it

To create a new project, create a folder that will contain a source code (for example it might be a folder that soon will be a GitHub repository root)

pipenv --python 3.6

The python version which you specify should be installed. Here is how to install a specific python version.

At this point, pipenv created all needed files and a virtual env for your packages (It is a dedicated folder in your filesystem, outside of the project, so you will not able to accidentally push all these heavy dependency packages to your GitHub).

Now to install some package to your project:

pipenv install requests

After this command, the request package will be added to special Pipfile and Pipfile.lock , please review them carefully. The Pipfile.lock will contain a locked version of all packages.

You should always commit both Pipfile and Pipfile.lock to your git repository, otherwise your team or you might face LockfileNotFound("Pipfile.lock")!

Once you installed a new package to your project, just commit, and ask your co-developers to run:

pipenv sync

So they will automatically create a virtual environment if they executed the command the first time. Also, it will install all the dependencies.

To run python in your environment use:

pipenv run python yourfile.py

So it will use your python3.6, even if the default system's python is 3.8.

If it is some specific framework command, just always prepend pipenv run ! For example, if you have Django installed in pipenv, run:

pipenv run django-admin help

Pro tip: never use pipenv shell command

There is an automatic command which activates pipenv so instead of always appending pipenv run you can do:

pipenv run python aa
pipenv run python bb

It allows you to do:

pipenv shell
python aa
python bb

Much simpler, is not it? But there is a drawback: when shell activated, if you accidentally run pip install instead of pipenv install, the package will still be installed into your env, but without reflecting Pipfiles.

For example, you can accidentally copy installation command from the guide, and most guides use pip:

pip install thelib 

And you will have no guess that you installed package without reflecting a change in Pipfile because the shell was activated and pip installed package into pipenv still so you app working locally great!

What happens next? Your colleague pulls the commit, runs code and sees:

ModuleNotFoundError: No module named the_lib

He tries pipenv sync but it has no changes so it will not help. He tries to guess the package name and fix the situation by doing

pipenv install the-lib

Package the-lib is published to PyPI by a hacker who made a fork of the open-source thelib package with a small unnotable injection that reads your SSH key and transmits it via DNS exfiltration to the hackers server.

When you are not using pipenv shell, pip command will install a package into another interpreter so your local instance will show the error:

ModuleNotFoundError: No module named the_lib

So you will notice it, and make correct pipenv install before commiting.

In which folders my packages were installed

To understand where pipenv creates a virtual environment filesystem with site-packages folder:

pipenv --venv

For me it prints:

/home/ivan/.local/share/virtualenvs/Ivan-dHPd5gk0

Also, it might be useful to open VSCode directly to quickly navigate PyPI packages source code:

code "$(`pipenv --venv`)/lib"

Then use Ctrl+P and time filename.

How to update to the latest version

This command will update the lock file and update the package to the latest version:

pipenv update requests

If you need, read more about Pipenv advanced usage

Environment view