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

KeyError 'Id' in _unwrap_response_single (creating callbacks) #154

Open
2 of 4 tasks
LeLunZ opened this issue Jan 5, 2021 · 1 comment
Open
2 of 4 tasks

KeyError 'Id' in _unwrap_response_single (creating callbacks) #154

LeLunZ opened this issue Jan 5, 2021 · 1 comment

Comments

@LeLunZ
Copy link

LeLunZ commented Jan 5, 2021

Steps to reproduce:

  1. 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:

  1. Don't know, because it's no where documented.....
    (also tinker example is old)

What happens:

  1. 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"...

@LeLunZ LeLunZ changed the title KeyError 'Id' when creating callbacks. Error in _unwrap_response_single KeyError 'Id' in _unwrap_response_single (creating callbacks) Jan 5, 2021
@rikvermeer
Copy link

rikvermeer commented Apr 25, 2021

@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:
e4fecd8

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

2 participants