Package: config-library
config-libraryutility library to find and load configuration filessee thedocumentationfor more informationconfig-libraryInstallationSupported Config-TypesInstall VariationsUsage ExampleBasic UsageLoading specific fileSpecify/Customise search locationsMore in detailSearchingLoadingAccessing configurationInstallationpip install config-librarypip install config-library[all]pip install config-library[watcher]pip install config-library[json5]pip install config-library[toml]pip install config-library[yaml]Supported Config-Typesextensionrequireslink (for more information).ini/.conf/.confighttps://en.wikipedia.org/wiki/INI_file.jsonhttps://en.wikipedia.org/wiki/JSON.jsonchttps://changelog.com/news/jsonc-is-a-superset-of-json-which-supports-comments-6LwR.json5config-library[json5]https://json5.org/.tomlconfig-library[toml]or python3.11+https://toml.io/.yaml/.ymlconfig-library[yaml]https://en.wikipedia.org/wiki/YAML.xmlhttps://en.wikipedia.org/wiki/XMLInstall Variationsvariationinformationconfig-library[all]adds all dependencies from the variations belowconfig-library[watcher]adds support to watch the config-file for changesconfig-library[json5]adds support to load.json5filesconfig-library[toml]adds support to load.tomlfilesconfig-library[yaml]adds support to load.yamlfilesUsage ExampleBasic Usagefromconfiglibimportfind_and_loadconfig=find_and_load("app.conf")# config = find_and_load("app.json")  # format could be easily exchanged# config = find_and_load("app.toml")  # depending on your needs and preferences# config = find_and_load("app.yaml")  # and it should continue to work# config = find_and_load("app.{yml,yaml}")  # (you can also specify multiple)address=config.get('database','address')# address = config.getstr('database', 'address')  # also possible to ensure it's of type strport=config.getint('database','port',fallback=5000)Loading specific fileimportconfiglibconfig=configlib.load("./app.conf")Loading from environmentimportconfiglibconfig=configlib.load_environ("APP")Specify/Customise search locationsfromconfiglib.finderimportfind,placesconfig_file=find("project-name.conf",# variant of the config-file to search for is 'app.conf'"project-name/settings.conf",# alternate variant name to search forplaces=[places.local,places.user_conf],# search in main.py folder and ~/.config/)More in detailFor the more detailed description we will use this code example.importconfiglibconfig=configlib.find_and_load('project.conf','project/app.conf')SearchingTheconfiglib.findersubpackage has a few predefined paths it attempts to search in.
In each of these places it attempts to find one of the passed variants (project.conf,project/app.conf).
If it can't find one it goes to the next place and repeats this process.system file-structure/
├─ etc/
├─ home/user/
│  ├─ path/to/repo/
│  │  ├─ src/code/
│  │  │  ├─ main.py
│  ├─ .config/places whereconfig-librarysearches for the config-file/home/user/path/to/repo/src/code/project.conf(next to the started script)/home/user/path/to/repo/src/code/project/app.conf/home/user/path/to/repo/project.conf(next to .git/)/home/user/path/to/repo/project/app.conf/home/user/.config/project.conf(~/.config/)/home/user/.config/project/app.conf/home/user/project.conf(~/)/home/user/project/app.conf/etc/project.conf(/etc/)/etc/project/app.confLoadingAfter the search returns a filepath it is passed to theload()function.
This function analyzes the file-extension and loads it with the correct loader.The loader can be extended via theconfiglib.loader.register_loaderdecorator.
Important is that it should return native types to be compatible with theConfigInterfacefromconfiglib.loaderimportregister_loader@register_loader("env","environ")# support for *.env or *.environ filesdefcustom_loader(fp)->dict:...Accessing configurationIn the end you get an instance of theConfigInterfacewith useful get-methodsfromconfiglibimportConfigInterfaceconfig:ConfigInterfaceconfig.get("database","address",fallback="localhost")# gets the value raw as parsedconfig.getstr("database","address",fallback="localhost")# gets as stringconfig.getint("database","port",fallback=5432)# gets as integerconfig.getfloat("database","timeout",fallback=10.0)# gets as floating point numberconfig.getbool("database","delayed-connect",fallback=False)# gets as booleanconfig.getlist("database","tables",fallback=[],cast=str)# gets as listconfig.gettuple("database","tables",fallback=[],cast=str)# gets as tupleconfig.getsplit("database","tables")# clean split by `,` or `;`config.getpath("database","client-paths",fallback="./")# returns as pathlib.Pathconfig.getpaths("database","client-paths",fallback=[],as_path=True)# split by os.path.altsep (commonly `:`)config.getshlex("database","additional-params",fallback=[])# split like the command-lineconfig.getinterface("database")# gets a new ConfigInterface for sub-optionconfig.gettype("database","timeout")# gets the type/class (e.g. int | float)