Google服务帐户凭据不起作用

问题描述:

我正在尝试创建一个简单的网络应用程序,该应用程序会自动上传我的数据库&媒体备份到指定的Google驱动器.我遵循了官方文档并创建了服务帐户凭据,为它提供了所有者角色,并从Google云平台提取了一个密钥(json文件).我在我的帐户上启用了Google Drive API并编写了此代码,但是凭据.有效返回False,并且我的文件不会上传到我的驱动器.

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'))

此修改如何?

  • 我认为在您的脚本中,可以使用 service = build('drive','v3',凭据=凭据) service 来上传文件.
    • 在我的环境中,我可以确认可以使用您的脚本上传文件.
    • 我的文件不会上传到我的驱动器.,我认为您可能对服务帐户有误解.使用服务帐户上传的文件已创建到服务帐户的驱动器中.此云端硬盘不同于您帐户的Google云端硬盘.我以为这可能是我的文件无法上传到驱动器的原因..
    • 如果您想在Google云端硬盘中查看使用服务帐户上传的文件,则需要与您的Google帐户共享上传的文件.或者,需要将文件上传到与服务帐户共享的Google云端硬盘中的文件夹.
    • 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.

      当以上几点反映到您的脚本中时,您的脚本将如下所示.

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

      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'))
      

      • 当您运行上述脚本时,可以在与我共享"位置看到上传的文件.在您的Google云端硬盘中.

        • When you run above script, the uploaded file can be seen at "Shared with me" in your Google Drive.

          如果要放置Google云端硬盘的特定文件夹,请使用以下脚本.在这种情况下,在运行脚本之前,请与服务帐户的电子邮件共享文件夹.请注意这一点.

          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'))
          

          • 在当前阶段,当更改了通过服务帐户上传的文件的所有者时,会出现类似的错误,您仍无法更改此项目的所有者.(我们正在努力.).所以我提出了上述修改过的脚本.
          • 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.