#######################################
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"
}