Constraints files are requirements files that only control which version of a requirement is installed, not whether it is installed or not.
In a previous post, I talked about ditching pip freeze because it didn't work well with second-level dependencies (especially cross-platform). I found an even better workflow where I use a requirements.txt and a constraints.txt file together. Check out the code in this commit.
requirements
├── constraints.txt
└── requirements.txt
Just add a second flag to pip install.
python3 -m pip install -r requirements.txt -c constraints.txt
Inside requirements.txt are packages blogthedata directly uses.
# requirements.txt
black
Brotli
chromedriver-autoinstaller
coverage
Django
...
Constraints.txt includes everything in requirements.txt plus sub-dependencies
# constraints.txt
black==22.3.0
Brotli==1.0.9
cachetools==5.2.0
certifi==2022.6.15
cffi==1.15.1
...
When used together, we are instructing pip to install everything in requirements.txt with the constraint that if anything is installed that is listed in constraints.txt, use the pinned version.
Now I can be certain sub-dependencies won't break my app without requiring that the sub-dependencies be installed.