【问题标题】:How to instantiate a Google API service using google-auth?如何使用 google-auth 实例化 Google API 服务?
【发布时间】:2019-01-07 06:35:16
【问题描述】:

我正在尝试使用 Python 程序的 API 从快速入门指南 (https://developers.google.com/sheets/api/quickstart/python) 作为起点填充 Google 表格:

from __future__ import print_function
from apiclient.discovery import build
from httplib2 import Http
from oauth2client import file as oauth_file, client, tools

# Setup the Sheets API
SCOPES = 'https://www.googleapis.com/auth/spreadsheets.readonly'
store = oauth_file.Storage('token.json')
creds = store.get()
if not creds or creds.invalid:
    flow = client.flow_from_clientsecrets('credentials.json', SCOPES)
    creds = tools.run_flow(flow, store)
service = build('sheets', 'v4', http=creds.authorize(Http()))

但是,我只能使用flow_from_clientsecrets() 方法来实现此功能,该方法(默认情况下)会在浏览器中打开一个身份验证页面。这似乎不适合我想在生产服务器上定期运行的东西。

无论如何,根据https://pypi.org/project/oauth2client/oauth2client 已被弃用,建议开发人员改用google-auth

因此,我尝试将这个示例改编如下(遵循https://google-auth.readthedocs.io/en/latest/user-guide.html#service-account-private-key-files):

from google.oauth2 import service_account

credentials = service_account.Credentials.from_service_account_file(
    'google_client_secret.json')

其中'google_client_secret.json' 是从 API 控制台下载的 JSON 文件,如下所示(打乱且打印精美):

{
  "installed": {
    "client_id": "33e.apps.googleusercontent.com",
    "project_id": "nps-survey-1532981793379",
    "auth_uri": "https://accounts.google.com/o/oauth2/auth",
    "token_uri": "https://accounts.google.com/o/oauth2/token",
    "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
    "client_secret": "foobar",
    "redirect_uris": [
      "urn:ietf:wg:oauth:2.0:oob",
      "http://localhost"
    ]
  }
}

但是,当我运行脚本时,我收到以下错误:

(lucy-web-CVxkrCFK) bash-3.2$ python nps.py
Traceback (most recent call last):
  File "nps.py", line 25, in <module>
    'google_client_secret.json')
  File "/Users/kurtpeek/.local/share/virtualenvs/lucy-web-CVxkrCFK/lib/python3.7/site-packages/google/oauth2/service_account.py", line 209, in from_service_account_file
    filename, require=['client_email', 'token_uri'])
  File "/Users/kurtpeek/.local/share/virtualenvs/lucy-web-CVxkrCFK/lib/python3.7/site-packages/google/auth/_service_account_info.py", line 73, in from_filename
    return data, from_dict(data, require=require)
  File "/Users/kurtpeek/.local/share/virtualenvs/lucy-web-CVxkrCFK/lib/python3.7/site-packages/google/auth/_service_account_info.py", line 51, in from_dict
    'fields {}.'.format(', '.join(missing)))
ValueError: Service account info was not in the expected format, missing fields token_uri, client_email.

从进入调试器,我注意到问题基本上是传入from_dict()方法的字典是google_client_secret.json文件中的整个字典,它只有一个键, "installed"from_dict() 方法似乎在“寻找”的是子字典,因为它包含一个 token_uri 键,尽管它不包含所需的 client_email 键。

我怀疑我为我的用例创建了错误类型的 OAuth2 客户端,因为包含客户端机密的 JSON 不是预期的格式。有什么想法可以解决这个问题吗?

【问题讨论】:

    标签: python google-api google-oauth google-sheets-api google-authentication


    【解决方案1】:

    来自https://developers.google.com/api-client-library/python/guide/aaa_oauth,客户端ID分为三种:

    1. Web 应用程序客户端 ID
    2. 已安装的应用程序客户端 ID
    3. 服务帐号客户端 ID

    我的用例是Service Account,在创建一个并选择提供新的私钥选项后,我发现我获得了一个与预期格式匹配的 JSON 文件。 (我拥有的是一个已安装的应用程序)。

    【讨论】:

    • @tehhowch,我想你的意思是我应该执行第 2 点:接受答案? StackOverflow 只允许您在一段时间后接受自己的答案;就我而言,我只能在明天接受。那我就做吧。
    猜你喜欢
    • 2023-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-12
    • 1970-01-01
    • 1970-01-01
    • 2012-10-23
    • 1970-01-01
    相关资源
    最近更新 更多