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消息

邮箱发送情况
flask 异步发送邮件的更多相关文章
- C# 利用SMTP异步发送邮件
C#实现收发邮件功能需要用到两个命名空间 System.Net; 和 System.Net.Mail; SmtpClient client = new SmtpClient("smtp.g ...
- Spring的JavaMail实现异步发送邮件
具体背景就不说了,可以网上搜索相关知识,或者直接看Sping MailSender的官坊网页.这里就直接实战了(Java实现异步发送电子邮件,包含中文无乱码). Maven: <dependen ...
- celery异步发送邮件
利用Django框架发送邮件的详细过程,在前两天的博客中有所记录,但是单纯的那样发邮件是有非常大的问题的,这就需要celery异步发送来解决 首先我们来看一下邮件发送的过程: Django网站先发送到 ...
- spring boot 异步发送邮件
发送邮件由于是一个耗时的操作,有可能需要一个几十秒的操作,但是呢,接口 是一个瞬间完成的,为了不影响接口的性能,所以需要对发送邮件的操作进行异步操作,我们这里呢,首先我们要引入发送邮件的测试模块. & ...
- (三)集成 JavaMail ,实现异步发送邮件
集成 JavaMail ,实现异步发送邮件 1.JavaMail的核心API 1.1 API功能图解 1.2 API说明 1.2.1 Message 类: 1.2.2 Transport 类 1.2. ...
- flask使用blinker信号机制解耦业务代码解决ImportError: cannot import name 'app',以异步发送邮件为例
百度了大半天,不知道怎么搞,直到学习了blinker才想到解决办法,因为之前写java都是文件分开的, 所以发送邮件业务代码也放到view里面,但是异步线程需要使用app,蛋疼的是其他模块不能从app ...
- SpringBoot 2.0 集成 JavaMail ,实现异步发送邮件
一.JavaMail的核心API 1.API功能图解 2.API说明 (1).Message 类: javax.mail.Message 类是创建和解析邮件的一个抽象类 子类javax.mail.in ...
- flask 异步celery使用
在开发过程中,耗时长,超时的任务经常发生,比如:获取后端某个大文件数据超时.需要后端计算任务超时,等等, 此时我们就会很自然的想到异步方式,根据需要完成的任务创建一个task_id, 由前端来监听该任 ...
- Flask 异步化
web网站包含前端和后端, 异步处理可以用在前端, 也可以用在后端. 前端 jquery 进行 ajax 请求时, 可设置 async 属性为 true, 并为 success 设置一个 callb ...
随机推荐
- 编写程序,将来自文件中的行保存在一个vector<string>,然后使用一个istringstream 从vector中读取数据,每次读一个单词
#include<fstream> #include <vector> #include<string> #include<iostream> #inc ...
- python 生成器generator
关于生成器,主要有以下几个 关键点的内容 一.什么是generator ,为什么要有generator? 二.两种创建生成器方式 三.yield关键字 四.generator 两个调用方法 next( ...
- centos7下NFS使用与配置
NFS是Network File System的缩写,即网络文件系统.客户端通过挂载的方式将NFS服务器端共享的数据目录挂载到本地目录下. nfs为什么需要RPC?因为NFS支持的功能很多,不同功能会 ...
- 秒杀ecshop的前台写shell 0day
ECSHOP号称最大的开源网店系统,官方是这样介绍它的:“ECShop网店系统是一套免费开源的网上商店软件,无论在稳定性.代码优化.运行效率.负载能力.安全等级.功能可操控性和权限严密性等方面都居国内 ...
- 防止enter提交表单
如何防止回车(enter)键提交表单,其实很简单,就一句话.onkeydown="if(event.keyCode==13)return false;"把这句写在from标签里面就 ...
- Sublime Text 3 使用心得
1.Ctrl + Shift + P : package control install package == > ConvertToUTF82.列模式: 苹果:OS X -鼠标左键+Optio ...
- webrtc如何进行错误恢复
视频的压缩方法:(三种帧) 为了视频尽可能的保持高效,视频数据通过不同的编码进行压缩.以帧为单位进行压缩,按照压缩中的不同作用可分类为:内帧(Intra-frames,I帧),预测帧(Predicti ...
- 6. Scala面向对象编程(基础部分)
6.1 基本介绍 6.1.1 Scala语言是面向对象的 1) Java时面向对象的编程语言,由于历史原因,Java中海存在着非面向对象的内容:基本类型,null,静态方法等 2) Scala语言来自 ...
- CentOS7 使用systemctl来管理服务
1.建立service文件 以tomcat为例 , 建立tomcat.service文件 #服务说明 [Unit] #服务描述 Description=Tomcat Service #前置需要启动的服 ...
- mysql(七)
多表查询: 显示内连接: select 字段列表 from 表名1 inner join 表名1 on 条件 * inner 可忽略 select * from student inner j ...