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"
}