Flask Mail - невозможно отправить сообщение с вложением - PullRequest
0 голосов
/ 15 января 2020

У меня есть некоторый рабочий код для асинхронной отправки электронных писем (любезно предоставлено Flask Megatutorial), но когда я пытаюсь добавить вложение, я получаю следующее сообщение:

Exception in thread Thread-5:
Traceback (most recent call last):
  File "C:\Users\tribl\AppData\Local\Programs\Python\Python37\lib\threading.py", line 926, in _bootstrap_inner
    self.run()
  File "C:\Users\tribl\AppData\Local\Programs\Python\Python37\lib\threading.py", line 870, in run
    self._target(*self._args, **self._kwargs)
  File "C:\Users\tribl\PycharmProjects\CM2020\app\email.py", line 11, in send_async_email
    mail.send(msg)
  File "C:\Users\tribl\PycharmProjects\CM2020\venv\lib\site-packages\flask_mail.py", line 492, in send
    message.send(connection)
  File "C:\Users\tribl\PycharmProjects\CM2020\venv\lib\site-packages\flask_mail.py", line 427, in send
    connection.send(self)
  File "C:\Users\tribl\PycharmProjects\CM2020\venv\lib\site-packages\flask_mail.py", line 190, in send
    message.as_bytes() if PY3 else message.as_string(),
  File "C:\Users\tribl\PycharmProjects\CM2020\venv\lib\site-packages\flask_mail.py", line 385, in as_bytes
    return self._message().as_bytes()
  File "C:\Users\tribl\PycharmProjects\CM2020\venv\lib\site-packages\flask_mail.py", line 349, in _message
    f = MIMEBase(*attachment.content_type.split('/'))
TypeError: __init__() missing 1 required positional argument: '_subtype'

Соответствующий код ниже первое def (send_async_email) вызывается вторым и третьим def, они идентичны, кроме добавления вложения во втором. Кажется, я не могу найти онлайн-справку по этому вопросу, поэтому спрашиваю сообщество.

def send_async_email(app,msg):
    with app.app_context():
        mail.send(msg)


def send_email(subject, sender, recipients, text_body, html_body):
    msg = Message(subject, sender=sender, recipients=recipients)
    msg.body = text_body
    msg.html = html_body
    Thread(target=send_async_email,
           args=(current_app._get_current_object(), msg)).start()



def send_email_with_attachment(subject, sender, recipients, text_body, html_body):
    msg = Message(subject, sender=sender, recipients=recipients)
    msg.body = text_body
    msg.html = html_body
    with open("welcome.txt") as fp:
        msg.attach("welcome.txt", "welcome.txt", fp.read())
    Thread(target=send_async_email,
           args=(current_app._get_current_object(), msg)).start()

1 Ответ

0 голосов
/ 16 января 2020

Вы используете Python 3. Ниже приведено определение MIMEBase (Python 3.7.3), обратите внимание, что необходимы подпись __init__, _maintype, _subtype. Вам нужно будет изменить flask_mail.py для отправки вложений.

class MIMEBase(message.Message):
    """Base class for MIME specializations."""

    def __init__(self, _maintype, _subtype, *, policy=None, **_params):
        """This constructor adds a Content-Type: and a MIME-Version: header.

        The Content-Type: header is taken from the _maintype and _subtype
        arguments.  Additional parameters for this header are taken from the
        keyword arguments.
        """
        if policy is None:
            policy = email.policy.compat32
        message.Message.__init__(self, policy=policy)
        ctype = '%s/%s' % (_maintype, _subtype)
        self.add_header('Content-Type', ctype, **_params)
        self['MIME-Version'] = '1.0'

В flask_mail.py строке 349 мы * MIMEBase реализованы следующим образом:

for attachment in attachments:
    f = MIMEBase(*attachment.content_type.split('/'))

Для работы с Python 3 это должно быть изменено на:

for attachment in attachments:
    maintype, subtype = attachment.content_type.split('/')
    f = MIMEBase(maintype, subtype)
...