iterative / PyDrive2

Google Drive API Python wrapper library. Maintained fork of PyDrive.
https://docs.iterative.ai/PyDrive2
Other
581 stars 69 forks source link

UnknownAPINameOrVersion Issue #197

Closed Investigamer closed 2 years ago

Investigamer commented 2 years ago

For some reason PyDrive2 stopped authenticating in the latest release of my app even though I haven't changed ANYTHING about my PyDrive setup since last release. The weird thing is, authentication works absolutely fine running the app with Python in IDE, but as soon as I build as an exe with Pyinstaller, the exe version throws this error. The only change I can think of is I upgraded from Python 3.8 to 3.10.5. This is the error I'm getting:

File "proxyshop\core.py", line 385, in authenticate_user
   File "pydrive2\auth.py", line 136, in _decorated
   File "pydrive2\auth.py", line 626, in Auth
   File "pydrive2\auth.py", line 671, in Authorize
   File "googleapiclient\_helpers.py", line 130, in positional_wrapper
   File "googleapiclient\discovery.py", line 287, in build
   File "googleapiclient\discovery.py", line 404, in _retrieve_discovery_doc
 googleapiclient.errors.UnknownApiNameOrVersion: name: drive  version: v2

This is my yaml config:

 client_config_backend: settings
client_config:
  client_id: *secret*
  client_secret: *secret*

save_credentials: True
save_credentials_backend: file
save_credentials_file: proxyshop/gauth.json

get_refresh_token: True
oauth_scope:
  - https://www.googleapis.com/auth/drive.readonly

This is the authentication setup:

 def authenticate_user():
    """
    Create a GoogleDrive object using on-file gauth token or create
    a new one by getting permission from the user.
    @return: GoogleDrive object to use for downloads.
    """
    try:
        # Create gauth file if it doesn't exist yet
        if not os.path.exists(os.path.join(os.getcwd(), "proxyshop/gauth.json")):
            with open(os.path.join(os.getcwd(), "proxyshop/gauth.json"), 'w', encoding="utf-8") as fp:
                fp.write("")

        # Authenticate, fetch file and metadata
        auth = GoogleAuth(os.path.join(os.getcwd(), "proxyshop/gdrive.yaml"))
        auth.LocalWebserverAuth()
        return GoogleDrive(auth)

    except pydrive2.auth.AuthenticationRejected: return None
    except pydrive2.auth.AuthenticationError: return None
Investigamer commented 2 years ago

I also tried switching to the current developer version of pydrive2 and having the same issue :(

EDIT: I discovered the cause of the issue. The built version is unable to locate the discovery file "drive.v2.json", what is the standard practice for having this file included via pyinstaller?

EDIT2: In the Pydrive2 source if I pass static_discovery=False here it fixes the issue:

self.service = build(
    "drive", "v2", http=self.http, cache_discovery=False, static_discovery=False
) 

Is there a way to modify this setting without changing the pydrive2 source code?

shcheklein commented 2 years ago

@MrTeferi please take a look here https://github.com/iterative/dvc/issues/5618 - I think it's the same problem.

shcheklein commented 2 years ago

Here is how it was fixed in that case https://github.com/iterative/dvc/pull/5619

shcheklein commented 2 years ago

static_discovery=False

I'm not familiar to be honest, in DVC we include drive.v2.json as far as I know. If you up to this, you can do some research and we can consider changing this option. But we need to know better what does it mean and what are the consequences.

Investigamer commented 2 years ago

So I took a look at the fix you linked, I toyed around with it a bit and this is the method that worked for me:

from PyInstaller.utils.hooks import ( collect_data_files )

datas = collect_data_files("googleapiclient.discovery_cache")



This worked for me, cheers!
efiop commented 2 years ago

I guess it might be time to contribute this to pyinstaller 🙂 We had https://github.com/iterative/dvc/blob/main/scripts/pyinstaller/hooks/hook-googleapiclient.model.py and https://github.com/iterative/dvc/blob/main/scripts/pyinstaller/hooks/hook-pydrive2.py for years and had contributed other hooks, but just not those yet.