PyDrive2
PyDrive2 copied to clipboard
Support default env credentials (e.g. needed in Google Colaboratory (Colab)) + workaround for now
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.
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.
Related https://github.com/iterative/PyDrive2/issues/179
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!