How to use pipenv in your python project
“goodbye requirements.txt, hello Pipfile”
In this article, I will introduce you to pipenv and show you how easy it is to use. pipenv removes the awkwardness of working with virtual environments and module dependencies. Once you spend 15 minutes with pipenv, you will realize the clarity and time savings it will bring to your python project.
DigitalOcean offers one-click deployment of popular applications such as WordPress, Django, MongoDB, Docker, and even preconfigured Kubernetes Clusters. Deploy your next app in seconds. Get $100 in cloud credits from DigitalOcean
Ad Notice I will receive a small commission that helps support this blog at no cost to you.
Read Python for Data Analysis from O’REILLY on Safari with a 10-day trial.
What is pipenv?
pipenv was created by Kenneth Writze, the author of the extremely popular Requests package for python. In his own words…
Pipenv is a dependency manager for Python projects. If you’re familiar with Node.js’ npm or Ruby’s bundler, it is similar in spirit to those tools. While pip can install Python packages, Pipenv is recommended as it’s a higher-level tool that simplifies dependency management for common use cases. – The Hitchhiker’s Guide to Python
The Python Software Foundation says pipenv and Pipfile
are the recommended (if not Official) dependency management tools for python.
How pipenv works
- pipenv keeps all virtual environment files in
~/.virtualenvs
- pipenv keeps track of module dependencies in
Pipfile
(stored in the root of your project) - pipenv’s
Pipfile
replacesrequirements.txt
- pipenv keeps track of what’s been installed in the file
Pipfile.lock
Here is an example Pipfile
from one of my projects
[[source]] url = "https://pypi.python.org/simple" verify_ssl = true name = "pypi" [packages] flask = "*" flask-pymongo = "*" jsonify = "*" flask-restful = "*" requests = "*" flask-limiter = "*" [dev-packages] [requires] python_version = "3.6"
How to install pipenv
pip install pipenv
pip3 install pipenv
How to use pipenv
Create a new virtual environment
pipenv --python 3.6
user1@host:~/dev$ mkdir myproject user1@host:~/dev$ cd myproject/ user1@host:~/dev/myproject$ pipenv --python 3.6 Creating a virtualenv for this project… Using /usr/bin/python3.6m to create virtualenv… ⠋Running virtualenv with interpreter /usr/bin/python3.6m Using base prefix '/usr' New python executable in /home/user1/.local/share/virtualenvs/myproject-PQ8tLRDS/bin/python3.6m Also creating executable in /home/user1/.local/share/virtualenvs/myproject-PQ8tLRDS/bin/python Installing setuptools, pip, wheel...done. Virtualenv location: /home/user1/.local/share/virtualenvs/myproject-PQ8tLRDS Creating a Pipfile for this project… user1@host:~/dev/myproject$
Activate a virtual environment
pipenv shell
# Activate a virtual environment with pipenv user1@host:~/dev/myproject$ pipenv shell Spawning environment shell (/bin/bash). Use 'exit' to leave. user1@host:~/dev/myproject$ source /home/user1/.local/share/virtualenvs/myproject-1kHtQjc6/bin/activate (myproject-1kHtQjc6) user1@host:~/dev/myproject$
Executing code without activating your virtual environment
pipenv run python app.py
No need to activate your virtual environment each time, just type pipenv run
followed by the command you would normally run after activating your venv.
Install a Package
pipenv install requests
pipenv install pandas
Traditionally, you would have to activate your virtualenv and then run pip install requests
. Or if you were using a requirements.txt file you would add the desired package to requirements.txt, activate your virualenv, and run pip install -r requirements.txt
Now, with just one command, we add the package to our Pipfile
and pipenv installs it immediately. We didn’t have to activate the virtualenv, just run the command from inside our project directory.
Install a specific version of a package
pipenv install Flask=='0.11.*'
This command will install the latest 0.11 version of flask and update the Pipfile to target this version.
[packages] requests = "*" pandas = "*" flask = "==0.11.*"
Development only Packages
pipenv install --dev nose
pipenv install --dev pytest
Your project will likely use some development only packages for testing such as nose, pytest, tox, etc. The -dev
flag will place these packages in a seperate [dev-packages]
section of your pipfile.
[packages] requests = "*" pandas = "*" flask = "==0.11.*" [dev-packages] "nose2" = "*" pytest = "*"
Uninstall all packages
pipenv uninstall --all
Remove all packages from the virtualenv.
pipenv uninstall --all-dev
Remove all dev packages from the virtualenv.
Migrate from requirements.txt to Pipfile
pipenv install -r requirements.txt
This command will read in an existing requirements.txt file and populate your Pipfile for you. Simple!
Module Dependency Graph
pipenv graph
This will print all of your project’s installed module versions as well as the pip modules they depend on.
user1@host$ pipenv graph Flask-Limiter==1.0.0 - Flask [required: >=0.8, installed: 0.12.2] - click [required: >=2.0, installed: 6.7] - itsdangerous [required: >=0.21, installed: 0.24] - Jinja2 [required: >=2.4, installed: 2.10] - MarkupSafe [required: >=0.23, installed: 1.0] - Werkzeug [required: >=0.7, installed: 0.12.2] - limits [required: Any, installed: 1.2.1] - six [required: >=1.4.1, installed: 1.11.0] - six [required: >=1.4.1, installed: 1.11.0] Flask-PyMongo==0.5.1 - Flask [required: >=0.8, installed: 0.12.2] - click [required: >=2.0, installed: 6.7] - itsdangerous [required: >=0.21, installed: 0.24] - Jinja2 [required: >=2.4, installed: 2.10] - MarkupSafe [required: >=0.23, installed: 1.0] - Werkzeug [required: >=0.7, installed: 0.12.2] - PyMongo [required: >=2.5, installed: 3.5.1] Flask-RESTful==0.3.6 - aniso8601 [required: >=0.82, installed: 1.3.0] - python-dateutil [required: Any, installed: 2.6.1] - six [required: >=1.5, installed: 1.11.0] - Flask [required: >=0.8, installed: 0.12.2] - click [required: >=2.0, installed: 6.7] - itsdangerous [required: >=0.21, installed: 0.24] - Jinja2 [required: >=2.4, installed: 2.10] - MarkupSafe [required: >=0.23, installed: 1.0] - Werkzeug [required: >=0.7, installed: 0.12.2] - pytz [required: Any, installed: 2017.3] - six [required: >=1.3.0, installed: 1.11.0] jsonify==0.5 requests==2.18.4 - certifi [required: >=2017.4.17, installed: 2017.11.5] - chardet [required: >=3.0.2,<3.1.0, installed: 3.0.4] - idna [required: >=2.5,<2.7, installed: 2.6] - urllib3 [required: <1.23,>=1.21.1, installed: 1.22] user1@host$
Update pip packages
After some time has passed we will want to upgrade to the latest versions of our installed pip packages. This is painless with pipenv, just type…
pipenv update
Here is what it looks like when you use pipenv to upgrade all of your pip packages.
user1@host:~/dev/myproject$ pipenv update Updating all dependencies from Pipfile… Found 4 installed package(s), purging… Uninstalling numpy-1.13.3: Successfully uninstalled numpy-1.13.3 Uninstalling pandas-0.21.0: Successfully uninstalled pandas-0.21.0 Uninstalling python-dateutil-2.6.1: Successfully uninstalled python-dateutil-2.6.1 Uninstalling pytz-2017.3: Successfully uninstalled pytz-2017.3 Environment now purged and fresh! Locking [dev-packages] dependencies… Locking [packages] dependencies… Updated Pipfile.lock (5de24b)! Installing dependencies from Pipfile.lock (5de24b)… ▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉ 5/5 — 00:00:09 To activate this project's virtualenv, run the following: $ pipenv shell All dependencies are now up-to-date! user1@host:~/dev/myproject$
Keeping your virtualenv inside your project directory
You might feel more comfortable storing your virtualenv inside your project directory. i.e.project/.venv
No problem, pipenv supports this if you set the environment variable PIPENV_VENV_IN_PROJECT
. Let’s try it.
user1@host:~/dev/myproject$ pipenv --rm Removing virtualenv (/home/user1/dev/myproject/.venv)… user1@host:~/dev/myproject$ export PIPENV_VENV_IN_PROJECT=1 user1@host:~/dev/myproject$ pipenv install Creating a virtualenv for this project… Using /usr/bin/python3.6m to create virtualenv… ⠋Running virtualenv with interpreter /usr/bin/python3.6m Using base prefix '/usr' New python executable in /home/user1/dev/myproject/.venv/bin/python3.6m Also creating executable in /home/user1/dev/myproject/.venv/bin/python Installing setuptools, pip, wheel...done. Virtualenv location: /home/user1/dev/myproject/.venv ... user1@host:~/dev/myproject$ pipenv --venv /home/user1/dev/myproject/.venv user1@host:~/dev/myproject$ ls -la total 32 drwxrwxr-x 3 user1 user1 4096 Jan 6 08:40 . drwxrwxr-x 3 user1 user1 4096 Jan 6 07:27 .. -rw-rw-r-- 1 user1 user1 226 Jan 6 08:04 Pipfile -rw-rw-r-- 1 user1 user1 14400 Jan 6 08:29 Pipfile.lock drwxrwxr-x 5 user1 user1 4096 Jan 6 08:40 .venv user1@host:~/dev/myproject$
If you would like to persist this behavior you can add the PIPENV_VENV_IN_PROJECT
variable to your .bashrc
file.
echo "export PIPENV_VENV_IN_PROJECT=1" >> ~/.bashrc
Amazon AWS too complex and expensive? You will love the simplicity of DigitalOcean. Deploy your next app in seconds. Get $100 in cloud credits from DigitalOcean
Ad Notice I will receive a small commission that helps support this blog at no cost to you.
In Closing
I hope you enjoyed following along with this pipenv tutorial. Maybe it will save you some time and pain on your next python project.
Don’t forget, pipenv is the new way to manage package dependencies for python.
Goodbye requirements.txt, Hello Pipfile
References
- pipenv Documentation
- pipenv on github
- pipenv section of The Hitchhiker’s Guide to Python
- Managing Application Dependencies on python.org
- Kenneth Reitz’s Website
- Header image is a derivative of this photo by Alice Chodura released under a CC BY-SA 3.0 license
One Reply to “How to use pipenv in your python project”
I’m loving pipenv, too. A couple of added benefits that you didn’t bring up. Running pipenv run or pipenv shell will automatically inject key-value pairs into your environment if you have a .env file in the same directory as the pipfile (there is a setting to configure that directory, though). Also combining pipenv with a setup.py file is a fantastic way to establish the module dependencies (in setup.py) and the environment (in the pipfile). In the setup() method, you can set the module requirements with install_requires=[‘module1>=2.1.0’, ‘module2==*’, ‘etc’]. And then you can do pipenv install -e . (note the .) to install the requirements you’ve specified. As an extra added bonus, doing this also sets up the pythonpath of the root of the module so that, if you’re in the pipenv venv, you no longer have to worry about relative import paths anywhere in your project.