chef
is an opinionated cookiecutter
template to develop internal packages and production ready Python code.
chef
offers the latest tooling to make development a breeze, while enforcing coding standards such as formatting, linting, dependency auditing and an elegant command runner with powerful default recipes.
cruft
ensures that your project is always up to date with this template.pdm
is a modern dependency manager.just
is a modern rewrite ofmake
in Rust π¦pre-commit
validates your commits.black
as code formatter.ruff
provides static code analysis and appliesisort
import formatting.mypy
validates your type hints.pytest
runs your test suite.mkdocs
builds your documentation, whilemkdocs-material
provides an elegant theme.mike
takes care of versioning your docs.commitizen
ensures you follow Conventional commit style and generates your release changelogs according to SemVer
Note
Developer guidelines
- The template adopts to the
src
layout.mypy
is configured with a strict ruleset. The recommended approach to loosen those constraints is by temporary per-module ignores.black
is used to format the code, while imports are sorted withisort
style.- Releases follow Semantic Versioning.
- Commit follow the Conventional Commit specification.
Note
just
a command runner
just
recipes will save you a ton of time! Install just. To see the available recipes, run the following:just
pipx install cruft
pipx install pdm
# for example, on macOS
brew install just
Warning
π Why
pipx
?pip install --user
is not recommended, as it does not ensure dependency isolation. For this purpose, the Python Packaging Authority (PyPA) advises to usepipx
.pipx
installs and runs python CLIs in isolated environments. To install it, follow the instructions here.
If you want to create a new package, or any coding project, you just have to run two short commands.
- Initialise the template:
cruft create git@github.com:baggiponte/chef
Note
π¬ How to configure SSH
Cloning over SSH is safer. Follow this guide. Alternatively, you can follow the steps in this workshop of GitHub's.
- Install all default dependencies and setup the GitHub secrets to run the CI/CD pipelines, run the following
just
recipe:
just init
For this command to execute successfully, you need to have pdm
and the GitHub CLI installed.
This recipe will set three GitHub secrets:
PDM_PUBLISH_REPO
: the URL to publish your package to.PDM_PUBLISH_USERNAME
: the username of the account used to publish the package.PDM_PUBLISH_PASSWORD
: the authentication token.
If you do not want to configure CI/CD on GitHub, you can simply run the following:
just install
This will only install the dev dependencies.
Please feel free to open a PR to configure a recipe to configure CI/CD on other providers, such as GitLab.
Note
The
init
command configures three GitHub secrets to use PDM to publish the package you are developing to PyPI. For the command to run successfully, you should configure PDM accordingly:pdm config repository.pypi.url "https://upload.pypi.org/legacy" pdm config repository.pypi.username "__token__" # literally this pdm config repository.pypi.password "<your-PyPI-token>"To get a PyPI token, you can follow the guidelines here. You could also register an account on
test.pypi.org
to test in your CI/CD whether your package can be uploaded.
cruft link git@github.com:baggiponte/chef
cruft check
cruft update
Conventional commits are enforced with commitizen
, which is configured as a pre-commit
hook at pre-push time. In other words, if you attempt to push to a remote repo and your commit messages do not follow the conventional commits, the push will be rejected. However, commitizen
also offers a git command to commit with the conventional commit specification with a terminal UI. With just
, you can simply run the following:
just commit
Or even the shorter just c
. A prompt will guide you through the commit.
{
"author_name": "",
"author_email": "",
"repo_name": "",
"package_name": "{{ cookiecutter.__repo_name.replace('-', '_') }}",
"package_description": "",
"package_emoji": "",
"requires_python": "3.9"
}
author_name
: the maintainer name.author_email
: the maintainer email address.repo_name
: the repository name.package_name
: the package name. Defaults to therepo_name
where-
are replaced with_
.package_description
: a one-line description of the package. It has to be effective and concise, so write it as if it would complete this prompt: "This library contains/offers ...".package_emoji
: the emoji associated with the project.requires_python
: the minimal python version required for the project.
-
Install
pdm
andjust
. -
Clone the repository:
# using github cli
gh repo clone baggiponte/chef
# using git (SSH recommended)
git clone git@github.com:baggiponte/chef
- Install the dependencies:
just install
Run the following:
just pre-release
The following operations will be performed:
- Format with
black
andisort
. - Lint with
ruff
. - Run type checks with
mypy
. - Audit dependencies with
pip-audit
. - Check commit messages are consistent with Conventional Commits using
commitizen
. - Check whether a version bump is possible.
- Run all tests.
- Wolt's project template leverages
cookiecutter
andcruft
.
mypy
in production at Spring- Static types in Python, oh my(py)! (one of the first posts of an enterprise using
mypy
to add types to an existing codebase) - Strictest
mypy
settings - Python is two languages now, and that's actually great