Convert script to using service account authentication

49 Views Asked by At

I have a script that is to grabbing a pdf from a url and saving it to google drive without saving in the local machine. Currently the script requires a user to manually authenticate. I am now trying to convert the same script to using a service account where it is automatically authenticated but I am getting an error.

The following works ok but needs user to authenticate

import chargebee
import json
import requests
import io

from pydrive.auth import GoogleAuth
from pydrive.drive import GoogleDrive

gauth = GoogleAuth()
gauth.LocalWebserverAuth()
drive = GoogleDrive(gauth)

chargebee.configure("test_key","test")
result = chargebee.Invoice.pdf("0266242350")
download = result.download
url = download.download_url

response = requests.get(url)


folderId = '1EzJebd84qkC-dAOxohXODkGj-XXXcki6'

metadata = {
    'name':'invoice.pdf',
    "parents": [{'id': folderId}]
}
files = {
    'data': ('metadata', json.dumps(metadata), 'application/json'),
    'file': io.BytesIO(requests.get(url).content)
}
r = requests.post(
    "https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart",
    headers={"Authorization": "Bearer " + gauth.credentials.access_token},
    files=files
)
print(r.text)

The following gives me this error

headers={"Authorization": "Bearer " + access_token},
TypeError: can only concatenate str (not "NoneType") to str


from google.oauth2 import service_account
from googleapiclient.discovery import build
from pydrive2.auth import GoogleAuth
from pydrive2.drive import GoogleDrive
from oauth2client.service_account import ServiceAccountCredentials
import io

import chargebee
import json
import requests

gauth = GoogleAuth()
scope = ["https://www.googleapis.com/auth/drive"]
gauth.credentials = ServiceAccountCredentials.from_json_keyfile_name('service_account_key.json', scope)
drive = GoogleDrive(gauth)


chargebee.configure("test_key","test")
result = chargebee.Invoice.pdf("0224452350")
download = result.download
url = download.download_url

response = requests.get(url)
folderId = '1EzJebd84qkC-dAOXXxXODkGj-OX4cki6'

metadata = {
    'name':'invoice.pdf',
    "parents": [{'id': folderId}]
}
files = {
    'data': ('metadata', json.dumps(metadata), 'application/json'),
    'file': io.BytesIO(requests.get(url).content)
}
access_token = gauth.attr['credentials'].access_token
r = requests.post(
    "https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart",   
    headers={"Authorization": "Bearer " + access_token},
    files=files
)
print(r.text)
 

Can anyone see where I am going wrong? I am new to python and google api so I have been following examples like this to get here.

The service_account_key.json has these properties.

{
  "type": "service_account",
  "project_id": "xxxx6",
  "private_key_id": "xxxxxxxxxxx",
  "private_key": "-----BEGIN PRIVATE KEY-----\nxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxm\n-----END PRIVATE KEY-----\n",
  "client_email": "test.iam.gserviceaccount.com",
  "client_id": "xxxxxxxxxx92150329",
  "auth_uri": "https://accounts.google.com/o/oauth2/auth",
  "token_uri": "https://oauth2.googleapis.com/token",
  "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
  "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/chargebee-sfinvoice-updatexxxx.iam.gserviceaccount.com",
  "universe_domain": "googleapis.com"
}
0

There are 0 best solutions below