This is a minimal Python project boilerplate I use as a starting point for new Python projects.
I use pipx to install Poetry, pre-commit, and tox globally.
-
Clone this repository.
-
Add the following to your
.bashrc
or.zshrc
. Note that you will need to change the value ofPYTHON_BOILERPLATE
to the path to the cloned repository.export PYTHON_BOILERPLATE="$HOME/sandbox/python-boilerplate/" # create a shell function `mkpythondir` mkpythondir() {( set -e local pyversion="${2:-$(pyenv version | cut -d' ' -f1)}" if [ ! -d "$(pwd)/$1" ] then rsync -r "$PYTHON_BOILERPLATE/" "$1" --exclude=".git" --exclude="README.md" # copy template files cd $1 pyenv local $pyversion # set python version mkdir "${1//[-.]/_}" && touch "${1//[-.]/_}/__init__.py" # create package echo "# $1" > README.md # create README git init && pre-commit autoupdate && pre-commit install # git and pre-commit poetry init --name="$1" \ --python="$pyversion" \ --dev-dependency=black \ --dev-dependency=ruff \ --dev-dependency="docformatter[tomli]" \ --dev-dependency=mypy \ --no-interaction && \ poetry env use $(pyenv version | cut -d' ' -f1) && \ poetry install # poetry pyenv local --unset # unset python version git add . && git commit -m "Initial commit" # initial commit else echo "Directory $(pwd)/$1 already exists" fi )}
Run mkpythondir <project-name> [python-version]
to create a new project. If the Python version is not specified, use the global Python version configured by pyenv or the local Python version (if configured by pyenv) in the current directory. The command does the following:
- Create a directory with the project name and make it a Git repository.
- Create an empty readme.
- Initialize pre-commit hooks for formatting black, docstring formatter docformatter, linter ruff, and type checker mypy.
- Configure tox to run formatting and linting checks.
- Create a Poetry virtual environment for the project with necessary development dependencies. I don't install black, docformatter, ruff, or mypy using pipx "globally" because different projects may require different versions (you and your collaborators will hate each other if using different versions of black).
- Make an initial commit.
Related to the above but not necessary, I also use the following configuration in my IDE:
- Run black and isort on save.
- Enable mypy and ruff linters.
This helps me to notice and fix issues before they are captured by pre-commit hooks or tox runs.