导语
今天在尝试
Flask-Mail
发送邮件的过程中,遇到一个小问题导致发送邮件失败,查到了半天问题,真是被自己蠢到了。
这里针对这个问题的前因后果做一个整理分享给大家,避免大家踩同样的坑。
安装 Flask-Mail
这里建议利用 virtualenv
来创建隔离的环境来测试发送邮件,关于 virtualenv相关的介绍和使用可以参考如下连接
Centos下pyenv安装python多版本-增强版
Centos下python纯净虚拟环境
** 安装并验证 Flask-Mail **
pip install flask-mail
root@pts/1 $ python
Python 2.7.5 (default, Nov 3 2016, 17:08:21)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-4)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import flask_mail
>>> print flask_mail.__version__
0.9.1
>>>
Flask-Mail 说明
参考 flask-mail 官方文档 需要注意一下配置
Configuring Flask-Mail
Flask-Mail is configured through the standard Flask config API. These are the available options (each is explained later in the documentation):
MAIL_SERVER : default ‘localhost’
MAIL_PORT : default 25
MAIL_USE_TLS : default False
MAIL_USE_SSL : default False
MAIL_DEBUG : default app.debug
MAIL_USERNAME : default None
MAIL_PASSWORD : default None
MAIL_DEFAULT_SENDER : default None
MAIL_MAX_EMAILS : default None
MAIL_SUPPRESS_SEND : default app.testing
MAIL_ASCII_ATTACHMENTS : default False
这里尤其注意下面两个参数吧
MAIL_USE_TLS : default False
MAIL_USE_SSL : default False
关于 TLS 和 SSL 的说明可以参考 聊聊HTTPS和SSL/TLS协议
遇到问题
参考网上flask web开发中实例设置 MAIL_USE_TLS=True
,考虑google email可能被墙的原因,在实际中自己的 MAIL_SERVER='smtp.exmail.qq.com'
但是测试过程中不报错,就直接卡死不动,以为是防火墙的问题,也修改了云端的防火墙开启了465端口
,还是不能发信。
思考...
MAIL_SERVER/MAIL_USERNAME/MAIL_PASSWORD可能是没有错,端口的话腾讯企业邮箱smtp开发的端口是465,那就剩下这个协议的问题了...
登陆网页端设置中查看,呃... 怎么不是TSL
协议,而是SSL协议,如下图
那么TLS是google mail的设置了吗?赶紧登陆 google mail去看看
还真是...
修改配置为:
app.config['MAIL_USE_SSL'] = True
app.config['MAIL_USE_TLS'] = False ## 默认就是 false, 加上警示自己
再次测试发送邮件成功,如下图
实际脚本
root@pts/1 $ cat flask-sendmail.py
#!/usr/bin/env python
#coding: utf-8
from flask import Flask, request
from flask_script import Manager,Shell
from flask_mail import Mail,Message
from threading import Thread
import os
app = Flask(__name__)
app.config['DEBUG'] = True
app.config['MAIL_SERVER'] = 'smtp.exmail.qq.com'
app.config['MAIL_PORT'] = 465
app.config['MAIL_USE_SSL'] = True
app.config['MAIL_USE_TLS'] = False
app.config['MAIL_USERNAME'] = os.environ.get('MAIL_USERNAME')
app.config['MAIL_PASSWORD'] = os.environ.get('MAIL_PASSWORD')
manager = Manager(app)
mail = Mail(app)
## 异步发送邮件
def send_async_email(app,msg):
with app.app_context():
mail.send(msg)
@app.route('/')
def index():
msg = Message(subject='Email test by flask-email',sender="[email protected]",recipients=['[email protected]','[email protected]'])
msg.body = 'hello 刘超'
msg.html = '测试Flask发送邮件'
thread = Thread(target=send_async_email,args=[app,msg])
thread.start()
# mail.send(msg)
return '邮件发送成功
'
if __name__ == '__main__':
manager.run()
邮件内容会以文本和html两种格式
呈现,而你能看到哪种格式取决于你的邮件客户端
。
flask-mail相关错误总结
没有开启POP3/SMTP服务
smtplib.SMTPAuthenticationError: (454, 'Authentication failed, please open smtp flag first!')
密码错误
QQ邮箱 开启POP3/SMTP服务
之后需要一个独立的邮箱密码
smtplib.SMTPAuthenticationError: (535, 'Authentication failed')
开启 TLS
smtplib.SMTPServerDisconnected: Connection unexpectedly closed