【问题标题】:Understanding how to use the Google APIs Client Library with Python了解如何在 Python 中使用 Google API 客户端库
【发布时间】:2016-01-12 12:30:28
【问题描述】:

为了提高我的Python技能,我尝试阅读和理解Google API Python client的源代码。
但是我被困住了,尽管谷歌搜索,我无法理解代码的特定部分的工作。

我做了一个小程序来演示这部分:

upload.py

from __future__ import print_function
import os
import httplib2

import apiclient
import oauth2client

try:
    import argparse
    flags = argparse.ArgumentParser(
        parents=[oauth2client.tools.argparser]).parse_args()
except ImportError:
    flags = None

SCOPES = 'https://www.googleapis.com/auth/drive'
CLIENT_SECRET_FILE = 'client_secret.json'

# Enter your project name here!!
APPLICATION_NAME = 'API Project'


def get_credentials():
    """Gets valid user credentials from storage.

    If nothing has been stored, or if the stored credentials are invalid,
    the OAuth2 flow is completed to obtain the new credentials.

    Returns:
        Credentials, the obtained credential.
    """
    home_dir = os.path.expanduser('~')
    credential_dir = os.path.join(home_dir, '.credentials')
    if not os.path.exists(credential_dir):
        os.makedirs(credential_dir)
    credential_path = os.path.join(credential_dir,
                                   'drive-credentials.json')

    store = oauth2client.file.Storage(credential_path)
    credentials = store.get()
    if not credentials or credentials.invalid:
        flow = oauth2client.client.flow_from_clientsecrets(
            CLIENT_SECRET_FILE, SCOPES)
        flow.user_agent = APPLICATION_NAME
        if flags:
            credentials = oauth2client.tools.run_flow(flow, store, flags)
        else:  # Needed only for compatibility with Python 2.6
            credentials = oauth2client.tools.run(flow, store)
        print('Storing credentials to ' + credential_path)
    return credentials


def main():
    credentials = get_credentials()
    http = credentials.authorize(httplib2.Http())

    file_service = apiclient.discovery.build('drive', 'v3', http=http).files()

    results = file_service.get(
        fileId="0Bw239KLrN7zoWl95Nml2ZUpsNnc").execute()
    print(results)

    results = file_service.list(
        pageSize=10, fields="files(id, name)").execute()
    print(results)

if __name__ == '__main__':
    main()

file_service = apiclient.discovery.build('drive', 'v3', http=http).files() 行中,我无法在库源代码的任何地方找到files() 方法的定义。我也找不到任何名为get()list() 的方法。

我在Github repositorycode documentation 上阅读了该库的源代码,但没有找到任何有用的东西。

这是我迄今为止尝试过的:

通过查看文件discovery.py,函数build() 返回函数build_from_document() 的结果,该函数又返回类Resource() 的实例。

但是现在有一个死胡同,因为类Resource() 没有任何称为files() 的方法。

那么,如何找到files()get()list() 等这些方法的内部工作原理?

【问题讨论】:

  • 但是Resource 类似乎有方法可以为自身动态添加方法。我会从那里开始。
  • @Jasper 我绝对不知道它是如何工作的(我是 Python 的初学者)。您能否更详细地解释一下从哪里开始?
  • github.com/google/google-api-python-client/blob/master/… 这是我猜的相关功能。添加诸如“print attr_name, value”之类的内容和代码以打印堆栈跟踪 (docs.python.org/2/library/traceback.html)(或使用您喜欢的调试器)以查看谁在调用此函数以添加 files()get() 等。

标签: python methods google-api google-drive-api google-api-python-client


【解决方案1】:

(2017 年 2 月) 好问题!当我第一次开始使用 Google API 时,我想我在理解上遇到了同样的问题。让我稍微简化一下您的代码。那么它应该更有意义,我也可以将您转发到正确的文档。

您使用的身份验证代码现在可以通过 Google API 客户端库中的最新更新得到显着简化。 (确保使用pip install -U google-api-python-client [或pip3 用于Python 3] 更新您的Python 库。)这是一个使用list() 的工作示例——您应该能够将此示例作为灵感并(重新)实现您的main() 让它工作。

# authorization boilerplate code
SCOPES = 'https://www.googleapis.com/auth/drive.readonly.metadata'
store = file.Storage('storage.json')
creds = store.get()
if not creds or creds.invalid:
    flow = client.flow_from_clientsecrets('client_id.json', SCOPES)
    creds = tools.run_flow(flow, store)

# call files().list() to display 1st 100 files in My Drive folder
DRIVE = discovery.build('drive', 'v3', http=creds.authorize(Http()))
files = DRIVE.files().list().execute().get('files', [])
for f in files:
    print(f['name'], f['mimeType'])

以下是我为使用 Python 中的 Drive API 而创建的一些其他资源(视频、博客文章等)...上面的代码在第一对中出现:

(*) - TL;DR:将纯文本文件上传到云端硬盘,导入/转换为 Google 文档格式,然后将该文档导出为 PDF。上面的帖子像您的代码示例一样使用 Drive API v2; this follow-up post 描述了将其迁移到 Drive API v3,这是一个 developer video 结合了两个“穷人的转换器”帖子。

要回答您问题的第二部分,答案是:您使用的方法(及其文档)不是客户端库的一部分(apiclientoauth2client 等。 )。这就是为什么您可以找到有关它们的任何文档的原因。请注意,在上面的代码中,我从 apiclient.discovery.build() 创建了一个 DRIVE 服务端点,当您在末尾添加一个 .files() 时停止。

Drive 服务端点是您想要离开它的地方,而不是像您那样**进入* API(在调用 build() 函数的末尾使用 .files())。如果将其保留在更高级别,则可以对 API 进行多次调用(而不是仅使用files()),即about().get()files().list()files().export(), 等。一些建议:

  1. 创建一个通用服务端点,如 DRIVE,然后使用那里的 API 调用(而不是您所做的,相当于 DRIVE.files())。
  2. 您正在使用的 API 的文档可以在 Drive API 文档中找到。即files()files().get()files().list() 等。它们不是您所知道的“Python 函数”,而是 API 调用本身的 Python 包装器,这就是您需要服务端点的原因。
  3. 这里是general overview to the Drive API 以供进一步阅读。

最后提示:尽可能使用最严格的范围 -- https://www.googleapis.com/auth/drive 是完全驱动器读写访问权限,通常不是必要的。由于我只显示上面的文件名和 MIMEtypes,我只需要只读范围。你知道当你安装一个应用程序时,它会要求所有这些疯狂的权限吗?这是相似的。您请求的范围越少,限制性越强,您的用户就越不会担心选择您加入。研究 all the Drive scopes 并找到最适合您和您的用户的范围。

请注意,我使用storage.json 来存储我的密钥,而不是.credentials/drive-credentials.json

【讨论】:

    【解决方案2】:

    以 wescpy 的精彩回答为基础:

    当您使用各种范围时,每次您都需要删除完成 google 登录时自动创建的 storage.json

    在我的例子中,我在玩drive.readonly,然后想开始上传文件drive,但是自从我玩只读工作以来已经好几个月了,我忘记了storage.json是如何创建的.

    所以我花了一段时间才意识到,与其删除 storage.json,不如让我的脚本指向一个新的(不存在的)storage2.json 来捕获drive 凭据。

    【讨论】:

      猜你喜欢
      • 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
      相关资源
      最近更新 更多