一尘不染

用Python覆盖Google Drive API v3 Argparse

python

我正在尝试将Google Drive API(v3)与Python结合使用,以获取文件并将其上传到我的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

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

如何使argparser覆盖run_flow中的argparser?

编辑:

有人建议使用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方法,而解析器不知道该如何处理…


阅读 174

收藏
2021-01-20

共1个答案

一尘不染

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

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

通常,解析器是从一个if __name__块中调用的。这样,导入的模块就不会解析,只会解析用作脚本的模块。但是我不知道Google
API是否能做到这一点。

2021-01-20