Python 谷歌服务帐户凭据不工作

Python 谷歌服务帐户凭据不工作,python,google-api,google-drive-api,google-oauth,google-api-python-client,Python,Google Api,Google Drive Api,Google Oauth,Google Api Python Client,我正在尝试创建一个简单的web应用程序,自动将我的数据库和媒体备份上传到指定的google驱动器。我遵循官方文档,创建了一个服务帐户凭据,赋予它所有者角色,并从谷歌云平台提取了一个密钥(json文件)。我在我的帐户上启用了Google Drive API并编写了此代码,但credentials.valid返回False,我的文件将不会上载到我的驱动器 from google.oauth2 import service_account import googleapiclient as googl

我正在尝试创建一个简单的web应用程序,自动将我的数据库和媒体备份上传到指定的google驱动器。我遵循官方文档,创建了一个服务帐户凭据,赋予它所有者角色,并从谷歌云平台提取了一个密钥(json文件)。我在我的帐户上启用了Google Drive API并编写了此代码,但credentials.valid返回False,我的文件将不会上载到我的驱动器

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',credentials=credentials)
    service
    来上载文件。
    • 在我的环境中,我可以确认可以使用您的脚本上载文件
    • 我的文件无法上传到我的驱动器。
      ,我认为您可能会误解服务帐户。随服务帐户上载的文件将创建到服务帐户的驱动器中。此驱动器与您帐户的Google驱动器不同。我想这可能是我的文件无法上传到硬盘的原因。
    • 如果您想在您的Google Drive上看到使用服务帐户上载的文件,则需要与您的Google帐户共享上载的文件。或者,需要将文件上载到与服务帐户共享的Google Drive中的文件夹中
  • 此外,在脚本中,还使用了
    file\u back.get('WebContentLink')
    。在这种情况下,始终返回
    None
    ,因为
    WebContentLink
    必须是
    WebContentLink
    。而且,在驱动器API v3中,默认返回值不包括
    webContentLink
    。因此需要设置
    字段
当上述各点反映到脚本中时,脚本将如下所示

修改脚本:
来自google.oauth2导入服务\u帐户
将GoogleAppClient作为google导入
从GoogleAppClient.http导入MediaFileUpload,HttpRequest
从GoogleAppClient.discovery导入生成
作用域=['https://www.googleapis.com/auth/drive']
credentials=service\u account.credentials.from\u service\u account\u文件('./service credentials.json',scopes=scopes)
服务=生成('drive','v3',凭据=凭据)
文件\元数据={'name':'python.png'}
media=MediaFileUpload('./python.png',mimetype='image/png')
file\u up=service.files().create(body=file\u元数据,media\u body=media,fields='id')。execute()
#创建权限。在这里,您的谷歌帐户与上传的文件共享。

yourEmailOfGoogleAccount='####'#这个修改怎么样

修改点:
  • 我认为在您的脚本中,可以使用
    service=build('drive','v3',credentials=credentials)
    service
    来上载文件。
    • 在我的环境中,我可以确认可以使用您的脚本上载文件
    • 我的文件无法上传到我的驱动器。
      ,我认为您可能会误解服务帐户。随服务帐户上载的文件将创建到服务帐户的驱动器中。此驱动器与您帐户的Google驱动器不同。我想这可能是我的文件无法上传到硬盘的原因。
  • 如果您想在您的Google Drive上看到使用服务帐户上载的文件,则需要与您的Google帐户共享上载的文件。或者,需要将文件上载到与服务帐户共享的Google Drive中的文件夹中
  • 此外,在脚本中,还使用了
    file\u back.get('WebContentLink')
    。在这种情况下,始终返回
    None
    ,因为
    WebContentLink
    必须是
    WebContentLink
    。而且,在驱动器API v3中,默认返回值不包括
    webContentLink
    。因此需要设置
    字段
  • 当上述各点反映到脚本中时,脚本将如下所示

    修改脚本:
    来自google.oauth2导入服务\u帐户
    将GoogleAppClient作为google导入
    从GoogleAppClient.http导入MediaFileUpload,HttpRequest
    从GoogleAppClient.discovery导入生成
    作用域=['https://www.googleapis.com/auth/drive']
    credentials=service\u account.credentials.from\u service\u account\u文件('./service credentials.json',scopes=scopes)
    服务=生成('drive','v3',凭据=凭据)
    文件\元数据={'name':'python.png'}
    media=MediaFileUpload('./python.png',mimetype='image/png')
    file\u up=service.files().create(body=file\u元数据,media\u body=media,fields='id')。execute()
    #创建权限。在这里,您的谷歌帐户与上传的文件共享。
    
    yourEmailOfGoogleAccount='#####
    打印(凭证)说什么?@yedpodtrzitko打印(凭证.valid)返回false这太棒了,但是
    打印(凭证)
    说什么呢?类似这样的东西,
    print(credentials)
    说什么?@yedpodtrzitko打印(credentials.valid)返回false这太棒了,但是
    print(credentials)
    说什么呢?像这样的谢谢你。我能够看到上传的文件。如何直接访问服务帐户驱动器?另外,为什么
    凭证.valid
    返回False?@Hesam Korki感谢您的回复。关于你的两个新问题,A1。在现阶段,无法使用浏览器直接访问服务帐户的驱动器。不幸的是,这是当前的规范。因此,我提出了上述修改。我为此道歉。A2。我认为
    service\u account.Credentials.from\u service\u account\u file()
    检索的值不包括访问令牌。这可能就是原因。但我不确定这是否是正确答案。这是因为我的技术差。对此我深表歉意。为了理解,我必须多学习
    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'))
    
      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'))