异步运行Flask-Mail

Ser*_*rov 2 python email flask

我正在使用Flask-Mail扩展程序从我的Flask应用程序发送电子邮件.它同步运行send()方法,我必须等到它发送消息.如何让它在后台运行?

Mar*_*oni 7

它不是那么复杂 - 你需要在另一个线程中发送邮件,所以你不会阻止主线程.但有一个技巧.

这是我的代码,它呈现模板,创建邮件正文,并允许同步和异步发送它:

mail_sender.py

import threading
from flask import render_template, copy_current_request_context, current_app
from flask_mail import Mail, Message

mail = Mail()

def create_massege(to_email, subject, template, from_email=None, **kwargs):
    if not from_email:
        from_email = current_app.config['ROBOT_EMAIL']
    if not to_email:
        raise ValueError('Target email not defined.')
    body = render_template(template, site_name=current_app.config['SITE_NAME'], **kwargs)
    subject = subject.encode('utf-8')
    body = body.encode('utf-8')
    return Message(subject, [to_email], body, sender=from_email)

def send(to_email, subject, template, from_email=None, **kwargs):
    message = create_massege(to_email, subject, template, from_email, **kwargs)
    mail.send(message)

def send_async(to_email, subject, template, from_email=None, **kwargs):
    message = create_massege(to_email, subject, template, from_email, **kwargs)

    @copy_current_request_context
    def send_message(message):
        mail.send(message)

    sender = threading.Thread(name='mail_sender', target=send_message, args=(message,))
    sender.start()
Run Code Online (Sandbox Code Playgroud)

请注意@copy_current_request_context装饰师.这是必需的,因为Flask-Mail内部使用请求上下文.如果我们将在新线程中运行它,将错过上下文.我们可以通过以下方式阻止这种装饰功能@copy_current_request_context- 当调用函数时,Flask将推送上下文.

要使用此代码,还需要mail使用Flask应用程序初始化对象:

run.py

app = Flask('app')
mail_sender.mail.init_app(app)
Run Code Online (Sandbox Code Playgroud)