kiwiz / gkeepapi

An unofficial client for the Google Keep API.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Parse error in <class 'gkeepapi.node.WebLink'>

github-of-wone opened this issue · comments

Please make sure you've done the following before submitting your issue:

  • Check that you're running the newest version of the library.
  • If you're providing a stack trace, make sure it doesn't contain your password.
  • If you're getting a KeyError or ParseException, please follow the instructions here to dump the raw data.

Additionally, please provide the following information:

  • Operating system - Windows 11
  • Python version - 3.11.4

{'webLink': {'kind': 'notes#webLink', 'url': 'https://support.google.com/keep/?p=migrated_from_assistant', 'provenanceUrl': 'https://support.google.com/keep/?p=migrated_from_assistant', 'hasThumbnailUrl': True}}


KeyError Traceback (most recent call last)
File ~\AppData\Roaming\Python\Python311\site-packages\gkeepapi\node.py:214, in Element.load(self, raw)
213 try:
--> 214 self._load(raw)
215 except (KeyError, ValueError) as e:

File ~\AppData\Roaming\Python\Python311\site-packages\gkeepapi\node.py:291, in WebLink._load(self, raw)
290 super(WebLink, self)._load(raw)
--> 291 self._title = raw['webLink']['title']
292 self._url = raw['webLink']['url']

KeyError: 'title'

The above exception was the direct cause of the following exception:

ParseException Traceback (most recent call last)
d:\Cloud\OneDrive\Projects\Python\GoogleKeep\gkeep_desktopper.pyw in line 16
14 keep = gkeepapi.Keep()
15 # success = keep.login('user@gmail.com', 'password')
---> 16 success = keep.login(login1, pw1)
20 note = keep.createNote('Todo', 'Eat breakfast')
21 note.pinned = True

File ~\AppData\Roaming\Python\Python311\site-packages\gkeepapi_init_.py:699, in Keep.login(self, email, password, state, sync, device_id)
697 ret = auth.login(email, password, device_id)
698 if ret:
--> 699 self.load(auth, state, sync)
701 return ret

File ~\AppData\Roaming\Python\Python311\site-packages\gkeepapi_init_.py:749, in Keep.load(self, auth, state, sync)
747 self.restore(state)
748 if sync:
--> 749 self.sync(True)

File ~\AppData\Roaming\Python\Python311\site-packages\gkeepapi_init_.py:1024, in Keep.sync(self, resync)
1021 self._clear()
1023 # self._sync_reminders(resync)
-> 1024 self._sync_notes(resync)
1026 if _node.DEBUG:
1027 self._clean()

File ~\AppData\Roaming\Python\Python311\site-packages\gkeepapi_init_.py:1074, in Keep._sync_notes(self, resync)
1072 # Hydrate notes and any children.
1073 if "nodes" in changes:
-> 1074 self._parseNodes(changes["nodes"])
1076 self._keep_version = changes["toVersion"]
1077 logger.debug("Finishing sync: %s", self._keep_version)

File ~\AppData\Roaming\Python\Python311\site-packages\gkeepapi_init_.py:1110, in Keep._parseNodes(self, raw)
1106 deleted_nodes.append(node)
1108 else:
1109 # Otherwise, this is a new node. Attempt to hydrate it.
-> 1110 node = _node.from_json(raw_node)
1111 if node is None:
1112 logger.debug("Discarded unknown node")

File ~\AppData\Roaming\Python\Python311\site-packages\gkeepapi\node.py:1930, in from_json(raw)
1928 return None
1929 node = ncls()
-> 1930 node.load(raw)
1932 return node

File ~\AppData\Roaming\Python\Python311\site-packages\gkeepapi\node.py:214, in Element.load(self, raw)
206 """Unserialize from raw representation. (Wrapper)
207
208 Args:
(...)
211 ParseException: If there was an error parsing data.
212 """
213 try:
--> 214 self._load(raw)
215 except (KeyError, ValueError) as e:
216 raise_from(exception.ParseException('Parse error in %s' % (type(self)), raw), e)

