config-decorator


Nameconfig-decorator JSON
Version 2.0.18 PyPI version JSON
download
home_page
SummaryClass @decorator for defining exquisite settings configurations
upload_time2023-12-28 05:03:27
maintainerTally Bark LLC
docs_urlNone
authorLandon Bouma
requires_python>=3.8.1,<4.0.0
licenseMIT
keywords python boilerplate pyoilerplate scaffolding framework cli tui skeleton cookiecutter library configuration settings options ini conf config
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            #######################################
config-decorator User Options Framework
#######################################
.. config-decorator Documentation

.. CXREF:
   https://docs.github.com/en/actions/monitoring-and-troubleshooting-workflows/adding-a-workflow-status-badge

.. image:: https://github.com/doblabs/config-decorator/actions/workflows/checks-unspecial.yml/badge.svg?branch=release
  :target: https://github.com/doblabs/config-decorator/actions/workflows/checks-unspecial.yml/badge.svg?branch=release
  :alt: Build Status

.. CXREF: https://app.codecov.io/gh/doblabs/config-decorator/settings/badge

.. image:: https://codecov.io/gh/doblabs/config-decorator/graph/badge.svg?token=JRDQTDPBzG
  :target: https://codecov.io/gh/doblabs/config-decorator
  :alt: Coverage Status

.. image:: https://readthedocs.org/projects/config-decorator/badge/?version=latest
  :target: https://config-decorator.readthedocs.io/en/latest/
  :alt: Documentation Status

.. image:: https://img.shields.io/github/v/release/doblabs/config-decorator.svg?style=flat
  :target: https://github.com/doblabs/config-decorator/releases
  :alt: GitHub Release Status

.. image:: https://img.shields.io/pypi/v/config-decorator.svg
  :target: https://pypi.org/project/config-decorator/
  :alt: PyPI Release Status

.. image:: https://img.shields.io/pypi/pyversions/config-decorator.svg
  :target: https://pypi.org/project/config-decorator/
  :alt: PyPI Supported Python Versions

.. image:: https://img.shields.io/github/license/doblabs/config-decorator.svg?style=flat
  :target: https://github.com/doblabs/config-decorator/blob/release/LICENSE
  :alt: License Status

.. |config-decorator| replace:: ``config-decorator``
.. _config-decorator: https://github.com/doblabs/config-decorator

.. |dob| replace:: ``dob``
.. _dob: https://github.com/tallybark/dob

.. |nark| replace:: ``nark``
.. _nark: https://github.com/tallybark/nark

.. |ConfigObj| replace:: ``ConfigObj``
.. _ConfigObj: https://github.com/DiffSK/configobj

User configuration framework developed for |dob|_.

========
Overview
========

``config-decorator`` makes it easy to define a hierarchical
collection of user-configurable key-value settings using
Pythonic ``@decorator`` syntax. It can be used with a modern
file round tripper, such as |ConfigObj|_, to add a capable,
robust user configuration subsystem to any application.

.. Build elegant, robust, and maintainable configuration settings
.. using common sense and ``@decorated`` class methods.

.. The configuration settings define a collection of user-settable values and
.. their defaults, as well as specifying type validation, value validation,
.. user help, and more.

.. An instantiated configuration object acts like a subscriptable ``dict``,
.. making it easy to drop into existing code.

.. The configuration settings can also be marshalled to or from a flat
.. dictionary, making it easy to persist using an external package
.. (for example, |ConfigObj|_, which reads and writes INI files to and
.. from dictionaries).

=======
Example
=======

Here's a simple example:

