What is pipenv and how to install it
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