File ~\AppData\Roaming\Python\Python311\site-packages\gkeepapi\node.py:1191, in TopLevelNode._load(self, raw)
1190 def _load(self, raw):
-> 1191 super(TopLevelNode, self)._load(raw)
1192 self._color = ColorValue(raw['color']) if 'color' in raw else ColorValue.White
1193 self._archived = raw['isArchived'] if 'isArchived' in raw else False

File ~\AppData\Roaming\Python\Python311\site-packages\gkeepapi\node.py:1046, in Node._load(self, raw)
1044 self.timestamps.load(raw['timestamps'])
1045 self.settings.load(raw['nodeSettings'])
-> 1046 self.annotations.load(raw['annotationsGroup'])

File ~\AppData\Roaming\Python\Python311\site-packages\gkeepapi\node.py:214, in Element.load(self, raw)
206 """Unserialize from raw representation. (Wrapper)
207
208 Args:
(...)
211 ParseException: If there was an error parsing data.
212 """
213 try:
--> 214 self._load(raw)
215 except (KeyError, ValueError) as e:
216 raise_from(exception.ParseException('Parse error in %s' % (type(self)), raw), e)

File ~\AppData\Roaming\Python\Python311\site-packages\gkeepapi\node.py:524, in NodeAnnotations._load(self, raw)
521 return
523 for raw_annotation in raw['annotations']:
--> 524 annotation = self.from_json(raw_annotation)
525 self._annotations[annotation.id] = annotation

File ~\AppData\Roaming\Python\Python311\site-packages\gkeepapi\node.py:505, in NodeAnnotations.from_json(cls, raw)
503 return None
504 annotation = bcls()
--> 505 annotation.load(raw)
507 return annotation

File ~\AppData\Roaming\Python\Python311\site-packages\gkeepapi\node.py:214, in Element.load(self, raw)
206 """Unserialize from raw representation. (Wrapper)
207
208 Args:
(...)
211 ParseException: If there was an error parsing data.
212 """
213 try:
--> 214 self._load(raw)
215 except (KeyError, ValueError) as e:
216 raise_from(exception.ParseException('Parse error in %s' % (type(self)), raw), e)

File ~\AppData\Roaming\Python\Python311\site-packages\gkeepapi\node.py:450, in Context._load(self, raw)
448 self._entries = {}
449 for key, entry in raw.get('context', {}).items():
--> 450 self._entries[key] = NodeAnnotations.from_json({key: entry})

File ~\AppData\Roaming\Python\Python311\site-packages\gkeepapi\node.py:505, in NodeAnnotations.from_json(cls, raw)
503 return None
504 annotation = bcls()
--> 505 annotation.load(raw)
507 return annotation

File ~\AppData\Roaming\Python\Python311\site-packages\gkeepapi\node.py:216, in Element.load(self, raw)
214 self._load(raw)
215 except (KeyError, ValueError) as e:
--> 216 raise_from(exception.ParseException('Parse error in %s' % (type(self)), raw), e)

File ~\AppData\Roaming\Python\Python311\site-packages\future\utils_init_.py:406, in raise_from(exc, cause)
404 myglobals['__python_future_raise_from_cause'] = cause
405 execstr = "raise __python_future_raise_from_exc from __python_future_raise_from_cause"
--> 406 exec(execstr, myglobals, mylocals)

File :1

ParseException: Parse error in <class 'gkeepapi.node.WebLink'>

I hit this recently too. Are you using the latest version? 0.15.1.

Yeah, so if this is the same thing that I was looking at, the issue is how this code is attempting to load weblinks.

Basically if it identifies a WebLink in the note, it assumes that there must be a title and description. Those values don't necessarily always exist anymore. The case is that now looks like google is adding a source in certain cases that looks something like "migrated by google assistant" or something like that in google keep. This source is being interpreted as a weblink. These objects do not have the expected title and descriptions, and so are throwing a parse exception all the way out. I was able to sidestep this by removing that source from all my notes. But a fix is a little larger than I have time for to PR the code base.

Hope this helps anyone that runs into this.

commented

Should've been resolved as of 0.15.1 (#153) - are you running the latest version?

