【问题标题】:How would one convert/wrap a HTTPLib2 instance as a Session?如何将 HTTPLib2 实例转换/包装为会话?
【发布时间】:2014-01-29 02:12:40
【问题描述】:

我知道这个标题很不靠谱,对此我深表歉意。我的困境是gspread 使用 Session 而Google APIs client library for Python 使用 HTTPLib2。我有一个与 Google API 客户端一起使用的服务帐户,并且想要获取经过身份验证的 httplib2.Http() 实例并将其包装,以便 gspread 可以像 Session 对象一样使用它。

更新:已修复 update 103 到 gspread。根据 Jay Lee 下面的精彩回答,以下是如何在 Python 2.7 中使用服务帐户初始化 gspread Client(您需要替换 /path/to/service-account.p12 并设置 sa_id):

import gspread
from oauth2client.client import SignedJwtAssertionCredentials
from apiclient.discovery import build
# ...
with open('/path/to/service-account.p12') as f: sa_key = f.read()
credentials = SignedJwtAssertionCredentials(
    sa_id, sa_key, 'https://spreadsheets.google.com/feeds')
http = httplib2.Http()
http = credentials.authorize(http)
build('drive', 'v2', http = http)
access_token = http.request.credentials.access_token
gspread_auth_headers = {'Authorization' : 'Bearer %s' % access_token}
gspread_session = gspread.httpsession.HTTPSession(headers=gspread_auth_headers)
fakeauth = ('notmyusername@gmail.com', 'notmypassword')
client = gspread.Client(fakeauth, http_session=gspread_session)
# https://github.com/burnash/gspread/issues/103
if False == hasattr(client, "session"):
    client = gspread.Client(fakeauth)
    client.session = gspread_session

现在您可以像往常一样使用client哇!

【问题讨论】:

    标签: python session google-api-python-client gspread


    【解决方案1】:

    快速查看 gspread 表明它使用的是已弃用的旧 ClientLogin 身份验证协议。但是您应该能够从 httplib2.Http() 实例中获取访问令牌并将相同的标头应用于 gspread 会话(有效地让 gspread 也使用 OAuth 2.0):

    http = <<<Your existing, authenticated httplib2.Http() object)>>>
    access_token = http.request.credentials.access_token
    gspread_auth_headers = {'Authorization': 'Bearer %s' % access_token}
    gspread_session = gspread.httpsession.HTTPSession(headers=gspread_auth_headers)
    my_gspread = gspread.Client(auth=('notmyusername@gmail.com', 'notmypassword'), http_session=gspread_session)
    

    notmyusername@gmail.comnotmypassword 在这里是随机字符串,它们只是需要,因为 gspread.Client 期望 auth 是传递给它的元组,除非您调用 my_gspread.login(),否则它们不会传递给 Google (你不会)。

    您需要注意并捕获过期的 access_tokens。如果 gspread 抛出有关无效令牌的错误,您应该捕获它,调用 http.request.credentials.refresh() 以获取新的访问令牌,然后使用新令牌重新创建 gspread 会话。

    【讨论】:

    • 我正在使用一个服务帐户,这让我想知道我是否会遇到过期的访问令牌,因为它使用密钥对进行身份验证。 (PS - 谢谢,我迫不及待想试试这个!)
    • 服务帐户访问令牌在 1 小时后过期,必须重新创建。请参阅developers.google.com/accounts/docs/… 代码未经测试,但理论上至少应该可以工作:-)
    • 更新:我修复了客户端上的 gspread 代码,以实际使用Client ctor 中的http_session 参数。现在它在使用“AttributeError: 'set' object has no attribute 'items'”(File "/Library/Python/2.7/site-packages/gspread/httpsession.py", line 59, in request)解析请求时崩溃了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-10
    • 2020-12-02
    • 2020-07-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多