Google API Python Client Import Issue

I’m having some issues getting the google-api-python-client to work on Anki.

I installed the necessary packages with pip to a target folder inside the Anki Add-Ons Folder and added the dist Folder to the sys path like I do with any other third party package.

In the following example:
pip install -t . functional google-auth google-auth-httplib2 google-api-python-client --upgrade

It works fine for other packages I tested, but appears to break on googles even though it gets properly installed.

A minimal example would be this:

AddOnFolder/ looks like this:

import os
import sys

sys.path.insert(0, os.path.join(os.path.dirname(__file__), "dist"))

import functional
import google.oauth2

I only added the functional to show that other packages work fine from the same folder.

Now what puzzles me is that when I run the same as a standalone and not via anki, it works fine so I don’t believe it’s a missing dependency or path issue. Only when I let Anki run the main it fails with the error:
(Note that it accepts the functional import in the line above just fine).", line 7, in <module>
    import google.oauth2
ModuleNotFoundError: No module named 'google.oauth2'

I believe it is caused by the fact that the Anki Directory Anki/lib/ contains a folder called google and thus interferes with the import of the google package in dist/google/ since it’s used as a search path.

I thought adding the dist/ path at the front of the sys.path would solve it (since python checks in the directories in sequential order), but it doesn’t.

Renaming the dist/google/ to something else and changing the import google.oauth2 to the new name works, but causes more issues down the line since the google api itself uses imports from google.x , too.

I’m honestly not sure how to approach this issue or fix it and would greatly appreciate any help or guidance.

I once had a similar problem when trying to use the google-cloud-texttospeech module in an add-on. I don’t remember the exact details of the problem, but something like this worked for me:

sys.path.insert(0, os.path.join(addon_path, "vendor"))
google_path = os.path.join(addon_path, "vendor", "google")
source = os.path.join(google_path, "")
spec = importlib.util.spec_from_file_location(
    "google", source, submodule_search_locations=[]
module = importlib.util.module_from_spec(spec)
sys.modules["google"] = module
del sys.modules["google.protobuf"]

from import texttospeech

(I might be wrong and your problem could be different though)


This is amazing. Not sure why, but your snippet did the trick for me too.

Thanks a lot for your help. You saved me hours of debugging <3

1 Like