boilerplates


Nameboilerplates JSON
Version 1.0.2 PyPI version JSON
download
home_pagehttps://github.com/mbdevpl/python-boilerplates
SummaryVarious boilerplates used in almost all of my Python packages.
upload_time2024-04-17 06:38:54
maintainerMateusz Bysiek
docs_urlNone
authorMateusz Bysiek
requires_python>=3.8
licenseApache License 2.0
keywords git logging packaging releasing
VCS
bugtrack_url
requirements version-query
Travis-CI No Travis.
coveralls test coverage No coveralls.
            .. role:: python(code)
    :language: python

.. role:: toml(code)
    :language: toml

===================
Python boilerplates
===================

Various boilerplates used in almost all of my Python packages.

.. image:: https://img.shields.io/pypi/v/boilerplates.svg
    :target: https://pypi.org/project/boilerplates
    :alt: package version from PyPI

.. image:: https://github.com/mbdevpl/python-boilerplates/actions/workflows/python.yml/badge.svg?branch=main
    :target: https://github.com/mbdevpl/python-boilerplates/actions
    :alt: build status from GitHub

.. image:: https://codecov.io/gh/mbdevpl/python-boilerplates/branch/main/graph/badge.svg
    :target: https://codecov.io/gh/mbdevpl/python-boilerplates
    :alt: test coverage from Codecov

.. image:: https://api.codacy.com/project/badge/Grade/f22939bf833e40b89833d96c859bd7a4
    :target: https://app.codacy.com/gh/mbdevpl/python-boilerplates
    :alt: grade from Codacy

.. image:: https://img.shields.io/github/license/mbdevpl/python-boilerplates.svg
    :target: https://github.com/mbdevpl/python-boilerplates/blob/v1.0.2/NOTICE
    :alt: license

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.

.. contents::
    :backlinks: none

Requirements
============

Python version 3.8 or later.

Python libraries as specified in `requirements.txt <https://github.com/mbdevpl/python-boilerplates/blob/v1.0.2/requirements.txt>`_.

Building and running tests additionally requires packages listed in `requirements_test.txt <https://github.com/mbdevpl/python-boilerplates/blob/v1.0.2/requirements_test.txt>`_.

Tested on Linux, macOS 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``:

.. code:: python

    """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:

.. code:: toml

    [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``:

.. code:: python

    """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):

.. code:: text

    boilerplates[packaging_tests] ~= <version>

Config boilerplate
------------------

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

Example usage:

.. code:: python

    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):

.. code:: text

    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``:

.. code:: python

    """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):

.. code:: python

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

        packages = ['package_name']
        level_global = 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``:

.. code:: python

    """Initialization of tests."""

    import logging

    import boilerplates.logging


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

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


    TestsLogging.configure()

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

.. code:: python

    """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:

.. code:: python

    # 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):

.. code:: text

    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:

.. code:: python

    """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:

.. code:: python

    """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):

.. code:: text

    boilerplates[cli] ~= <version>

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

.. code:: text

    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_package --version`` will look like:

.. code:: text

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

Git repo tests boilerplate
--------------------------

This boilerplate aims at making it easier to test your package in a context of a git repository.

It's only useful if you create a Python package that operates on git repositories, and helps to
create and modify synthetic git repositories for testing purposes.

To start using ``boilerplates.git_repo_tests``, you can start with a file like this
in your test folder, for example ``test/test_with_git_repo.py``:

.. code:: python

    """Perform tests on and in synthetic git repositories."""

    import pathlib

    import boilerplates.git_repo_tests


    class Tests(boilerplates.git_repo_tests.GitRepoTests):

        ...

However, you will need to check the ``boilerplates.git_repo_tests.GitRepoTests`` class
for details of available features.

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

