kiwiz/gkeepapi

gkeepapi.exception.LoginException: ('BadAuthentication', None)

WiliTest opened this issue ยท 93 comments

I tried to run this code , it gives me the error above.

I tried with the Gmail login and password, then with my email login and an "app password" following these step:

  1. Enable 2-step authentication in your Google settings.
  2. Create an app password here: https://myaccount.google.com/apppasswords
  3. Choose for the app other, I named it gkeepapi and I generated a password.
  4. I user the generated password in the scrip instead of my Google password.

I get the very same error, I am trying to login with my email address and password. Less secure apps are enables in my google settings.

Is there any solution for this?

File "/usr/local/lib/python3.7/site-packages/gkeepapi/init.py", line 693, in login
ret = auth.login(username, password, get_mac())
File "/usr/local/lib/python3.7/site-packages/gkeepapi/init.py", line 60, in login
res.get('Error'), res.get('ErrorDetail')
gkeepapi.exception.LoginException: ('BadAuthentication', None)

alils commented

I'm getting the same error with both account password without 2fa and app password with 2fa. Please help anyone??

I tried to modify script and get oauth token by "legal" ways of oauth2, but to use that token for API, that particular API must be enabled for your account account, and as Google Keep API is not supported officially, there is no way to enable it for the token.

Here is the error I'm getting while using oauth2

gkeepapi.exception.APIException: {'errors': [{'domain': 'usageLimits', 'reason': 'accessNotConfigured', 'message': 'Access Not Configured. Reminders API has not been used in project 1052062629689 before or it is disabled. Enable it by visiting https://console.developers.google.com/apis/api/reminders.googleapis.com/overview?project=1052062629689 then retry. If you enabled this API recently, wait a few minutes for the action to propagate to our systems and retry.', 'extendedHelp': 'https://console.developers.google.com/apis/api/reminders.googleapis.com/overview?project=1052062629689'}], 'code': 403, 'message': 'Access Not Configured. Reminders API has not been used in project 1052062629689 before or it is disabled. Enable it by visiting https://console.developers.google.com/apis/api/reminders.googleapis.com/overview?project=1052062629689 then retry. If you enabled this API recently, wait a few minutes for the action to propagate to our systems and retry.'}

alils commented

I'm getting the same error with both account password without 2fa and app password with 2fa. Please help anyone??

I tried to modify script and get oauth token by "legal" ways of oauth2, but to use that token for API, that particular API must be enabled for your account account, and as Google Keep API is not supported officially, there is no way to enable it for the token.

Here is the error I'm getting while using oauth2

gkeepapi.exception.APIException: {'errors': [{'domain': 'usageLimits', 'reason': 'accessNotConfigured', 'message': 'Access Not Configured. Reminders API has not been used in project 1052062629689 before or it is disabled. Enable it by visiting https://console.developers.google.com/apis/api/reminders.googleapis.com/overview?project=1052062629689 then retry. If you enabled this API recently, wait a few minutes for the action to propagate to our systems and retry.', 'extendedHelp': 'https://console.developers.google.com/apis/api/reminders.googleapis.com/overview?project=1052062629689'}], 'code': 403, 'message': 'Access Not Configured. Reminders API has not been used in project 1052062629689 before or it is disabled. Enable it by visiting https://console.developers.google.com/apis/api/reminders.googleapis.com/overview?project=1052062629689 then retry. If you enabled this API recently, wait a few minutes for the action to propagate to our systems and retry.'}

Here is the script I used to get API token (if anyone needs it)


import os
from google_auth_oauthlib.flow import InstalledAppFlow

CLIENT_SECRETS_FILE = "secrets.json"
SCOPES = ['https://www.googleapis.com/auth/memento', 'https://www.googleapis.com/auth/reminders']

if __name__ == '__main__':
    os.environ['OAUTHLIB_INSECURE_TRANSPORT'] = '1'
    flow = InstalledAppFlow.from_client_secrets_file(CLIENT_SECRETS_FILE, SCOPES)
    credentials = flow.run_console()
    print(flow.credentials.token)


@kiwiz gkeepapi has been working pretty fine for the last 3,4 weeks and now suddenly I got this error! Could anyone please suggest a fix for this, because my app really depends on gkeepapi, and without this working, its really affecting me!

