MtE
MtE

Reputation: 11

OAuth2 service account credentials for Google Drive upload script

Apologies in advance if anyone has asked this before, but I've got some basic questions about a server-side Python script I'm writing that does a nightly upload of CSV files to a folder in our Google Drive account. The folder owner has created a Google API project, enabled the Drive API for this and created a credentials object which I've downloaded as a JSON file. The folder has been shared with the service account email, so I assume that the script will now have access to this folder, once it is authorized.

The JSON file contains the following fields private_key_id, private_key, client_email, client_id, auth_uri, token_uri, auth_provider_x509_cert_url, client_x509_cert_url.

  1. I'm guessing that my script will not need all of these - which are the essential or compulsory fields for OAuth2 authorization?

  2. The example Python script given here

https://developers.google.com/drive/web/quickstart/python

seems to assume that the credentials are retrieved directly from a JSON file:

...
home_dir = os.path.expanduser('~')
credential_dir = os.path.join(home_dir, '.credentials')
if not os.path.exists(credential_dir):
    os.makedirs(credential_dir)
credential_path = os.path.join(credential_dir,
                               'drive-python-quickstart.json')

store = oauth2client.file.Storage(credential_path)
credentials = store.get()
...

but in our setup we are storing them in our own DB and the script accesses them via a dict. How would the authorization be done if the credentials were in a dict?

Thanks in advance.

Upvotes: 1

Views: 1820

Answers (2)

MtE
MtE

Reputation: 11

Actually it looks like a SignedJwtAssertionCredentials may be one answer. Another possibly is

from oauth2client import service_account
...
credentials = service_account._ServiceAccountCredentials(
      service_account_id=client.clid,
      service_account_email=client.email,
      private_key_id=client.private_key_id,
      private_key_pkcs8_text=client.private_key,
      scopes=client.auth_scopes,
)
....

Upvotes: 0

Avantol13
Avantol13

Reputation: 1059

After browsing the source code, it seems that it was designed to accept only JSON files. They are using simplejson to encode and decode. Take a look at the source code:

This is where is gets the content from the file you provide:

 62 def locked_get(self): 
 63      """Retrieve Credential from file. 
 64   
 65      Returns: 
 66        oauth2client.client.Credentials 
 67   
 68      Raises: 
 69        CredentialsFileSymbolicLinkError if the file is a symbolic link. 
 70      """ 
 71      credentials = None 
 72      self._validate_file() 
 73      try: 
 74        f = open(self._filename, 'rb') 
 75        content = f.read() 
 76        f.close() 
 77      except IOError: 
 78        return credentials 
 79   
 80      try: 
 81        credentials = Credentials.new_from_json(content) #<----!!!
 82        credentials.set_store(self) 
 83      except ValueError: 
 84        pass 
 85   
 86      return credentials 

In new_from_json they attempt to decode the content using simplejson.

 205 def new_from_json(cls, s): 
 206      """Utility class method to instantiate a Credentials subclass from a JSON 
 207      representation produced by to_json(). 
 208   
 209      Args: 
 210        s: string, JSON from to_json(). 
 211   
 212      Returns: 
 213        An instance of the subclass of Credentials that was serialized with 
 214        to_json(). 
 215      """ 
 216      data = simplejson.loads(s) 

Long story short, it seems you'll have to construct a JSON file from your dict. See this. Basically, you'll need to json.dumps(your_dictionary) and create a file.

Upvotes: 2

Related Questions