Package: dataconf
DataconfSimple dataclasses configuration management for Python with
hocon/json/yaml/properties/env-vars/dict/cli support.Getting startedRequires at least Python 3.8.# pypipipinstalldataconf
poetryadddataconf# remote masterpipinstall--upgradegit+https://github.com/zifeo/dataconf.git
poetryaddgit+https://github.com/zifeo/dataconf.git# local repo/devpoetryinstall
pre-commitinstallUsageimportosfromdataclassesimportdataclass,fieldfromtypingimportList,Dict,Text,Unionfromdateutil.relativedeltaimportrelativedeltafromdatetimeimportdatetimeimportdataconfconf="""str_name = teststr_name = ${?HOME}dash-to-underscore = truefloat_num = 2.2iso_datetime = "2000-01-01T20:00:00"iso_duration = "P123DT4H5M6S"# this is a commentlist_data = [ab]nested {a = testb : 1}nested_list = [{a = test1b : 2.5}]duration = 2sunion = 1people {name = Thailand}zone {area_code = 42}"""classAbstractBaseClass:pass@dataclassclassPerson(AbstractBaseClass):name:Text@dataclassclassZone(AbstractBaseClass):area_code:int@dataclassclassNested:a:Textb:float@dataclassclassConfig:str_name:Textdash_to_underscore:boolfloat_num:floatiso_datetime:datetimeiso_duration:timedeltalist_data:List[Text]nested:Nestednested_list:List[Nested]duration:relativedeltaunion:Union[Text,int]people:AbstractBaseClasszone:AbstractBaseClassdefault:Text='hello'default_factory:Dict[Text,Text]=field(default_factory=dict)print(dataconf.string(conf,Config))# Config(#   str_name='/users/root',#   dash_to_underscore=True,#   float_num=2.2,#   list_data=['a', 'b'],#   nested=Nested(a='test'),#   nested_list=[Nested(a='test1', b=2.5)],#   duration=relativedelta(seconds=+2),#   union=1,#   people=Person(name='Thailand'),#   zone=Zone(area_code=42),#   default='hello',#   default_factory={}# )@dataclassclassExample:hello:strworld:strfoo:List[str]os.environ['DC_WORLD']='monde'print(dataconf.multi.url('https://raw.githubusercontent.com/zifeo/dataconf/main/confs/simple.hocon').env('DC').on(Example))# Example(hello='bonjour',world='monde')APIimportdataconfconf=dataconf.string('{ name: Test }',Config)conf=dataconf.string('name:\n\tvalue: Test',Config,loader=dataconf.YAML)# dataconf.HOCON by defaultconf=dataconf.env('PREFIX_',Config)conf=dataconf.dict({'name':'Test'},Config)conf=dataconf.url('https://raw.githubusercontent.com/zifeo/dataconf/master/confs/test.hocon',Config)# hocon, json, yaml, propertiesconf=dataconf.file('confs/test.hocon',Config)# hocon, json, yaml, propertiesconf=dataconf.cli(sys.argv,Config)# Aggregationconf=dataconf.multi.string(...).env(...).url(...).file(...).dict(...).cli(...).on(Config)# Same api as Python json/yaml packages (e.g. `load`, `loads`, `dump`, `dumps`)conf=dataconf.load('confs/test.hocon',Config)# hocon, json, yaml, propertiesconf=dataconf.load('confs/test.yaml',Config,loader=dataconf.YAML)# dataconf.HOCON by defaultdataconf.dump('confs/test.hocon',conf,out='hocon')dataconf.dump('confs/test.json',conf,out='json')dataconf.dump('confs/test.yaml',conf,out='yaml')dataconf.dump('confs/test.properties',conf,out='properties')For full HOCON capabilities seehere.Parse env varsPREFIX_VAR=aPREFIX_VAR_NAME=bPREFIX_TEST__NAME=cPREFIX_LS_0=dPREFIX_LS_1=ePREFIX_LSLS_0_0=fPREFIX_LSOB_0__NAME=gPREFIX_NESTED_="{ name: Test }"PREFIX_SUB_="{ value:${PREFIX_VAR}}"is equivalent to{
    var = a
    var_name = b
    test {
        name = c
    }
    ls = [
        d
        e
    ]
    lsls = [
        [
            f
        ]
    ]
    lsob = [
        {
            name = g
        }
    ]
    nested {
        # parse nested config by suffixing env var with `_`
        name: Test
    }
    sub {
        # will have value "a" at parsing, useful for aliases
        value = ${PREFIX_VAR}
    }
}Note that when using.envsource, the strict mode is disabled and value might
be casted.Parse CLI argumentsSame as env vars parse (dashes are converted to underscore, e.g.TEST_A→--test-a).CLI usageCan be used for validation or converting between supported file formats (-o).dataconf-cconfs/test.hocon-mtests.configs-dTestConf-ohocon# dataconf.exceptions.TypeConfigException: expected type <class 'datetime.timedelta'> at .duration, got <class 'int'>