I have a function that receives multiple different json string objects with different structure and/or field names, like so:
event = '{"userId": "TDQIQb2fQaORKvCyepDYoZgsoEE3", "profileIsCreated": true}'
or
event = '{"userId": "TDQIQb2fQaORKvCyepDYoZgsoEE3", "signUpFinished": true}'
And I have data classes like so:
from dataclasses import dataclass, field
@dataclass_json(letter_case=LetterCase.CAMEL)
@dataclass(frozen=True)
class UserId:
userId: str
@dataclass_json(letter_case=LetterCase.CAMEL)
@dataclass(frozen=True)
class SignUpFinished(UserId):
signUpFinished: bool
@dataclass_json(letter_case=LetterCase.CAMEL)
@dataclass(frozen=True)
class UserProfileCreated(UserId):
profileIsCreated: bool
Currently, the way I write my function is like this:
def cast_event(event):
user_details = None
try:
user_details = SignUpFinished.from_json(event)
except KeyError:
pass
try:
user_details = UserProfileCreated.from_json(event)
except KeyError:
pass
if user_details:
return "OK"
else:
return "UNHANDLED"
The problem is, as I have more and more events to handle, my function will become longer and longer, however, it is only doing the same thing.
Is there a better way to achieve what I want to achieve?
I have checked out some of the SO questions:
but they don't seem to be the best way of trying to achieve what I want.
Since each case is syntactically the same, you can handle them in a single loop. Iterate through a sequence of cases and try
to return
; this automatically keeps on trying later cases until one succeeds.
def cast_event(event):
for case in (UserId , SignUpFinished, UserProfileCreated):
try:
return case.from_json(event)
except KeyError:
pass
raise ValueError(f'not a valid event: {event}')