After it became obvious that pipenv
is dead (and had a lot of problems) I’ve decided to swtich to an alternative. Enter pip-tools
.
Installation
I find its workflow a bit more verbose and technical than pipenv
but it seems like a more stable tool. In order to use it, make sure that you have virtualenv installed on you machine:
sudo apt install python3.7 python3-venv python3.7-venv
Make the project directory, and create virtualenv:
mkdir my-project
cd my-project
python3.7 -m venv env
If you’re using git
(you’re using git
r-right?) don’t forget to add env/
to your .gitignore
(echo 'env/' >> .gitignore
).
Now activate the environment and install pip-tools
:
. env/bin/activate
pip install pip-tools
pip-compile
and pip-sync
pip-tools
consists of two tools:
pip-compile
- compilesrequirements.txt
from your dependenciespip-sync
- updates your virtual environment
Before you compile requirements.txt
you need to define dependencies. They are usually located in requirements.in
directory.
mkdir requirements.in
Now you can easily define dev, production, and other types of dependencies, based on your needs. I usually create three types of dependencies:
touch requirements.in/base.txt
touch requirements.in/dev.txt
touch requirements.in/prod.txt
base.txt
contains required dependencies for your application e.g. django
. dev.txt
contains dependencies that you need only during the development e.g. flake8
, pylint
, coverage
, etc. And sometimes you need some packages that are specific only to your production environment. In that case I add prod.txt
. For example, in case of django
deployment, you can add gunicorn
to prod.txt
.
When wirting you dependencies you should pin them to specific version!
# requirements.in/base.txt
django>=3.0.5
djangorestframework>=3.11.0
requests==2.23.0
# requirements.in/dev.txt
-r base.txt
flake8==3.7.9
# requirements.in/prod.txt
-r base.txt
gunicorn==20.0.4
You must add -r base.txt
at the start of your prod.txt
and dev.txt
dependecy files. In this way base requirements are always compiled with your additional environment specific dependencies.
Now, let’s say that you want to compile requirements on your dev machine. You will use the following:
mkdir requirements
pip-compile --output-file requirements/dev.txt requirements.in/dev.txt
By splitting these files on requirements/
and requirements.in/
you are separating your main project dependencies from the standard requirements.txt
dependencies (which contains all of the main dependnencies and subdependencies). In essence, the files in requirements/
will act as your lock files.
Now, you can upadte your virtual environment with pip-sync
:
pip-sync requirements/dev.txt
And that’s it, it is as simple as that.