我如何正确地base64编码Gmail API的MIMEText?
问题描述:
从Gmail API's developer guide:我如何正确地base64编码Gmail API的MIMEText?
下面的代码示例演示创建MIME消息,编码一个base64url串,并将其分配给该消息的资源的原始字段:
def create_message(sender, to, subject, message_text):
"""Create a message for an email.
Args:
sender: Email address of the sender.
to: Email address of the receiver.
subject: The subject of the email message.
message_text: The text of the email message.
Returns:
An object containing a base64url encoded email object.
"""
message = MIMEText(message_text)
message['to'] = to
message['from'] = sender
message['subject'] = subject
return {'raw': base64.urlsafe_b64encode(message.as_string())}
但如果我这样做
from email.MIMEText import MIMEText
import base64
message = MIMEText('This is a test')
message['to'] = '[email protected]'
message['from'] = '[email protected]'
message['subject'] = 'Test'
body = {'raw': base64.urlsafe_b64encode(message.as_string())}
我得到TypeError: a bytes-like object is required, not 'str'
相反,如果我做的:
body = {'raw': base64.urlsafe_b64encode(message.as_bytes())}
message = (service.users().messages().send(userId='me', body=body)
.execute())
我得到一些二进制不是JSON序列化下面的回溯:
~/env/lib/python3.5/site-packages/googleapiclient/discovery.py in method(self, **kwargs)
792 headers = {}
793 headers, params, query, body = model.request(headers,
--> 794 actual_path_params, actual_query_params, body_value)
795
796 expanded_url = uritemplate.expand(pathUrl, params)
~/env/lib/python3.5/site-packages/googleapiclient/model.py in request(self, headers, path_params, query_params, body_value)
149 if body_value is not None:
150 headers['content-type'] = self.content_type
--> 151 body_value = self.serialize(body_value)
152 self._log_request(headers, path_params, query, body_value)
153 return (headers, path_params, query, body_value)
~/env/lib/python3.5/site-packages/googleapiclient/model.py in serialize(self, body_value)
258 self._data_wrapper):
259 body_value = {'data': body_value}
--> 260 return json.dumps(body_value)
261
262 def deserialize(self, content):
/usr/lib/python3.5/json/__init__.py in dumps(obj, skipkeys, ensure_ascii, check_circular, allow_nan, cls, indent, separators, default, sort_keys, **kw)
228 cls is None and indent is None and separators is None and
229 default is None and not sort_keys and not kw):
--> 230 return _default_encoder.encode(obj)
231 if cls is None:
232 cls = JSONEncoder
/usr/lib/python3.5/json/encoder.py in encode(self, o)
196 # exceptions aren't as detailed. The list call should be roughly
197 # equivalent to the PySequence_Fast that ''.join() would do.
--> 198 chunks = self.iterencode(o, _one_shot=True)
199 if not isinstance(chunks, (list, tuple)):
200 chunks = list(chunks)
/usr/lib/python3.5/json/encoder.py in iterencode(self, o, _one_shot)
254 self.key_separator, self.item_separator, self.sort_keys,
255 self.skipkeys, _one_shot)
--> 256 return _iterencode(o, 0)
257
258 def _make_iterencode(markers, _default, _encoder, _indent, _floatstr,
/usr/lib/python3.5/json/encoder.py in default(self, o)
177
178 """
--> 179 raise TypeError(repr(o) + " is not JSON serializable")
180
181 def encode(self, o):
TypeError: b'Q29udGVudC1UeXBlOiB0ZXh0L3BsYWluOyBjaGFyc2V0PSJ1cy1hc2NpaSIKTUlNRS1WZXJzaW9uOiAxLjAKQ29udGVudC1UcmFuc2Zlci1FbmNvZGluZzogN2JpdApGcm9tOiBUZXN0IFB5dGhvbgpUbzogcmFwaGFlbC5hLmR1bWFzQGdtYWlsLmNvbQpTdWJqZWN0OiBQbGVhc2Ugc3RheSBjYWxtLCB0aGlzIGlzIGEgdGVzdAoKVGhpcyBpcyBhIHRlc3Q=' is not JSON serializable
答
尝试:
b64_bytes = base64.urlsafe_b64encode(message.as_bytes())
b64_string = b64_bytes.decode()
body = {'raw': b64_string}
base64.urlsafe_b64encode
返回bytes对象(见docs ),所以你需要在将它输出为JSON之前将输出转换为字符串。
对我来说,答案本质上是这样做的:直接对encode(message.as_bytes())。decode()进行编码,但是在这里我们是,并且它工作正常。 – raphael