sdk_python
sdk_python copied to clipboard
KeyError 'Id' in _unwrap_response_single (creating callbacks)
Steps to reproduce:
- Create a Bunq Context load it and then try to register a callback.
(only showing the callback part here)
filters = [NotificationFilterUrl('REQUEST', url),
NotificationFilterUrl('DRAFT_PAYMENT', url)]
endpoint.NotificationFilterUrlUser.create(notification_filters=filters)
What should happen:
- Don't know, because it's no where documented..... (also tinker example is old)
What happens:
- Throws an KeyError (probably in the response)
Traceback
File "/app/helper/bunq_helper.py", line 17, in add_callback_url home_1 | endpoint.NotificationFilterUrlUser.create( home_1 | File "/usr/local/lib/python3.9/site-packages/bunq/sdk/model/generated/endpoint.py", line 30113, in create home_1 | cls._process_for_id(response_raw) home_1 | File "/usr/local/lib/python3.9/site-packages/bunq/sdk/model/core/bunq_model.py", line 73, in _process_for_id home_1 | cls._unwrap_response_single(obj, cls._FIELD_ID) home_1 | File "/usr/local/lib/python3.9/site-packages/bunq/sdk/model/core/bunq_model.py", line 61, in _unwrap_response_single home_1 | return obj[cls._FIELD_RESPONSE][cls._INDEX_FIRST][wrapper] home_1 | KeyError: 'Id' homeserver_home_1 exited with code 1
SDK version and environment
Response id
- Response id: There it fails. There is no response Id in this object....
Extra info:
As response we get this object:
{
"Response": [
{
"NotificationFilterUrl": {
"id": XXXXXXXX,
"created": "2021-01-05 20:44:21.473228",
"updated": "2021-01-05 20:44:21.473228",
"category": "REQUEST",
"notification_target": "XXXXXXXXXXX"
}
},
{
"NotificationFilterUrl": {
"id": XXXXXXXXX,
"created": "2021-01-05 20:44:21.478947",
"updated": "2021-01-05 20:44:21.478947",
"category": "DRAFT_PAYMENT",
"notification_target": "XXXXXXXXXX"
}
}
]
}
Now in _unwrap_response_single we do this:
- return obj[cls._FIELD_RESPONSE][cls._INDEX_FIRST][wrapper]
- cls._FIELD_RESPONSE is "Response"
- cls._INDEX_FIRST is 0
- wrapper is "Id"
So if we take the first element of "Response" there is no "Id". Only a NotificationFilterUrl... And then again there is no "Id" only a "id"...
@classmethod BunqModel._from_json_list assumes that the endpoint name is the same as the model name.
This does not work for the "abstract" type NotificationFilterUrl which can be loaded from multiple endpoints (NotificationFilterUrlUser, NotificationFilterUrlMonetaryAccount)
item_unwrapped in BunqModel._from_json_list needs to be deserialized to NotificationFilterUrl (wrapper) when cls is NotificationFilterUrlUser or NotificationFilterUrlMonetaryAccount
# bunq/sdk/model/core/bunq_model.py:56
@classmethod
def _unwrap_response_single(cls,
obj: Dict,
wrapper: str = None)
...
# bunq/sdk/model/core/bunq_model.py:60
if wrapper is not None:
return obj[cls._FIELD_RESPONSE][cls._INDEX_FIRST][wrapper]
from bunq.sdk.model.generated.endpoint import NotificationFilterUrlUser, NotificationFilterUrlMonetaryAccount
if cls == NotificationFilterUrlUser or cls == NotificationFilterUrlMonetaryAccount:
return obj[cls._FIELD_RESPONSE][cls._INDEX_FIRST]['NotificationFilterUrl']
else:
return obj[cls._FIELD_RESPONSE][cls._INDEX_FIRST][wrapper]
# bunq/sdk/model/core/bunq_model.py:91
@classmethod
def _from_json_list(cls,
response_raw: BunqResponseRaw,
wrapper: str = None)
...
# bunq/sdk/model/core/bunq_model.py:102
for item in array:
item_unwrapped = item if wrapper is None else item[wrapper]
# item_unwrapped needs to be deserialized to NotificationFilterUrl (wrapper)
# when cls is NotificationFilterUrlUser or NotificationFilterUrlMonetaryAccount
if wrapper=='NotificationFilterUrl':
from bunq.sdk.model.generated.endpoint import NotificationFilterUrlUser, NotificationFilterUrlMonetaryAccount
from bunq.sdk.model.generated.object_ import NotificationFilterUrl
if cls == NotificationFilterUrlUser or cls == NotificationFilterUrlMonetaryAccount:
cls_orig = cls
cls = NotificationFilterUrl
#print(f'NotificationFilterUrlUser deserialization, changing cls from: {cls_orig} to: {cls}')
#TODO: Test deserialize for NotificationFilterUrlUser and NotificationFilterUrlMonetaryAccount
Please see: https://github.com/bunq/sdk_python/pull/157/commits/e4fecd8454f235ad8530d2c97d132a28dc873772