在 Python 中覆盖 Google 驱动器 API v3 Argparse

Overwriting Google Drive API v3 Argparse in Python

我正在尝试通过 Python 使用 Google Drive API (v3) 来获取文件并将其上传到我的 Google Drive 帐户。

我使用本指南设置身份验证:https://developers.google.com/drive/v3/web/quickstart/python

但对于我的程序,我想使用命令行输入用户名、文件名和 output_filename。我修改了 google 文档代码并执行了以下操作:

  from __future__ import print_function
    import httplib2
    import os
    from sys import argv 
    from apiclient import discovery
    from oauth2client import client
    from oauth2client import tools
    from oauth2client.file import Storage
    from apiclient.http import MediaIoBaseDownload, MediaIoBaseUpload 
    import io  

    try:
        import argparse
        parser = argparse.ArgumentParser(description="I want your name, the file ID, and the folder you want to dump output to")
        parser.add_argument('-u', '--username', help='User Name', required=True)
        parser.add_argument('-f', '--filename', help='File Name', required=True)
        parser.add_argument('-d', '--dirname', help = 'Directory Name', required=True)
        flags = parser.parse_args()

    except ImportError:
        flags = None

    SCOPES = 'https://www.googleapis.com/auth/drive'
    CLIENT_SECRET_FILE = 'client_secret.json'
    APPLICATION_NAME = 'Drive API Python Quickstart'
    ...#rest of the code is from the Google Drive Documentation (see above)

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-python-quickstart.json')

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

    print("check")
    return credentials

问题是在get_credentials方法中,有一行说:

if flags:
  credentials = tools.run_flow(flow, store, flags)
else: # Needed only for compatibility with Python 2.6
  credentials = tools.run(flow, store)

run_flow 方法虽然使用了 google 编写的不同的 argparser(参见:http://oauth2client.readthedocs.io/en/latest/source/oauth2client.tools.html

因此,每当我 运行 这个脚本使用我自己的用户名、文件名等输入时,我总是收到一个错误 "Unrecognized Arguments"。

如何让我的 argparser 重写 run_flow 中的那个?

编辑:

有人建议使用 parse_known_args()。

好吧,我修改了我的代码以通过说 args, flags = parser.parse_known_args() 来解析,因为那样的话,任何杂项。输入将进入标志。

我的想法是,如果我 运行 脚本并给它我的 3 个参数,它应该将它们拉入 "args"。

但是这个问题又是后来当我调用 get_credentials 中的 run_flow 方法时,它抛出一个错误说:

Usage: name.py [--auth_host_name AUTH_HOST_NAME] [--noauth_local_webserver] [--auth_host_port [AUTH_HOST_PORT ...]]] [--logging_level {DEBUG, INFO, WARNING, ERROR, CRITICAL}] Unrecognized arguments: -u shishy -f fname -d random_name

我认为它仍在将我的命令行输入传递给 get_info 方法,解析器不知道如何处理它...

我认为还有其他关于 argparsegoogle api 的问题,但我没有使用后者。

解析器是独立的,不能重写。但它们都(无论如何作为默认值)使用 sys.argv[1:]。因此,如果您的代码在另一个代码之前运行,您可以编辑 sys.argv 以删除多余的字符串。使用 parse_known_args 是一种将您的参数与其他解析器应使用的参数分开的简便方法。

通常从 if __name__ 块调用解析器。这样导入的模块不做解析,只有用作脚本的模块。但如果 google api 做出这种区分,我不会。

没关系,我想通了。 hpaulj 做对了。

在 get_credentials() 方法中,就在它调用 run_flow() 之前,我只需要添加一行:

flags=tools.argparser.parse_args(args=[])
credentials=tools.run_flow(flow, store, flags)

一开始当我阅读带有输入的命令行时,我只是按照 hpaulj 的建议使用了 parser_known_flags()!

谢谢, 害羞