4

为了提高我的Python技能,我尝试阅读并理解Google API Python client的源代码。
但我陷入了困境,尽管四处搜索,我无法理解代码的特定部分的工作。了解如何在Python中使用Google API客户端库

我做了一个小程序,以证明部分:

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.pybuild()返回函数build_from_document(),这反过来又返回类Resource()的一个实例的结果的功能。

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

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

+0

但'Resource'类我的钥匙似乎有方法动态方法添加到自身。我会从那里开始。 – Jasper

+0

@Jasper我绝对没有任何关于如何工作的线索(我是Python的初学者)。你能否详细解释一下更详细的情况? –

+0

https://github.com/google/google-api-python-client/blob/master/googleapiclient/discovery.py#L967这是我猜测的相关函数。添加类似“'attr_name,value'”和代码以打印栈跟踪(https://docs.python.org/2/library/traceback.html)(或者使用您最喜欢的调试器)来查看谁在调用此函数函数添加'文件()','get()'等 – Jasper

回答

1

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

您使用的授权码现在可以通过Google API客户端库中的最新更新显着简化。 (请确保您使用pip install -U google-api-python-client [或pip3 for 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']) 

下面是一些额外的资源(视频,博客等),我已经使用驱动API在Python创建...上面的代码中第一对特色:

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

要回答你的问题的第二部分,答案是:你的使用(和他们的文档)的方法是客户端库(apiclientoauth2client等)的一部分。这就是为什么你可以找到他们的任何文件。请注意,在我上面的代码中,我创建了一个DRIVE服务端点,从apiclient.discovery.build()开始,在最后添加.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

相关问题