Sir*_*ost 5 python google-api python-3.x oauth2client google-api-python-client
我在某些脚本中使用了 Google API 服务,但遇到了一些问题。这个错误很奇怪,但我们走了。我有一个列出我的 Google Drive 文件的脚本。
from apiclient import discovery
from httplib2 import Http
from oauth2client import file, client, tools
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_secret.json', SCOPES)
creds = tools.run_flow(flow, store)
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'],f['id'])
Run Code Online (Sandbox Code Playgroud)
它运行良好,我client_secret.json从 Google API下载并将其保存在同一文件夹中,然后我启动脚本以检查一切正常。
然后我开始编辑我的文件以改变我执行它的方式而不是读取文件,而是调用脚本并将client_id和client_secret字符串发送到脚本,最终版本是这样的:
import sys
from apiclient import discovery
from httplib2 import Http
from oauth2client import file, client, tools
# ID and SECRET arguments
client_id = sys.argv[1]
client_secret = sys.argv[2]
SCOPES = 'https://www.googleapis.com/auth/drive.readonly.metadata'
def listFiles(drive):
"""Receive the service and list the files"""
files = drive.files().list().execute().get('files', [])
for f in files:
print(f['name'], f['mimeType'],f['id'])
def main():
store = file.Storage('storage.json')
creds = store.get()
if not creds or creds.invalid:
flow = client.OAuth2WebServerFlow(client_id, client_secret, SCOPES)
creds = tools.run_flow(flow, store, tools.argparser.parse_args())
DRIVE = discovery.build('drive', 'v3', http=creds.authorize(Http()))
listFiles(DRIVE)
if __name__ == "__main__":
main()
Run Code Online (Sandbox Code Playgroud)
我第一次启动这个新版本的脚本时它可以工作,因为旧版本中的脚本已经创建了该storage.json文件。然后我将我的新版本脚本移动到另一个文件夹或机器(storage.json文件不存在的地方)以检查它是否有效,然后我得到这个:
$ python3 drive_list.py asdasdasdsa jijfkljflksdjflksdj
/usr/local/lib/python3.4/dist-packages/oauth2client/_helpers.py:255: UserWarning: Cannot access storage.json: No such file or directory
warnings.warn(_MISSING_FILE_MESSAGE.format(filename))
usage: drive_list.py [--auth_host_name AUTH_HOST_NAME]
[--noauth_local_webserver]
[--auth_host_port [AUTH_HOST_PORT [AUTH_HOST_PORT ...]]]
[--logging_level {DEBUG,INFO,WARNING,ERROR,CRITICAL}]
drive_list.py: error: unrecognized arguments: asdasdasdsa jijfkljflksdjflksdj
Run Code Online (Sandbox Code Playgroud)
关于 storage.json 文件的警告是正常的,在两个脚本版本中都会出现,是 oauth2client 的一部分。
这是古玩部分,为什么在storage.json文件存在时识别参数(仅创建读取client_secret.json)?如果脚本第一次启动它会创建文件。这个错误真的很奇怪,我只是想找出到底发生了什么。如果有人可以帮助我,我将非常感激。
发生这种情况是因为您正在导入 oauth2client.tools 模块。
为了正常工作,该模块依赖于标准argparse模块。如果您不知道,这个标准模块用于编写用户友好的命令行界面,并轻松管理命令行参数。sys.argv[1]这与您对和参数的使用不相符sys.argv[2]。
要解决此问题,您可以向命令行添加新参数,如下面的示例所示。通过此修改,您将像这样运行该工具
python3 drive_list.py -ci "your_client_id" -cs "your_client_secret"
Run Code Online (Sandbox Code Playgroud)
这是您的代码,稍作修改以添加新的命令行参数:
import argparse
from apiclient import discovery
from httplib2 import Http
from oauth2client import file, client, tools
# ID and SECRET arguments as new command line parameters
# Here is where you extend the oauth2client.tools startnd arguments
tools.argparser.add_argument('-ci', '--client-id', type=str, required=True, help='The client ID of your GCP project')
tools.argparser.add_argument('-cs', '--client-secret', type=str, required=True,
help='The client Secret of your GCP project')
SCOPES = 'https://www.googleapis.com/auth/drive.readonly.metadata'
def list_files(drive):
"""Receive the service and list the files"""
files = drive.files().list().execute().get('files', [])
for f in files:
print(f['name'], f['mimeType'], f['id'])
def main():
store = file.Storage('storage.json')
creds = store.get()
if not creds or creds.invalid:
# You want to be sure to parse the args to take in consideration the new parameters
args = argparse.ArgumentParser(parents=[tools.argparser]).parse_args()
flow = client.OAuth2WebServerFlow(args.client_id, args.client_secret, SCOPES)
creds = tools.run_flow(flow, store, tools.argparser.parse_args())
drive_sdk = discovery.build('drive', 'v3', http=creds.authorize(Http()))
list_files(drive_sdk)
if __name__ == "__main__":
main()
Run Code Online (Sandbox Code Playgroud)