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。
我正在尝试使用 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.
修复还包括将所有代码从 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。