To elaborate on @TheGreatestAlan's comment (and perhaps this belongs in a separate issue)

A number of my Google Keep notes recently had a "Moved from Google Assistant" tag on them. Logging into Keep and Manually deleting these fixed gkeepapi 0.14.2 for me.

Should've been resolved as of 0.15.1 (#153) - are you running the latest version?

Yes, still not working!

commented
 --> 291 self._title = raw['webLink']['title']

This code from the stack trace no longer exists on 0.15.1

DOn;t understand what is to be done. Please can you update the version and let me know. Thanks.

Plz can someone revert !

Plz can someone revert on this!

commented

@github-of-wone The issue is fixed in the newest version of the library (0.15.1). Your stack trace indicates you are not running the latest version, so upgrading will resolve the issue for you.

@kiwiz thanks for the above but

---------------------------------------------------------------------------
LoginException                            Traceback (most recent call last)
Cell In[61], [line 4](vscode-notebook-cell:?execution_count=61&line=4)
      [1](vscode-notebook-cell:?execution_count=61&line=1) # %%
      [2](vscode-notebook-cell:?execution_count=61&line=2) from loginpw import login1, pw1
----> [4](vscode-notebook-cell:?execution_count=61&line=4) keep.login(
      [5](vscode-notebook-cell:?execution_count=61&line=5)     login1, pw1
      [6](vscode-notebook-cell:?execution_count=61&line=6) )  # , "xyz")  
      [8](vscode-notebook-cell:?execution_count=61&line=8) gnotes = keep.all()

File [c:\pi\python312\Lib\site-packages\gkeepapi\__init__.py:703](file:///C:/pi/python312/Lib/site-packages/gkeepapi/__init__.py:703), in Keep.login(self, email, password, state, sync, device_id)
    [700](file:///c%3A/pi/python312/Lib/site-packages/gkeepapi/__init__.py?line=699) if device_id is None:
    [701](file:///c%3A/pi/python312/Lib/site-packages/gkeepapi/__init__.py?line=700)     device_id = f"{get_mac():x}"
--> [703](file:///c%3A/pi/python312/Lib/site-packages/gkeepapi/__init__.py?line=702) auth.login(email, password, device_id)
    [704](file:///c%3A/pi/python312/Lib/site-packages/gkeepapi/__init__.py?line=703) self.load(auth, state, sync)

File [c:\pi\python312\Lib\site-packages\gkeepapi\__init__.py:58](file:///C:/pi/python312/Lib/site-packages/gkeepapi/__init__.py:58), in APIAuth.login(self, email, password, device_id)
     [56](file:///c%3A/pi/python312/Lib/site-packages/gkeepapi/__init__.py?line=55) # Bail if no token was returned.
     [57](file:///c%3A/pi/python312/Lib/site-packages/gkeepapi/__init__.py?line=56) if "Token" not in res:
---> [58](file:///c%3A/pi/python312/Lib/site-packages/gkeepapi/__init__.py?line=57)     raise exception.LoginException(res.get("Error"), res.get("ErrorDetail"))
     [60](file:///c%3A/pi/python312/Lib/site-packages/gkeepapi/__init__.py?line=59) self._master_token = res["Token"]
     [62](file:///c%3A/pi/python312/Lib/site-packages/gkeepapi/__init__.py?line=61) # Obtain an OAuth token.

LoginException: ('BadAuthentication', None)

:-(

@kiwiz yup that should do it. Your changes are similar to the ones I made. I've updated my version, but don't really have a way to test it because I don't know how to create a note that google assistant migrated.

Thanks for the work again

@kiwiz What actually changed here - all of the backward compatible libraries have this error now. Was this a Google change?
For example, to get past the auth errors before I have Docker Debian images running older versions 0.14.2 that were working on Python 3.9. Now it seems those are all broken unless I upgrade Python on Debian to 3.10+ and gkeepapi to 0.15.1?

commented

See this issue for details: simon-weber/gpsoauth#48

An alternative mechanism for authenticating has been merged into gpsoauth (per #137). Once a new release is made, I can bump the dependency in gkeepapi.

commented

Closing this in favor of #81