I've been getting the same issue. does this mean a google keep api is coming?

try using python3.7.7

also getting this, just now addressing it. last successful login was April 9. I've tried regenerating the app password, and also clean installing latest version on a different system. running python 3.5.3 on a pi3 for one install and 3.5.2 on an Xenial pine64 for the other. is 3.7 really the solution for this? doesn't seem like it should matter.

@wilsonmfg - see issue #86 to fix this.

I'm using python 3, and it's a new clean install. I'm not sure how that "fix" applies

@wilsonmfg - hmmmm.....I had the same issue. So what I did was upgrade my Anaconda install to Python 3.7.7 and also updated this library to the latest version (pip install --upgrade gkeepapi) and that fixed the issue.

which goes back to my question, is 3.7 actually needed or just 3.x? 3.7 is not an easy fix on a Pi.

agreed! seems the python version shouldn't make any difference. @kiwiz - any thoughts here?

@wilsonmfg - hmmmm.....I had the same issue. So what I did was upgrade my Anaconda install to Python 3.7.7 and also updated this library to the latest version (pip install --upgrade gkeepapi) and that fixed the issue.

This solved it for me, i used pyenv to manage the python versions and made sure the latest version of python was being used (3.8.5). https://opensource.com/article/19/5/python-3-default-macac was helpful - see the 'what we should do section in particular'

that link doesn't work.

No luck here either.

kiwiz commented

Try testing on another system/another account to see if you can isolate the cause of the issues. As for why Py3 is being suggested, see #69 for more details.

I did. #81 (comment)

#69 doesn't answer why python 3.7 would work any better than 3.5

kiwiz commented

@wilsonmfg One potential cause for these issues is described here. Updating to a newer version of Python might change your TLS fingerprint enough to get through the check.

Additionally, try checking out the FAQ for other suggestions to maintain access.

Installing a new python 3.7 env did solve it for me.

This didn't work for me with either 3.7.7, 3.9.0, 3.6.12

pyenv install x.x.x
pyenv shell x.x.x
pip install --upgrade gkeepapi

@givanse - when you did your tests - were you logged into your Google account on your default browser? And, did you try using the step to UnlockCaptcha manually link at all after you first authenticated? I tried a fresh Debian install recently and it worked fine.

  • On my default browser, I am logged in with two different Google accounts.
  • I did follow the UnlockCaptcha link manually and I'm pretty sure I did it with the right account.

Hadn't thought about the potential for issues if more than one account is logged in, I'll check on that, thanks.

Got the same issue here... running on python 3.9, followed all instructions in the FAQ. Anything new?

EDIT: It doesn't work on macOS, but it does on linux (on python 3.8.6). Hope this can help.

Has anyone found a solution? Also does not work

Logger: homeassistant.components.sensor
Source: custom_components/google_keep/sensor.py:39
Integration: ื—ื™ื™ืฉืŸ (documentation, issues)
First occurred: 3:02:30 (1 occurrences)
Last logged: 3:02:30

