I'm using attrs
lib to parse my configuration file, and I'm looking for a better way to parse nested data objects.
Example :
from attrs import define, field, validators
from typing import Dict
class HoconParser:
@classmethod
def from_hocon(cls, file_path):
from pyhocon import ConfigFactory
return cls(
**ConfigFactory.parse_file(file_path)
)
@classmethod
def from_dictstrobj(cls, dictstrobj):
if dictstrobj:
return {
key: cls(**value) for key, value in dictstrobj.items()
}
return {}
@define
class ClassOne(HoconParser):
id: str = field(validator=validators.instance_of(str))
name: str = field(validator=validators.instance_of(str))
@define
class ClassTwo(HoconParser):
id: str = field(validator=validators.instance_of(str))
name: str = field(validator=validators.instance_of(str))
test: Dict[str, ClassOne] = field(
converter=ClassOne.from_dictstrobj,
validator=validators.deep_mapping(
key_validator=validators.instance_of(str),
value_validator=validators.instance_of(ClassOne)
)
)
a = ClassTwo.from_hocon("test.conf")
Basically, ClassTwo has an attribute which is a Dict[str, ClassOne]
.
In order to make this work, I had to make a specific function named from_dictstrobj
and use it as a converter for test
attribute.
Is there any better way to do this ?
I'm a major contributor to attrs and the author of cattrs.
You might want to use the cattrs library here. I'm assuming ConfigFactory.parse_file(file_path)
produces a dictionary?
cattrs can recursively transform this dictionary into a graph of objects.
Here's the modified code:
from cattrs import structure
class HoconParser:
@classmethod
def from_hocon(cls, file_path):
from pyhocon import ConfigFactory
return structure(ConfigFactory.parse_file(file_path), cls)
Hope this helps!