Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for list messages #25

Open
Antoine-dh opened this issue Sep 19, 2024 · 0 comments
Open

Support for list messages #25

Antoine-dh opened this issue Sep 19, 2024 · 0 comments

Comments

@Antoine-dh
Copy link

I wanted to return a json message that is directly a list at its root element
For context, my use case is for making a REST client that returns the response body as a IOP message that can be deserialized into a dataclass.
This works well for singular objects, however I have some troubles when the json response's root element is a list, because of course:

The message must be an instance of a class that is a subclass of Message or IRISObject %Persistent class. -

To work around this issue, I tried to make a list/message hybrid class such as:

@dataclass(init=False)
class PetList(list[Pet], Message):
    pass

This works well as the list is correctly serialized into a IOP message, until the sender tries to deserialize it

Traceback (most recent call last):
File "/irisdev/app/src/python/demo/bs.py", line 31, in on_process_input
response: PetList = self.send_request_sync('PetstoreOperation', RESTRequest.create('find_pets_by_status'))
File "/home/irisowner/.local/lib/python3.10/site-packages/iop/_business_host.py", line 70, in dispatch_serializer
return fonction(self, *serialized, **param2)
File "/home/irisowner/.local/lib/python3.10/site-packages/iop/_business_host.py", line 84, in dispatch_deserializer
return self._dispatch_deserializer(fonction(self,*params, **param2))
File "/home/irisowner/.local/lib/python3.10/site-packages/iop/_business_host.py", line 302, in _dispatch_deserializer
return self._deserialize_message(serial)
File "/home/irisowner/.local/lib/python3.10/site-packages/iop/_business_host.py", line 340, in _deserialize_message
msg = self._dataclass_from_dict(msg,jdict)
File "/home/irisowner/.local/lib/python3.10/site-packages/iop/_business_host.py", line 358, in _dataclass_from_dict
for key,val in dikt.items():
AttributeError: 'list' object has no attribute 'items'

So I thought I could just alternatively wrap every response into a generic class such as:

from iop import Message
from dataclasses import dataclass
from pydantic import BaseModel
from typing import TypeVar, Generic, Optional

_T = TypeVar('T')

@dataclass(init=False)
class RESTResponse(BaseModel, Generic[_T], Message):
    data: Optional[_T] = None

And this almost worked, but unfortunately the generic type is interpreted as a dict and is not deserialized correctly.
So in order to make this work I would have to define a wrapper class for every different list type my API returns which is not ideal.

Maybe a solution would be for IOP to implement a ListMessage class, or detect if the response class is a list and deserialize objects individually.

Let me know what you think about this,
Thank you

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant