Я использую google-api- python -client == 1.7.11
У меня был python 2 код, который работал нормально, адаптированный с https://developers.google.com/gmail/api/v1/reference/users/messages/send
Я преобразовал свой код в python 3 и увидел ошибку TypeEr из urlsafe_b64encode ниже
Мой код:
# standard
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from base64 import urlsafe_b64encode
# pypi
from flask import current_app
from apiclient import errors
def sendmail(subject, fromaddr, toaddr, html, text='', ccaddr=None ):
'''
send mail
:param subject: subject of email
:param fromaddr: from address to use
:param toaddr: to address to use, may be list of addresses
:param html: html to send
:param text: optional text alternative to send
'''
current_app.logger.info('sendmail(): from={}, to={}, cc={}, subject="{}"'.format(fromaddr, toaddr, ccaddr, subject))
# Create message container - the correct MIME type is multipart/alternative.
msg = MIMEMultipart('alternative')
msg['Subject'] = subject
msg['From'] = fromaddr
if not isinstance(toaddr, list):
toaddr = [toaddr]
msg['To'] = ', '.join(toaddr)
if ccaddr:
if not isinstance(ccaddr, list):
ccaddr = [ccaddr]
msg['Cc'] = ', '.join(ccaddr)
# Record the MIME types of both parts - text/plain and text/html.
# Attach parts into message container.
# According to RFC 2046, the last part of a multipart message, in this case
# the HTML message, is best and preferred.
if text:
part1 = MIMEText(text, 'plain')
msg.attach(part1)
part2 = MIMEText(html, 'html')
msg.attach(part2)
# get credentials using the service account file
gmail = gmail_service_account_login( current_app.config['APP_SERVICE_ACCOUNT_FILE'], 'librarian@steeplechasers.org' )
try:
if debug: current_app.logger.debug('sendmail(): msg.as_string()={}'.format(msg.as_string()))
message = { 'raw' : urlsafe_b64encode(msg.as_string()) }
sent = gmail.users().messages().send(userId='me', body=message).execute()
return sent
except errors.HttpError as error:
current_app.logger.error('sendmail(): An error occurred: {}'.format(error))
raise
Я изменил код для использования as_bytes (), похоже на то, что упомянуто в Как решить, что требуется «похожий на байты объект, а не« str »» в функции create_message ()?
message = { 'raw' : urlsafe_b64encode(msg.as_bytes()) }
Теперь я вижу json ошибка сериализации при вызове messages (). Send (). Я вижу, API Google указывает, что он поддерживает python 3,6 на Pypi. Не уверен, какие дополнительные моды мне нужно сделать, чтобы интерфейс gmail работал правильно.
Traceback (most recent call last):
File "C:\Users\lking\Documents\Lou's Software\projects\contracts\contracts\venv\lib\site-packages\flask\app.py", line 2463, in __call__
return self.wsgi_app(environ, start_response)
File "C:\Users\lking\Documents\Lou's Software\projects\contracts\contracts\venv\lib\site-packages\flask\app.py", line 2449, in wsgi_app
response = self.handle_exception(e)
File "C:\Users\lking\Documents\Lou's Software\projects\contracts\contracts\venv\lib\site-packages\flask\app.py", line 1866, in handle_exception
reraise(exc_type, exc_value, tb)
File "C:\Users\lking\Documents\Lou's Software\projects\contracts\contracts\venv\lib\site-packages\flask\_compat.py", line 39, in reraise
raise value
File "C:\Users\lking\Documents\Lou's Software\projects\contracts\contracts\venv\lib\site-packages\flask\app.py", line 2446, in wsgi_app
response = self.full_dispatch_request()
File "C:\Users\lking\Documents\Lou's Software\projects\contracts\contracts\venv\lib\site-packages\flask\app.py", line 1951, in full_dispatch_request
rv = self.handle_user_exception(e)
File "C:\Users\lking\Documents\Lou's Software\projects\contracts\contracts\venv\lib\site-packages\flask\app.py", line 1820, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "C:\Users\lking\Documents\Lou's Software\projects\contracts\contracts\venv\lib\site-packages\flask\_compat.py", line 39, in reraise
raise value
File "C:\Users\lking\Documents\Lou's Software\projects\contracts\contracts\venv\lib\site-packages\flask\app.py", line 1949, in full_dispatch_request
rv = self.dispatch_request()
File "C:\Users\lking\Documents\Lou's Software\projects\contracts\contracts\venv\lib\site-packages\flask\app.py", line 1935, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "C:\Users\lking\Documents\Lou's Software\projects\contracts\contracts\venv\lib\site-packages\flask\views.py", line 89, in view
return self.dispatch_request(*args, **kwargs)
File "C:\Users\lking\Documents\Lou's Software\projects\contracts\contracts\venv\lib\site-packages\flask\views.py", line 163, in dispatch_request
return meth(*args, **kwargs)
File "C:\Users\lking\Documents\Lou's Software\projects\contracts\contracts\contracts\views\frontend\eventscalendar.py", line 249, in post
sendmail( subject, fromlist, tolist, html, ccaddr=cclist )
File "C:\Users\lking\Documents\Lou's Software\projects\contracts\contracts\contracts\mailer.py", line 77, in sendmail
sent = gmail.users().messages().send(userId='me', body=message).execute()
File "C:\Users\lking\Documents\Lou's Software\projects\contracts\contracts\venv\lib\site-packages\googleapiclient\discovery.py", line 789, in method
actual_path_params, actual_query_params, body_value)
File "C:\Users\lking\Documents\Lou's Software\projects\contracts\contracts\venv\lib\site-packages\googleapiclient\model.py", line 158, in request
body_value = self.serialize(body_value)
File "C:\Users\lking\Documents\Lou's Software\projects\contracts\contracts\venv\lib\site-packages\googleapiclient\model.py", line 267, in serialize
return json.dumps(body_value)
File "C:\Users\lking\AppData\Local\Programs\Python\Python36\lib\json\__init__.py", line 231, in dumps
return _default_encoder.encode(obj)
File "C:\Users\lking\AppData\Local\Programs\Python\Python36\lib\json\encoder.py", line 199, in encode
chunks = self.iterencode(o, _one_shot=True)
File "C:\Users\lking\AppData\Local\Programs\Python\Python36\lib\json\encoder.py", line 257, in iterencode
return _iterencode(o, 0)
File "C:\Users\lking\AppData\Local\Programs\Python\Python36\lib\json\encoder.py", line 180, in default
o.__class__.__name__)
TypeError: Object of type 'bytes' is not JSON serializable