我正在使用 Flask-Mail 扩展从我的 Flask 应用程序发送电子邮件。它同步运行 send() 方法,我必须等到它发送消息。我怎样才能让它在后台运行?
最佳答案
没那么复杂——你需要在另一个线程中发送邮件,这样你就不会阻塞主线程。但是有一个技巧。
这是我的代码,它呈现模板、创建邮件正文并允许同步和异步发送:
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()
注意
@copy_current_request_context
装饰器。这是必需的,因为 Flask-Mail 内部使用请求上下文。如果我们在新线程中运行它,上下文将被遗漏。我们可以使用 @copy_current_request_context
来阻止这个装饰函数——当函数被调用时,Flask 会推送上下文。要使用此代码,您还需要使用 Flask 应用程序初始化
mail
对象:run.py
app = Flask('app')
mail_sender.mail.init_app(app)
关于python - 异步运行 Flask-Mail,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/11047307/