【问题标题】:oauth2client/appengine.py returns "InvalidResponseError: header values must be str, got 'unicode'" with webapp2/python27/wsgioauth2client/appengine.py 使用 webapp2/python27/wsgi 返回“InvalidResponseError: header values must be str, got 'unicode'”
【发布时间】:2013-03-18 02:37:07
【问题描述】:

事先,我的问题类似于问题Pyramid on App Engine gets "InvalidResponseError: header values must be str, got 'unicode',还有几个google-api-python-client bugs,但对我的情况没有帮助。另外,我在issue #254 上没有答案(它本身看起来类似于#111,所以我在这里尝试。

在本地 GAE 上,下面的简单示例(this sample 的简化和 python27 化版本)返回 InvalidResponseError: header values must be str, got 'unicode',尽管我的代码没有进行任何 unicode 标头设置。更准确地说,我期待结果 Hello,但我得到的是:

Internal Server Error
    The server has either erred or is incapable of performing the requested operation.
    Traceback (most recent call last):
      File "/home/ronj/.gae/lib/webapp2-2.5.2/webapp2.py", line 1546, in __call__
        return response(environ, start_response)
      File "/home/ronj/.gae/lib/webob_0_9/webob/__init__.py", line 2000, in __call__
        start_response(self.status, self.headerlist)
      File "/home/ronj/.gae/google/appengine/runtime/wsgi.py", line 156, in _StartResponse
        (_GetTypeName(value), value, name))
    InvalidResponseError: header values must be str, got 'unicode' (u'https://accounts.google.com/o/oauth2/auth?state=http%3A%2F%2Flocalhost%3A8080%2F&redirect_uri=http%3A%2F%2Flocalhost%3A8080%2Foauth2callback&response_type=code&client_id=xxxxxxxxxxxx.apps.googleusercontent.com&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fyoutube&access_type=offline') for 'Location'

有什么想法吗?我在 Ubuntu 12.10 x64 上的 Python 2.7.3 上使用 GAE 1.7.5。

编辑:Jonas 在issue #254 中提供了一个答案:“将一些 str() 添加到 OAuth2WebServerFlow 上生成 URL 的方法中应该相对容易。用 str() 包装在 oauth2client/client.py 中的第 830 行返回之前"。
→ 看起来不错,但我应该如何实现呢?我同意我可以在我安装了 GAE 的本地计算机上修改文件,但是一旦部署,它将使用 Google 的 GAE,对吗?我怎样才能覆盖它? (对于新手问题感到抱歉)

感谢您的帮助!


app.yaml:

application: yourapp
version: 1
runtime: python27
api_version: 1
threadsafe: true

handlers:

- url: /
  script: yourapp.main

libraries:
- name: webapp2
  version: latest

yourapp.py:

import webapp2, os, httplib2
from apiclient.discovery import build
from oauth2client.appengine import oauth2decorator_from_clientsecrets
from google.appengine.api import memcache

CLIENT_SECRETS = os.path.join(os.path.dirname(__file__), 'client_secrets.json')
MISSING_CLIENT_SECRETS_MESSAGE = "Warning: Please configure OAuth 2.0"
YOUTUBE_READ_WRITE_SCOPE = "https://www.googleapis.com/auth/youtube"
YOUTUBE_API_SERVICE_NAME = "youtube"
YOUTUBE_API_VERSION = "v3"

http = httplib2.Http(memcache)
youtube = build(YOUTUBE_API_SERVICE_NAME, YOUTUBE_API_VERSION, http=http)
decorator = oauth2decorator_from_clientsecrets(
    CLIENT_SECRETS,
    scope=YOUTUBE_READ_WRITE_SCOPE,
    message=MISSING_CLIENT_SECRETS_MESSAGE)


class MainPage(webapp2.RequestHandler):

  @decorator.oauth_required
  def get(self):
    self.response.headers['Content-Type'] = 'text/plain'
    self.response.write('Hello')

main = webapp2.WSGIApplication([('/', MainPage)], debug=True)

【问题讨论】:

  • Jonas 在issue #254 中提供了答案:“在OAuth2WebServerFlow 上的生成URL 的方法中添加一些str() 应该相对容易。在返回之前用str() 包裹起来oauth2client/client.py 中的 830"。看起来不错,但是我应该如何实现呢?我同意我可以在我安装了 GAE 的本地计算机上修改文件,但是一旦部署,它将使用 Google 的 GAE,对吗?我怎样才能覆盖它? (对于新手问题感到抱歉)

标签: python google-app-engine oauth-2.0


【解决方案1】:

另一个答案...添加 str() 可以解决问题,但不是根本原因。我花了几个小时试图弄清楚为什么一个特定的重定向会引发此错误而其他人没有,然后才注意到错误重定向的 URL 缺少初始的“/”。

我不知道为什么会出现这种情况 - 可能不完整的路径与完整路径的处理方式不同。但是,如果您遇到此错误,请尝试更改:

self.redirect('home.view')

到:

self.redirect('/home.view')

【讨论】:

    【解决方案2】:

    即使我已经在使用最新版本的 apiclient,我也遇到了同样的问题。

    帮助我解决此问题的答案已发布在问题跟踪器中http://code.google.com/p/google-api-python-client/issues/detail?id=254

    不工作

    flow = client.flow_from_clientsecrets(CLIENT_SECRETS,scope=scopes)
    callback = self.request.relative_url('/oauth2callback')
    auth_url = flow.step1_get_authorize_url(callback)
    return self.redirect(auth_url)
    

    工作

    flow = client.flow_from_clientsecrets(CLIENT_SECRETS,scope=scopes)
    callback = self.request.relative_url('/oauth2callback')
    auth_url = str(flow.step1_get_authorize_url(callback))
    return self.redirect(auth_url)
    

    注意包装 flow.step1_get_authorize_url 调用的 str()

    【讨论】:

    • 有点晚了,但您的回答仍然对我有帮助。 +1
    【解决方案3】:

    我使用的是 GAE 的捆绑版本的 python API,显然不应该这样做。安装托管在项目download page 上的google-api-python-client-1.1 后,一切正常。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-04
      • 2021-04-29
      • 2022-07-27
      • 2021-05-13
      相关资源
      最近更新 更多