Use pip-tools rather than pipenv for dependency management #17
Description
Creating this issue for a PR I'd like to submit. Instead of using pipenv, an approach my team and I have been enjoying moreso recently has been to create a make
command named refresh-dev
that idempotently creates a virtual environment for a developer, compiles all necessary and local dev-oriented requirements from requirements*.in
using pip-tools
pip-compile
command to to generate requirements*.txt files, finally installing Python package dependencies from those files.
Here's a sample of what the our Makefiles look like for each Python-heavy repository we work in:
pip-compile: ## runs pip-compile to build requirements files
@echo "Pinnning Versions"
./.venv/bin/python -m pip install --upgrade pip
./.venv/bin/python -m pip install pip-tools
./.venv/bin/pip-compile requirements.in -o requirements.txt --upgrade --no-emit-index-url --generate-hashes
./.venv/bin/pip-compile requirements-dev.in -o requirements-dev.txt --upgrade --no-emit-index-url --generate-hashes
pip-install: ## Install requirements*.txt
@echo "Installing All Requirements"
./.venv/bin/python -m pip install -r requirements.txt
./.venv/bin/python -m pip install -r requirements-dev.txt
refresh-dev: ## Idemponently setup or refresh local dev environment
@echo "Refreshing Dev Virtual Env"
rm -fr ./.venv
python3 -m venv .venv
chmod +x ./.venv/bin/activate
./.venv/bin/activate
make pip-compile
make pip-install
source ./.venv/bin/activate
When the dev first checks out the repo, they'll need to configure the appropriate version of Python for their project. I use pyenv
and add a .python-version
file at root of repo with the version of Python we're targeting per the context of the project and the context of the eventually production environment.
For example, pyenv shell 3.8.12
will write 3.8.12
in a file named .python-version
.
After that, all I or any other dev on the team needs to do is run these commands at the root of their freshly-cloned repo:
make refresh-dev
They may need to manually activate the virtual environment at the end of the process. If they need to add a new dependency, they can simply add the name of the dependency to the appropriate requirements*.in
file, then run make pip-compile
and pip-sync
or make pip-install
to refresh their dev environment without having to rebuild it from scratch (although I usually run make refresh-dev
just to make sure all packages will work with each other and to start with a clean slate).