- GitHub repo: https://github.com/opinionated-digital-center/cookiecutter-pypackage/
- Free software: MIT license
Fully working scaffold with the following out-of-the-box and running features (although external environments like Gitlab-CI, PyPI and Read the Docs require to be set up separately):
- Pytest: Unit tests
- Behave: BDD/Functional tests
- Flake8: Linting/Style guide enforcement
- Black & isort: Uncompromising formatting and automated import sorting
- Mypy: Static typing
- Coverage: Code coverage
- Poetry: Easy packaging and dependency management, set up to isolate the different test dependencies (unit tests, bdd, ...) for speedy test runs
- Pyenv: Simple Python version management to install multiple versions on your host
- Make: Used as single doorway to all your tasks:
- For setup (development environment and machine, CI/CD pipeline job environments)
- For test tasks
- For the whole development and release lifecycle
- Tox testing: Set up to easily test for Python 3.6, 3.7, 3.8 and used as single source for all your test invocations
- Sphinx docs: Documentation ready for generation with, for example, Read the Docs
- Gitlab-CI: CI-CD pipeline with:
- Test phase running all tests in parallel jobs
- Release phase (see semantic-release below)
- Semantic-release: Pre-configured version bumping, changelog generation, auto-release to PyPI and Gitlab (yes... not a Python written tool... but works really well and has way more advanced features than any of the existing Python tools)
- Command line interface (optional) using Cleo (default), Click or Argparse
Install the latest Cookiecutter if you haven't installed it yet (this requires Cookiecutter 1.4.0 or higher; see the installation doc for more details):
# On macOS $ brew install cookiecutter # On linux and other systems $ pip install -U cookiecutter
Generate a Python package project (follow the instructions):
$ cd your/projects/root/dir $ cookiecutter https://github.com/opinionated-digital-center/cookiecutter-pypackage.git
Then:
Move to your newly created project's directory, initialise its git repo. Here we also commit the generated code:
$ cd <your-project> $ git init . $ git add . $ git commit -m 'chore: initial commit'
If you have not installed Pyenv and Poetry on your machine yet, you can use the following
make
target to do so:$ make setup-dev-host
Don't forget to restart your shell or source your shell configuration file. For example for Bash:
$ source ~/.bashrc
You might want to tell Poetry to create your virtualenvs in your project directory (makes it easier to add the virtualenv to your IDE):
$ poetry config virtualenvs.in-project true
Set up you development environment:
# Minimal setup $ make setup-dev-env-minimal # OR alternatively, full setup (allows for IDE completion) $ make setup-dev-env-full
Create a repo on Github or Gitlab (cloud or hosted) and push your local repo to it.
If you did not use Gitlab for hosting your project, you need to create a pipeline on Gitlab.com.
Configure your Gitlab CI project environment variables with the following variables:
For Gitlab publishing, follow the doc for @semantic-release/gitlab, and set:
GITLAB_TOKEN
: Don't forget to mask it.GITLAB_URL
(optional - see doc).GITLAB_PREFIX
(optional - see doc).
For Pypi publishing (requires you to register your project with PyPI first or with any other equivalent Python package repository):
PYPI_REPOSITORY_NAME
(only needed if you are using a repository other thanpypi
):name
for your Python package repository.name
can only contain alphanumerical characters, ".
", "-
" and "_
" (for example:my-repository
ormy.repository
ormy_repository
).In the remaining environment variables,
<NAME>
is to be replaced by this repository's name, in uppercase, with ".
" and "-
" replaced by "_
" (for instancemy-repository
ormy.repository
ormy_repository
all becomeMY_REPOSITORY
).POETRY_REPOSITORIES_<NAME>_URL
(required if repository is notpypi
): URL of the repository.One of the following credential mechanism has to be set (http basic will take precedence if set):
- Http basic credential:
POETRY_HTTP_BASIC_<NAME>_USERNAME
: username credential for repositoryname
POETRY_HTTP_BASIC_<NAME>_PASSWORD
: password credential for repositoryname
- API token credential :
POETRY_PYPI_TOKEN_<NAME>
:API token credential for repository=> there is currently an issue with setting API tokens through environment variables. As a workaround, use:name
.POETRY_HTTP_BASIC_<NAME>_USERNAME=__token__
POETRY_HTTP_BASIC_<NAME>_PASSWORD=<your_api_token>
.
- Http basic credential:
Release your package by running a manual pipeline on your master branch.
If you have differences in your preferred setup, we encourage you to fork this to create your own version. Or create your own; it doesn't strictly have to be a fork.
- It's up to you whether or not to rename your fork/own version. Do whatever you think sounds good.
We also accept pull requests on this, if they're small, atomic, and if they make my own packaging experience better.