Error while setting up google_keep platform for sensor
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/helpers/entity_platform.py", line 199, in _async_setup_platform
    await asyncio.shield(task)
  File "/usr/local/lib/python3.8/concurrent/futures/thread.py", line 57, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/config/custom_components/google_keep/sensor.py", line 39, in setup_platform
    login_success = keep.login(username, password)
  File "/usr/local/lib/python3.8/site-packages/gkeepapi/__init__.py", line 693, in login
    ret = auth.login(username, password, get_mac())
  File "/usr/local/lib/python3.8/site-packages/gkeepapi/__init__.py", line 59, in login
    raise exception.LoginException(
gkeepapi.exception.LoginException: ('BadAuthentication', None)```

Mines intermittent, every 4 in 5 reboots of Home Assistant nets this error, however it does still work if I keep rebooting it enough. When it does succeed, it works completely fine. I've tried using 0.13.1 and it doesn't appeared to have made it any better.

Having the same issue (using HA. Started seeing after upgrading to 0.118).
Tried running a python (Python 3.8.6) snippet to test:

import gkeepapi
keep = gkeepapi.Keep()
success = keep.login('foo@gmail.com', 'barbarbarbar')

Using 2FA; I even created a new app password for testing reasons; Tried the Unlock Captcha idea - doesn't work:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python3.8/site-packages/gkeepapi/__init__.py", line 693, in login
    ret = auth.login(username, password, get_mac())
  File "/usr/local/lib/python3.8/site-packages/gkeepapi/__init__.py", line 59, in login
    raise exception.LoginException(
gkeepapi.exception.LoginException: ('BadAuthentication', None)

Shooting in the dark, as I'm not a python developer. Could there be an issue with the get_mac() function?

>>> get_mac()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'get_mac' is not defined
kiwiz commented

@callifo If you get a valid session, you should consider caching it to reduce the chance of issues with authenticating: https://gkeepapi.readthedocs.io/en/latest/#logging-in

@maximunited The get_mac method is pulled from the uuid module. If you want to try providing an alternate value, I've exposed that in v0.13.2. To generate a device_id, try the following:

  • 'ios:' + str(uuid.uuid4())
  • os.urandom(8).hex()

Then call the login method: keep.login(user, password, device_id).

If the device_id works, you should save it and pass it every time (in other words, don't generate a new id each time you log in).

I was playing around with the gkeepapi version used by this component, and moved to 0.13.1 instead of the 0.11.x version in the latest release, and it was happening less often.

Then a few days ago, mine actually stopped with the Bad Auth messages completely. Between when I was testing 0.13.1 and now, I've changed absolutely nothing...

Edit: Nope, back again within a week.

Ok, just hit a snag @kiwiz . I was running python 3.7.7 and gkeepapi 0.11.8 successfully for the last 6 months on Windows 10. Updated to python 3.7.9 and gkeepapi 0.13.3 and I cannot log in. Tried turning off 2FA and using the captcha link. Also, tried a different account and different IP - no luck. On my Debian 10 instance I have python 3.7.3 and gkeepapi 0.13.1 and it works without any issues first time. Tried reinstalling fresh version on Windows of Python 3.7.9 and 3.8.6 with gkeepapi 0.11.x and 0.13.x with no luck.

As I think through this - wondering what is unique about Linux vs Windows. What might be blocking Windows authentication?

PS - just tried it on a Mac Catalina 10.15.7 running python 3.7.3 and gkeepapi 0.13.1 - worked first time without doing anything.
And, tried reinstall of 3.7.3 and 0.13.1 on Windows - still no luck

PSS - updated Mac to python 3.7.9 and gkeepapi 0.13.3 and it worked fine. Still can't get Windows to authenticate - still errs to gkeepapi.exception.LoginException: ('BadAuthentication', None)

Other things I've tried on Windows 10:

  1. Used a VPN to different location and different Google accounts
  2. Turned off all firewall/security
  3. Three different versions of Python and gkeepapi
  4. Connected through hotspot 5G connection (different IP)
  5. Used a different Windows 10 pc - fresh python install and gkeepapi
  6. Changed my Google password
  7. Moved the test script to a new directory, renamed it and new virtual env
  8. Turned on "less safe" app access to my account in Google Security

All failed - what's really odd is how fast the BadAuthentication comes back so quickly. Feels like I'm being blocked on the edge. My Linux VM is on the same PC which works.

kiwiz commented

@djsudduth Does it work if you copy a working master token from one of the working systems to the Windows one?

Try using the Keep.resume() method like so:

keep.resume("user@email.com", "master_token")

@kiwiz - interesting idea! I will try it. In the mean time I was digging into gpsoauth to see if there might be something going on with Windows there.

@kiwiz Keep.resume() worked! What does that tell you? It seems to make sense if the token is common.

When i run the app in my pc works fine but when i try to deploy it to Heroku gkeepapi.exception.LoginException: ('BadAuthentication', None)

kiwiz commented

@djsudduth My best guess is that it's related to this. If you're the mood to debug, it might be interesting to record PCAPs of the TLS traffic on Windows vs Linux to see what the differences are.

It might be easiest to just copy over the master token instead of getting authentication to work. Note that the master token has full access to your account - you should take care when storing it.

@julianfere the above might work for you too.

@kiwiz thanks - I might just do that. What nags at me however, is that it was working on this Windows PC before when it was using Python 3.7.3 and gkeepapi 0.11.8 and only stopped when I updated to 3.7.9 and 0.13.3. Now, I was using Anaconda which updated a lot of Python packages as well. How that relates to TLS is odd to me since all 3 of my Windows 10 PCs in the house all fail with different versions of Python and gkeepapi (and different VPN IPs).

Makes me want to try installing Anaconda again in the same way. As for PCAPs - might try it but that's a lot of work.

Was looking at something else about Python and found this (not sure it means anything) - but I was using 3.7.3 when Windows was working:
"Python uses OpenSSL as its TLS implementation. Python v3.7.4 and later use OpenSSL v1.1.1. Python v3.7.0 to v3.7.3 use OpenSSL v1.1.0. Earlier versions of Python use OpenSSL v1.0.2. On Windows and macOS the standard Python binary installers include copies of the corresponding OpenSSL libraries."

@kiwiz - here's what I tried tonight: went back and installed Anaconda 2019.07 which was what I had when it worked (python 3.7.3) - then installed gkeepapi 0.11.7. The only packages installed for gkeepapi were:
gpsoauth 0.4.1
pycryptodomex 3.9.4

all other requirements were satisfied by Anaconda:
six 1.12.0
future 0.17.1
requests 2.22.0
certifi 2019.6.16
chardet 3.0.4
urllib3 1.24.2
idna 2.8

It definitely acted different but failed with - feels like I missed something - JSON errors??:
File "keep-test.py", line 21, in keep_login
keepapi.login(userid, pw)
File "C:\ProgramData\Anaconda3\lib\site-packages\gkeepapi_init_.py", line 549, in login
self.load(auth, state, sync)
File "C:\ProgramData\Anaconda3\lib\site-packages\gkeepapi_init_.py", line 595, in load
self.sync(True)
File "C:\ProgramData\Anaconda3\lib\site-packages\gkeepapi_init_.py", line 850, in sync
changes = self.reminders_api.list()
File "C:\ProgramData\Anaconda3\lib\site-packages\gkeepapi_init
.py", line 458, in list
json=params
File "C:\ProgramData\Anaconda3\lib\site-packages\gkeepapi_init_.py", line 220, in send
response = self.send(**req_kwargs).json()
File "C:\ProgramData\Anaconda3\lib\site-packages\requests\models.py", line 897, in json
return complexjson.loads(self.text, **kwargs)
File "C:\ProgramData\Anaconda3\lib\json_init
.py", line 348, in loads
return _default_decoder.decode(s)
File "C:\ProgramData\Anaconda3\lib\json\decoder.py", line 337, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "C:\ProgramData\Anaconda3\lib\json\decoder.py", line 355, in raw_decode
raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

kiwiz commented

@djsudduth Hmm, can you edit the line at C:\ProgramData\Anaconda3\lib\site-packages\gkeepapi\_init_.py to print out the results of the send() call like so print(self.send(**req_kwargs)) and report the output? If there are any IDs or tokens, please replace them with placeholder values.

Do you need to do anything in the google account settings to authorise the connexion through this api?

What is this master token being discussed? Can I get one if, for example, my browser is logged in to Keep?

kiwiz commented

See gpsoauth for details. tl;dr it's the flow that Google Play Services uses to authenticate with Google.

@simon-weber suggests pinning requests to version 2.23.0 over on the gpsoauth issue for the same error. This resolved the issue for me.
simon-weber/gpsoauth#24

@JamesGlover @kiwiz - went to one of my Windows test machines and downgraded requests to 2.23.0 - that did work for me as well! Also, just tried it on my development Windows PC and it worked there.

kiwiz commented

@JamesGlover good find! I've bumped the version and pinned requests to 2.23.0 (only on Windows).

kiwiz commented

Looking at issues on other repos, it seems like people on OSX and Linux might be affected by the same issue too. If someone has time, I'd be curious how a request generated by 2.23.0 differs from a more recent version.

kiwiz commented

Super hacky alternative fix:

# Put this at the top of your code (before any imports)
import ssl
del ssl.HAS_SNI

@kiwiz I've had no issues with both Linux and OSX with the later releases. For Windows, if I had a standard Python install - my 2 test cases works with 2.23.0. However, on a 3rd Windows test case using Anaconda trying to revert to 2.23.0 didn't work even though all libraries including chardet and urllib3 reverted. I also tried the super hacky alternative and that didn't work either.

Any thoughts on why removing the SNI (Server Name Indication) flag from TLS fixes this?? Reading the RFC - is there a client/server name conflict here???

"If there is a mismatch between the server name used
by the client application and the server name of the credential
chosen by the server, this mismatch will become apparent when the
client application performs the server endpoint identification, at
which point the client application will have to decide whether to
proceed with the communication. TLS implementations are encouraged
to make information available to application callers about warning-
level alerts that were received or sent during a TLS handshake. Such
information can be useful for diagnostic purposes."

kiwiz commented

It seems that versions of requests after 2.23.0 default to ssl instead of pyopenssl. By unsetting HAS_SNI, the code should fall back to pyopenssl.

It sounds like it might be a separate issue with that Windows test box. ๐Ÿค”

Yeah, I think so too. I'm going to reinstall Anaconda on a box and try it. What's odd about ssl vs pyopenssl is that Mac and Linux work fine. Wondering what's in the Windows 10 OS that is causing the issue for the ssl lib?

It seems that versions of requests after 2.23.0 default to ssl instead of pyopenssl. By unsetting HAS_SNI, the code should fall back to pyopenssl.

It sounds like it might be a separate issue with that Windows test box.

@kiwiz So this has nothing to do with problems we are having on Linux?

I encountered the same issue on Linux - pinning requests with pip install requests==2.23.0 as described in simon-weber/gpsoauth#24 fixed things for me

I'm seeing this on Fedora 32 (python 3.8.6, python-requests 2.22.0). Also happens in Fedora 33 and 34 containers. Forcing requests==2.23.0 doesn't seem to help.

macOS Catalina, Python 3.8.6, downgrading requests to 2.23.0 fixed the issue for me!
Thank you @kiwiz and everyone for debugging.

Also confirmed. macOS, Python 3.9.0, installing ndbeals/keep-exporter using pipx:

pipx install keep-exporter 
pipx inject keep-exporter requests===2.23.0

Without the second line, I was having authentication issues.

The second line fixed my login issues, and I was then able to run and export my notes using a Google app password.

Multiple times I started to use this python module again and again.
This time it finally worked.
I have a Mac and I have 2-Step-Verification activated for my google account.
So the following things worked for me to get notes out of it:

  1. Generating an app password in your Google Account (https://support.google.com/accounts/answer/185833?hl=en)
  2. Updating to the latest python3 version (as I am writing this comment this is 3.9.1, I used homebrew for that, brew install python3 or brew upgrade python3, in case python3 is not used as the default python3 on your mac execute brew link python3 and reopen the terminal)
  3. Creating a python3 virtual environment (python3 -m venv gkeep-venv)
  4. Activating the virtual environment (source /path/to/venv/bin/activate so if you are in the directory where you created the virtual environment like above it would be source gkeep-venv/bin/activate)
  5. Install the gkeep library pip install gkeepapi
  6. Pin the older requests library for the virtual environment only pip install requests==2.23.0
  7. Create a file (example.py) with the example code below for listing a note with a label
  8. python3 example.py

Example code:

import gkeepapi

gkeepapi.node.DEBUG = True
keep = gkeepapi.Keep()
keep.login('something@googlemail.com', '<your generated app password from google>')

gnotes = keep.find(labels=[keep.findLabel('PHP')])

print(next(gnotes))

So I think finally important was pinning the requests library and updating to the latest python3 version.

I hope this helps.

I was on python 3.6.1 and I also got the gkeepapi.exception.LoginException: ('BadAuthentication', None) error.
I tried using the solution with from google_auth_oauthlib.flow import InstalledAppFlow from alils but it didn't work.
I was able to make it work by:

  • updating to the latest python (currently 3.9.5): it can be done easily along side your current python version, without interfering with your current setup (see here for how to)
  • activating the 2 step authentification and creating an app password which I use in  success = keep.login('...@gmail.com', 'APP password HERE')

I never was able to successfully get past this login issue. I even got myself locked out of a Google account. Instead, I took a different approach. I used WebdriverIO to open Chrome and scrape the content from all of my Google Keep notes directly from the browser. If anyone is interested in this, you can find it here: https://github.com/jamesmortensen/archiver-for-google-keep. It has its own challenges that are going to be different from using the API. I haven't yet tried it on a CI server like GitHub Actions, but eventually, I'd like to find a way to automate backups. This largely depends on whether or not I can copy a user-data-dir from one machine to another and not have Google force re-authentication.

@kiwiz thanks for investing your time in creating the unofficial gkeepapi and inspiring me to try a different approach.

New user here so is there any way to get past the login error as of today?

Hi all!

Don't know if this helps, but if I run the code locally with app password used instead of using my personal password - it works.
If I run the same code in a Docker container - it fails with a BadRequest.
I suspect, it might have something to do with a device from which the call is made, but I haven't investigated further.

Still looking for a solution on Mac OS Ventura. Tried everything mentioned before and still having

('BadAuthentication', None)```

Also on Mac Ventura, but I'm not getting the "None," just getting

Username or password is incorrect (LoginException('BadAuthentication'))
Could not excute KIM

Multiple times I started to use this python module again and again. This time it finally worked. I have a Mac and I have 2-Step-Verification activated for my google account. So the following things worked for me to get notes out of it:

  1. Generating an app password in your Google Account (https://support.google.com/accounts/answer/185833?hl=en)
  2. Updating to the latest python3 version (as I am writing this comment this is 3.9.1, I used homebrew for that, brew install python3 or brew upgrade python3, in case python3 is not used as the default python3 on your mac execute brew link python3 and reopen the terminal)
  3. Creating a python3 virtual environment (python3 -m venv gkeep-venv)
  4. Activating the virtual environment (source /path/to/venv/bin/activate so if you are in the directory where you created the virtual environment like above it would be source gkeep-venv/bin/activate)
  5. Install the gkeep library pip install gkeepapi
  6. Pin the older requests library for the virtual environment only pip install requests==2.23.0
  7. Create a file (example.py) with the example code below for listing a note with a label
  8. python3 example.py

Example code:

import gkeepapi

gkeepapi.node.DEBUG = True
keep = gkeepapi.Keep()
keep.login('something@googlemail.com', '<your generated app password from google>')

gnotes = keep.find(labels=[keep.findLabel('PHP')])

print(next(gnotes))

So I think finally important was pinning the requests library and updating to the latest python3 version.

I hope this helps.

This works. tried python 3.10.9 and python 3.7, only with python 3.9.1 did it work

Python 3.9 didn't work for me on Windows (Cygwin).

I did get gkeepapi working with Python 3.8 on Ubuntu. I created a fresh DigitalOcean Droplet running Ubuntu 20.04 and then ran

apt-get update
apt-get install python3.8 python3-pip
pip3 install gkeepapi
pip3 install requests==2.23.0

I used an app password as described above.

doesn't work on Ubuntu 22.04
tried all Python version from 3.8, 3.9, 3.10
maybe it's related to the ssl version

see
simon-weber/gpsoauth#48

and if someone know how to change the ssl version from 3 to 1, without uninstalling ssl3 please explain

Mac Ventura
Python 3.9.6
App password
gkeepapi.exception.LoginException: ('BadAuthentication', None)

The easiest workaround while this gets solved is use a docker image with right versions, mine could be found here: https://hub.docker.com/r/rcdeoliveira/gkeepapi

As @engdorm mentions, the issue shows up with openssl3, but not with openssl1.

I also wrote a Dockerfile like @rcdeoliveira, but instead of running my whole application within the Docker image, I just delegated the login process.

See Dockerfile here: simon-weber/gpsoauth#48 (comment)

ilesm commented

I've been unable to get around this problem on OS X (OS X 13.5.1, Python 3.11.5, gkeepapi 0.14.2, gpsoauth 1.0.2, requests 2.31.0, Google 2FA with app password). Downgrading requests to 2.23.0 or downgrading Python doesn't help.

I'm successfully able to use rcdeoliveira's image (above) though.

Has anyone been able to solve this problem on Windows using python 3.10.x or 3.11.x (not using the Docker image)? I was able to get it to work on 3.9.1 by pinning urllib3==1.25.11 and gpsoauth==1.0.2.

I'm wondering what it was about the 3.10 changes to SSL that started causing this issue on Windows (or just generally). Feels definitely like a combo OS and Python version issue.

Here's how I solved it for now for Windows 10 with Python >= 3.10.x without Docker. I used v3.9.1 to save the key in keyring and then reverted back to 3.10/3.11:

  1. Already had default system install of Python 3.11.6 and then executed pip install gkeepapi keyring
  2. Installed pyenv-win and then installed Python 3.9.1 -> pyenv install 3.9.1
  3. Set the version with pyenv global 3.9.1
  4. pip install gkeepapi keyring
    a) pinned urllib3==1.25.11 and gpsoauth==1.0.2 as noted above
  5. Ran my python test app with the Google app pw that saves the token to the keyring
  6. Uninstalled pyenv

Now all works in Python 3.10.x and 3.11.x when my app loads the token from keyring

(You could, of course, just use pyenv for multiple versions without all this rigamarole!) :)

