Skip to main content

Various boilerplates used in almost all of my Python packages.

Project description

Various boilerplates used in almost all of my Python packages.

license package version from PyPI build status from GitHub test coverage from Codecov grade from Codacy

This package includes boilerplates for various common tasks in Python packages, such as building the package, testing the packaging process, storing the package config, logging for the package or creating a CLI.

Requirements

Python version 3.8 or later.

Python libraries as specified in requirements.txt.

Building and running tests additionally requires packages listed in requirements_test.txt.

Tested on Linux, OS X and Windows.

Available boilerplates

Setup boilerplate

Module boilerplates.setup provides a class Package that abstracts out many of the common tasks needed to set up the package. The class has a setup() class method that can be called from the if __name__ == '__main__' block in your setup.py file.

To avoid setup script boilerplate, create setup.py file with the minimal contents as given below and modify it according to the specifics of your package.

See the implementation of boilerplates.setup.Package for all other available options. Some fields don’t need to be entered and will be automatically initialised using various detectors. Also, some fields have default values. See DEFAULT_* constants in the boilerplates.setup for those values.

Example setup.py:

"""Setup script."""

import boilerplates.setup


class Package(boilerplates.setup.Package):
    """Package metadata."""

    name = ''
    description = ''
    url = 'https://github.com/mbdevpl/...'
    author = '...'
    author_email = '...'
    classifiers = [
        'Development Status :: 1 - Planning',
        'Programming Language :: Python :: 3.8',
        'Programming Language :: Python :: 3.9',
        'Programming Language :: Python :: 3.10',
        'Programming Language :: Python :: 3.11',
        'Programming Language :: Python :: 3 :: Only']
    keywords = []


if __name__ == '__main__':
    Package.setup()

You will also need the following in your pyproject.toml file:

[build-system]
requires = ['boilerplates[setup] ~= <version>']

Packaging tests

As an extension of setup boilerplate, there’s an extra boilerplate for testing the packaging process, in a way that enables 100% code coverage, including the setup.py script.

In order to use it, all you need to do is create a file as follows in your tests directory.

Example test/test_packaging.py:

"""Tests for packaging."""

import boilerplates.packaging_tests

class Tests(boilerplates.packaging_tests.PackagingTests):
    pass

And, you will need to add the following to your requirements_test.txt file (or equivalent):

boilerplates[packaging_tests] ~= <version>

Config boilerplate

Module boilerplates.config provides few utility functions useful to handle local configuration.

Example usage:

import boilerplates.config

...

boilerplates.config.initialize_config_directory('app_name')

And, you will need to add the following to your requirements.txt file (or equivalent):

boilerplates[config] ~= <version>

Logging boilerplate

Assumptions for this boilerplate are that you want to use the standard built-in Python logging module (logging), and that your application probably has a CLI entry point or some executable script, as opposed to only being a library.

To reduce boilerplate necessary to setup logging for such application, add the following in your __main__.py:

"""Entry point of the command-line interface."""

import boilerplates.logging


class Logging(boilerplates.logging.Logging):
    """Logging configuration."""

    packages = ['package_name']


...


if __name__ == '__main__':
    Logging.configure()
    ...

More advanced usage could be (just changing the Logging class definition):

class Logging(boilerplates.logging.Logging):
    """Logging configuration."""

    packages = ['package_name']
    level_package = logging.INFO
    enable_file = True
    directory = 'package_name'

You can and should adjust the class fields to your needs, please take a look at the boilerplates.logging.Logging class implementation for details.

You may also use this boilerplate in tests even if your code is just a library. In such case, add the following to your test/__init__.py:

"""Initialization of tests."""

import logging

import boilerplates.logging


class TestsLogging(boilerplates.logging.Logging):
    """Logging configuration for tests."""

    packages = ['package_name']
    level_package = logging.DEBUG


TestsLogging.configure_basic()

If you wish, you can make your test logging config be a variant of your application logging config, like so:

"""Initialization of tests."""

from my_package.__main__ import Logging


class TestsLogging(Logging):
    """Logging configuration for tests."""

    enable_file = False

As for using the logging in your code, you can use it as usual, for example:

# in a standalone script:
_LOG = logging.getLogger(pathlib.Path(__file__).stem)
# in a standalone script that can also be imported:
_LOG = logging.getLogger(pathlib.Path(__file__).stem if __name__ == '__main__' else __name__)
# in __main__.py:
_LOG = logging.getLogger(pathlib.Path(__file__).parent.name)
# in usual module files:
_LOG = logging.getLogger(__name__)

And, you will need to add the following to your requirements.txt file (or equivalent):

boilerplates[logging] ~= <version>

CLI boilerplate

This boilerplate aims at making CLIs easier to write, by providing a few utility functions.

Your example cli.py file which defines your command-line interface may look like:

"""Command-line interface definition."""

import argparse

import boilerplates.cli

def main(args=None):
    """Entry point of the command-line interface."""
    parser = argparse.ArgumentParser(
        prog='my-cli',
        description='''My command-line interface.''',
        epilog=boilerplates.cli.make_copyright_notice(
            2019, 2023, author='The Author', license_name='Apache License 2.0',
            url='https://github.com/...'))

    boilerplates.cli.add_version_option(parser, '1.0.1')
    boilerplates.cli.add_verbosity_group(parser)

    parsed_args = parser.parse_args(args)

    verbosity = boilerplates.cli.get_verbosity_level(parsed_args)
    ...

You can see the above example in action in the examples.ipynb notebook. Please see the boilerplates.cli module for details of the available features.

And then, an example __main__.py file may look like:

"""Entry point of the command-line interface."""

# PYTHON_ARGCOMPLETE_OK

from my_package import cli


if __name__ == '__main__':
    cli.main()

And, you will need to add the following to your requirements.txt file (or equivalent):

boilerplates[cli] ~= <version>

Then, the output of running python -m my_pacakge -h will look like:

usage: my-cli [-h] [--version] [--verbose | --quiet | --verbosity LEVEL]

My command-line interface.

options:
-h, --help         show this help message and exit
--version          show program's version number and exit
--verbose, -v      be more verbose than by default (repeat up to 3 times for
                    stronger effect)
--quiet, -q        be more quiet than by default (repeat up to 2 times for
                    stronger effect)
--verbosity LEVEL  set verbosity level explicitly (normally from 0 to 5)

Copyright 2019-2023 by The Author. Apache License 2.0. https://github.com/...

And the output of running python -m my_pacakge --version will look like:

my-cli 1.0.1, Python 3.11.0 (main, Feb 13 2023, 00:02:15) [GCC 12.1.0]

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

boilerplates-0.4.0.tar.gz (26.2 kB view hashes)

Uploaded Source

Built Distribution

boilerplates-0.4.0-py3-none-any.whl (20.9 kB view hashes)

Uploaded Python 3

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page