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.
cruftensures that your project is always up to date with this template.pdmis a modern dependency manager.justis a modern rewrite ofmakein Rust π¦pre-commitvalidates your commits.blackas code formatter.ruffprovides static code analysis and appliesisortimport formatting.mypyvalidates your type hints.pytestruns your test suite.mkdocsbuilds your documentation, whilemkdocs-materialprovides an elegant theme.miketakes care of versioning your docs.commitizenensures you follow Conventional commit style and generates your release changelogs according to SemVer
Note
Developer guidelines
- The template adopts to the
srclayout.mypyis configured with a strict ruleset. The recommended approach to loosen those constraints is by temporary per-module ignores.blackis used to format the code, while imports are sorted withisortstyle.- Releases follow Semantic Versioning.
- Commit follow the Conventional Commit specification.
Note
justa command runner
justrecipes 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 justWarning
π Why
pipx?pip install --useris not recommended, as it does not ensure dependency isolation. For this purpose, the Python Packaging Authority (PyPA) advises to usepipx.pipxinstalls 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/chefNote
π¬ 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
justrecipe:
just initFor 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
initcommand 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.orgto test in your CI/CD whether your package can be uploaded.
cruft link git@github.com:baggiponte/chefcruft check
cruft updateConventional 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 commitOr 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_namewhere-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
pdmandjust. -
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
blackandisort. - 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
cookiecutterandcruft.
mypyin production at Spring- Static types in Python, oh my(py)! (one of the first posts of an enterprise using
mypyto add types to an existing codebase) - Strictest
mypysettings - Python is two languages now, and that's actually great