Here's how I solved it for now for Windows 10 with Python >= 3.10.x without Docker. I used v3.9.1 to save the key in keyring and then reverted back to 3.10/3.11:

  1. Already had default system install of Python 3.11.6 and then executed pip install gkeepapi keyring
  2. Installed pyenv-win and then installed Python 3.9.1 -> pyenv install 3.9.1
  3. Set the version with pyenv global 3.9.1
  4. pip install gkeepapi keyring
    a) pinned urllib3==1.25.11 and gpsoauth==1.0.2 as noted above
  5. Ran my python test app with the Google app pw that saves the token to the keyring
  6. Uninstalled pyenv

Now all works in Python 3.10.x and 3.11.x when my app loads the token from keyring

(You could, of course, just use pyenv for multiple versions without all this rigamarole!) :)

Any chance you could expand on the keyring portion of this a bit? I am new to this authentication stuff, but it seems like it is just storing my password. Is there a credential/login token you are saving to keyring as well? I seem to have it semi-working but it will not log me in once I swap back to 3.11

Thank you!

@wilsxt - when you login with gkeepapi via Python 3.9 with the Google App pw, Keep returns a long token key. That is the value you want to save in the keystore via keyring. Then, retrieve that to login with 3.10+ versions. You only need the token and no pw from that point on.

