了解如何在Python

时间:2016-01-12 12:30:28

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

为了提高我的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 repository及其code documentation上阅读了该库的源代码,但未能找到任何有用的内容。

这是我到目前为止所尝试的内容:

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

但现在有一个死路,因为班级files()没有任何名为files()的方法。

那么,我如何找到这些方法get()list()filesystem.readdirSync('./folder', function(err, files) { files.sort(function(a, b) { a = a.replace(/\w/, ""); //removing 's' or word character b = b.replace(/\w/, ""); return +a - +b; }).forEach(function(file) { console.log(file); }); }); 等的内部工作原理?

2 个答案:

答案 0 :(得分:2)

(2017年2月)好问题!当我第一次开始使用Google API时,我认为我在理解时遇到了同样的问题。让我简化你的代码。然后它应该更有意义,我也可以转发给你正确的文档。

现在可以使用Google API客户端库中的最新更新大大简化您使用的身份验证代码。 (确保使用{3}}更新Python库[或者Python 3的pip install -U google-api-python-client]。)以下是使用pip3的工作示例 - 您应该能够将此示例作为灵感来源并(重新)实施您的list()以便它可以正常运作。

main()

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

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

要回答问题的第二部分,答案是:您使用的方法(及其文档)是客户端库的一部分(# 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']) ,{{1}等等)。这就是为什么你可以找到关于它们的任何文档。请注意,在上面的代码中,我从apiclient创建了一个DRIVE服务端点,并在最后添加oauth2client时停在那里。

Drive服务端点是您要离开的位置,而不是像您一样潜入**(在调用apiclient.discovery.build()函数时使用.files())。如果您将其保留在更高级别,则可以多次调用API(而不是仅使用.files()),即build()files(),{{1一些建议:

  1. 创建一个通用服务端点,例如about().get(),然后使用那里的API调用(而不是你所做的,相当于files().list())。
  2. 您可以在Drive API文档中找到您正在使用的API的文档。即,files()files().get()files().list()等。它们不是你所知道的“Python函数”,而是API调用自己的包装器,这就是为什么你需要服务端点。
  3. 以下是进一步阅读的general overview to the Drive API
  4. 最终提示:尽可能使用限制范围最广的范围 - files().export(),是完整的驱动器读写访问权限,通常需要。因为我只显示文件名和上面的MIME类型,我只需要只读范围。您知道在安装应用程序时,它会询问所有这些疯狂的权限吗?这是类似的。您请求的范围越少,限制越多,您的用户不再担心选择加入的机会就越大。研究all the Drive scopes并找到最适合您和您的用户的那个。

    请注意,我使用DRIVE来存储我的密钥而不是DRIVE.files()

答案 1 :(得分:0)

建立在wescpy的绝佳答案之上:

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

在我的情况下,我正在玩drive.readonly然后想要开始上传文件drive,但是自从我玩了只读工作已经好几个月了,我忘记了{ {1}}已创建。

所以我花了一段时间才意识到,我可以让我的脚本指向一个新的(不存在的)storage.json来捕获storage2.json凭据,而不是删除storage.json。 / p>