Как получить учетные данные Google Analytics без gflags - вместо этого используйте run_flow()?
Это может занять секунду, чтобы объяснить, поэтому, пожалуйста, несите меня:
Я работаю над проектом для работы, который требует от меня загрузки данных Google Analytics. Я изначально сделал это, следуя этой ссылке, поэтому после установки клиента API pip install --upgrade google-api-python-client
и настройки вещей, как client_secrets.json
, он хотел, чтобы gflags для выполнения оператора run()
. (т.е. credentials = run(FLOW, storage)
)
Теперь я получил сообщение об ошибке для установки gflags или лучше использовать run_flow()
(точное сообщение об ошибке было):
NotImplementedError: библиотека gflags должна быть установлена для использования tools.run(). Установите gflags или, желательно, переключитесь на использование tools.run_flow().
Я изначально использовал gflags (несколько месяцев назад), но он не был совместим с нашей каркасной (пирамидой), поэтому мы удалили ее, пока не выяснили, в чем проблема. И причина, по которой предпочтительнее переключиться с gflags на run_flow()
, - это то, что gflags был устаревшим, поэтому я не хочу использовать его, как я. Теперь я пытаюсь перейти к использованию run_flow()
Проблема с этим run_flow()
ожидает, что к нему будет отправлен аргумент командной строки, и это не приложение командной строки. Я нашел некоторые документы, которые были полезны, но я застрял в создании флагов для функции run_flow()
.
Перед тем, как показывать код, еще одно объяснение.
run_flow()
принимает три аргумента (здесь документация). Он принимает поток и хранилище так же, как и run()
, но также принимает объект флагов. в библиотеке gflags встроен флаг ArgumentParser
, который использовался в методе выполнения oauth2client
.
несколько других ссылок, которые были полезны при построении объекта ArgumentParser
:
Вторая ссылка очень полезна, чтобы увидеть, как она будет выполнена, поэтому теперь, когда я пытаюсь сделать что-то подобное, sys.argv
втягивает расположение моей виртуальной среды, которая работает aka pserve
, а также втягивает мои .ini
файл (который хранит учетные данные для моего компьютера для запуска виртуальной среды). Но это порождает ошибку, потому что она ожидает чего-то еще, и именно здесь я застрял.
- Я не знаю, какие объекты флагов мне нужно построить для отправки через
run_flow()
- Я не знаю, какие аргументы argv мне нужно передать, чтобы оператор
flags = parser.parse_args(argv[1:])
получал правильную информацию (я не знаю, какая должна быть правильная информация)
Код:
CLIENT_SECRETS = client_file.uri
MISSING_CLIENT_SECRETS_MESSAGE = '%s is missing' % CLIENT_SECRETS
FLOW = flow_from_clientsecrets(
CLIENT_SECRETS,
scope='https://www.googleapis.com/auth/analytics.readonly',
message=MISSING_CLIENT_SECRETS_MESSAGE
)
TOKEN_FILE_NAME = 'analytics.dat'
def prepare_credentials(self, argv):
storage = Storage(self.TOKEN_FILE_NAME)
credentials = storage.get()
if credentials is None or credentials.invalid:
parser = argparse.ArgumentParser(description=__doc__,
formatter_class=argparse.RawDescriptionHelpFormatter,
parents=[tools.argparser])
flags = parser.parse_args(argv[1:]) # i could also do just argv, both error
credentials = run_flow(self.FLOW, storage, flags)
return credentials
def initialize_service(self, argv):
http = httplib2.Http()
credentials = self.prepare_credentials(self, argv)
http = credentials.authorize(http)
return build('analytics', 'v3', http=http)
Я вызываю передачу основной функции sys.argv
, которая вызывает initialize_service
def main(self, argv):
service = self.initialize_service(self, argv)
try:
#do a query and stuff here
Я знал, что это не сработает, потому что мое приложение не является приложением командной строки, а скорее полным интегрированным сервисом, но я решил, что это стоит того. Любые мысли о том, как правильно создать объект флагов?
Ответы
Ответ 1
from oauth2client import tools
flags = tools.argparser.parse_args(args=[])
credentials = tools.run_flow(flow, storage, flags)
Немного поморщился, но поднялся по моим двум ловушкам, в которые он бросил меня:
- должны использовать параметр argparser, предоставляемый в инструментах
- Мне пришлось кормить args пустым списком, чтобы он не читал args из командной строки, что было проблемой, потому что я запускаю его из unittest (так что разные аргументы cmdline).
Ответ 2
Эта часть кода работает для меня для gmail api.
(Также эта ссылка помогла. Инструменты командной строки)
import argparse
import httplib2
from oauth2client.tools import run_flow
from oauth2client.tools import argparser
from oauth2client.file import Storage
CLIENT_SECRETS_FILE = "your_file.json"
OAUTH_SCOPE = 'https://www.googleapis.com/auth/gmail.readonly'
STORAGE = Storage("storage")
flow = flow_from_clientsecrets(CLIENT_SECRETS_FILE, scope=OAUTH_SCOPE)
http = httplib2.Http()
credentials = STORAGE.get()
if credentials is None or credentials.invalid:
#magic
parser = argparse.ArgumentParser(parents=[argparser])
flags = parser.parse_args()
credentials = run_flow(flow, STORAGE, flags, http=http)
http = credentials.authorize(http)
gmApi = build('gmail', 'v1', http=http)
# ...
Ответ 3
Флаги, которые можно передать, можно найти здесь и являются следующими:
--auth_host_name: Host name to use when running a local web server
to handle redirects during OAuth authorization.
(default: 'localhost')
--auth_host_port: Port to use when running a local web server to handle
redirects during OAuth authorization.;
repeat this option to specify a list of values
(default: '[8080, 8090]')
(an integer)
--[no]auth_local_webserver: Run a local web server to handle redirects
during OAuth authorization.
(default: 'true')
Мне еще предстоит разобраться, как именно их разобрать, я пробовал передавать разные значения для каждого из этих трех флагов, но для меня ничего не работает. У меня есть богатый вопрос здесь, который может быть вам полезен при ответе.