Skip to content
/ python-library Public template

Python library boilerplate

License

Notifications You must be signed in to change notification settings

8percent/python-library

Repository files navigation

Python Library

Build Code style: black pre-commit pre-commit.ci status

This repository is a template repository providing boilerplate for Python library.

Developer can start writing code without wasting so much time to set up basic stuffs like CI, lint, etc.

Table of Content


Usage

We recommand to use GitHub's Use this template button to kick off this template. But yet, you can set up copy this template by cloning or downloading this repository.

Once you prepared this repository on your local machine, remaining part is project configuration. Unless you are familiar with stacks(poetry, tox, GitHub action, etc.), Subsequent Installation step might be helpful.


Installation

Install Poetry

Please read this installation guide to install poetry.

Then install package dependencies with this command at project root. This will resolve package dependencies and install it in poetry managed virtual environment.

poetry install

(Optional) Install Pyenv

pyenv lets you easily switch between multiple versions of Python. It's simple, unobtrusive, and follows the UNIX tradition of single-purpose tools that do one thing well.

As quoted pyenv readme demonstrates, It provide us handy python version management.

Configuration

pyproject.toml

This file contains build system requirements and information, which are used by poetry to build the package. We tried to gather every package related settings as much as possible here. Through this design decision, project could remove package dependant configuration files like .isort.cfg, pytest.ini, etc.

  • [tool.poetry]: Describe package's metadata. Including package name, versions, dscription, authors etc.
  • [tool.poetry.dependencies], [tool.poetry.dev-dependencies]: Manage package's dependencies. Poetry will check this section to resolve requirements version.
  • [build-system]: Define how to build package. Generally no need to edit this section.
  • [tool.isort], [tool.black]: By Editing this part, you can set how linting library should work.
  • [tool.pytest.ini_options]: pytest configuration.

Except [build-system], We suggest you to update every settings above.

.github/workflows/ci.yml

We choose GitHub action as Continuous Integration tool. It contains package-build, unittest, and lint job. Each job works concurrently on different virtual machines.

  • package-build: Use tox to test package against multiple python versions.
  • unittest: Test code and report coverage using pytest.
  • lint: Lint code using flake, isort, black.

Change python-version value in this file according to package compatible python versions which configured at pyproject.toml.

tox.ini

Tox runs test against packages which built in isolated virtual environment.

  • [tox]: Tox global settings.
  • [gh-actions]: Mapping between GitHub action python-version matrix and tox virtual environment.
  • [testenv]: Test environment setting.

According to package's python compatible versions, [tox.envlist] and [gh-actions] should be defined.

Source code

Make your own named package in src directory.

NOTE: package setting in pyproject.toml should be changed as you set up your own package.

packages = [
    { include = "{your-python-package-name}", from = "src" },
]

Test Code

Every test code should resides in tests package at project root.

To test your source code, simply use 'pytest' or 'tox'.

# Use pytest
$ pytest tests/

# Use Tox
$ tox

Architecture

Detailed explanation about stacks used in this template is covered in this section.

Project Layout

This template repository follows src layout style. As the name suggests, its distinctive feature is subdirectory named src. Main python packages lives inside src directory.

To tests python built package. Testing should be done against built package. not from the source code itself. Src layout helps to achieve this condition. By separating source code from project root, It prevents test code to import source code.

This layout is better explained in this blog post by Ionel Cristian Mărieș.

Dependency Management & Packaging

We use Poetry to control dependencies and build package. Advantages of using poetry is well explained in their README.md.

By default, Poetry automatically manages virtual environment for each project and python version. It frees developer from virtual environment management. But also offers option to manage virtual environment manually. For more information read this docs

Continuous Integration

Our GitHub action consists of two workflows. one for CI, and one for release draft.

ci.yml workflow contains three different jobs. Those are package-build, unittest, lint.

  • package-build job is responsible for build package and test it. so it uses tox and can have multiple python versions.
  • unittest job is in charge of test on source code, and report test coverage.
  • lint job processes every linting stuffs.

release_drafter.yml workflow is activated whenever master branch changed. It tracks merged pull requests and generate release draft containing chagelog and contributors. Release draft template can be modified by editing .github/release-drafter.yml file. It demonstrates how draft should be presented.

Testing

Pytest is our main test runner.

Linting

Code is double-checked during development process. One at commit phase, and the other at CI process.

pre-commit is help us to check at commit time. By executing installation command pre-commit install, It automatically adds pre commit hooks. Types of hook are managed using .pre-commit-config.yaml.

Coverage

Coverage of test functions is one of important metrics which decides code quality. ci.yml workflow runs unittest and reports coverage report on pull request comment. We use orgoros's github action as our coverage component of our CI workflow.


Contributing

Pull requests are always welcome.

Check CONTRIBUTING.md for more details.


License

Distributed under the terms of the MIT license.