.. code-block:: Python

    #!/usr/bin/env python3

    from config_decorator import section

    def generate_config():

        @section(None)
        class ConfigRoot(object):
            '''Decorate an empty class to create the root settings section.'''
            pass


        @ConfigRoot.section('mood')
        class ConfigSection(object):
            '''Use the root settings section decorator to define setting groups.'''

            @property
            @ConfigRoot.setting(
                "The color",
                choices=['red', 'yellow', 'blue'],
            )
            def color(self):
                return 'red'

            @property
            @ConfigRoot.setting(
                "The volume",
                validate=lambda val: 0 <= val and val <= 11,
            )
            def volume(self):
                return 11

        @ConfigRoot.section('vibe')
        class ConfigSection(object):
            '''Another settings section.'''

            @property
            @ConfigRoot.setting(
                "Is it funky yet?",
                value_type=bool,
            )
            def funky(self):
                # Because value_type=bool, str will be converted to bool.
                # - Useful for config files where all values are strings!
                return 'False'

            @property
            @ConfigRoot.setting(
                "A list of numbers I heard in a song",
            )
            def cleopatra(self):
                return [5, 10, 15, 20, 25, 30, 35, 40]

            @property
            @ConfigRoot.setting(
                "Example showing how to use dashes in a settings name",
                name='kick-out-the-jams'
            )
            def kick_out_the_jams(self):
                return "I done kicked em out!"

        return ConfigRoot


    cfgroot = generate_config()

    # The config object is subscriptable.
    assert cfgroot['mood']['color'] == 'red'

    # You can override defaults with user values.
    cfgroot['mood']['color'] = 'blue'
    assert cfgroot['mood']['color'] == 'blue'

    # And you can always reset your values back to default.
    assert cfgroot.mood.color.default == 'red'
    cfgroot.forget_config_values()
    assert cfgroot['mood']['color'] == 'red'

    # The config object is attribute-aware (allows dot-notation).
    cfgroot.vibe.cleopatra.value = 100
    # And list-type values intelligently convert atoms to lists.
    assert cfgroot.vibe.cleopatra.value == [100]

    # The config object is environ-aware, and prefers values it reads
    # from the environment over those from a config file.
    import os
    from config_decorator.key_chained_val import KeyChainedValue
    KeyChainedValue._envvar_prefix = 'TEST_'
    os.environ['TEST_MOOD_VOLUME'] = '8'
    assert cfgroot.mood.volume.value == 8

    # The config object can be flattened to a dict, which makes it easy
    # to persist settings keys and values to disk using another package.
    from configobj import ConfigObj
    saved_cfg = ConfigObj('path/to/persisted/settings')
    cfgroot.apply_items(saved_cfg)
    saved_cfg.write()

    # Likewise, values can be read from a dictionary, which makes loading
    # them from a file saved to disk easy to do as well.
    saved_cfg = ConfigObj('path/to/persisted/settings')
    cfgroot.update_known(saved_cfg)

========
Features
========

* A setting value may come from one or more sources, but the value of the
  most important source is the value used. A setting value may come from
  the following sources, ordered from most important to least:

  * A "forced" value set internally by the application.

  * A "cliarg" value read from command line arguments.

  * An "envvar" value read from an environment variable.

  * A "config" value read from a user-supplied dictionary
    (e.g., from an INI file loaded by |ConfigObj|_).

  * A default value (determined by decorated method used to define the setting).

* Each setting value is:

  * always type-checked, though the type check could be a no-op;

  * optionally validated, possibly against a user-supplied *choices* list;

  * always documented, either by the first decorator argument,
    or from the decorated method ``'''docstring'''``;

  * sometimes hidden (e.g., for developer-only or experimental settings,
    to keep the user from seeing the setting unless its value differs
    from the default value);

  * sometimes ephemeral, or not saved (e.g., for values based on other
    values that must be generated at runtime, after all value sources
    are loaded).

=======
Explore
=======

* For complete usage examples, see this project's ``tests/``.

* For a real-world usage example, see |nark|_'s ``ConfigRoot`` and related.



            

