为了提高我的Python技能,我尝试阅读并理解Google API Python客户端的源代码
但我一直被卡住了,尽管我在谷歌上搜索,但我无法理解代码的特定部分的工作原理。
我制作了一个小程序来演示这一部分:
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存储库上的源代码以及代码文档,但没有找到任何有用的东西。
以下是我迄今为止所尝试的:
通过查看文件discovery.py
,函数build()
返回函数build_from_document()
的结果,后者又返回类Resource()
的实例。
但现在有一条死胡同,因为类Resource()
没有任何名为files()
的方法。
那么,如何找到这些方法files()
、get()
、list()
等的内部工作原理呢。?
(2017年2月)好问题!我想当我第一次开始使用谷歌API时,我在理解方面也遇到了同样的问题。让我稍微简化一下你的代码。然后它应该更有意义,我也可以向您转发正确的文档。
随着GoogleAPI客户端库的最新更新,您使用的身份验证代码现在可以大大简化。(请确保使用pip install -U google-api-python-client
[或适用于Python 3的pip3
]更新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创建的一些额外资源(视频、博客文章等)。。。上面的代码出现在第一对中:
- 在Google Drive中列出您的文件并深入研究代码
- 谷歌硬盘:上传&下载文件视频加上"穷人的纯文本到PDF转换器"代码深潜帖子(*)
- 仅将Google工作表导出为CSV博客文章
(*)-TL;DR:将纯文本文件上传到Drive,导入/转换为谷歌文档格式,然后将该文档导出为PDF。上面的帖子使用驱动器API v2,就像您的代码示例一样;这篇后续文章描述了将其迁移到Drive API v3,下面是一个结合了两篇"穷人的转换器"文章的开发人员视频。
要回答问题的第二部分,答案是:您使用的方法(及其文档)是而不是客户端库的一部分(apiclient
、oauth2client
等)。这就是为什么您可以找到关于它们的任何文档。请注意,在上面的代码中,我从apiclient.discovery.build()
创建了一个DRIVE服务端点,并在最后添加了一个.files()
。
Drive服务端点是您想要离开它的地方,而不是像您那样**进入API(.files()
位于调用build()
函数的末尾)。如果你把它放在更高的级别,你可以对API进行多次调用(而不是被锁定为只使用files()
),即about().get()
、files().list()
、files().export(),
等
- 创建一个类似
DRIVE
的通用服务端点,然后从那里使用API调用(而不是您所做的,相当于DRIVE.files()
) - 您正在使用的API文档可以在Drive API文档中找到。即,files()、files(.get)和files(.list)等。它们不是您所知道的"Python函数",而是API的Python包装器调用它们自己,这就是您需要服务端点的原因
- 以下是驱动器API的一般概述,以供进一步阅读
最后一点提示:尽可能使用最严格的作用域——https://www.googleapis.com/auth/drive
是完整的驱动器读写访问,通常不需要。由于我只显示文件名&MIMEtypes上面,我只需要只读范围。你知道当你安装一个应用程序时,它会要求所有这些疯狂的权限吗?这是类似的。你请求的作用域越少,限制性越强,你的用户就越不担心选择你加入。研究所有驱动器作用域,找到最适合你和你的用户的作用域。
请注意,我使用storage.json
来存储密钥,而不是.credentials/drive-credentials.json
只是建立在wescpy的惊人答案之上:
当你玩各种作用域时,每次你都需要删除在你完成谷歌登录时自动创建的storage.json
。
在我的情况下,我在玩drive.readonly
,然后想开始上传文件drive
,但我已经有好几个月没有玩只读工作了,我已经忘记了storage.json
是如何创建的。
因此,我花了一段时间才意识到,与其删除storage.json,不如让我的脚本指向一个新的(不存在的)storage2.json
来捕获drive
凭据。