Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/alex-ber/AlexBerUtils/llms.txt

Use this file to discover all available pages before exploring further.

The init_app_conf module is the primary configuration entry point for AlexBerUtils applications. It unifies command-line argument parsing with hierarchical YAML file loading and profile-based overriding into one function call.
Optional dependency required. This module depends on ymlparsers, which requires third-party packages. Install them first:
pip install alex-ber-utils[yml]

How it works

1

Parse CLI arguments

CLI arguments of the form --key=value are read first. The special argument --general.config.file (default: config.yml) points to the base YAML file.
2

Load base YAML

The base config file is loaded. general.profiles determines which additional profile files to layer on top.
3

Apply profile layering

If profiles are [dev, local], the module loads config.yml, then overrides with config-dev.yml, then config-local.yml.
4

Apply CLI overrides

CLI arguments are applied last, overriding YAML values. Which keys can be overridden is controlled by general.whiteListSysOverride.
5

Return merged dict

The result is an OrderedDict of dicts containing the fully merged configuration, including resolved general.profiles, general.whiteListSysOverride, and general.config.file.

Setup

Call initConfig() once at application startup — typically in the main thread — before calling any other function in this module.
import alexber.utils.init_app_conf as init_app_conf
import alexber.utils.ymlparsers as ymlparsers

# Initialize ymlparsers first (required dependency)
ymlparsers.initConfig()

# Initialize init_app_conf (uses defaults: implicit_convert=True)
init_app_conf.initConfig()
To disable implicit type conversion globally:
init_app_conf.initConfig(
    default_parser_kwargs={'implicit_convert': False}
)
You can also supply a custom parser class by name:
init_app_conf.initConfig(
    default_parser_cls='myapp.config.MyAppConfParser'
)

Complete example

Directory layout

myapp/
  config.yml
  config-dev.yml
  config-local.yml
  main.py

config.yml

general:
  profiles:
    - dev
    - local

  log:
    version: 1
    disable_existing_loggers: False
    formatters:
      detail:
        format: '%(asctime)-15s %(levelname)s [%(name)s.%(funcName)s] %(message)s'
        datefmt: '%Y-%m-%d %H:%M:%S'
    handlers:
      console:
        class: logging.StreamHandler
        level: DEBUG
        formatter: detail
        stream: ext://sys.stdout
    root:
      level: DEBUG
      handlers: [console]

app:
  host_name: google.com
  news: cnn.com
  white_list:
    - gamma
    - alpha
    - betha

config-dev.yml

general:
  log:
    root:
      level: INFO

app:
  host_name: yahoo.com
  news: cnn.com

main.py

import alexber.utils.init_app_conf as init_app_conf
import alexber.utils.ymlparsers as ymlparsers

def main():
    ymlparsers.initConfig()
    init_app_conf.initConfig()

    dd = init_app_conf.parse_config()
    # dd['app']['host_name'] => 'yahoo.com'  (from config-dev.yml)
    # dd['general']['profiles'] => ['dev', 'local']
    # dd['general']['config']['file'] => '/absolute/path/to/config.yml'
    return dd

if __name__ == '__main__':
    main()

CLI invocation

# Use a custom config file and override the profile
python main.py \
  --general.config.file=config.yml \
  --general.profiles=dev \
  --app.host_name=staging.example.com

Profile system

Profiles allow environment-specific config files to layer on top of the base config.
# Loads: config.yml -> config-dev.yml -> config-local.yml -> CLI args
python main.py --general.profiles=dev,local
Profiles can also be defined directly in config.yml:
general:
  profiles:
    - dev
    - local
CLI --general.profiles always takes precedence over the YAML value.

general.whiteListSysOverride

By default, any top-level key that exists in the base YAML can be overridden from the CLI. To restrict which keys are CLI-overridable, set general.whiteListSysOverride in the YAML:
general:
  whiteListSysOverride:
    - app.host_name
With this setting, only --app.host_name will be accepted from the CLI. All other CLI keys (e.g., --app.portal) are silently ignored.
# app.host_name is allowed; app.portal is ignored
python main.py \
  --app.host_name=10.20.40.60 \
  --app.portal=reddit.com
general.whiteListSysOverride itself cannot be overridden from the CLI — it is always read from the YAML file.

general.listEnsure

Keys listed under general.listEnsure are treated as comma-delimited lists when provided as CLI arguments:
general:
  listEnsure:
    - app.white_list
    - app.alt_white_list
