学习Flask之六、Email

本文介绍了如何在Flask应用中使用Flask-Mail扩展来发送邮件,包括安装、配置SMTP服务器,特别是通过Gmail帐户发送邮件的示例,以及如何实现异步发送邮件以提高应用响应性。
摘要由CSDN通过智能技术生成

许多类型的应用需要通知用户当某些事件发生时,常用的通讯方法是使用 email。虽然python标准库中的smtplib包可以在Flask应用内发送邮件,Flask-Mail扩展打包了smtplib 并能很好的与Flask集成。

使用Flask-Mail的Email支持

Flask-Mail通过pip安装:

(venv) $ pip install flask-mail

这个扩展连接Simple Mail Transfer Protocol (SMTP)服务器并将emails传递给服务器发送。 如果不提供配置,Flask-Mail连接localhost在端口25,发送email不需要授权。

Table 6-1展示可以用来配置SMTP服务器的配置列表

见http://www.aluoyun.cn/details.php?article_id=202

在开发过程中,使用外部的SMTP服务器更方便。

作为例子,Example 6-1显示如何配置应用来通过Google Gmail帐户发送email。

Example 6-1. hello.py: Flask-Mail configuration for Gmail

import os

# ...

app.config['MAIL_SERVER'] = 'smtp.googlemail.com'

app.config['MAIL_PORT'] = 587

app.config['MAIL_USE_TLS'] = True

app.config['MAIL_USERNAME'] = os.environ.get('MAIL_USERNAME')

app.config['MAIL_PASSWORD'] = os.environ.get('MAIL_PASSWORD')

不要将帐户密码直接写在你的脚本里,特别是如果不想将你的作品发布为开源。为了保护你的帐户信息,使你的脚本导入敏感信息自环境。

Flask-Mail如Example 6-2初始化。

Example 6-2. hello.py: Flask-Mail initialization

from flask.ext.mail import Mail

mail = Mail(app)

两个环境变量存贮邮箱的用户名和密码,需要在环境中定义。如果你在Linux 或Mac OS X中使用bash, 你可以这样设置变量:

(venv) $ export MAIL_USERNAME=<Gmail username>

(venv) $ export MAIL_PASSWORD=<Gmail password>

对于Microsoft Windows用户,环境变量的设置如下:

(venv) $ set MAIL_USERNAME=<Gmail username>

(venv) $ set MAIL_PASSWORD=<Gmail password>

从Python Shell发送邮件

要测试配置,你可以开始一个shell会话并发送一个测试邮件:

(venv) $ python hello.py shell

>>> from flask.ext.mail import Message

>>> from hello import mail

>>> msg = Message('test subject', sender='you@example.com',

... recipients=['you@example.com'])

>>> msg.body = 'text body'

>>> msg.html = '<b>HTML</b> body'

>>> with app.app_context():

... mail.send(msg)

...

注意Flask-Mail的send()函数使用current_app,所以它需要执行具有一个激活的应用上下文。

用应用集成Emails

为了避免每次手工创建email消息, 将应用的发送邮件功能提取到一个函数中是很好的主意。另外的好处是,这个函数可以宣染邮件主体自Jinja2模板以获得最大的灵活性。其实施见Example 6-3。

Example 6-3. hello.py: Email support

from flask.ext.mail import Message

app.config['FLASKY_MAIL_SUBJECT_PREFIX'] = '[Flasky]'

app.config['FLASKY_MAIL_SENDER'] = 'Flasky Admin <flasky@example.com>'

def send_email(to, subject, template, **kwargs):

msg = Message(app.config['FLASKY_MAIL_SUBJECT_PREFIX'] + subject,

sender=app.config['FLASKY_MAIL_SENDER'], recipients=[to])

msg.body = render_template(template + '.txt', **kwargs)

msg.html = render_template(template + '.html', **kwargs)

mail.send(msg)

这个函数依赖于两个应用特定的配置键,为主题配置一个前置字符串和发送者的地址。 send_email 函数取目的地址,主题行, email主体模板,关键字参数列表。模板名称不能带扩展名,以便两个版本的模板可以给明文和富文本主体使用。

调用者传递的关键字参数给render_template()调用,以便它们可以被产生邮件主体的模板使用。index()函数可以易容的扩展到发送邮件给管理者只要表单中有新的 name接收。Example 6-4展示了这种变更

Example 6-4. hello.py: Email example

# ...

app.config['FLASKY_ADMIN'] = os.environ.get('FLASKY_ADMIN')

# ...

@app.route('/', methods=['GET', 'POST'])

def index():

form = NameForm()

if form.validate_on_submit():

user = User.query.filter_by(username=form.name.data).first()

if user is None:

user = User(username=form.name.data)

db.session.add(user)

session['known'] = False

if app.config['FLASKY_ADMIN']:

send_email(app.config['FLASKY_ADMIN'], 'New User',

'mail/new_user', user=user)

else:

session['known'] = True

session['name'] = form.name.data

form.name.data = ''

return redirect(url_for('index'))

return render_template('index.html', form=form, name=session.get('name'),

known=session.get('known', False))

邮件的接收者在FLASKY_ADMIN环境变量里,在启动时导入到同名的配置变量里。对于 text 和HTML的邮件需要创建二个模板文件。这些文件放在templates目录的mail子目录,与正常的模板分开。

email模板需要指出用户作为模板的参数,所以调用 send_email()包含它作为关键字参数。

除了前面描述的MAIL_USERNAME和MAIL_PASSWORD环境变量,这个版本的应用需要 FLASKY_ADMIN。对于Linux和Mac OS X用户,启动应用的命令为:

(venv) $ export FLASKY_ADMIN=<your-email-address> 

对于Microsoft Windows用户,下面的命令是等价的:

(venv) $ set FLASKY_ADMIN=<Gmail username>

通过设置这些环境变量,你可以测试应用并接收邮件,当你在表单里输入新的名字时。

发送异步Email

如果你发送一些测试邮件,你可能会注意到当发送邮件时mail.send() 阻塞几秒钟,这过程中浏览器看起来没有响应。为了避免请求处理过程的不必要的延时,email 发送函数可以放到背景线程中。 Example 6-5 展示这种变更。

Example 6-5. hello.py: Asynchronous email support

from threading import Thread

def send_async_email(app, msg):

with app.app_context():

mail.send(msg)

def send_email(to, subject, template, **kwargs):

msg = Message(app.config['FLASKY_MAIL_SUBJECT_PREFIX'] + subject,

sender=app.config['FLASKY_MAIL_SENDER'], recipients=[to])

msg.body = render_template(template + '.txt', **kwargs)

msg.html = render_template(template + '.html', **kwargs)

thr = Thread(target=send_async_email, args=[app, msg])

thr.start()

return thr

这个实施突出一个有兴趣的问题。许多Flask扩展在假定有活动的应用和请求上下文。 Flask-Mail的send()函数使用current_app,所以它要求应用上下文是激活的。但是当 mail.send()函数执行不同的线程时,应用上下文需要用app.app_context()创建。

如果你现在运行应用,你发注意到它更有响应性,但是注意对于发送大容量的邮件,有一个专门的发送邮件的线程比每个邮件用一个线程更全合适。例如,send_async_email()函数的执行可以发送到Celery任务队列。本章完成全了大部分网络应用开发都有的概要特征。现在的问题是hello.py脚本变得越来越大,难于维护。下一章,你将学习如可构建大型的应用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lishaoan77

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值