Question: Sequence of Objects
Closed this issue · 2 comments
Hi,
I'm trying to handle the case where I want to transform a JSON dictionary to a sequence of objects (e.g. List[T]). For instance, I create a model for an Error such as:
class Error(JsonObject):
message = StringProperty()
status_code = IntegerProperty()
error_code = IntegerProperty()
I can call Error(json['data'])
when my JSON looks like this:
{
"data": {
"message": "some error message",
"status_code": 404,
"error_code": -1234
}
}
But sometimes my JSON response looks like this instead:
{
"data": [
{
"message": "err message 1",
"status_code": 500,
"error_code": -5677
},
{
"message": "err message 2",
"status_code": 400,
"error_code": -9876
}
]
}
In this case what I want is to be able to call Error(json['data'])
and get back a List[Error]
. Or at least, I want to be able to define an object Errors
that I can call like Errors(json['data'])
and get my List[Error]
. I know I can define a class such as:
class Errors(JsonObject):
errors = ListProperty(Error)
but that does not preserve the semantics of a List[Error]
. I tried to fudge with __
methods such as __getitem__
, __setattr__
, etc to make Errors
look like a container / List, but I get into trouble since some of those are already defined in JsonObject
. So far, what I am doing is this:
class Errors(object):
def __new__(cls, json: Dict[str, Union[int, str, bool]]) -> List[Error]:
return [Error(elem) for elem in json]
Is there a better way to go about this? Does the library provide any way of doing this that I'm missing?
Thanks!
Hi @adrianbn, I think the short answer is that there's nothing specifically in this library that lets you define a custom list type (that isn't a property of a object type).
The longer answer is (getting outside the scope of the library for a moment) that my two cents is that it sounds like what you want is maybe just a function that takes in a list of dicts and returns the list of those dicts wrapped with Error
:
def wrap_errors(elems):
return [Error(elem) for elem in elems]
or something like that. Alternatively, you could define your schema one level up to include the "data" property:
class ErrorListData(JsonObject):
data = ListProperty(Error) # with the Error you defined above
Then, you can date the original json
json = {
"data": [
{
"message": "err message 1",
"status_code": 500,
"error_code": -5677
},
{
"message": "err message 2",
"status_code": 400,
"error_code": -9876
}
]
}
and wrap it with ErrorListData(json)
.
Let me know if I misunderstood your point. Otherwise I can go ahead and close the issue.
Thanks @dannyroberts, those are good suggestions. I'm closing this one :)