# app.white_list will be parsed as ['alpha', 'betha', 'gamma']
python main.py --app.white_list=alpha,betha,gamma

API reference

initConfig(**kwargs)

Initializes the module. Must be called before parse_config(). Safe to call with no arguments.
default_parser_cls
class | str
The parser class to use. Accepts a class object or a fully-qualified class name string. Defaults to AppConfParser.
default_parser_kwargs
dict
Default keyword arguments passed to the parser class constructor. Supported keys:
  • implicit_convert (bool, default True): whether to auto-convert string values to Python types.

parse_config(argumentParser=None, args=None, implicit_convert=None)

The main function. Parses CLI arguments and YAML files, returning a fully merged OrderedDict.
argumentParser
ArgumentParser
An argparse.ArgumentParser instance. If None, a new one is created automatically.
args
list[str]
Explicit argument list. If provided, sys.argv is suppressed. Useful for testing.
dd = parse_config(args=['--general.profiles=dev', '--app.host_name=localhost'])
implicit_convert
bool
Controls type conversion for CLI argument values.
  • None (default): uses the value set in initConfig() (default True).
  • True: converts strings to Python types ('1000'1000, 'True'True, 'None'None).
  • False: all CLI values remain as strings.
Returns: OrderedDict with the fully merged configuration. Always includes:
  • general.config.file — absolute path to the resolved base YAML file
  • general.profiles — the resolved list of active profiles
  • general.whiteListSysOverride — the resolved whitelist
  • general.listEnsure — the resolved list-ensure keys

mask_value(value, implicit_convert=None)

Converts a string value to an appropriate Python type.
value
str
The string to convert.
implicit_convert
bool
If None, uses the value from initConfig(). If True, converts to Python built-in types. If False, returns the value as-is.
from alexber.utils.init_app_conf import mask_value

mask_value('1000')    # => 1000   (int)
mask_value('0.1')     # => 0.1   (float)
mask_value('True')    # => True  (bool, case-insensitive)
mask_value('None')    # => None
mask_value('John')    # => 'John' (str, unchanged)

# Disable conversion for a specific call
mask_value('True', implicit_convert=False)  # => 'True' (str)
Boolean conversion is case-insensitive: 'true', 'True', 'TRUE' all become True.

to_convex_map(d, white_list_flat_keys=None, implicit_convert=None)

Converts a flat dot-notation dictionary into a nested OrderedDict.
d
dict
A flat dictionary with dot-separated keys, e.g. {'general.profiles': 'dev', 'app.host_name': 'localhost'}.
white_list_flat_keys
list[str]
If provided, only keys that start with one of the listed prefixes are included in the output.
implicit_convert
bool
Controls type conversion of values. Defaults to the value set in initConfig().
from alexber.utils.init_app_conf import to_convex_map

flat = {
    'general.profiles': 'dev',
    'app.host_name': 'localhost',
    'app.port': '8080',
    'db.unused': 'ignored',
}

# Filter to only 'general' and 'app' keys
result = to_convex_map(flat, white_list_flat_keys=['general', 'app'])
# => OrderedDict({
#      'general': {'profiles': 'dev'},
#      'app': {'host_name': 'localhost', 'port': 8080}
#    })
Keys without a dot are skipped. Values are converted via mask_value() when implicit_convert=True.

merge_list_value_in_dicts(flat_d, d, main_key, sub_key, implicit_convert=None)

Merges a list value from a flat dict and a nested dict. The flat dict value takes precedence when non-empty.
flat_d
dict
Flat dictionary (typically from parsed CLI args). Key is main_key + '.' + sub_key.
d
dict
Nested dictionary (typically from parsed YAML). Value is at d[main_key][sub_key].
main_key
str
The top-level key, e.g. 'general'.
sub_key
str
The nested key, e.g. 'profiles'.
implicit_convert
bool
Applied only to the flat_d value. Defaults to the value set in initConfig().
from alexber.utils.init_app_conf import merge_list_value_in_dicts

flat_d = {'app.ports': '10000,10001'}
d = {'app': {'ports': ['default']}}

result = merge_list_value_in_dicts(flat_d, d, 'app', 'ports')
# => [10000, 10001]  (flat_d value wins; converted to ints)

# When flat_d has no value, d's value is used:
result = merge_list_value_in_dicts({}, d, 'app', 'ports')
# => ['default']