Reputation: 341
I want to parse json and save it in dataclasses to emulate DTO. Currently, I ahve to manually pass all the json fields to dataclass. I wanted to know is there a way I can do it by just adding the json parsed dict ie. "dejlog" to dataclass and all the fields are populated automactically.
from dataclasses import dataclass, asdict
@dataclass
class Dejlog(Dataclass):
PK: str
SK: str
eventtype: str
result: str
type: str
status: str
def lambda_handler(event, context):
try:
dejlog = json.loads(event['body'])
x = Dejlog(dejlog['PK'])
print(x)
print(x.PK)
Upvotes: 21
Views: 31988
Reputation: 11
Here is a simple classmethod that handles missing or extra keys. Building on an earlier answer:
import dataclasses
import json
json_data_str = """
{
"PK" : "Foo",
"SK" : "Bar",
"eventtype" : "blah",
"result" : "something",
"type" : "badger",
"status" : "active",
"unexpected": "I did not expect this"
}
"""
@dataclasses.dataclass
class Dejlog:
PK: str
SK: str
eventtype: str
result: str
type: str
status: str
@classmethod
def from_dict(cls, data):
return cls(
*[data.get(fld.name)
for fld in dataclasses.fields(Dejlog)]
)
json_obj = json.loads(json_data_str)
dejlogInstance = Dejlog.from_dict(json_obj)
Upvotes: 1
Reputation: 379
You can load json to your dataclass object using hook_object
param like this:
import json
from dataclasses import dataclass
@dataclass
class Dejlog:
PK: str
SK: str
eventtype: str
result: str
type: str
status: str
my_obj = json.loads(
open('/path/to/file', 'r').read(),
object_hook=lambda args: Dejlog(**args)
)
Upvotes: 0
Reputation: 1604
Unpacking works as long as you don't have any unexpected keys in the json object, otherwise you'll get a TypeError. An alternative is to use a classmethod to create instances of the dataclass. Building on the earlier example:
json_data_str = """
{
"PK" : "Foo",
"SK" : "Bar",
"eventtype" : "blah",
"result" : "something",
"type" : "badger",
"status" : "active",
"unexpected": "I did not expect this"
}
"""
@dataclass
class Dejlog:
PK: str
SK: str
eventtype: str
result: str
type: str
status: str
@classmethod
def from_dict(cls, data):
return cls(
PK = data.get('PK'),
SK = data.get('SK'),
eventtype = data.get('eventtype'),
result=data.get('result'),
type=data.get('type'),
status=data.get('status')
)
json_obj = json.loads(json_data_str)
dejlogInstance = Dejlog.from_dict(json_obj)
Upvotes: 11
Reputation: 274
As mentioned in other comments you can use the in-built json
lib as so:
from dataclasses import dataclass
import json
json_data_str = """
{
"PK" : "Foo",
"SK" : "Bar",
"eventtype" : "blah",
"result" : "something",
"type" : "badger",
"status" : "active"
}
"""
@dataclass
class Dejlog:
PK: str
SK: str
eventtype: str
result: str
type: str
status: str
json_obj = json.loads(json_data_str)
dejlogInstance = Dejlog(**json_obj)
print(dejlogInstance)
Upvotes: 16