The goal of this article is to provide an example to create a custom Python object out of a complex JSON structure. The reason for using a custom Python object is to account for additional processing/formatting from an API service that could evolve over time and provides a better interface. Also using a custom Python object provides better control for decoupling and information hiding.
With the example provided, I’m choosing to use a JSON structure that has a mix of strings, structures and arrays which better represent more common JSON message structures.
Sample JSON (testdata2.json)
{ "name": "Bob", "arr1": [ { "PropA": "A1", "PropB": "B1" }, { "PropA": "A2", "PropB": "B2" } ], "totalCount": 1, "props": { "field1": "a", "field2": "b", "field3": "c" } }
# sample.py class Arry1Rec (object): def __init__(self, PropA: str, PropB: str): self.PropA = PropA self.PropB = PropB @classmethod def from_json(cls, data): return cls(**data) class Propscls(object): def __init__(self, field1: str, field2: str, field3: str): self.field1 = field1 self.field2 = field2 self.field3 = field3 @classmethod def from_json(cls, data): return cls(**data) class Filecls(object): def __init__(self, name: str, arry1: List[Arry1Rec], totalCount: int, props: Propscls ): self.name = name self.totalCount = totalCount self.props = props self.data = data self.arry1=arry1 @classmethod def from_json(cls, data): name = data["name"] arry1 = list(map(Arry1Rec.from_json, data["arr1"])) totalCount = data["totalCount"] props = Propscls.from_json(data=data["props"]) return cls(name=name, arry1=arry1, totalCount=totalCount, props=props) with open('./sampleData/testdata2.json', encoding='utf-8-sig', errors='ignore') as infile2: jsonDataComplex1 = json.load(infile2, strict=False) decoded_file = Filecls.from_json(jsonDataComplex1) print('test: decoded_file.props.field1') print(decoded_file.props.field3)