The basic resolution mechanism just loops over a dict's key/value pairs, tries to fill in their format strings using the established configuration, and catches errors to retry in a later round of resolution:
template_dict = {
'app_root': '/usr/local/myapp',
'log': '{app_root}/logs',
'uwsgi_log': '{log}/uwsgi.log',
'deploy': '{app_root}/.deploy/{commit_sha}',
'version_src': '{deploy}/src',
'src_link': '{app_root}/src',
'version_env': '{deploy}/env',
'env_link': '{app_root}/env',
'commit_sha': 'a1b2c3',
}
resolve(template_dict)
>>> {
'app_root': '/usr/local/myapp',
'log': '/usr/local/myapp/logs',
'uwsgi_log': '/usr/local/myapp/logs/uwsgi.log',
'deploy': '/usr/local/myapp/.deploy/a1b2c3',
'version_src': '/usr/local/myapp/.deploy/a1b2c3/src',
'src_link': '/usr/local/myapp/src',
'version_env': '/usr/local/myapp/.deploy/a1b2c3/env',
'env_link': '/usr/local/myapp/env',
'commit_sha': 'a1b2c3',
}
The configuration wrapper object provides both attr- and item-based lookups on the resolved configuration, and takes **kwargs rather than a dict as configuration:
config = ConfigResolver(template_dict)
# or, equivalently...
config = ConfigResolver(
app_root='/usr/local/myapp',
log='{app_root}/logs',
uwsgi_log='{log}/uwsgi.log',
deploy='{app_root}/.deploy/{commit_sha}',
version_src='{deploy}/src',
src_link='{app_root}/src',
version_env='{deploy}/env',
env_link='{app_root}/env',
commit_sha='a1b2c3',
)
config['version_src']
>>> '/usr/local/myapp/.deploy/a1b2c3'
config.uwsgi_log
>>> '/usr/local/myapp/logs/uwsgi.log'