Skip to content

Instantly share code, notes, and snippets.

@esciara
Created March 23, 2020 11:13
Show Gist options
  • Save esciara/e8b54f5dffba67215524abeb80aeead2 to your computer and use it in GitHub Desktop.
Save esciara/e8b54f5dffba67215524abeb80aeead2 to your computer and use it in GitHub Desktop.

Cookiecutter PyPackage

Cookiecutter template for a Python package.

Features

Fully working scaffold with out-of-the-box and running (although external environments like Gitlab-CI, PyPI and Read the Docs require to be set up):

  • A bullet list

    • Nested bullet list.
    • Nested item 2.
  • Item 2.

    Paragraph 2 of item 2.

    • Nested bullet list.
    • Nested item 2.
      • Third level.
      • Item 2.
    • Nested item 3.
  • 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

  • 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

  • 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
  • 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

Build Status

Linux:

Linux build status on Gitlab CI

Windows:

This template is not tested on Windows yet, and some feature will most probably not be working on it, unless you use Windows Subsystem for Linux.

Quickstart

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:

cookiecutter https://github.com/opinionated-digital-center/cookiecutter-pypackage.git

Then:

  • Create a repo on Github or Gitlab (cloud or hosted) and put it there.

  • If you did not use Gitlab, create a pipeline on Gitlab.com.

  • 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 you IDE)
    $ poetry config virtualenvs.in-project true
    
  • Set up you development environment:

    # Minimal setup
    $ make setup-dev-env-minimal
    
    # Or full setup (allows for IDE completion)
    $ make setup-dev-env-full
    
  • 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 that you register your project with PyPI first):
      • PYPI_REPOSITORY_NAME (optional): to set if you are using a repository other than pypi (for example: my-repository; can only contain alphanumerical characters, ".", "-" and "_").
      • POETRY_REPOSITORIES_<NAME>_URL (required if repository is not pypi): URL of the repository. <NAME> is to be replaced by the value of PYPI_REPOSITORY_NAME in uppercase, with "." and "-" replaced by "_" (for instance my-repository or my.repository => MY_REPOSITORY).
      • POETRY_HTTP_BASIC_<NAME>_USERNAME: username credential for repository <name> (to be set together with POETRY_HTTP_BASIC_<NAME>_PASSWORD; not needed if API credential is set).
      • POETRY_HTTP_BASIC_<NAME>_PASSWORD: password credential for repository <name> (to be set together with POETRY_HTTP_BASIC_<NAME>_USERNAME; not needed if API credential is set).
      • POETRY_PYPI_TOKEN_<NAME>: API token credential for repository <name>. (not needed if username and password credentials are set) => there is an issue regarding setting API tokens through environment variables. As a workaround, use POETRY_HTTP_BASIC_<NAME>_USERNAME=__token__ and POETRY_HTTP_BASIC_<NAME>_PASSWORD=<your_api_token>.
  • Add the repo to your Read the Docs account + turn on the Read the Docs service hook. => to be added soon.
  • Release your package by running a manual pipeline on your master branch.

Fork This / Create Your Own

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.

Or Submit a Pull Request

We also accept pull requests on this, if they're small, atomic, and if they make my own packaging experience better.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment