Package: jcfg
jcfgjcfg is an easy-to-use json-based configuration tool for building python programs.Suppose that you want to develop an program that has three config options: a file path (type of string), an integer (type of int), and a float number. And also want to be able to load configs from a local file. Then, you can write code like this, with jcfg:# in file: my_program.pyfromjcfgimportJsonCfgdefmain():cfg=JsonCfg({'input_path':'','input_int':0,'input_float':0.0})cfg.parse_args()# do any work you want below# you can get the input_path, input_int, or input_float like this:res=cfg.input_int+cfg.input_float# `cfg.input_int` and `cfg.input_float` will get the actual value depending on the cli input. jcfg have done the type check work for you. If the input option cannot be parsed as an integer, it will raise error....if__name__=='__main__':main()Typepython3 my_program.py -hin your terminal, you will get:usage:test_readme.py[-h][-cCONFIG_PATH][--input_floatINPUT_FLOAT][--input_intINPUT_INT][--input_pathINPUT_PATH]optionalarguments:-h,--helpshowthishelpmessageandexit-cCONFIG_PATHfilepathtoupdateconfig--input_floatINPUT_FLOATtype:<class'float'>,default:0.0--input_intINPUT_INTtype:<class'int'>,default:0--input_pathINPUT_PATHtype:<class'str'>,default:As you can see above, these config options can be loaded from either cli input or a json file with cli option-c your_config.json.UsageTo define config optionsThe config options should be defined based on the dict object provided when constructingJsonCfg. Each key in the dict will be the name of an config option, and the corresponding value will be either the default value for this config or a sub-config under this key name, based on:if the value is a dict without the key_default, this value will define a sub-config under this key,otherwise, the value indicates the default value (and also some other meta info) for this key. The type of this config will be implicitly determined as the type of the default value.For better understanding, here is an example:cfg=jcfg.JsonCfg({'option_int':-1,# this define an config option with name `option_int` with default value of -1, and also with type of int (type(-1) is int).'option_float':0.0,# this define config `option_float`, with default value 0.0, and type of float.'option_str':'default_value',# default value: 'default_value', with type str'option_list':[],# this defins an config with default value of empty list, of type list'sub_config':{# this will define and sub-config'sub_int':0,'sub_float':0.0,'sub_sub_config':{# sub-config can be recursively defined'leaf_key':0,}},'not_sub_config':{# however, this won't define a sub-config, but an config with value type: string'_default':'this_is_default_value','_desc':'this_si_description',# this will provide detailed description for this config when typing --help},'option_by_tuple':(2,'this is a description'),# this option is defined with a 2-size tuple, the 1st is default value, 2rd is description'option_by_tuple_3':(0.0,'this is a description',lambdax:x>=0.0),# this option is defined with a 3-size tuple, the 3rd is to validate the value.})The config option value currently only supports following types:intfloatstrlistNote that, if you want a config option with type of dict, you'd better define it as an 2-size list, then parse this option as dict in your code yourself.To load configs from cliAll config options could be overrided from cli with the corresponding config key name. For sub-config, the config key name is defined by all the config key name between root config and leaf config. Here is an example to override the sub-config value:python3test.py--sub_config.sub_int2To load configs from fileAll configs can also be loaded from ajsonfile with a more tolerant json loader:jstyleson, which supports js-style comments and also allows trailing comma, or fromyamlfile. Here is an examples of loading from json:\\config.json/* js-style comments supported!*/{"option_str":"new_string",// in-line comments supported!"sub_config":{"sub_int":1,// trailing comma allowed},"sub_config.sub_float":3}These config can be updated bypython3 test.py -c config.json.Note that, sub-config value can be defined as a dict or key-value pair with full config path, like above.If both config file and cli option are provided, the config will befirst overrided from config file, then overrided from cli options.Access to configs.The configs can be easily accessed like this:cfg.option_int# orcfg['option_int']# for sub-configcfg.sub_config.sub_int# orcfg['sub_config']['sub_int']# orcfg['sub_config.sub_int']Other featuresConfig key startswith_denotes private config options, which will never be overrided from cli or file.'_default' is the reserved key, you should never define a config with key name '_default'.'_desc' is another reserved key for defining cli description of config keySome other reserved key startswith_may be added someday, to provide more advanced meta control.TestRuncd test; python3 test_main.py -v.