A sample implementation for storing the master token can be found here.

I have a pending PR (simon-weber/gpsoauth#41) that I can update with (#137) in a couple of days.

@kiwiz - now caught in an unsuccessful loop. Authentication was working on python 3.9.x with the pinned gpsoauth and urllib3 packages. But, with your recent 0.15.1 change - gkeepapi doesn't run on python 3.9.x anymore. You can't get a token with python 3.10+ and the Google app pw - it just won't work (tried multiple debian and ubuntu images). So we're stuck now. Is there any way you can make 0.15.1 compatible with python 3.9 (is seems you're using the new python "|" that won't work on 3.9).

@djsudduth Given the persistent issues people have been experiencing with user/pass authentication, I'd like to deprecate it in favor of using keep.resume() (which requires passing in a master token). I'm still waiting on a release of gpsoauth, but in the meantime you could use something like the following:

sudo docker run --rm -it --entrypoint /bin/sh python:3 -c 'pip install git+https://github.com/simon-weber/gpsoauth.git@8a5212481f80312e06ba6e0a29fbcfca1f210fd1; python3 -c '\''print(__import__("gpsoauth").exchange_token(input("Email: "), input("OAuth Token: "), input("Android ID: ")))'\'

Instructions:

  1. Visit https://accounts.google.com/EmbeddedSetup
  2. Authenticate and go thru the flow. It should stay on the loading spinner
  3. Obtain the value of the oauth_token cookie
  4. Run the command and fill in the requested info
  5. Extract the Token value

Any update here?

@kiwiz - got pretty far at this point - but the script you provided with Simon's package is asking for both an OAuth and an AndroidID - I got the OAuthID but which one is the AndroidID in the cookie?

Perhaps @rukins can answer this!

AndroidID can be whatever. You can make it MAC addressy if you want.

Yeah, right, it can be even empty.
Check this file, i described the api to obtain tokens here: https://github.com/rukins/gpsoauth-java/blob/master/server-endpoints.md

Thank you @rukins and @kiwiz - that worked. I really hope Google doesn't change it's auth again (or, finally moves the official Google Keep API for Workspace to public Keep users)

For others - here's the Docker image I created:
FROM ubuntu:22.04
RUN apt update
RUN apt install -y python-is-python3 python3-pip
RUN apt-get install -y git
RUN pip install git+https://github.com/simon-weber/gpsoauth.git@8a5212481f80312e06ba6e0a29fbcfca1f210fd1

Get an OAuth ID using @rukins "Second way" instructions: https://github.com/rukins/gpsoauth-java?tab=readme-ov-file - or log into your Google account via https://accounts.google.com/EmbeddedSetup and use the Chrome extension called "Cookie Tab Viewer" to retrieve the oauth_token

Log into the Docker image, paste this script, and run:
python -c 'print(__import__("gpsoauth").exchange_token(input("Email: "), input("OAuth Token: "), input("Android ID: ")))'

Enter your Google Email ID, the OAuth ID and any value for the Android ID (I used a fake Mac address)

The Keep Token will display at the top of the returned data array

Maybe its time to create A Dockerfile, for example with the content of @djsudduth, and add it to this repo or even dockerhub so not everyone has to create its own Dockerfile and find this issue.

What do you think about this?

@kiwiz - do you happen to know when gpsoauth commit 8a52124 will be packaged and in pypi? I'm assuming it will be in 1.0.5

How can I make gkeepapi work for the time being before the relevant releases are made for its pip module and for gpsauth?

I have read through much but not all of the above thread and it was not clear how to proceed despite the fact that it seems a partial solution has been arrived at.

I have tried both running pip install git+https://github.com/kiwiz/gkeepapi.git#egg=gkeepapi and pip install gpsoauth==1.0.2 neither of which have solved the issue I am encountering, which is that I receive the following error when using keep.login() with either my account password or an app password which I created after enabling 2fa on my account:

Traceback (most recent call last):
  File "/home/pimania/dev/manageTodoList/keep.py", line 25, in <module>
    notes_text = fetch_notes_text(email, password)
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/pimania/dev/manageTodoList/keep.py", line 7, in fetch_notes_text
    success = keep.login(email, password)
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/pimania/.local/lib/python3.12/site-packages/gkeepapi/__init__.py", line 703, in login
    auth.login(email, password, device_id)
  File "/home/pimania/.local/lib/python3.12/site-packages/gkeepapi/__init__.py", line 58, in login
    raise exception.LoginException(res.get("Error"), res.get("ErrorDetail"))
gkeepapi.exception.LoginException: ('BadAuthentication', None)

many thx! :)

