2016-10-06 2 views
1

Я пытаюсь использовать API-интерфейс Google Drive (v3) с Python для получения и загрузки файлов в аккаунт Google Диска.Перезапись API Google Диска v3 Argparse в Python

Я использовал это руководство для настройки моей аутентификации: https://developers.google.com/drive/v3/web/quickstart/python

Но для моей программы, я хотел бы воспользоваться командной строкой для ввода имени пользователя, имени файла и Файл_вывода. Я изменил код документа 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 хотя использует другой argparser что google написал (см .: http://oauth2client.readthedocs.io/en/latest/source/oauth2client.tools.html)

Так что всякий раз, когда я запускаю этот скрипт с моими собственными входами с именем пользователя, именем файла и т. д., я продолжаю получать сообщение об ошибке «Unrecognized Arguments».

Как я могу заставить свой argparser перезаписать файл в run_flow?

EDIT:

Кто-то предложил использовать parse_known_args().

Ну, я изменил свой код на синтаксический анализ, указав args, flags = parser.parse_known_args(), потому что таким образом, любой разный. входы будут входить в флаги.

Идея состоит в том, что если я запустил скрипт и передам ему свои 3 аргумента, он должен потянуть их в «args».

Но проблема с этим еще раз в том, что позже, когда я вызываю метод run_flow в get_credentials, он выдает ошибку, говоря:

Использование: 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 имя_файла -d random_name

Я думаю, что он все еще передает мой ввод в командной строке к методу get_info и парсеру не имеет понятия, что с этим делать ...

ответ

1

Я думаю, что были и другие вопросы о argparse и google api, но я не использовал последний.

Парсеры независимы и не могут быть написаны выше. Но все они (по умолчанию в любом случае) используют sys.argv[1:]. Поэтому, если ваш код работает до другого, вы можете отредактировать sys.argv, чтобы удалить дополнительные строки. Использование parse_known_args - это удобный способ разделения ваших аргументов от тех, которые должен использовать другой синтаксический анализатор (ы).

Часто парсер вызывается из блока if __name__. Таким образом, импортированные модули не выполняют синтаксический анализ, а только те, которые используются в качестве скриптов. Но я не делаю, если google api делает это различие.

+0

Блок if__name__ в их рожне просто инициализирует главное(). Элемент argparse находится только в начале за пределами функций. Я действительно думал об этом сообщении и о том, как я мог бы сделать что-то подобное: https://stackoverflow.com/questions/26130741/using-argparse-with-google-admin-api, это просто, что samples_tools.init() здесь нет в новой версии. – shishy

+0

Проблема с parse_known_args заключается в том, что метод get_info вызывает эту ошибку, и это часть метода google. Если я передаю информацию в командной строке, она разглашает это и пытается сказать «о, черт возьми, это не то, что я ожидаю» – shishy

1

Ничего, я понял. hpaulj правильно.

В get_credentials() метод, прямо перед его называют run_flow(), я просто должен был добавить строку говоря:

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

И в самом начале, когда я прочитал командную строку с моими входами, я просто использовал parser_known_flags(), как предложил hpaulj!

Благодаря, shishy

Смежные вопросы