google service account credentials not working

孤者浪人 提交于 2021-02-17 05:55:10

问题


I am trying to create a simple web application that automatically uploads my database & media backup to a designated google drive. I have followed the official document and created a service account credential, gave it the owner role, and extracted a key(json file) from Google cloud platform. I enabled the Google Drive API on my account and wrote this code, but the credentials.valid returns False and my file would not upload to my drive.

from google.oauth2 import service_account
import googleapiclient as google
from googleapiclient.http import MediaFileUpload, HttpRequest
from googleapiclient.discovery import build

SCOPES = ['https://www.googleapis.com/auth/drive']

credentials = service_account.Credentials.from_service_account_file('./service-credentials.json', scopes=SCOPES)

print(credentials.valid)

service = build('drive', 'v3', credentials=credentials)
file_metadata = {'name' : 'python.png'}
media = MediaFileUpload('./python.png', mimetype='image/png')
file_up = service.files().create(body=file_metadata, media_body=media, fields='id').execute()

file_back = service.files().get(fileId=file_up['id']).execute()

print(file_back.get('WebContentLink'))


回答1:


How about this modification?

Modification points:

  • I think that in your script, service of service = build('drive', 'v3', credentials=credentials) can be used for uploading the file.
    • In my environment, I could confirm that the file can be uploaded using your script.
    • From my file would not upload to my drive., I thought that you might misunderstand about the service account. The file uploaded with the service account is created to the Drive of the service account. This Drive is different from your Google Drive of your account. I thought that this might be the reason of my file would not upload to my drive..
    • If you want to see the file uploaded with the service account at your Google Drive, it is required to share the uploaded file with your Google account. Or, it is required to upload the file to the folder in your Google Drive shared with the service account.
  • And also, in your script, file_back.get('WebContentLink') is used. In this case, None is always returned because WebContentLink is required to be WebContentLink. And also, in Drive API v3, the default returned values don't include webContentLink. So it is required to set fields.

When above points are reflected to your script, your script becomes as follows.

Modified script:

from google.oauth2 import service_account
import googleapiclient as google
from googleapiclient.http import MediaFileUpload, HttpRequest
from googleapiclient.discovery import build

SCOPES = ['https://www.googleapis.com/auth/drive']
credentials = service_account.Credentials.from_service_account_file('./service-credentials.json', scopes=SCOPES)

service = build('drive', 'v3', credentials=credentials)
file_metadata = {'name': 'python.png'}
media = MediaFileUpload('./python.png', mimetype='image/png')
file_up = service.files().create(body=file_metadata, media_body=media, fields='id').execute()

# Create a permission. Here, your Google account is shared with the uploaded file.
yourEmailOfGoogleAccount = '###'  # <--- Please set your Email address of Google account.
permission = {
    'type': 'user',
    'role': 'writer',
    'emailAddress': yourEmailOfGoogleAccount,
}
service.permissions().create(fileId=file_up['id'], body=permission).execute()

file_back = service.files().get(fileId=file_up['id'], fields='webContentLink').execute()  # or fields='*'
print(file_back.get('webContentLink'))
  • When you run above script, the uploaded file can be seen at "Shared with me" in your Google Drive.

  • If you want to put the specific folder of your Google Drive, please use the following script. In this case, before you run the script, please share the folder with the email of the service account. Please be careful this.

      from google.oauth2 import service_account
      import googleapiclient as google
      from googleapiclient.http import MediaFileUpload, HttpRequest
      from googleapiclient.discovery import build
    
      SCOPES = ['https://www.googleapis.com/auth/drive']
      credentials = service_account.Credentials.from_service_account_file('./service-credentials.json', scopes=SCOPES)
    
      service = build('drive', 'v3', credentials=credentials)
      file_metadata = {'name': 'python.png', 'parents': ['###']}  # <--- Please set the folder ID shared with the service account.
      media = MediaFileUpload('./python.png', mimetype='image/png')
      file_up = service.files().create(body=file_metadata, media_body=media, fields='id').execute()
    
      file_back = service.files().get(fileId=file_up['id'], fields='webContentLink').execute()  # or fields='*'
      print(file_back.get('webContentLink'))
    

Note:

  • In the current stage, when the owner of file uploaded with the service account is changed, an error like You can't yet change the owner of this item. (We're working on it.). So I proposed above modified script.

References:

  • Files: create
  • Files: get
  • Permissions: create


来源:https://stackoverflow.com/questions/63545788/google-service-account-credentials-not-working

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!