@distbit0 try installing only the latest gpsoauth from github in a fresh python 3.10+ venv (pip install git+https://github.com/simon-weber/gpsoauth.git@8a5212481f80312e06ba6e0a29fbcfca1f210fd1) using the manual instructions (@rukins "Second way" instructions: https://github.com/rukins/gpsoauth-java?tab=readme-ov-file) to get the Keep token in my comment above. Then install gkeepapi and use that token with your code.

@distbit0 try installing only the latest gpsoauth from github in a fresh python 3.10+ venv (pip install git+https://github.com/simon-weber/gpsoauth.git@8a5212481f80312e06ba6e0a29fbcfca1f210fd1) using the manual instructions (@rukins "Second way" instructions: https://github.com/rukins/gpsoauth-java?tab=readme-ov-file) to get the Keep token in my comment above. Then install gkeepapi and use that token with your code.

Thanks that worked! Although only when I provided by google username (i.e. everything before @gmail.com) to the python command, and provided an empty string for android id.

However I am not sure how to actually "use that token with your code" given that the standard login function accepts a username and password rather than a master key. Would you mind elaborating on how to do this? many thx again :)

Ah nvm I figured it out by looking at: https://github.com/kiwiz/gkeepapi/blob/main/examples/resume.py

keep.resume(
        "<USERNAME>",
        "<master key>",
)

Ah nvm I figured it out by looking at: https://github.com/kiwiz/gkeepapi/blob/main/examples/resume.py

keep.resume(
        "<USERNAME>",
        "<master key>",
)

This works.
Does the master token have an expiration time, and if so, what is the time limit?

So far mine has lasted for several months without having to be updated @artur-pf. Seems to never expire

@kiwiz looks like gpsoauth 1.1.0 was released yesterday with the manual token exchange added - FYI!

https://github.com/simon-weber/gpsoauth/blob/master/CHANGELOG.md

I haven't tested it yet

I've released version 0.16.0, which deprecates Keep.login and encourages users to use the "alternative flow".

Closing this one out. If there are any new issues with authentication, please open an issue.