Package: roconfiguration
Python configuration utilitiesImplementation of key-value pair based configuration for Python applications.Features:support for most common sources of application settingssupport for overriding settings in sequencesupport for nested structures and lists, using attribute notationstrategy to use environment specific settingsThis library is freely inspired by .NET CoreMicrosoft.Extensions.Configurationnamespace and its pleasant design (ref.MSDN documentation,Microsoft Extensions Configuration Deep Dive).The main class is influenced by Luciano Ramalho`s example of
JSON structure explorer using attribute notation, in his bookFluent Python.Supported sources:yamlfilesjsonfilesinifilesenvironmental variablesdictionarieskeys and valuesInstallationpipinstallroconfigurationExamplesYAML file and environmental variablesIn this example, configuration will be comprised of anything inside a filesettings.yamland environmental variables. Settings are applied in order, so
environmental variables with matching name override values from theyamlfile.fromroconfigurationimportConfigurationconfig=Configuration()config.add_yaml_file("settings.yaml")config.add_environmental_variables()YAML file, optional file by environmentIn this example, if an environmental variable with nameAPP_ENVIRONMENTand
valuedevexists, and a configuration file with namesettings.dev.yamlis
present, it is read to override values configured insettings.yamlfile.importosfromroconfigurationimportConfigurationenvironment_name=os.environ["APP_ENVIRONMENT"]config=Configuration()config.add_yaml_file("settings.yaml")config.add_yaml_file(f"settings.{environment_name}.yaml",optional=True)config.add_environmental_variables()Filtering environmental variables by prefiximportosfromroconfigurationimportConfigurationconfig=Configuration()# will read only environmental variables# starting with "APP_", case insensitivelyconfig.add_environmental_variables("APP_")Ini filesIni files are parsed using the built-inconfigparsermodule, therefore
support[DEFAULT]section; all values are kept as strings.fromroconfigurationimportConfigurationconfig=Configuration()config.add_ini_file("settings.ini")JSON filesJSON files are parsed using the built-injsonmodule.fromroconfigurationimportConfigurationconfig=Configuration()config.add_json_file("settings.json")DictionariesfromroconfigurationimportConfigurationconfig=Configuration({"host":"localhost","port":8080})config.add_map({"hello":"world","example":[{"id":1},{"id":2}]})assertconfig.host=="localhost"assertconfig.port==8080assertconfig.hello=="world"assertconfig.example[0].id==1assertconfig.example[1].id==2Keys and valuesfromroconfigurationimportConfigurationconfig=Configuration({"host":"localhost","port":8080})config.add_value("port",44555)assertconfig.host=="localhost"assertconfig.port==44555Overriding nested valuesconfig=Configuration({"a":{"b":1,"c":2,"d":{"e":3,"f":4,},}})assertconfig.a.b==1assertconfig.a.d.e==3assertconfig.a.d.f==4config.add_value("a:d:e",5)assertconfig.a.d.e==5assertconfig.a.d.f==4Overriding nested values using env variablesconfig=Configuration({"a":{"b":1,"c":2,"d":{"e":3,"f":4,},}})assertconfig.a.b==1assertconfig.a.d.e==3assertconfig.a.d.f==4# NB: if an env variable such as:# a:d:e=5# or...# a__d__e=5## is defined, it overrides the value  from the dictionaryconfig.add_environmental_variables()assertconfig.a.d.e==5Overriding values in list items using env variablesconfig=Configuration({"b2c":[{"tenant":"1"},{"tenant":"2"},{"tenant":"3"},]})config.add_value("b2c:1:tenant","4")assertconfig.b2c[0].tenant=="1"assertconfig.b2c[1].tenant=="4"assertconfig.b2c[2].tenant=="3"Develop and run tests locallypipinstall-rrequirements.txt# run tests using automatic discovery:pytest