• flask 异步发送邮件 --


    异步发送邮件

    当使用SMTP的方式发送电子邮件时,如果你手动使用浏览器测试程序的注册功能,在提交注册表单后,浏览器会有几秒钟的不响应。因为这时候程序正在发送电子邮件,发信的操作阻断了请求--响应循环,直到发信的send_mail()函数调用结束后,视图函数才会返回响应。这几秒的延迟带了不好的用户体验,为了避免这个延迟,我们可以将发信函数放入后台线程异步执行,以Flask-Mail为例:

    app.py: 异步发送电子邮件

    from threading import Thread
    
    def _send_async_mail(app, message):
        with app.app_context():
            mail.send(message)
    
    def send_mail(subject, to, body):
        message = Message(subject, recipients=[to], body = body)
        thr = Thread(target=_send_async_mail, args=[app, message])
        thr.start()
        return thr

    因为Flask-Mail的send()方法内部的调用逻辑中使用了current_app变量,而这个变量只在激活的程序上下文中才存在,这里在后台线程调用发信函数,但是后台线程并没有程序上下文存在。为了正常实现发信功能,我们传入app作为参数,并调用app.app_context()手动激活程序上下文。

    app.py文件增加相关的类和函数
    #send over SMTP
    def send_smtp_mail(subject, to, body):
        message = Message(subject, recipients=[to], body=body)
        mail.send(message)
    
    class EmailForm(FlaskForm):
        to = StringField('To', validators=[DataRequired(),Email()])
        subject = StringField('Subject', validators=[DataRequired()])
        body = TextAreaField('Body', validators=[DataRequired()])
        submit_smtp = SubmitField('Send with SMTP')
        submit_async = SubmitField('Send with SMTP asynchronously')
    
    #send email asynchronously
    def _send_async_mail(app, message):
        with app.app_context():
            mail.send(message)
    
    def send_async_mail(subject, to ,body):
        message = Message(subject, recipients=[to],body=body)
        thr = Thread(target=_send_async_mail, args=[app, message])
        thr.start()
        return thr
    
    @app.route('/', methods=['GET','POST'])
    def index():
        form = EmailForm()
        if form.validate_on_submit():
            to = form.to.data
            subject = form.subject.data
            body = form.body.data
            if form.submit_smtp.data:
                send_smtp_mail(subject, to, body)
                print "request.form:",request.form
                method = request.form.get('submit_smtp')  #提交按钮的文字
            else:
                send_async_mail(subject, to, body)
                print "request.form:", request.form
                method = request.form.get('submit_async')  #提交按钮的文字
                print "method:",method
                print "method.split():",method.split()
            flash('Email sent %s! Check your inbox.' % ' '.join(method.split()[1:]))  #把按钮上的问题的前一个单词去掉,显示剩下的,用来提示发送方式
            return redirect(url_for('index'))
        form.subject.data = 'Keep on learning Flask!'
        form.body.data = 'Across the Great Wall we can reach every corner in the world.'
        return render_template('index.html', form=form)
    
    if __name__ == '__main__':
        print app.config
        app.run(debug = True)

    新建index.html:

    {% extends 'base.html' %}
    {% from 'macros.html' import form_field %}
    
    {% block content %}
    <h2>Send an Email to Yourself</h2>
    <p>or subscribe <a href="{{ url_for('subscribe') }}">the fake newsletter</a></p>
    
    <form method="post">
        {{ form.csrf_token }}
        {{ form_field(form.to, placeholder='xiaxiaoxu1987@163.com') }}
        {{ form_field(form.subject, size=30) }}
        {{ form_field(form.body, rows=5, cols=50) }}<br>
        {{ form.submit_smtp(class='btn') }}
        {{ form.submit_async(class='btn') }}
    </form>
    {% endblock %}

    在测试前,确保在demos/email目录下添加一个.env文件,保存发送邮件所需要的MAIL_SERVER、MAIL_USERNAME、MAIL_PASSWORD的值。准备好后,访问index页面,在表单To字段里填入你的邮箱地址,然后单击下面的按钮发送邮件,Send with SMTP将通过普通的SMTP方式发信,Send with SMTP asynchronously则会以异步的方式通过SMTP发信。

    访问127.0.0.1:5000,渲染index页面,在页面中输入你的名称和邮件,就会收到包含HTML正文的邮件。

    发送Send with SMTP asynchronously: 异步发送邮件,页面立刻会看到flash消息

     

    SMTP方式发送邮件,需要等待几秒才能看到flash消息

     

    邮箱发送情况
     
  • 相关阅读:
    iOS证书的使用
    ios设备管理
    矩阵的相关问题(旋转矩阵&螺旋矩阵)
    flex实现多列布局效果&对角线布局
    peerdependencies
    数组和对象遍历方法对比
    async和defer
    Promise.all并发限制
    electron+react开发属于自己的桌面应用
    webpack代码切割
  • 原文地址:https://www.cnblogs.com/xiaxiaoxu/p/10753543.html
Copyright © 2020-2023  润新知