【问题标题】:Overwriting Google Drive API v3 Argparse in Python在 Python 中覆盖 Google Drive API v3 Argparse
【发布时间】:2017-02-14 14:40:17
【问题描述】:

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

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

但是对于我的程序,我想为用户名、文件名和输出文件名使用命令行输入。我修改了谷歌文档代码并做了以下操作:

  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

因此,每当我使用自己的用户名、文件名等输入运行此脚本时,我都会收到一条错误消息,显示“无法识别的参数”。

如何让我的 argparser 覆盖 run_flow 中的那个?

编辑:

有人建议使用 parse_known_args()。

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

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

但是这个问题再次是,稍后当我在 get_credentials 中调用 run_flow 方法时,它会抛出一个错误:

用法:name.py [--auth_host_name AUTH_HOST_NAME] [--noauth_local_webserver] [--auth_host_port [AUTH_HOST_PORT ...]]] [--logging_level {DEBUG, INFO, WARNING, ERROR, CRITICAL}] 无法识别的参数:-u shishy -f fname -d random_name

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

【问题讨论】:

    标签: python google-drive-api argparse oauth2


    【解决方案1】:

    没关系,我想通了。 hpaulj 说得对。

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

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

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

    谢谢, 害羞的

    【讨论】:

    • 这对我来说非常有效。感谢您分享您的解决方案
    【解决方案2】:

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

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

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

    【讨论】:

    • goad 中的 if__name__ 块只是初始化 main()。 argparse 部分只是在函数之外的开始。我实际上正在考虑这篇文章以及如何做类似的事情:stackoverflow.com/questions/26130741/… 只是新版本中没有 samples_tools.init()。
    • parse_known_args 的问题是 get_info 方法导致了这个错误,这是 google 方法的一部分。如果我将信息传递到命令行,它会解析它并试图说“哦,哇,这些不是我所期望的”
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-18
    相关资源
    最近更新 更多