电子邮件是最常用的通信方式之一。虽然Python标准库中的smtplib包可用在Flask程序中发送电子邮件,但包装了smtplib的Flask-Mail扩展能更好的和Flask集成。

1.安装Flask-Mail

1.1使用pip安装

pip install flask-mail

1.2 下载源码安装

git clone https://github.com/mattupstate/flask-mail.git
cd flask-mail
python setup.py install

2.flask-mail初始化

from flask import Flask
from flask_mail import Mail, Message app = Flask(__name__)
mail = Mail(app)

3.Flask-Mail 配置

3.1 Flask-Mail常用配置项

Flask-Mail通过标准的Flask配置API进行配置,这些常用的配置项如下:

配置  默认值 说明
MAIL_SERVER localhost 电子邮件服务器的主机名或IP地址         
MAIL_PORT 25 电子邮件服务器的端口
MAIL_USE_TLS False 启用传输层安全(Transport Layer Security,TLS)协议
MAIL_USE_SSL Flase 启用安全套接层(Secure Sockets Layer,SSL)协议
MAIL_USERNAME None 邮件账户的用户名
MAIL_PASSWORD None 邮件账户的密码
MAIL_DEFAULT_SENDER None 默认发件人,如果Message对象里没指定发件人,就采用默认发件人
MAIL_MAX_EMAILS None 邮件批量发送个数上限,默认为没有上限
MAIL_SUPPRESS_SEND app.testing 调用“Mail.send()”方法后,邮件不会真的被发送,在测试环境中使用,默认为False
MAIL_ASCII_ATTACHMENTS Flase 将附件的文件名强制转换为ASCII字符,避免在某些情况下出现乱码

3.2 常见的SMTP邮箱服务配置

(1)配置QQ邮箱服务器

MAIL_SERVER = 'smtp.qq.com',
MAIL_PROT = 25,
MAIL_USE_TLS = True,
MAIL_USE_SSL = False,
MAIL_USERNAME = "",
MAIL_PASSWORD = "",

QQ邮箱的配置方式如下:

开启了授权之后,就会弹出生成授权码页面:

注意:

a.qq邮箱的服务器地址为smtp.qq.com;

b.邮箱服务的端口为25或者465都可以;

c.TLS,SSL的选择很多人发不出去邮件的关键之一,这里QQ邮箱选择TLS;

d.账号和密码需要特别注意,这里的账号是自己的QQ邮箱账号,密码不是QQ邮箱密码,而是生成的授权码

(2)其他邮箱后续补充

4. 简单功能实现

下面举例说明flask-email扩展是如何实现简单邮件发送的:

from flask import Flask
from flask_mail import Mail, Message
app = Flask(__name__)
app.config.update(
MAIL_SERVER='smtp.qq.com',
MAIL_PROT=465,
MAIL_USE_TLS=True,
MAIL_USE_SSL=False,
MAIL_USERNAME="xxxxxxxxxxxxx@qq.com",
MAIL_PASSWORD="****************",
) mail = Mail(app) @app.route('/')
def index():
# sender 发送方,recipients 邮件接收方列表
msg = Message("Hi!This is a test ",sender='xxxxxxxxxxxxxx@qq.com', recipients=['test@example.com'])
# msg.body 邮件正文
msg.body = "This is a first email"
mail.send(msg)
print("Mail sent")
return 'send successfully'
if __name__ == "__main__": app.run(debug=True)

如果想发送信息,首先需要创建一个Message实例:

msg = Message("Hello",sender="from@example.com",recipients=["to@example.com"])

当然,我们也可以单独添加邮件接收对象:

msg.recipients = ["you@example.com"]
msg.add_recipient("somebodyelse@example.com")

在配置参数的时候,如果我们设置了MAIL_DEFAULT_SENDER参数,在后面创建message实例时不需要清楚指明邮件发送方,此时程序会自动获取默认配置:

msg = Message("Hello",recipients=["to@example.com"])

5.异步发送邮件

