文 | 思诚之道
泉源 :https://www.bjhee.com/flask-ext2.html
继承 先容 Flask 常用的扩展,很多 站点都必要 发送邮件功能 ,比如 用户注册乐成 邮件,用户重置暗码 邮件。你可以利用 Python 的 smtplib来发邮件,不外 Flask 有个第三方扩展 Flask-Mail ,可以更方便的实现此功能 。这里我们就来先容 下这个 Flask-Mail。
系列文章
Flask 扩展系列(一)–Restful
安装和启用
发起 通过 pip 安装,简单 方便:
$ pip install Flask-Mail
我们可以采取 下面的方法初始化一个 Mail 的实例:
fromflask importFlask
fromflask_mail importMail
app =Flask(__name__)
mail =Mail(app)
同其他扩展一样,末了 一行实例化代码也可以写成下面的方式:
...
mail =Mail()
mail.init_app(app)
如许 的写法在应用工厂模式下常常 会用到。
发送邮件
我们来看一段发送 Hello World 邮件的代码:
fromflask importFlask
fromflask_mail importMail,Message
app =Flask(__name__)
app.config.update(
MAIL_SERVER='smtp.example.com',
MAIL_USERNAME='bjhee',
MAIL_PASSWORD='example'
)
mail =Mail(app)
@app.route('/mail')
defsend_mail():
msg =Message('Hello',
sender=('Billy.J.Hee','bjhee@example.com'),
recipients=['you@example.com'])
msg.html ='h1Hello World/h1'
mail.send(msg)
return'Successful'
if__name__ =='__main__':
app.run(host='0.0.0.0',debug=True)
访问"https://localhost:5000/mail" ,邮件就会被发送出去 。不消 过多表明 信托 各人 都看懂了,由于 确实很简单 。我们在 Flask 的设置 项中配上邮件 SMTP 服务器,用户名和暗码 ;在哀求 中创建一个 Message 消息实例,传入邮件标题 ,发件人(元组,包罗 表现 名和地点 ),收件人(列表)和邮件体;然后调用"Mail.send()"方法发送该消息即可。
Message 对象的属性 ,可以在初始化时当作 参数(key=value) 传入,也可以在初始化后赋值 。比如 我们可以如许 界说 收件人:
msg.recipients=['you@example.com']
由于收件人可以多个,我们也可以通过"add_recipient()"方法添加收件人:
msg.add_recipient('he@example.com')
发件人可以没有表现 名 ,只要一个地点 字符串即可:
msg.sender='bjhee@example.com'
别的 ,上例中的邮件体是 HTML 格式,假如 是 Plain Text 格式的话 ,你可以如许 写:
msg.body ='Hello World'
设置 参数
Flask-Mail 扩展可以在 Flask 应用设置 项中设置 其参数,上例中我们已经看到了 SMTP 服务器,用户名和暗码 的设置 项 ,这里罗列 一些常用的:
设置 项
功能
MAIL_SERVER
SMTP邮件服务器地点 ,默以为 localhost
MAIL_PORT
SMTP邮件服务器端口,默以为 25
MAIL_USERNAME
邮件服务器用户名
MAIL_PASSWORD
邮件服务器暗码
MAIL_DEFAULT_SENDER
默认发件人,假如 Message对象里没指定发件人 ,就采取 默认发件人
MAIL_USE_TLS
是否启用TLS,默以为 False
MAIL_USE_SSL
是否启用SSL,默以为 False
MAIL_MAX_EMAILS
邮件批量发送个数上限 ,默以为 没有上限
MAIL_ASCII_ATTACHMENTS
将附件的文件名逼迫 转换为ASCII字符,克制 在某些环境 下出现乱码,默以为 False
MAIL_SUPPRESS_SEND
调用”Mail.send() ”方法后 ,邮件不会真的被发送,在测试环境 中利用 ,默以为 False
批量发送
假如 一次必要 发送大量邮件 ,发起 采取 下面的方式:
@app.route('/batch')
defsend_batch():
withmail.connect()asconn:
foruser inusers:
msg =Message(subject='Hello, %s'%user['name'],
body='Welcome, %s'%user['name'],
recipients=[user['email']])
conn.send(msg)
return'Successful'
如许 应用同邮件服务器的毗连 "mail.connect()"会不停 保持到全部 邮件发送完毕,也就是退出 with 语句后再关闭,克制 多次创建关闭毗连 的开销。批量发送邮件个数上限由设置 项"MAILMAXEMAILS"决定。
邮件带附件
回到第一个发送邮件的例子 ,让我们在 Hello World 邮件中加上附件:
@app.route('/mail')
defsend_mail():
msg =Message('Hello',
sender=('Billy.J.Hee','bjhee@example.com'),
recipients=['you@example.com'])
msg.html ='h1Hello World/h1'
# Add Attachment
withapp.open_resource('blank.docx')asfp:
msg.attach('blank.docx','application/msword',fp.read())
mail.send(msg)
return'Successful'
上面的代码中,我们通过"app.open_resource()"方法打开了本地 当前目次 下的"blank.docx"文件,然后通过"Message.attach()"方法将其附到消息对象中即可。"Message.attach()"方法的第一个参数指定了附件上的文件名,第二个参数指定了文件内容的 MIME 范例 ,第三个参数就是文件内容 。
假如 各人 不知道要附上的文件 MIME 范例 是什么,可以查下 MIME 参考手册。
email_dispatched 信号
Flask-Mail 扩展还提供了一个信号"email_dispatched",当邮件被调治 时 ,该信号就会被发出。假如 各人 忘了什么是信号,可以参考 进阶系列的第二篇 。开辟 者可以通过这个信号来确定邮件是否被发送乐成 。固然 ,发送乐成 不代表被吸取 乐成 。
fromflask_mail importemail_dispatched
deflog_mail_sent(message,app):
print'Message "%s" is sent successfully'%(message.subject)
email_dispatched.connect(log_mail_sent)
别的 ,在跑测试时我们不盼望 邮件真的被发出去,此时可以将 Flask 应用的设置 项"TESTING"设成 True,大概 将 Flask-Mail 扩展的设置 项"MAILSUPPRESSSEND"设成 True 。如许 ,调用"Mail.send()"方法后,邮件不会被发出,但是你依然可以吸取 到"email_dispatched"信号。
本篇中的示例参考了 Flask-Mail 的官方文档和 Flask-Mail 的源码。本篇的示例代码可以在这里下载 。
题图:pexels ,CC0 授权。