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