gmail API: TypeError: sequence item 0: expected str instance, bytes found

gmail API: TypeError: sequence item 0: expected str instance, bytes found

我正在尝试使用 GMail 下载一封邮件 API。以下是我的回溯: pdiracdelta@pdiracdelta-笔记本电脑:~/GMail 元数据 $ ./main.py

<oauth2client.client.OAuth2Credentials object at 0x7fd6306c4d30>
False
Traceback (most recent call last):
  File "./main.py", line 105, in <module>
    main()
  File "./main.py", line 88, in main
    service = discovery.build('gmail', 'v1', http=http)
  File "/usr/lib/python3/dist-packages/oauth2client/util.py", line 137, in positional_wrapper
    return wrapped(*args, **kwargs)
  File "/usr/lib/python3/dist-packages/googleapiclient/discovery.py", line 197, in build
    resp, content = http.request(requested_url)
  File "/usr/lib/python3/dist-packages/oauth2client/client.py", line 562, in new_request
    redirections, connection_type)
  File "/usr/lib/python3/dist-packages/httplib2/__init__.py", line 1138, in request
    headers = self._normalize_headers(headers)
  File "/usr/lib/python3/dist-packages/httplib2/__init__.py", line 1106, in _normalize_headers
    return _normalize_headers(headers)
  File "/usr/lib/python3/dist-packages/httplib2/__init__.py", line 194, in _normalize_headers
    return dict([ (key.lower(), NORMALIZE_SPACE.sub(value, ' ').strip())  for (key, value) in headers.items()])
  File "/usr/lib/python3/dist-packages/httplib2/__init__.py", line 194, in <listcomp>
    return dict([ (key.lower(), NORMALIZE_SPACE.sub(value, ' ').strip())  for (key, value) in headers.items()])
TypeError: sequence item 0: expected str instance, bytes found

下面是一段代码,它在 Traceback 之前生成凭证对象和布尔打印。它确认凭据对象有效并且正在按照 Google:

的建议使用
credentials = get_credentials()
print(credentials)
print(str(credentials.invalid))
http = credentials.authorize(httplib2.Http())
service = discovery.build('gmail', 'v1', http=http)

这里出了什么问题?在我看来,我没有错,因为问题可以追溯到 service = discovery.build('gmail', 'v1', http=http),它只使用有效信息(暗示堆栈中进一步使用的包之一无法处理此有效信息)。这是一个错误,还是我做错了什么?

更新:_normalize_headers 功能似乎已经被修补。更新您的 python 版本应该可以解决问题(我现在使用的是 3.6.7)。

在 Padraic Cunningham 的帮助下解决了问题,他将问题确定为编码问题。我通过将 .decode('utf-8') 应用于 header 键和值(headers 是一个字典)解决了这个问题,如果它们是字节类型的对象(显然是 UTF-8 编码的)并转换它们成 python3 个字符串。这可能是由于在 google API.

中混合了一些 python2/3

修复还包括将所有代码从 google API 示例更改为 python3 代码(例如异常处理),但最重要的是我的解决方法涉及编辑 /usr/lib/python3/dist-packages/httplib2/__init__.py第 193-194 行,将 _normalize_headers(headers) 函数重新定义为:

def _normalize_headers(headers):
     for key in headers:
         # if not encoded as a string, it is ASSUMED to be encoded as UTF-8, as it used to be in python2.
         if not isinstance(key, str):
             newkey = key.decode('utf-8')
             headers[newkey] = headers[key]
             del headers[key]
             key = newkey
         if not isinstance(headers[key], str): 
             headers[key] = headers[key].decode('utf-8')
     return dict([ (key.lower(), NORMALIZE_SPACE.sub(value, ' ').strip())  for (key, value) in headers.items()])

警告:此解决方法显然很脏,因为它涉及编辑 httplib2 包中的文件。如果有人找到更好的修复方法,请在此处 post。