Package: confight
confightOne simple way of parsing configsExtensible "Unix-like"conf.ddirectoryAllow formultiple formats(toml,json,yaml,ini)Full unicode supportUser settings~/.configsupportNice out-of-the-box defaultsSeeexamplesconfightfocuses on making application configuration easy to load, change,
extend, generate and audit. It does so by allowing to use separated files for
different topics, simplifying changes and new additions, without messing with
already existing defaults or deleting or moving protected files.This is achieved by using at least one config file (/etc/app/config.toml)
and an extra directory (/etc/app/conf.d) for extra files.Those extra files are calleddropletswhich consist in is a small config
file that is"dropped"into aconf.ddirectory where they will be parsed
and merged nicely into a single final configuration.This approach is very common in Unix and used in several applications such as:cron (/etc/cron.d)bash profiles (/etc/profile.d)apt (/etc/apt/sources.list.d)systemdand many others.The idea is to "map reduce" configurations, by parsing all filesin order,
giving more relevance to the latest appearance and then merge them into asingle configthat holds all the data:C₀ -- parse -----|
    C₁ -- parse --|
    C₂ -- parse --|-- merge --> C
       ⋮          |
    Cₙ -- parse --|The name of those files will determine the order in which they're parsed and
the priority their values will have when merging. The last one wins./etc/app/config.toml/etc/app/conf.d/*~/.config/app/config.toml~/.config/app/conf.d/*Is specially good for externally managed configs ordebian-packagedapplications, avoiding clashes between installed files and generated configs,
for changes that would stay forever unless manually merged.Usage>>>importconfight>>>confight.load_app('myapp'){"section":{"key":"value"}}The previous fragment got all the config files at/etc/myapp/config.tomland
within the/etc/myapp/conf.ddirectory and merged them into a single config.# /etc/myapp/config.toml    /etc/myapp/conf.d/00_first.json    /etc/myapp/conf.d/99_second.ini
[section]                   {                                  [section]
key = "base config"           "section": {                     key = value
                                 "key": "not this"
                              }
                            }Default file locations for an application namedmyappwould be at:/etc/myapp/config.toml/etc/myapp/conf.d/*User custom configurations would be read (if any) from:~/.config/myapp/config.toml~/.config/myapp/conf.d/*See theexamplessection for more information on how to use these
functions.LoadingTheloadfamily of functions take a list of names, files or directories to
easily parse and merge a related set of configurations:confight.load_app('myapp')confight.load_user_app('myapp')confight.load_paths(['/path/to/config','/path/to/dir'])confight.load(['/path/to/config.toml','/path/to/dir/droplet.toml'])Each function offers different parameters to improve the ease of use.The extension of the configuration file can be given with theextensionparameter. For instance,load_app('myapp', extension='json')would look for
the/etc/myapp/config.jsonfile.All files in theconf.ddirectory are read by default regardless the
extension. To enforce that only.extensionfiles are read, add theforce_extensionflag.FormatsSome formats arebuiltinin the default installation and some others areoptionaland must be declared when installingconfight.The list ofbuiltinfile formats:toml(default)jsoniniThe list ofoptionalfile formats:yamlhclIn order to install confight withoptionalformats seeinstallationwithoptional features.ParsingGiven a path to an existing configuration file, it will be loaded in memory
using basic types (string,int,float,list,dict).The given file can be in one of the allowed formats. For a complete list see
theconfight.FORMATSlist.confight.parse('/path/to/config', format='toml')When no format is given, it tries to guess by looking at file extensions:confight.parse('/path/to/config.json')  # will gess json formatYou can see the list of all available extensions atconfight.FORMAT_EXTENSIONS.A custom parsing can be provided by passing aparserfunction to theloadfamily of functions, matching the signature:defparser(path,format=None)The function takes a filesystempathand aformatand  the result should
be a single dictionary with all the loaded data.  WhenformatisNonethe
parser is expected to guess it.MergingGiven a list of parsed configs in order, merge them into a single one.
For values that appears several times, the last one wins.Sections and subsections are recursively merged, keeping all keys along the
way and overriding the ones in more than one file with the latest appearance.A custom merging can be provided by passing amergerfunction to theloadfamily of functions, matching the signature:defmerger(configs)The function takes a list of dictionaries containing the parsed configuration
in ascending order of priority. It should return a single dictionary with all
the configuration.Finding configsThe default behaviour is that all files at theconf.ddirectory will be
opened, in lexicographical order, and parsed.A custom config locator can be provided by passing afinderfunction to theloadfamily of functions, matching the signature:deffinder(path)The function takes a filesystem path (aconf.ddirectory supposedly) and
returns a list of paths to config files in the desired order of parsing and
merging, this is from less to more priority for their values.ExamplesLoad application config from the default locations by using theload_appfunction which will look by default at the/etc/myapp/config.tomland
configuration directory at/etc/myapp/conf.d:# /etc/myapp/config.toml    # /etc/myapp/conf.d/production.toml
user = myapp                password = aX80@klj
password = guest>>>confight.load_app('myapp'){"user":"myapp","password":"aX80@klj"}Allow the user to override the default value when wanting to use a different
configuration. WhenNoneis given, the default is used:importargparseimportconfightparser=argparse.ArgumentParser()parser.add_argument('--config',default=None)parser.add_argument('--config-dir',default=None)args=parser.parse_args()config=confight.load_app('myapp',file_path=args.config,dir_path=args.config_dir)If the application supports user configuration the functionload_user_appmight come handy as it will first load the regular app config and then the one
defined in the user directory~/.config/myapp/config.tomland~/.config/myapp/conf.d/*:# /etc/myapp/config.toml      # ~/.config/myapp/conf.d/mysettings.toml
url = http://teg.avature.net  password = Avature123!>>>confight.load_user_app('myapp'){"url":"http://teg.avature.net","password":"Avature123!"}To ignore config file extensions, set aformatand all files will be parsed
using such:# /etc/myapp/config.toml      # /etc/myapp/config.d/extra
name = test                   name = erebus>>>confight.load_app('myapp',format='toml'){"name":"erebus"}To load configs from adevordebuglocation use theprefixoption.
This will change the base to calculate default paths.# Loads from ./configs/config.toml and ./configs/config.d/*>>>confight.load_app('myapp',prefix='./configs')Theuser_prefixoption can be used altogether for user config files:# Loads from regular places and ./user/config.toml and ./user/config.d/*>>>confight.load_user_app('myapp',user_prefix='./user')Added in version 1.0Command lineconfightallows to inspect configuration from the command line.By using theconfightcommand it would load themyappconfiguration from
it's default places and display the output in toml format:confight show myappThis allows to preview the resulting config for an application after all
merges have been resolved. It can come handy when figuring out what the
application has loaded or to debug complex config scenarios.By passing the--verbose INFOinteresting data such as all visited files is
listed.Added in version 0.3Command line optionsusage: confight [-h] [--version] [-v {DEBUG,INFO,WARNING,ERROR,CRITICAL}]
                {show} ...

One simple way of parsing configs

positional arguments:
{show}

optional arguments:
-h, --help            show this help message and exit
--version             show program's version number and exit
-v {DEBUG,INFO,WARNING,ERROR,CRITICAL}, --verbose {DEBUG,INFO,WARNING,ERROR,CRITICAL}
                        Logging level default: ERROR ['DEBUG', 'INFO',
                        'WARNING', 'ERROR', 'CRITICAL']InstallationInstall it via pip using:pip install confightAlso withyamlsupport usingoptional features:pip install confight[yaml]Similarly, forhclsupport:pip install confight[hcl]DevelopmentRun application teststoxInstall the application and run tests in development:pip install -e .
python -m pytestChangelog2.0 (2023-12-13)[dd040ae2] feat(confight): Only support Python v3.8+[266de3d4] chore(confight): Drop support for Python v21.4.0 (2023-12-12)[ Federico Fapitalle ][3e618f3b] feat: adds support for HCL languaje[ Frank Lenormand ][a9b3b9a2] fix(confight): Stick to olderruamel.yamlAPI[4de6a3ff] fix(setup): Do not freezepyhclpackage version1.3.2 (2023-10-25)[241dca89] Update ownership to Platform Operability[96a1def0] fix(setup): Freeze version ofruamel.yaml1.3.1 (2020-04-28)[f6183081] Adds tests for ignore load file behaviour[9686602f] Import pkg_resources only when needed[7e7cbe5c] Update README with optional dependencies[a766b09f] Pin hamcrest version to be python3.5 compatible1.3 (2019-09-19)[995d00f6] Adds a default config parameter for the load_app family of functions[a99f3604] Deprecate support for Python 3.4[f73a8931] Add setuptools to dependencies1.2.3 (2019-02-25)[c1f5c919] Show missing file warnings as debug info1.2.2 (2019-02-19)[7344c929] Fixes man generation in debian rules1.2.1 (2019-02-19)[491f8b05] Fixes find path expansion1.2 (2019-02-14)[3c266c8d] Force all loaded files to have the same extension1.1.1 (2019-01-31)[ javier.lasheras ][a1646871] OrderedDict for yaml too1.1 (2019-01-29)[4a5920af] Adds pypi version badge to README[59c47a5e] Drops support for Python 3.3 and Python 3.4[dfa9c436] Adds support for Python 3.7[6979074d] Fix manpage generation[8f6b58f5] Create a parser with ExtendedInterpolation[7d74246d] Avoid DeprecationWarnings[633b1571] Ordered dicts everywhere1.0 (2018-06-26)[736a6493] Adds prefix and user_prefix options[023158e5] Adds --prefix and --user-prefix cli options[f395fc44] Adapt tests to run in python 3.3 and 3.4[a144dab1] Update package metadata0.3 (2018-06-14)[a7b46ef1] Adds travis config file[5f625da9] Add tox-travis integration[1b678173] Adds confight command line tool[691e042a] Adds cli unit tests0.2.2 (2018-04-13)[3322a7a4] Allow custom file extensions when format is defined0.2.1 (2018-04-09)[93cd8a1c] Update README0.2 (2018-04-04)[63d55fa8] Add Yaml support0.1.1 (2018-04-03)[80087037] Allows to pass extra paths in load functions0.1.0 (2018-03-27)[23927421] Reorganize pretty functions and find behaviour[fade6dd0] Adds debian packaging[c818857a] Update README0.0.1 (2018-03-27)Initial release.