.. code:: text

    boilerplates[git_repo_tests] ~= <version>

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/mbdevpl/python-boilerplates",
    "name": "boilerplates",
    "maintainer": "Mateusz Bysiek",
    "docs_url": null,
    "requires_python": ">=3.8",
    "maintainer_email": "mateusz.bysiek@gmail.com",
    "keywords": "git, logging, packaging, releasing",
    "author": "Mateusz Bysiek",
    "author_email": "mateusz.bysiek@gmail.com",
    "download_url": "https://files.pythonhosted.org/packages/bc/3a/f3eb69f91f0336d35962276c4ed67d7a6490b1412f03f213c2634707c6f0/boilerplates-1.0.2.tar.gz",
    "platform": null,
    "description": ".. role:: python(code)\n    :language: python\n\n.. role:: toml(code)\n    :language: toml\n\n===================\nPython boilerplates\n===================\n\nVarious boilerplates used in almost all of my Python packages.\n\n.. image:: https://img.shields.io/pypi/v/boilerplates.svg\n    :target: https://pypi.org/project/boilerplates\n    :alt: package version from PyPI\n\n.. image:: https://github.com/mbdevpl/python-boilerplates/actions/workflows/python.yml/badge.svg?branch=main\n    :target: https://github.com/mbdevpl/python-boilerplates/actions\n    :alt: build status from GitHub\n\n.. image:: https://codecov.io/gh/mbdevpl/python-boilerplates/branch/main/graph/badge.svg\n    :target: https://codecov.io/gh/mbdevpl/python-boilerplates\n    :alt: test coverage from Codecov\n\n.. image:: https://api.codacy.com/project/badge/Grade/f22939bf833e40b89833d96c859bd7a4\n    :target: https://app.codacy.com/gh/mbdevpl/python-boilerplates\n    :alt: grade from Codacy\n\n.. image:: https://img.shields.io/github/license/mbdevpl/python-boilerplates.svg\n    :target: https://github.com/mbdevpl/python-boilerplates/blob/v1.0.2/NOTICE\n    :alt: license\n\nThis package includes boilerplates for various common tasks in Python packages, such as building\nthe package, testing the packaging process, storing the package config, logging for the package\nor creating a CLI.\n\n.. contents::\n    :backlinks: none\n\nRequirements\n============\n\nPython version 3.8 or later.\n\nPython libraries as specified in `requirements.txt <https://github.com/mbdevpl/python-boilerplates/blob/v1.0.2/requirements.txt>`_.\n\nBuilding and running tests additionally requires packages listed in `requirements_test.txt <https://github.com/mbdevpl/python-boilerplates/blob/v1.0.2/requirements_test.txt>`_.\n\nTested on Linux, macOS and Windows.\n\nAvailable boilerplates\n======================\n\nSetup boilerplate\n-----------------\n\nModule ``boilerplates.setup`` provides a class ``Package`` that abstracts out\nmany of the common tasks needed to set up the package. The class has a\n``setup()`` class method that can be called from the ``if __name__ == '__main__'`` block\nin your ``setup.py`` file.\n\nTo avoid setup script boilerplate, create ``setup.py`` file with the minimal contents as given\nbelow and modify it according to the specifics of your package.\n\nSee the implementation of ``boilerplates.setup.Package`` for all other available options.\nSome fields don't need to be entered and will be automatically initialised using various detectors.\nAlso, some fields have default values.\nSee ``DEFAULT_*`` constants in the ``boilerplates.setup`` for those values.\n\nExample ``setup.py``:\n\n.. code:: python\n\n    \"\"\"Setup script.\"\"\"\n\n    import boilerplates.setup\n\n\n    class Package(boilerplates.setup.Package):\n        \"\"\"Package metadata.\"\"\"\n\n        name = ''\n        description = ''\n        url = 'https://github.com/mbdevpl/...'\n        author = '...'\n        author_email = '...'\n        classifiers = [\n            'Development Status :: 1 - Planning',\n            'Programming Language :: Python :: 3.8',\n            'Programming Language :: Python :: 3.9',\n            'Programming Language :: Python :: 3.10',\n            'Programming Language :: Python :: 3.11',\n            'Programming Language :: Python :: 3 :: Only']\n        keywords = []\n\n\n    if __name__ == '__main__':\n        Package.setup()\n\nYou will also need the following in your ``pyproject.toml`` file:\n\n.. code:: toml\n\n    [build-system]\n    requires = ['boilerplates[setup] ~= <version>']\n\nPackaging tests\n~~~~~~~~~~~~~~~\n\nAs an extension of setup boilerplate, there's an extra boilerplate for testing the packaging process,\nin a way that enables 100% code coverage, including the ``setup.py`` script.\n\nIn order to use it, all you need to do is create a file as follows in your tests directory.\n\nExample ``test/test_packaging.py``:\n\n.. code:: python\n\n    \"\"\"Tests for packaging.\"\"\"\n\n    import boilerplates.packaging_tests\n\n\n    class Tests(boilerplates.packaging_tests.PackagingTests):\n        pass\n\nAnd, you will need to add the following to your ``requirements_test.txt`` file (or equivalent):\n\n.. code:: text\n\n    boilerplates[packaging_tests] ~= <version>\n\nConfig boilerplate\n------------------\n\nModule ``boilerplates.config`` provides few utility functions useful to handle local configuration.\n\nExample usage:\n\n.. code:: python\n\n    import boilerplates.config\n\n    ...\n\n    boilerplates.config.initialize_config_directory('app_name')\n\nAnd, you will need to add the following to your ``requirements.txt`` file (or equivalent):\n\n.. code:: text\n\n    boilerplates[config] ~= <version>\n\nLogging boilerplate\n-------------------\n\nAssumptions for this boilerplate are that you want to use the standard built-in Python\nlogging module (``logging``), and that your application probably has a CLI entry point\nor some executable script, as opposed to only being a library.\n\nTo reduce boilerplate necessary to setup logging for such application,\nadd the following in your ``__main__.py``:\n\n.. code:: python\n\n    \"\"\"Entry point of the command-line interface.\"\"\"\n\n    import boilerplates.logging\n\n\n    class Logging(boilerplates.logging.Logging):\n        \"\"\"Logging configuration.\"\"\"\n\n        packages = ['package_name']\n\n\n    ...\n\n\n    if __name__ == '__main__':\n        Logging.configure()\n        ...\n\nMore advanced usage could be (just changing the ``Logging`` class definition):\n\n.. code:: python\n\n    class Logging(boilerplates.logging.Logging):\n        \"\"\"Logging configuration.\"\"\"\n\n        packages = ['package_name']\n        level_global = logging.INFO\n        enable_file = True\n        directory = 'package_name'\n\nYou can and should adjust the class fields to your needs, please take a look\nat the ``boilerplates.logging.Logging`` class implementation for details.\n\nYou may also use this boilerplate in tests even if your code is just a library. In such case,\nadd the following to your ``test/__init__.py``:\n\n.. code:: python\n\n    \"\"\"Initialization of tests.\"\"\"\n\n    import logging\n\n    import boilerplates.logging\n\n\n    class TestsLogging(boilerplates.logging.Logging):\n        \"\"\"Logging configuration for tests.\"\"\"\n\n        packages = ['package_name']\n        level_package = logging.INFO\n\n\n    TestsLogging.configure()\n\nIf you wish, you can make your test logging config be a variant of your application logging config,\nlike so:\n\n.. code:: python\n\n    \"\"\"Initialization of tests.\"\"\"\n\n    from my_package.__main__ import Logging\n\n\n    class TestsLogging(Logging):\n        \"\"\"Logging configuration for tests.\"\"\"\n\n        enable_file = False\n\nAs for using the logging in your code, you can use it as usual, for example:\n\n.. code:: python\n\n    # in a standalone script:\n    _LOG = logging.getLogger(pathlib.Path(__file__).stem)\n    # in a standalone script that can also be imported:\n    _LOG = logging.getLogger(pathlib.Path(__file__).stem if __name__ == '__main__' else __name__)\n    # in __main__.py:\n    _LOG = logging.getLogger(pathlib.Path(__file__).parent.name)\n    # in usual module files:\n    _LOG = logging.getLogger(__name__)\n\nAnd, you will need to add the following to your ``requirements.txt`` file (or equivalent):\n\n.. code:: text\n\n    boilerplates[logging] ~= <version>\n\nCLI boilerplate\n---------------\n\nThis boilerplate aims at making CLIs easier to write, by providing a few utility functions.\n\nYour example ``cli.py`` file which defines your command-line interface may look like:\n\n.. code:: python\n\n    \"\"\"Command-line interface definition.\"\"\"\n\n    import argparse\n\n    import boilerplates.cli\n\n    def main(args=None):\n        \"\"\"Entry point of the command-line interface.\"\"\"\n        parser = argparse.ArgumentParser(\n            prog='my-cli',\n            description='''My command-line interface.''',\n            epilog=boilerplates.cli.make_copyright_notice(\n                2019, 2023, author='The Author', license_name='Apache License 2.0',\n                url='https://github.com/...'))\n\n        boilerplates.cli.add_version_option(parser, '1.0.1')\n        boilerplates.cli.add_verbosity_group(parser)\n\n        parsed_args = parser.parse_args(args)\n\n        verbosity = boilerplates.cli.get_verbosity_level(parsed_args)\n        ...\n\nYou can see the above example in action in the `<examples.ipynb>`_ notebook.\nPlease see the ``boilerplates.cli`` module for details of the available features.\n\nAnd then, an example ``__main__.py`` file may look like:\n\n.. code:: python\n\n    \"\"\"Entry point of the command-line interface.\"\"\"\n\n    # PYTHON_ARGCOMPLETE_OK\n\n    from my_package import cli\n\n\n    if __name__ == '__main__':\n        cli.main()\n\nAnd, you will need to add the following to your ``requirements.txt`` file (or equivalent):\n\n.. code:: text\n\n    boilerplates[cli] ~= <version>\n\nThen, the output of running ``python -m my_package -h`` will look like:\n\n.. code:: text\n\n    usage: my-cli [-h] [--version] [--verbose | --quiet | --verbosity LEVEL]\n\n    My command-line interface.\n\n    options:\n    -h, --help         show this help message and exit\n    --version          show program's version number and exit\n    --verbose, -v      be more verbose than by default (repeat up to 3 times for\n                        stronger effect)\n    --quiet, -q        be more quiet than by default (repeat up to 2 times for\n                        stronger effect)\n    --verbosity LEVEL  set verbosity level explicitly (normally from 0 to 5)\n\n    Copyright 2019-2023 by The Author. Apache License 2.0. https://github.com/...\n\nAnd the output of running ``python -m my_package --version`` will look like:\n\n.. code:: text\n\n    my-cli 1.0.1, Python 3.11.0 (main, Feb 13 2023, 00:02:15) [GCC 12.1.0]\n\nGit repo tests boilerplate\n--------------------------\n\nThis boilerplate aims at making it easier to test your package in a context of a git repository.\n\nIt's only useful if you create a Python package that operates on git repositories, and helps to\ncreate and modify synthetic git repositories for testing purposes.\n\nTo start using ``boilerplates.git_repo_tests``, you can start with a file like this\nin your test folder, for example ``test/test_with_git_repo.py``:\n\n.. code:: python\n\n    \"\"\"Perform tests on and in synthetic git repositories.\"\"\"\n\n    import pathlib\n\n    import boilerplates.git_repo_tests\n\n\n    class Tests(boilerplates.git_repo_tests.GitRepoTests):\n\n        ...\n\nHowever, you will need to check the ``boilerplates.git_repo_tests.GitRepoTests`` class\nfor details of available features.\n\nAnd, you will need to add the following to your ``requirements_test.txt`` file (or equivalent):\n\n.. code:: text\n\n    boilerplates[git_repo_tests] ~= <version>\n",
    "bugtrack_url": null,
    "license": "Apache License 2.0",
    "summary": "Various boilerplates used in almost all of my Python packages.",
    "version": "1.0.2",
    "project_urls": {
        "Homepage": "https://github.com/mbdevpl/python-boilerplates"
    },
    "split_keywords": [
        "git",
        " logging",
        " packaging",
        " releasing"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "f146c9f434f9b9fb8b880b99c3e0c4544463e2809533dbd6c175a8cd6603df77",
                "md5": "9b96548ce5e81883b904c0df47436556",
                "sha256": "08be18295ca8f52a64a20dc2db47477d44bf38d8b51fb7fbbee5fbff6df45e1a"
            },
            "downloads": -1,
            "filename": "boilerplates-1.0.2-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "9b96548ce5e81883b904c0df47436556",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.8",
            "size": 22629,
            "upload_time": "2024-04-17T06:38:53",
            "upload_time_iso_8601": "2024-04-17T06:38:53.107263Z",
            "url": "https://files.pythonhosted.org/packages/f1/46/c9f434f9b9fb8b880b99c3e0c4544463e2809533dbd6c175a8cd6603df77/boilerplates-1.0.2-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "bc3af3eb69f91f0336d35962276c4ed67d7a6490b1412f03f213c2634707c6f0",
                "md5": "22cffe77b6a14b5c9350c8a789357f72",
                "sha256": "ca630fb06270b2f905d6c34b26f6baae550e115bcfd8ce62576aad2ed6580366"
            },
            "downloads": -1,
            "filename": "boilerplates-1.0.2.tar.gz",
            "has_sig": false,
            "md5_digest": "22cffe77b6a14b5c9350c8a789357f72",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.8",
            "size": 28801,
            "upload_time": "2024-04-17T06:38:54",
            "upload_time_iso_8601": "2024-04-17T06:38:54.914206Z",
            "url": "https://files.pythonhosted.org/packages/bc/3a/f3eb69f91f0336d35962276c4ed67d7a6490b1412f03f213c2634707c6f0/boilerplates-1.0.2.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-04-17 06:38:54",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "mbdevpl",
    "github_project": "python-boilerplates",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "requirements": [
        {
            "name": "version-query",
            "specs": [
                [
                    "~=",
                    "1.5"
                ]
            ]
        }
    ],
    "lcname": "boilerplates"
}
        
Elapsed time: 0.26492s