使用上面的方式发送邮件,会发现页面卡顿了几秒才出现消息,这是因为我们使用了同步的方式。为了避免发送邮件过程中出现的延迟,我们把发送邮件的任务移到后台线程中。代码如下:

# -*- coding:utf-8 -*-

from flask import Flask
from flask_mail import Mail, Message
from threading import Thread
import os app = Flask(__name__) app.config['MAIL_SERVER'] = 'smtp.qq.com'
app.config['MAIL_PORT'] = 25
app.config['MAIL_USE_TLS'] = True
app.config['MAIL_USERNAME'] = os.environ.get('MAIL_USERNAME') or 'xxxxxxxxxx@qq.com'
app.config['MAIL_PASSWORD'] = os.environ.get('MAIL_PASSWORD') or '*********' mail = Mail(app) def send_async_email(app, msg):
with app.app_context():
mail.send(msg) @app.route('/sync')
def send_email():
msg = Message('Hi', sender='xxxxxxxx@qq.com', recipients=['test@example.com'])
msg.html = '<b>send email asynchronously</b>' thr = Thread(target=send_async_email, args=[app, msg])
thr.start()
return 'send successfully' if __name__ == '__main__':
app.run(debug=True)

在上面,我们创建了一个线程,执行的任务是send_async_email,该任务的实现涉及一个问题:

很多 Flask 扩展都假设已经存在激活的程序上下文和请求上下文。Flask-Mail 中的 send() 函数使用 current_app,因此必须激活程序上下文。不过,在不同线程中执行 mail.send() 函数时,程序上下文要使用 app.app_context()人工创建。

6.带附件的邮件

有时候,我们发邮件的时候需要添加附件,比如文档和图片等,这也很简单,代码如下:

# -*- coding: utf-8 -*-

from flask import Flask
from flask_mail import Mail, Message
import os app = Flask(__name__) app.config['MAIL_SERVER'] = 'smtp.qq.com'
app.config['MAIL_PORT'] = 25
app.config['MAIL_USE_TLS'] = True
app.config['MAIL_USERNAME'] = os.environ.get('MAIL_USERNAME') or 'xxxxxxxxx@qq.com'
app.config['MAIL_PASSWORD'] = os.environ.get('MAIL_PASSWORD') or '**********' mail = Mail(app) @app.route('/attach')
def add_attchments():
msg = Message('A photo', sender='xxxxxxxxx@qq.com', recipients=['ltest@example.com'])
msg.html = '<b>A beautiful photo!</b>' with app.open_resource("1111.jpg") as fp:
msg.attach("photo.jpg", "image/jpeg", fp.read()) mail.send(msg)
return '<h1>OK!</h1>' if __name__ == '__main__':
app.run(debug=True)

上面的代码中,我们通过 app.open_resource(path_of_attachment) 打开了本机的某张图片,然后通过msg.attach() 方法将附件内容添加到 Message 对象。msg.attach() 方法的第一个参数是附件的文件名,第二个参数是文件内容的 MIME (Multipurpose Internet Mail Extensions) 类型,第三个参数是文件内容。

7.批量发送

在某些情况下,我们需要批量发送邮件,比如给网站的所有注册用户发送改密码的邮件,这时为了避免每次发邮件时都要创建和关闭跟服务器的连接,我们的代码需要做一些调整,类似如下:

with mail.connect() as conn:
for user in users:
subject = "hello, %s" % user.name
msg = Message(recipients=[user.email], body='...', subject=subject)
conn.send(msg)

上面的工作方式,使得应用与电子邮件服务器保持连接,一直到所有邮件已经发送完毕。某些邮件服务器会限制一次连接中的发送邮件的上限,这样的话,你可以配置 MAIL_MAX_EMAILS

