Package: config2
config2Python environment configuration simplified.IntroductionConfig2(for Python) - which is highly inspired bynode-config- organizes hierarchical configurations for your app deployments.It lets you define a set of default parameters, and extend them for different deployment environments (development, qa, staging, production, etc.).Configurations are stored inconfiguration fileswithin your application, and can be overridden and extended byenvironment variables,command line parameters, orexternal sources.This gives your application a consistent configuration interface shared among a growing list of npm modules also using node-config.NOTE:This project is more or less in pair withnode-configimplementation, with exception for some fluff that could be considered too much magic such as deployment specificmulti-instance deploymentswhich I so far haven't found any good motivation for, and some other questionable advanced features mentioned in the wiki pages.Project Guidelines...based onnode-configproject guidelines:Simple- Get started fastPowerful- For multi-node enterprise deployment- excluded becausewith power comes responsabilityFlexible- Supporting multiple config file formatsLightweight- Small file and memory footprintPredictable- Well tested foundation for module and app developersInstallInstall usingpip:$pipinstallconfig2Use1.Assuming we have apython applicationproject...some_project
└── app.pyapp.py- some app making serious$$$# business logicprint('$$$')2.Let's add some environment specificconfig files...some_project
└── config
    ├── default.yml
    ├── development.yml
    ├── foo.yml
    └── production.yml
└── app.pydefault.yml- with some bogus nested settings shared for all environments (defaults)a1:DEFAULT 1a2:b1:[1,2,3]b2:-foo-barb3:c1:1c2:"DEFAULT2"development.yml- with some bogus nested settings overriden fordevelopmentenvironment (overriden)a2:b2:-DEV 1b3:c2:"DEV2"some_key_only_for_dev:truefoo.yml- with some bogus nested settings overriden forfooenvironment (overriden)a2:b2:-FOO 1b3:c2:"FOO2"some_key_only_for_foo:trueproduction.yml- with some bogus nested settings overriden forproductionenvironment (overriden)a2:b2:-PROD 1b3:c2:"PROD2"some_key_only_for_prod:true3.Let's nowrun the appusingvarious environments...$ python app.pyfromconfig2.configimportconfigconfig.get_env()# => Noneconfig.get()# => {'a1': 'DEFAULT 1', 'a2': {'b1': [1, 2, 3], 'b2': ['foo', 'bar'], 'b3': {'c1': 1, 'c2': 'DEFAULT 2'}}}config.a1# => 'DEFAULT 1'config.a2# => {'b1': [1, 2, 3], 'b2': ['foo', 'bar'], 'b3': {'c1': 1, 'c2': 'DEFAULT 2'}}config.a2.b3.c2# => 'DEFAULT 2'print('$$$')$ ENV=development python app.pyfromconfig2.configimportconfigconfig.get_env()# => 'development'config.get()# => {'a1': 'DEFAULT 1', 'a2': {'b1': [1, 2, 3], 'b2': ['DEV 1'], 'b3': {'c1': 1, 'c2': 'DEV 2'}}, 'some_key_only_for_dev': True}config.a1# => 'DEFAULT 1'config.a2# => {'b1': [1, 2, 3], 'b2': ['DEV 1'], 'b3': {'c1': 1, 'c2': 'DEV 2'}}config.a2.b3.c2# => 'DEV was here 2'config.some_key_only_for_dev# => Trueconfig.some_key_only_for_foo# => AttributeErrorconfig.some_key_only_for_prod# => AttributeErrorprint('$$$')$ ENV=foo python app.pyfromconfig2.configimportconfigconfig.get_env()# => 'foo'config.get()# => {'a1': 'DEFAULT 1', 'a2': {'b1': [1, 2, 3], 'b2': ['FOO 1'], 'b3': {'c1': 1, 'c2': 'FOO 2'}}, 'some_key_only_for_foo': True}config.a1# => 'DEFAULT 1'config.a2# => {'b1': [1, 2, 3], 'b2': ['FOO 1'], 'b3': {'c1': 1, 'c2': 'FOO 2'}}config.a2.b3.c2# => 'FOO was here 2'config.key_only_for_foo# => Trueconfig.some_key_only_for_dev# => AttributeErrorconfig.some_key_only_for_prod# => AttributeErrorprint('$$$')$ ENV=production python app.pyfromconfig2.configimportconfigconfig.get_env()# => 'production'config.get()# => {'a1': 'DEFAULT 1', 'a2': {'b1': [1, 2, 3], 'b2': ['PROD 1'], 'b3': {'c1': 1, 'c2': 'PROD 2'}}, 'some_key_only_for_foo': True}config.a1# => 'DEFAULT 1'config.a2# => {'b1': [1, 2, 3], 'b2': ['PROD 1'], 'b3': {'c1': 1, 'c2': 'PROD 2'}}config.a2.b3.c2# => 'PROD was here 2'config.some_key_only_for_prod# => Trueconfig.some_key_only_for_dev# => AttributeErrorconfig.some_key_only_for_foo# => AttributeErrorprint('$$$')etc.4.Optionally, let's now introduce customconfig environment variables...some_project
└── config
    ├── custom-environment-variables.yml
    ├── default.yml
    ├── development.yml
    ├── foo.yml
    └── production.yml
└── app.pycustom-environment-variables.yml- with mappings of config keys to environment variablesa1:A1a2:b3:c2:C25.Let's nowrun the appusingcustom environment variablesto override config...$ A1=x C2=y python app.pyfromconfig2.configimportconfigconfig.get_env()# => Noneconfig.get()# => {'a1': 'x', 'a2': {'b1': [1, 2, 3], 'b2': ['foo', 'bar'], 'b3': {'c1': 1, 'c2': 'y'}}}config.a1# => 'x'config.a2# => {'b1': [1, 2, 3], 'b2': ['foo', 'bar'], 'b3': {'c1': 1, 'c2': 'y'}}config.a2.b3.c2# => 'y'print('$$$')TestClone down source code:$makeinstallRuncolorful tests, with only native environment (dependency sandboxing up to you):$maketestRunless colorful tests, withmulti-environment(usingtox):$maketest-toxAboutThis project was mainly initiated - in lack of existing alternatives - to be used at our work atMarkable.aito have common code conventions between various programming environments wherePython(research, CV, AI) andNode.js(I/O, APIs, UIs, scripts) currently are most used.LicenseReleased under the MIT license.