iterative / iterative/PyDrive2

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

Open
#187 3 comments 2 reactions 0 assignees View on GitHub
feature request priority-p1
Dominant language
Python
Stars
670
Forks
75
PR merge metrics
No merged PRs in 30d

Description

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)
in ()
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](https://github.com/googlecolab/colabtools/blob/7c5503e6cdaa23971c08b5a3f5a6d23667a753cb/google/colab/_import_hooks/_pydrive.py) to avoid these errors.

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

```python
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.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.