question 226 CLI & Automation · medium
Typed settings from prefixed variables
A service keeps its defaults in a dictionary and lets the environment override any of them with variables like SHOP_PORT or SHOP_DEBUG. Each override must come out with the same type as its default.
Function
merge_settings(defaults, env, prefix)defaultsa dictionary like
{"port": 8000, "debug": False, "rate": 0.2, "name": "shop"}Returnsa new dictionary with every key of
defaults; a key is overridden when prefix + KEY (upper case) is in envConversionto the default's type:
int, float, str as-is; for bool, 1/true/yes/on and 0/false/no/off (any capitals, spaces trimmed)Raises
ValueError when a value can't be converted (e.g. SHOP_PORT=eighty, SHOP_DEBUG=maybe)Rules
defaults is not changed; variables without the prefix, or for unknown keys, are ignoredExamples
callmerge_settings({'port': 8000, 'debug': False, 'rate': 0.2, 'name': 'shop'}, {'SHOP_PORT': '9000', 'SHOP_DEBUG': ' Yes', 'HOME': '/root'}, 'SHOP_')returns{'port': 9000, 'debug': True, 'rate': 0.2, 'name': 'shop'}
callmerge_settings({'port': 8000, 'debug': True}, {}, 'SHOP_')returns{'port': 8000, 'debug': True}
callmerge_settings({'name': 'shop', 'workers': 2}, {'SHOP_NAME': 'outlet', 'SHOP_WORKERS': '8'}, 'SHOP_')returns{'name': 'outlet', 'workers': 8}
callmerge_settings({'port': 8000}, {'SHOP_PORT': 'eighty'}, 'SHOP_')raisesValueError