尝试对凭据进行授权时出错:UserWarning:无法访问token.json:没有此类文件或目录

时间:2019-01-14 01:41:37

标签: python windows google-calendar-api

我正在尝试为命令行工具构建授权功能,以便我可以在命令行上授权certificate.json文件。我收到错误消息,即使不应有UserWarning: Cannot access C:\...\token.json: No such file or directory文件,控制台也会显示token.json。我在credentials.json所在的目录中运行quickstart.py,但似乎可以正常运行,但这不是。

代码如下:

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 :(得分:0)

问题是您正在使用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

这将为您提供正在执行的文件的相对路径,相对于您从中调用文件的位置。因此,如果您是从 inside 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)