代码之家  ›  专栏  ›  技术社区  ›  Sir Cost

使用oauth2和Google API的无法识别的参数

  •  5
  • Sir Cost  · 技术社区  · 7 年前

    我在一些脚本中使用谷歌API服务,但遇到了一些问题。这个错误有些奇怪,但我们开始吧。 我有一个脚本,列出了我的谷歌驱动器文件。

    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'])
    

    它工作得很好,我下载了 client_secret.json 从谷歌API和保存在同一个文件夹,然后我启动脚本,检查一切都是好的。

    然后我开始编辑我的文件,以改变我执行它的方式,而不是读取文件,而是调用脚本并发送 客户端id client\u机密 字符串,最终版本如下:

    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()
    

    我第一次启动这个新版本的脚本时,它就工作了,因为旧版本中的脚本创建了 storage.json 然后,我将新版本脚本移动到另一个文件夹或机器(其中 存储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
    

    关于存储的警告。json文件是正常的,并出现在两个脚本版本中,是oauth2client的一部分。

    存储json 文件存在(仅在读取 client\u机密。json 这个错误真的很奇怪,我只是想找出到底发生了什么。 如果有人能帮助我,我会非常感激。

    1 回复  |  直到 6 年前
        1
  •  2
  •   Lorenzo Persichetti    6 年前

    这是因为您正在导入oauth2client。工具模块。

    为了正确工作,本模块依赖于标准 argparse 单元如果您不知道,这个标准模块用于编写用户友好的命令行界面,可以轻松管理命令行参数。这与您使用 sys.argv[1] sys.argv[2] 论据。

    为了解决这个问题,可以向命令行添加新参数,如下面的示例所示。通过这种修改,您可以像这样运行该工具

    python3 drive_list.py -ci "your_client_id" -cs "your_client_secret"
    

    以下是经过轻微修改的代码,用于添加新的命令行参数:

    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()