If you’re a Python developer, you probably know about pip and the different environment management solutions like virtualenv or venv. The pip
tool is currently the standard way to install a Python package. Virtualenv has been a popular way of isolating Python environments for a long time. Pipenv combines the very best of these tools and brings us the one true way to install packages while keeping the dependencies from each project isolated. It claims to have brought the very best from all other packaging worlds (the package manager for other languages / runtimes / frameworks) to the Python world. From what I have seen so far, that claim is quite valid. And it does support Windows pretty well too.
How does Pipenv work?
Pipenv works by creating and managing a virtualenv
and a Pipfile
for your project. When we install / remove Python packages, the changes are reflected in the Pipfile
. It also generates a lock file named Pipfile.lock
which is used to lock the version of dependencies and help us produce deterministic builds when needed. In a typical virtualenv
setup, we usually create and manage the virtualenv ourselves. Then we activate the environment and pip
just installs / uninstalls from that particular virtual environment. Packages like virtualenvwrapper
helps us easily create and activate virtualenv
with some of it’s handy features. But pipenv
takes things further by automating a large part of that. The Pipfile
would also make more sense if you have used other packaging systems like Composer, npm, bundler etc.
Getting Started
We need to start by installing pipenv
globally. We can install it using pip
from PyPi:
1 |
pip install pipenv |
Now let’s switch to our project directory and try installing a package:
1 |
pipenv install flask |
When you first run the pipenv install
command, you will notice it creates a virtualenv
, Pipfile
and Pipfile.lock
for you. Feel free to go ahead inspect their contents. If you’re using an IDE like PyCharm and want to configure your project interpreter, it would be a good idea to note down the virtualenv
path.
Since we have installed Flask, let’s try and running a sample app. Here’s my super simple REST API built with Flask:
1 2 3 4 5 6 7 8 |
from flask import Flask, jsonify app = Flask(__name__) @app.route('/') def hello_world(): return jsonify({"message": "Hello World!"}) |
Assuming that you have the FLASK_APP
environment variable set to app.py
(which contains the above code), we can just run the app like this:
1 |
pipenv run flask run |
Any executables in the current environment can be run using the pipenv run
command. But I know what you might be thinking – we want to do just flask run
, not use the entire, long command. That’s easy too. We just need to activate the virtualenv with this command:
1 |
pipenv shell |
Now you can just do flask run
or in fact run any executables in the way we’re used to doing.
Handling Dependencies
We can install and uninstall packages using the install
and uninstall
commands. When we install a new package, it’s added to our Pipfile
and the lock file is updated as well. When we uninstall a package, the Pipfile
and the lock files are again updated to reflect the change. The update
command uninstalls the packages and installs them again so we have the latest updates.
If you would like to check your dependency graph, just use the graph
command which will print out the dependencies in a nice format, kind of like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
PS C:\Users\Masnun\Documents\Python\pipenvtest> pipenv graph celery==4.1.0 - billiard [required: >=3.5.0.2,<3.6.0, installed: 3.5.0.3] - kombu [required: >=4.0.2,<5.0, installed: 4.1.0] - amqp [required: >=2.1.4,<3.0, installed: 2.2.2] - vine [required: >=1.1.3, installed: 1.1.4] - pytz [required: >dev, installed: 2017.3] Flask==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] |
Pipenv is Awesome!
Trust me, it is! It packs a lot of cool and useful features that can help gear up your Python development workflow. There are just too many to cover in a blog post. I would recommend checking out the Pipenv Docs to get familiar with it more.