【问题标题】:Google Drive API for Python: how to create credential?适用于 Python 的 Google Drive API:如何创建凭证?
【发布时间】:2021-03-31 17:01:44
【问题描述】:

我正在编写一个 Python 脚本来自动将一些文件上传到 Google Drive。由于我仍然是一名 Python 程序员新手,而且这与其他任何事情一样多,所以我开始关注Google Quickstart 并决定使用他们的quickstart.py 作为我自己脚本的基础。在讨论如何为 Python 脚本创建凭据的部分中,它指的是“创建凭据”链接,位于 https://developers.google.com/workspace/guides/create-credentials

我点击链接,进入我的一个 Google Cloud 项目,并尝试使用“内部”项目设置 OAuth 同意屏幕,正如他们告诉你的那样……但我做不到。谷歌说:

“由于您不是 Google Workspace 用户,因此您只能将您的 可供外部(普通观众)用户使用的应用程序。 ”

所以我尝试创建一个“外部”项目,然后继续使用桌面应用程序创建一个新的客户端 ID。然后我下载 JSON 凭据并将它们放在与我的 Python 脚本相同的文件夹中,即"credentials.json"。然后我执行 Python 脚本以对其进行身份验证:浏览器打开,我登录我的 Google 帐户,给它我的权限......然后浏览器挂起,因为它正在重定向到 localhost URL,显然我的小 Python 脚本是根本不听我的电脑。

我相信他们最近一定改变了这一点,因为一年前我开始遵循相同的 Python 教程并且可以毫无问题地创建凭据,但 Google Drive API 文档尚未更新。那么...我现在如何为 Python 脚本创建凭据?

编辑:在此处添加我的脚本的源代码。正如我所说,它与 Google 的“quickstart.py”非常相似:

from __future__ import print_function
import pickle
import os.path
from googleapiclient.discovery import build
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request
from googleapiclient.errors import HttpError


# If modifying these scopes, delete the file token.pickle.
SCOPES = ['https://www.googleapis.com/auth/drive.metadata', 'https://www.googleapis.com/auth/drive']



def main():
    """Shows basic usage of the Drive v3 API.
    Prints the names and ids of the first 10 files the user has access to.
    """
    creds = None
    # The file token.pickle stores the user's access and refresh tokens, and is
    # created automatically when the authorization flow completes for the first
    # time.
    if os.path.exists('token_myappname.pickle'):
        with open('token_myappname.pickle', 'rb') as token:
            creds = pickle.load(token)
    # If there are no (valid) credentials available, let the user log in.
    if not creds or not creds.valid:
        if creds and creds.expired and creds.refresh_token:
            creds.refresh(Request())
        else:
            flow = InstalledAppFlow.from_client_secrets_file(
                'credentials.json', SCOPES)
            creds = flow.run_local_server(port=0)
        # Save the credentials for the next run
        with open('token_myappname.pickle', 'wb') as token:
            pickle.dump(creds, token)



    service = build('drive', 'v3', credentials=creds)

    # Call the Drive v3 API
    results = service.files().list(
        pageSize=10, fields="nextPageToken, files(id, name)").execute()
    items = results.get('files', [])


    if not items:
        print('No files found.')
    else:
        #print(items[0])
 
        print('Files:')
        for item in items:
            #print (item)
            print(u'{0}   {1}   {2}'.format(item['name'], item['owners'], item['parents']))
 

【问题讨论】:

  • 您是否通过了应用验证流程?当您使用 Google Drive 时,我相信您的应用程序可能会使用以下 scopes 中的一些要求您的应用程序通过验证过程。
  • 我没有。我的应用程序现在正处于“测试”阶段。但是,这在创建凭证时会有所不同吗?
  • 这个脚本是否会自动运行(在后台,例如由调度程序运行,没有连接的用户)?脚本是否始终访问同一个 Google Drive?另外,你能分享一下你与 Drive API 建立连接的代码吗?
  • @guillaumeblaquiere:是的,我们的想法是它最终将作为 cron 作业运行,始终将文件上传到同一个驱动器。我已经添加了源代码,尽管它与 Google 教程的快速入门几乎相同。

标签: python google-cloud-platform google-drive-api google-oauth


【解决方案1】:

我建议您使用服务帐户来访问云端硬盘。

为此,您需要与服务帐户电子邮件共享驱动器(或文件夹)。然后使用这段代码

from googleapiclient.discovery import build
import google.auth

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



def main():
    credentials, project_id = google.auth.default(scopes=SCOPES)


    service = build('drive', 'v3', credentials=credentials)

    # Call the Drive v3 API
    results = service.files().list(
        q=f"'1YJ6gMgACOqVVbcgKviJKtVa5ITgsI1yP' in parents",
        pageSize=10, fields="nextPageToken, files(id, name, owners, parents)").execute()
    items = results.get('files', [])


    if not items:
        print('No files found.')
    else:
        #print(items[0])

        print('Files:')
        for item in items:
            #print (item)
            print(u'{0}   {1}   {2}'.format(item['name'], item['owners'], item['parents']))

如果您在 GCP 上运行代码,例如在计算引擎实例中,您需要使用您在驱动器中授权的服务帐号自定义虚拟机。 (不要使用计算引擎默认服务帐户,否则您需要在 VM 上进行额外配置)

如果您在 GCP 之外运行脚本,则需要生成服务帐户密钥文件并将其存储在本地服务器上。然后,创建一个环境变量GOOGLE_APPLICATION_CREDENTIALS 引用存储的密钥文件的完整路径。

【讨论】:

  • 感谢您的帮助!当我有时间时,我会尝试一下,看看会发生什么。不过,我有一个问题:代码中的“1YJ6gMgACOqVVbcgKviJKtVa5ITgsI1yP”标记是什么意思?
  • 另外,这更像是一个评论而不是一个问题:Google 快速入门文档旨在作为初学者的教程,但是,由于这一变化,现在开发人员不可能完成它按照 Google 自己的官方说明进行快速入门。我不得不说,有点令人沮丧。
  • 此字符串 1YJ6gMgACOqVVbcgKviJKtVa5ITgsI1yP 如果是我在云端硬盘文件夹中时在浏览器中找到的值。是的,我经常告诉 Google:Cloud 和 Workspace(前 GSuite)之间的桥梁是一个黑洞,任何人(无论是否初学者)都很难找到最新且值得信赖的文档。
【解决方案2】:

除了 Guillaume Blaquiere 发布的其他解决方案之外,我还自己找到了另一个解决方案,我想将其发布在这里以防万一。我所要做的就是......呃,实际上阅读我正在复制和粘贴的代码,特别是这一行:

creds = flow.run_local_server(port=0)

我在快速入门之外查看了 Google 的文档,发现如下:https://google-auth-oauthlib.readthedocs.io/en/latest/reference/google_auth_oauthlib.flow.html

事实证明,示例代码 在我的计算机中打开了一个本地端口来侦听请求,但它无法正常工作可能是由于“端口 0”部分或其他原因网络问题。

所以我发现的解决方法是使用文档中的不同身份验证方法:

  creds = flow.run_console()  

在这种情况下,您需要在命令行中手动粘贴 Google 提供给您的身份验证代码。我刚试了一下,我的凭据愉快地存储在我的本地泡菜文件中。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多