Raw data

            {
    "_id": null,
    "home_page": "",
    "name": "config-decorator",
    "maintainer": "Tally Bark LLC",
    "docs_url": null,
    "requires_python": ">=3.8.1,<4.0.0",
    "maintainer_email": "doblabs@tallybark.com",
    "keywords": "python,boilerplate,pyoilerplate,scaffolding,framework,CLI,TUI,skeleton,cookiecutter,library,configuration,settings,options,ini,conf,config",
    "author": "Landon Bouma",
    "author_email": "doblabs@tallybark.com",
    "download_url": "https://files.pythonhosted.org/packages/87/b1/c77b5dee6051da2c362be6e524a73ff7ebfda85954d9def765684663b651/config_decorator-2.0.18.tar.gz",
    "platform": null,
    "description": "#######################################\nconfig-decorator User Options Framework\n#######################################\n.. config-decorator Documentation\n\n.. CXREF:\n   https://docs.github.com/en/actions/monitoring-and-troubleshooting-workflows/adding-a-workflow-status-badge\n\n.. image:: https://github.com/doblabs/config-decorator/actions/workflows/checks-unspecial.yml/badge.svg?branch=release\n  :target: https://github.com/doblabs/config-decorator/actions/workflows/checks-unspecial.yml/badge.svg?branch=release\n  :alt: Build Status\n\n.. CXREF: https://app.codecov.io/gh/doblabs/config-decorator/settings/badge\n\n.. image:: https://codecov.io/gh/doblabs/config-decorator/graph/badge.svg?token=JRDQTDPBzG\n  :target: https://codecov.io/gh/doblabs/config-decorator\n  :alt: Coverage Status\n\n.. image:: https://readthedocs.org/projects/config-decorator/badge/?version=latest\n  :target: https://config-decorator.readthedocs.io/en/latest/\n  :alt: Documentation Status\n\n.. image:: https://img.shields.io/github/v/release/doblabs/config-decorator.svg?style=flat\n  :target: https://github.com/doblabs/config-decorator/releases\n  :alt: GitHub Release Status\n\n.. image:: https://img.shields.io/pypi/v/config-decorator.svg\n  :target: https://pypi.org/project/config-decorator/\n  :alt: PyPI Release Status\n\n.. image:: https://img.shields.io/pypi/pyversions/config-decorator.svg\n  :target: https://pypi.org/project/config-decorator/\n  :alt: PyPI Supported Python Versions\n\n.. image:: https://img.shields.io/github/license/doblabs/config-decorator.svg?style=flat\n  :target: https://github.com/doblabs/config-decorator/blob/release/LICENSE\n  :alt: License Status\n\n.. |config-decorator| replace:: ``config-decorator``\n.. _config-decorator: https://github.com/doblabs/config-decorator\n\n.. |dob| replace:: ``dob``\n.. _dob: https://github.com/tallybark/dob\n\n.. |nark| replace:: ``nark``\n.. _nark: https://github.com/tallybark/nark\n\n.. |ConfigObj| replace:: ``ConfigObj``\n.. _ConfigObj: https://github.com/DiffSK/configobj\n\nUser configuration framework developed for |dob|_.\n\n========\nOverview\n========\n\n``config-decorator`` makes it easy to define a hierarchical\ncollection of user-configurable key-value settings using\nPythonic ``@decorator`` syntax. It can be used with a modern\nfile round tripper, such as |ConfigObj|_, to add a capable,\nrobust user configuration subsystem to any application.\n\n.. Build elegant, robust, and maintainable configuration settings\n.. using common sense and ``@decorated`` class methods.\n\n.. The configuration settings define a collection of user-settable values and\n.. their defaults, as well as specifying type validation, value validation,\n.. user help, and more.\n\n.. An instantiated configuration object acts like a subscriptable ``dict``,\n.. making it easy to drop into existing code.\n\n.. The configuration settings can also be marshalled to or from a flat\n.. dictionary, making it easy to persist using an external package\n.. (for example, |ConfigObj|_, which reads and writes INI files to and\n.. from dictionaries).\n\n=======\nExample\n=======\n\nHere's a simple example:\n\n.. code-block:: Python\n\n    #!/usr/bin/env python3\n\n    from config_decorator import section\n\n    def generate_config():\n\n        @section(None)\n        class ConfigRoot(object):\n            '''Decorate an empty class to create the root settings section.'''\n            pass\n\n\n        @ConfigRoot.section('mood')\n        class ConfigSection(object):\n            '''Use the root settings section decorator to define setting groups.'''\n\n            @property\n            @ConfigRoot.setting(\n                \"The color\",\n                choices=['red', 'yellow', 'blue'],\n            )\n            def color(self):\n                return 'red'\n\n            @property\n            @ConfigRoot.setting(\n                \"The volume\",\n                validate=lambda val: 0 <= val and val <= 11,\n            )\n            def volume(self):\n                return 11\n\n        @ConfigRoot.section('vibe')\n        class ConfigSection(object):\n            '''Another settings section.'''\n\n            @property\n            @ConfigRoot.setting(\n                \"Is it funky yet?\",\n                value_type=bool,\n            )\n            def funky(self):\n                # Because value_type=bool, str will be converted to bool.\n                # - Useful for config files where all values are strings!\n                return 'False'\n\n            @property\n            @ConfigRoot.setting(\n                \"A list of numbers I heard in a song\",\n            )\n            def cleopatra(self):\n                return [5, 10, 15, 20, 25, 30, 35, 40]\n\n            @property\n            @ConfigRoot.setting(\n                \"Example showing how to use dashes in a settings name\",\n                name='kick-out-the-jams'\n            )\n            def kick_out_the_jams(self):\n                return \"I done kicked em out!\"\n\n        return ConfigRoot\n\n\n    cfgroot = generate_config()\n\n    # The config object is subscriptable.\n    assert cfgroot['mood']['color'] == 'red'\n\n    # You can override defaults with user values.\n    cfgroot['mood']['color'] = 'blue'\n    assert cfgroot['mood']['color'] == 'blue'\n\n    # And you can always reset your values back to default.\n    assert cfgroot.mood.color.default == 'red'\n    cfgroot.forget_config_values()\n    assert cfgroot['mood']['color'] == 'red'\n\n    # The config object is attribute-aware (allows dot-notation).\n    cfgroot.vibe.cleopatra.value = 100\n    # And list-type values intelligently convert atoms to lists.\n    assert cfgroot.vibe.cleopatra.value == [100]\n\n    # The config object is environ-aware, and prefers values it reads\n    # from the environment over those from a config file.\n    import os\n    from config_decorator.key_chained_val import KeyChainedValue\n    KeyChainedValue._envvar_prefix = 'TEST_'\n    os.environ['TEST_MOOD_VOLUME'] = '8'\n    assert cfgroot.mood.volume.value == 8\n\n    # The config object can be flattened to a dict, which makes it easy\n    # to persist settings keys and values to disk using another package.\n    from configobj import ConfigObj\n    saved_cfg = ConfigObj('path/to/persisted/settings')\n    cfgroot.apply_items(saved_cfg)\n    saved_cfg.write()\n\n    # Likewise, values can be read from a dictionary, which makes loading\n    # them from a file saved to disk easy to do as well.\n    saved_cfg = ConfigObj('path/to/persisted/settings')\n    cfgroot.update_known(saved_cfg)\n\n========\nFeatures\n========\n\n* A setting value may come from one or more sources, but the value of the\n  most important source is the value used. A setting value may come from\n  the following sources, ordered from most important to least:\n\n  * A \"forced\" value set internally by the application.\n\n  * A \"cliarg\" value read from command line arguments.\n\n  * An \"envvar\" value read from an environment variable.\n\n  * A \"config\" value read from a user-supplied dictionary\n    (e.g., from an INI file loaded by |ConfigObj|_).\n\n  * A default value (determined by decorated method used to define the setting).\n\n* Each setting value is:\n\n  * always type-checked, though the type check could be a no-op;\n\n  * optionally validated, possibly against a user-supplied *choices* list;\n\n  * always documented, either by the first decorator argument,\n    or from the decorated method ``'''docstring'''``;\n\n  * sometimes hidden (e.g., for developer-only or experimental settings,\n    to keep the user from seeing the setting unless its value differs\n    from the default value);\n\n  * sometimes ephemeral, or not saved (e.g., for values based on other\n    values that must be generated at runtime, after all value sources\n    are loaded).\n\n=======\nExplore\n=======\n\n* For complete usage examples, see this project's ``tests/``.\n\n* For a real-world usage example, see |nark|_'s ``ConfigRoot`` and related.\n\n\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "Class @decorator for defining exquisite settings configurations",
    "version": "2.0.18",
    "project_urls": {
        "documentation": "https://config-decorator.readthedocs.io/en/latest",
        "download": "https://pypi.org/project/config-decorator/#files",
        "history": "https://github.com/doblabs/config-decorator/blob/release/HISTORY.rst",
        "homepage": "https://github.com/doblabs/config-decorator#\ud83c\udf80",
        "issues": "https://github.com/doblabs/config-decorator/issues"
    },
    "split_keywords": [
        "python",
        "boilerplate",
        "pyoilerplate",
        "scaffolding",
        "framework",
        "cli",
        "tui",
        "skeleton",
        "cookiecutter",
        "library",
        "configuration",
        "settings",
        "options",
        "ini",
        "conf",
        "config"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "04d46f3b05102344a035d9dcea0454651612a0aa3a81fe212ab245008597a291",
                "md5": "35f1f2118bbac6b3f5415f71011f99ae",
                "sha256": "8057e83ab87c11c9af9a2a89b887e01fd8523954ff39857691aa44ee44f8e421"
            },
            "downloads": -1,
            "filename": "config_decorator-2.0.18-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "35f1f2118bbac6b3f5415f71011f99ae",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.8.1,<4.0.0",
            "size": 23818,
            "upload_time": "2023-12-28T05:03:25",
            "upload_time_iso_8601": "2023-12-28T05:03:25.390135Z",
            "url": "https://files.pythonhosted.org/packages/04/d4/6f3b05102344a035d9dcea0454651612a0aa3a81fe212ab245008597a291/config_decorator-2.0.18-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "87b1c77b5dee6051da2c362be6e524a73ff7ebfda85954d9def765684663b651",
                "md5": "edef91333f8d2799c6e739cb2c788ac3",
                "sha256": "87d2184ea017f2514128fd34235851fe5a00ce6c30281b866034bd6e98ec84aa"
            },
            "downloads": -1,
            "filename": "config_decorator-2.0.18.tar.gz",
            "has_sig": false,
            "md5_digest": "edef91333f8d2799c6e739cb2c788ac3",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.8.1,<4.0.0",
            "size": 50558,
            "upload_time": "2023-12-28T05:03:27",
            "upload_time_iso_8601": "2023-12-28T05:03:27.098348Z",
            "url": "https://files.pythonhosted.org/packages/87/b1/c77b5dee6051da2c362be6e524a73ff7ebfda85954d9def765684663b651/config_decorator-2.0.18.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2023-12-28 05:03:27",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "doblabs",
    "github_project": "config-decorator",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "tox": true,
    "lcname": "config-decorator"
}
        
Elapsed time: 0.95110s