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

Support default env credentials (e.g. needed in Google Colaboratory (Colab)) + workaround for now #187

Open
jpmckinney opened this issue Jun 30, 2022 · 3 comments

Comments

@jpmckinney
Copy link

jpmckinney commented Jun 30, 2022

Google Colaboratory provides these instructions for using PyDrive: https://colab.research.google.com/notebooks/snippets/drive.ipynb#scrollTo=bRFyEsdfBxJ9

Running the same code, but substituting pydrive2 for pydrive, produces errors as collapsed here.

FileNotFoundError                         Traceback (most recent call last)
/usr/local/lib/python3.7/dist-packages/oauth2client/clientsecrets.py in _loadfile(filename)
    120     try:
--> 121         with open(filename, 'r') as fp:
    122             obj = json.load(fp)

FileNotFoundError: [Errno 2] No such file or directory: 'client_secrets.json'

During handling of the above exception, another exception occurred:

InvalidClientSecretsError                 Traceback (most recent call last)
9 frames
/usr/local/lib/python3.7/dist-packages/pydrive2/auth.py in LoadClientConfigFile(self, client_config_file)
    476             client_type, client_info = clientsecrets.loadfile(
--> 477                 client_config_file
    478             )

/usr/local/lib/python3.7/dist-packages/oauth2client/clientsecrets.py in loadfile(filename, cache)
    164     if not cache:
--> 165         return _loadfile(filename)
    166 

/usr/local/lib/python3.7/dist-packages/oauth2client/clientsecrets.py in _loadfile(filename)
    124         raise InvalidClientSecretsError('Error opening file', exc.filename,
--> 125                                         exc.strerror, exc.errno)
    126     return _validate_clientsecrets(obj)

InvalidClientSecretsError: ('Error opening file', 'client_secrets.json', 'No such file or directory', 2)

During handling of the above exception, another exception occurred:

InvalidConfigError                        Traceback (most recent call last)
<ipython-input-3-e7c1a9729564> in <module>()
     16 uploaded = drive.CreateFile({'title': 'Sample file.txt'})
     17 uploaded.SetContentString('Sample upload file content')
---> 18 uploaded.Upload()
     19 print('Uploaded file with ID {}'.format(uploaded.get('id')))

/usr/local/lib/python3.7/dist-packages/pydrive2/files.py in Upload(self, param)
    495                 self._FilesPatch(param=param)
    496         else:
--> 497             self._FilesInsert(param=param)
    498 
    499     def Trash(self, param=None):

/usr/local/lib/python3.7/dist-packages/pydrive2/auth.py in _decorated(self, *args, **kwargs)
     58                 self.auth.ServiceAuth()
     59             else:
---> 60                 self.auth.LocalWebserverAuth()
     61 
     62         # Initialise service if not built yet.

/usr/local/lib/python3.7/dist-packages/pydrive2/auth.py in _decorated(self, *args, **kwargs)
    122             self.LoadCredentials()
    123         if self.flow is None:
--> 124             self.GetFlow()
    125         if self.credentials is None:
    126             code = decoratee(self, *args, **kwargs)

/usr/local/lib/python3.7/dist-packages/pydrive2/auth.py in GetFlow(self)
    565             config in self.client_config for config in self.CLIENT_CONFIGS_LIST
    566         ):
--> 567             self.LoadClientConfig()
    568         constructor_kwargs = {
    569             "redirect_uri": self.client_config["redirect_uri"],

/usr/local/lib/python3.7/dist-packages/pydrive2/auth.py in LoadClientConfig(self, backend)
    454                 )
    455         if backend == "file":
--> 456             self.LoadClientConfigFile()
    457         elif backend == "settings":
    458             self.LoadClientConfigSettings()

/usr/local/lib/python3.7/dist-packages/pydrive2/auth.py in LoadClientConfigFile(self, client_config_file)
    478             )
    479         except clientsecrets.InvalidClientSecretsError as error:
--> 480             raise InvalidConfigError("Invalid client secrets file %s" % error)
    481         if client_type not in (
    482             clientsecrets.TYPE_WEB,

InvalidConfigError: Invalid client secrets file ('Error opening file', 'client_secrets.json', 'No such file or directory', 2)

The google-colab package would monkey-patch pydrive to avoid these errors.

To monkey-patch pydrive2 in the same way, you need to:

import httplib2
from oauth2client.contrib.gce import AppAssertionCredentials
from pydrive2.auth import GoogleAuth

old_local_webserver_auth = GoogleAuth.LocalWebserverAuth


def LocalWebServerAuth(self, *args, **kwargs):
    if isinstance(self.credentials, AppAssertionCredentials):
        self.credentials.refresh(httplib2.Http())
        return
    return old_local_webserver_auth(self, *args, **kwargs)


GoogleAuth.LocalWebserverAuth = LocalWebServerAuth

Then, you can use the same code as in Google Colaboratory's instructions.

@shcheklein
Copy link
Member

I think when the migration is done here #89, we can add support for GoogleCredentials.get_application_default(). I think it would be very handy. We can add an explicit method ApplicationDefaultAuth for this.

I'm hesitant to do it now, since oauth2client is deprecated and we need to migrate from it first.

@shcheklein shcheklein changed the title Documentation: Replacing pydrive with pydrive2 in Google Colaboratory (Colab) Support default env credentials (e.g. needed in Google Colaboratory (Colab)) + workaround for now Jul 24, 2022
@shcheklein
Copy link
Member

Related #179

@ppawlak
Copy link

ppawlak commented Sep 29, 2022

Hello

I was about to create a new issue but I think this one cover my use case: I would like to use PyDrive2 on a Google App Engine, without using a JSON key file, but authenticating with the default Service Account.

I tried the workaround above but it yields to a 403 error

ApiRequestError: <HttpError 403 when requesting https://www.googleapis.com/drive/v2/files?q=MyDriveId+in+parents+and+trashed%3Dfalse&maxResults=1000&supportsAllDrives=true&includeItemsFromAllDrives=true&alt=json returned "Insufficient Permission: Request had insufficient authentication scopes.". Details: "[{'domain': 'global', 'reason': 'insufficientPermissions', 'message': 'Insufficient Permission: Request had insufficient authentication scopes.'}]">

I know my Service Account has enough permissions to access the Drive because it works with a JSON key file.
Am I missing something? Any chance to see this issue resolved in the near future?

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants