When contributing to this repository, please adhere to our Code of Conduct and first discuss the change you wish to make via an issue before submitting a pull request.

Local Development

The following sections will guide you through setting up a local development environment for working on this project package. At the very least, make sure that you have the necessary pre-commit hooks installed to make sure that all commits are pristine before they make it into the change history.

Installing Python


If you already have Python 3.7+ installed on your local system, you can skip this step completely.

Installing Python should be done through pyenv. To first install pyenv please follow the guide they provided at When you finally have pyenv you should be good to continue on.

$ pyenv --version
pyenv x.x.x

Now that you have pyenv we can install the necessary Python version. This project’s package depends on Python 3.7+, so we can request that through pyenv.

$ pyenv install 3.7  # to install Python 3.7+

$ pwd
$ pyenv local 3.7  # to mark the project directory as needing Python 3.7+

$ pyenv global 3.7  # if you wish Python 3.7 to be aliased to `python` everywhere

After installing and marking the repository as requiring Python 3.7+ you should be good to continue on installing the project’s dependencies.

Virtual Environment

We use Poetry to manage both our dependencies and virtual environments. Setting up poetry just involves installing it through pip as a user-level dependency.

$ pip install --user poetry
Collecting poetry
Downloading poetry-x.x.x-py2.py3-non-any.whl

You can quickly setup your entire development environment by running the installation process from poetry.

$ poetry install
Installing dependencies from lock file

This with create a virtual environment for you and install the necesary development dependencies. From there you can jump into a subshell using the newly created virtual environment using the shell subcommand.

$ poetry shell
pawning shell within ~/.local/share/virtualenvs/my-project-py3.7

$ exit # when you wish to exit the subshell

From this shell you have access to all the necessary development dependencies installed in the virutal environment and can start actually writing and running code within the client package.

Style Enforcement

This project’s preferred styles are fully enforced through pre-commit hooks. In order to take advantage of these hooks please make sure that you have pre-commit and the configured hooks installed in your local environment.

Installing pre-commit is done through pip and should be installed as a user-level dependency as it adds some console scripts that all projects using pre-commit will need.

$ pip install --user pre-commit
Collecting pre-commit
Downloading pre_commit-x.x.x-py2.py3-none-any.whl

$ pre-commit --version
pre-commit 2.4.0

Once pre-commit is installed you should also install the hooks into the cloned repository.

$ pwd

$ pre-commit install
pre-commit installed at .git/hooks/pre-commit

After this you should be good to continue on. These installed hooks will do a first-time setup when you attempt your next commit to build hook environments. Changes that violate the defined style specifications in setup.cfg and pyproject.toml will cause the commit to fail and will likely make the necessary changes to added / changed files to be written to the failing files.

This will give you the opprotunity to view the changes the hooks made to the failing files and add the new changes to the commit in order to make the commit pass. It also gives you the opprotunity to make tweaks to the autogenerated changes to make them more human accessible (only if necessary).

Editor Configuration

We also have some specific settings for editor configuration via editorconfig. We recommend you install the appropriate plugin for your editor of choice if your editor doesn’t already natively support .editorconfig configuration files.

Project Tasking

All of our tasks are built and run through invoke which is basically just a more advanced (a little too advanced) Python alternative to make. The only reason we are using this utility is because I know how it works and I already had most of the necessary tasks defined from other projects.

From within the Poetry subshell, you can access and run these commands through the provided invoke development dependency.

$ invoke --list
Available tasks:

   build                  Build the project.
   clean                  Clean the project.
   lint                   Lint the project.
   profile                Run and profile a given Python script.
   test                   Test the project.             Build docs.        Build towncrier newsfragments.
   docs.clean             Clean built docs.
   docs.view              Build and view docs.           Run Black tool check against source.
   linter.flake8          Run Flake8 tool against source.
   linter.isort           Run ISort tool check against source.
   linter.mypy            Run MyPy tool check against source.          Build pacakge source files.
   package.check          Check built package is valid.
   package.clean          Clean previously built package artifacts.
   package.coverage       Build coverage report for test run.
   package.format         Auto format package source files.
   package.requirements   Generate requirements.txt from Poetry's lock.
   package.stub           Generate typing stubs for the package.
   package.test           Run package tests.
   package.typecheck      Run type checking with generated package stubs.

You can run these tasks to do many miscellaneous project tasks such as building documentation.

$ invoke
[] ... building 'html' documentation
Running Sphinx v3.0.3
loading pickled environment... done
building [mo]: targets for 0 po files that are out of date
building [html]: targets for 0 source files that are out of date
updating environment: 0 added, 0 changed, 0 removed
looking for now-outdated files... none found
no targets are out of date.
build succeeded.

The HTML pages are in build/html.

All of these tasks should just work right out of the box, but something might break eventually after required tooling gets enough major updates.

Opening Issues

Issues should follow the included ISSUE_TEMPLATE found in .github/

  • Issues should contain the following sections:
    • Expected Behavior

    • Current Behavior

    • Possible Solution

    • Steps to Reproduce (for bugs)

    • Context

    • Your Environment

These sections help the developers greatly by providing a large understanding of the context of the bug or requested feature without having to launch a full fleged discussion inside of the issue.

Creating Pull Requests

Pull requests should follow the included PULL_REQUEST_TEMPLATE found in .github/

  • Pull requests should always be from a topic / feature / bugfix (left side) branch.
    Pull requests from master branches will not be merged.
  • Pull requests should not fail our requested style guidelines or linting checks.