Ошибка при попытке авторизации credentials.json: UserWarning: Не удается получить доступ token.json: Нет такого файла или каталога - PullRequest
0 голосов
/ 14 января 2019

Я пытаюсь создать функцию авторизации для инструмента командной строки, чтобы я мог авторизовать файл credentials.json в командной строке. Я получаю сообщение об ошибке, когда консоль говорит UserWarning: Cannot access C:\...\token.json: No such file or directory, хотя не должно быть файла token.json. Я запускаю quickstart.py в том же каталоге, что и credentials.json, и, кажется, все работает хорошо, но это не так.

Вот код:

import calendar
import datetime
import json
import pathlib
import os
import pprint
import time
import re
import sys

import click

from googleapiclient.discovery import build
from httplib2 import Http
from oauth2client import file, client, tools

#code omitted for brevity

current_path = pathlib.Path.cwd()
file_path = str(current_path) + '\\' + 'credentials.json'
if os.path.exists(file_path):
    if True: #omitted for simplicity
        #copy pasta from quickstart.py
        store = file.Storage(str(current_path) + '\\token.json')
        creds = store.get()
        if not creds or creds.invalid:
            flow = client.flow_from_clientsecrets(str(current_path) + '\\credentials.json', SCOPES)
            creds = tools.run_flow(flow, store)
        service = build('calendar', 'v3', http=creds.authorize(Http()))

        print('You have been authorized. Feel free to run any commands you would like.')
        return 0

Вот структура файла:

project_file
|
L _ _ other_file
|     L_ _ file_where_the_above_code_is_located
|     L_ _ credentials.json
|     L_ _ quickstart.py
|
L setup.py, license, tests, etc

1 Ответ

0 голосов
/ 14 января 2019

Проблема в том, что вы используете os.getcwd(). Это не работает, если вы пытаетесь выполнить из другого места.

Пример: Если я нахожусь в /path/to/otherfile:

os.getcwd()
# /path/to/otherfile

Но если я запускаю тот же сценарий (сидит в otherfile из project_file:

os.getcwd()
# /path/to/project_file

Чтобы получить каталог файла, pathlib правильно, но вызов функции неверен:

FILE_PATH = str(pathlib.Path(__file__).parent)
# /relative/path/to/otherfile

Это даст вам относительный путь к исполняемому файлу, конечно, относительно того, откуда вы вызываете файл. Таким образом, если вы звоните по номеру из otherfile, print(FILE_PATH) будет выглядеть как ., потому что вы уже находитесь в этом каталоге.

Однако, если вы позвоните с project_file, оно будет выглядеть как project_file/otherfile. Вставка этого в ваш код будет выглядеть следующим образом:

# Store the current path as a string like so. This is a relative path from cwd() to the file's directory
current_path = str(pathlib.Path(__file__).parent)

# I'm using os.path.join here so you don't have to add the '\\' every time
file_path = os.path.join(current_path, 'credentials.json')
if os.path.exists(file_path):
    if True: #omitted for simplicity
        #copy pasta from quickstart.py

        # Note, you've already stored the working directory, so we can just join it with 'token.json'
        store = file.Storage(os.path.join(current_path, 'token.json'))
        creds = store.get()
        if not creds or creds.invalid:

            # You've stored file_path already, no need to re-create it
            flow = client.flow_from_clientsecrets(file_path, SCOPES)
            creds = tools.run_flow(flow, store)

Для полноты pathlib.Path(__file__) выглядит как /relative/path/to/file.py, поэтому .parent получает имя папки для вас

Чтобы сделать это немного легче для чтения, вы можете сохранить эти переменные пути в начале вашего скрипта, чтобы было легче вносить изменения в будущем

SCRIPT_DIRECTORY = str(pathlib.Path(__file__).parent)
CREDENTIALS_PATH = os.path.join(SCRIPT_DIRECTORY, 'credentials.json')
TOKEN_PATH = os.path.join(SCRIPT_DIRECTORY, 'token.json')

# use isfile here, since it could accidentally be created as a directory
if os.path.isfile(CREDENTIALS_PATH):
    if True:
        store = file.Storage(TOKEN_PATH)

        creds = store.get()
        if not creds or creds.invalid:
            flow = client.flow_from_clientsecrets(CREDENTIALS_PATH, SCOPES)
            creds = tools.run_flow(flow, store)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...