UsageΒΆ
Example of an utility that can take settings from:
- a set of default values
- environment variables
- config file
- command line arguments
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 | import argparse
import json
import sys
import cfglib
from cfglib.sources.args import ArgsNamespaceConfig
from cfglib.sources.env import EnvConfig
# Config definitions
# These will normally be in a separate module,
# to be imported by the rest of the project like:
# from xyz.config import cfg
def parse_config_file(config_file_path) -> cfglib.Config:
with open(config_file_path) as config_file:
file_config = cfglib.DictConfig(json.load(config_file))
return cfglib.ProjectedConfig(file_config, cfglib.UPPERCASE_PROJECTION)
class ExampleToolConfig(cfglib.SpecValidatedConfig):
MESSAGE = cfglib.StringSetting(default='Hello!')
CONFIG_FILE = cfglib.StringSetting(default=None)
cfg = ExampleToolConfig([
EnvConfig(prefix='EXAMPLE_', lowercase=False),
])
# Main program
def parse_cmdline_arguments():
parser = argparse.ArgumentParser()
parser.add_argument(
'--config-file', type=str,
required=False, default=cfglib.MISSING,
help='Path to a json-encoded config file',
)
parser.add_argument(
'--message', type=str,
required=False, default=cfglib.MISSING,
help='The message that will be printed',
)
return parser.parse_args()
def initialize_config():
cmdline_config = ArgsNamespaceConfig(
parse_cmdline_arguments(),
uppercase=True,
)
# Command line arguments shoule be highest priority, so append them to the end
cfg.subconfigs.append(cmdline_config)
if cfg.get('config_file'):
# Load configuration from a config file, if specified
# Config file's priority is below that of cmdline args, so insert at position 1
cfg.subconfigs.insert(1, parse_config_file(cfg['config_file']))
# With the additional configuration sources injected, the end priority order
# from lowest to highest priority is now:
# - environment variables
# - config file
# - command line arguments
cfg.validate()
def main():
initialize_config()
print(f'Config: {cfg}', file=sys.stderr)
message = cfg.MESSAGE
print(message)
if __name__ == '__main__':
main()
|