Flask扩展 -- flask-mail的更多相关文章

  1. Flask 扩展 Mail

    安装 pip install flask-mail from flask import Flask from flask_mail import Mail, Message app = Flask(_ ...

  2. Inside Flask - flask 扩展加载过程

    Inside Flask - flask 扩展加载过程 flask 扩展(插件)通常是以 flask_<扩展名字> 为扩展的 python 包名,而使用时,可用 import flask. ...

  3. flask 扩展之 -- flask-sqlalchemy

    flask-sqlalchemy.md 一. 安装 $ pip install flask-sqlalchemy 二. 配置 配置选项列表 : 选项 说明 SQLALCHEMY_DATABASE_UR ...

  4. Flask從入門到入土(二)——請求响应與Flask扩展

    ———————————————————————————————————————————————————————————— 一.程序和請求上下文 Flask從客戶端收到請求時,要讓視圖函數能訪問一些對象 ...

  5. Flask 扩展 国际化 本地化

    pip install flask-babel 先初始化一个Flask-Babel的实例 from flask import Flask from flask.ext.babel import Bab ...

  6. Flask 扩展 自定义扩展

    创建一个为视图访问加日志的扩展Flask-Logging,并从中了解到写Flask扩展的规范. 创建工程 先创建一个工程,目录结构如下: flask-logging/ ├ LICENSE # 授权说明 ...

  7. Flask 扩展 HTTP认证

    Restful API不保存状态,无法依赖Cookie及Session来保存用户信息,自然也无法使用Flask-Login扩展来实现用户认证.所以这里,我们就要介绍另一个扩展,Flask-HTTPAu ...

  8. Flask 扩展 用户会话

    pip install flask-login 接下来创建扩展对象实例: from flask import Flask from flask_login import LoginManager ap ...

  9. Flask 扩展 表单

    pip install flask-wtf 一个简单的表单 from flask_wtf import Form from wtforms import StringField from wtform ...

随机推荐

  1. es6注意点

    补救方法: 详情:http://es6.ruanyifeng.com/#docs/array 取出文本内容 实现深拷贝 jq实现不完全深拷贝 jQuery.extend = jQuery.fn.ext ...

  2. mac下Python安装路径的说明

    Python安装路径的说明 mac在安装Python时, 对不同的安装方式 不同的型号均会安装在不同的文件夹下 安装方式 路径 系统默认(2.7) /System/Library/Frameworks ...

  3. v-bind和v-model的区别

    1:v-bind动态绑定指令,默认情况下标签自带属性的值是固定的,在为了能够动态的给这些属性添加值,可以使用v-bind:你要动态变化的值="表达式" 2:v-bind用于绑定属性 ...

  4. UVA11021 Tribles 概率dp

    题目传送门 题意:开始有$k$只兔子,每只都是活一天就死,每只死前都会有$pi$的概率生出$i$只兔子.求$m$天后兔子死光的概率. 思路: 设$f[i]$为一只兔子在第i天死完的概率,那么答案就是$ ...

  5. python 编写暴力破解mysql用户名密码

    本文摘自别人的,自己运行调试了一下#!/user/bin/env python#-*- coding:utf-8 -*- import pymysql#导入连接数据库的模块import sys cla ...

  6. sqlmap结合burpsuite对post请求进行注入测试

    1. 浏览器打开目标地址 http://testasp.vulnweb.com/Login.asp 2. 配置burp代理(127.0.0.1:8080)以拦截请求 3. 点击login表单的subm ...

  7. vue 外卖app(2) stylus

    1.安装 npm  install stylus   stylus-loader  --save-dev 安装成功 2.编写样式 <style  lang="stylus" ...

  8. 【JZOJ6409】困难的图论

    description 给定由 n 个点 m 条边组成的无向连通图,保证没有重边和自环. 你需要找出所有边,满足这些边恰好存在于一个简单环中.一个环被称为简单环,当且仅当它包含的所有点都只在这个环中被 ...

  9. 【转载】带你吃透RTMP

    RTMP协议是Real Time Message Protocol(实时信息传输协议)的缩写,它是由Adobe公司提出的一种应用层的协议,用来解决多媒体数据传输流的多路复用(Multiplexing) ...

  10. bzoj1006题解

    [题意分析] 给你一张弦图,求图的最小染色数. [解题思路] 这篇讲稿已经讲得很详尽了.. 直接求完美消除序列,然后倒着染色即可.复杂度O(n2+nm). [参考程序] 求完美消除序列我是用的MCS( ...