利用Flask-Mail开发邮件API

之前也写过<a target="_blank" href="https://www.361way.com/smtplib/1922.html" rel="noopener">python smtplib发送邮件</a> ,其是基于smtpmlib模块写的应用,这里是想利用flask写一个简单的API ,具体的应用场景是,假如一个局域网环境中,只有一台主机可以上外网外发邮件。其他主机不可以上外网。该主机启动一个flask API邮件外发服务,其他主机需要发送告警邮件时,就可以通过调用该主机的邮件服务外发告警信息。该功能的实现准备分两篇走,第一篇先讲下fask-mail模块,第二篇来具体实现该需求。

一、flask-mail 模块介绍

其初还准备参考之前的smtplib,通过flask调用该程序外出,不过flask对应的邮件扩展有现成的模块有:flask-mail 、flask.ext.mail、flask-sendmail 。这里使用flask-mail 实现。<a target="_blank" href="https://pypi.python.org/pypi/Flask-Mail" rel="noopener">Flask-Mail </a>提供了一个简单的接口,让我们可以方便的在 Flask 应用中使用 SMTP协议 发送邮件。

二、flask-mail 模块的安装与使用

1、安装

pip install Flask-Mail 或
easy_install Flask-Mail
查看该模块的源码会发现,其最终还是调用的smtplib模块来实现的。

2、配置

Flask-Mail 使用 Flask 标准的配置 API 进行配置。下面是所有的配置选项:



<br />
MAIL_SERVER : 默认为 '127.0.0.1'
MAIL_PORT : 默认为 25
MAIL_USE_TLS : 默认为 False
MAIL_USE_SSL : 默认为 False
MAIL_DEBUG : 默认为 app.debug
MAIL_USERNAME : 默认为 None
MAIL_PASSWORD : 默认为 None
MAIL_DEFAULT_SENDER : 默认为 None
MAIL_MAX_EMAILS : 默认为 None
MAIL_SUPPRESS_SEND : 默认为 app.testing
MAIL_ASCII_ATTACHMENTS : 默认为 False
具体的参数我们可以查看<a target="_blank" href="https://github.com/mattupstate/flask-mail/blob/master/flask_mail.py" rel="noopener">源码</a> 。

3、初始化

这个在官方的文档中也进行了说明,有两种方法。



<strong>方法1:</strong>



使用传入到 Mail 实例中的应用程序的配置项进行邮件发送:



<br />
from flask import Flask
from flask_mail import Mail
app = Flask(__name__)
mail = Mail(app)
<strong>方法2:</strong>



使用 Flask 的 current_app 中的配置项进行邮件发送,如果我们有多个 不同配置的应用程序 则使用此种方式比较方便:



<br />
mail = Mail()
app = Flask(__name__)
mail.init_app(app)
<br />

三、利用flask-mail 发送邮件

<strong>发送详解</strong>



发送之前我们需要先构建一个 Message 对象,如下:



<br />
from flask_mail import Message
msg = Message("Hello Flask", sender="itybku@gmail.com",  recipients=["itybku@163.com"])
我们也可以同时指定多个收件人:



<br />
msg.recipients = ["itybku@gmail.com", "itybku@163.com"]
msg.add_recipient("itybku@126.com")
如果我们配置了 MAIL_DEFAULT_SENDER 字段,就可以不再设置 sender ,这个时候会使用 MAIL_DEFAULT_SENDER 中指定的发件人,像这样:



<br />
msg = Message("Hello Flask", recipients=["itybku@live.com"])
如果我们希望在收件列表中显示一个名字(string),可以通过一个二元祖来指定:



<br />
msg = Message("Hello", sender=("itybku", "itybku@live.com"))
同时, 我们还可以指定下面两个字段:



<br />
msg.body = "this is body string"
msg.html = "

this is html message"

最后就是发送:



<br />
mail.send(msg)
发送完毕后,与邮件服务器的链接就会关闭。



<strong>发送大量邮件</strong>



如果我们一次发送大量的邮件,可以通过下面的方式发送:



<br />
with mail.connect() as conn:
    for user in users:
        message = '...'
        subject = "hello, %s" % user.name
        msg = Message(recipients=[user.email],
                      body=message,
                      subject=subject)
        conn.send(msg)
与电子邮件服务器的连接会一直保持直到所有的邮件都已经发送完毕才会断开。注意大量发送的时候,还可以设置MAIL_MAX_EMAILS变量 。



<br />
Some mail servers set a limit on the number of emails sent in a single connection.
You can set the max amount of emails to send before reconnecting by specifying theMAIL_MAX_EMAILS setting.
<strong>添加附件</strong>



<br />
with app.open_resource("image.png") as fp:
    msg.attach("image.png", "image/png", fp.read())
<strong>不使用SSL示例</strong>



<br />
# coding: utf-8
from flask import Flask
from flask_mail import Mail, Message
app = Flask(__name__)
app.config['MAIL_SERVER'] = 'smtp.163.com'
app.config['MAIL_PORT'] = 25
app.config['MAIL_USE_SSL'] = False
app.config['MAIL_USERNAME'] = 'sender@163.com'
app.config['MAIL_PASSWORD'] = 'password'
app.config['MAIL_DEFAULT_SENDER'] = 'sender@163.com'
mail = Mail(app)
@app.route("/")
def index():
        msg = Message('这是一封测试邮件Header', recipients=['itybku@139.com'])
        msg.body = "This is the email body"
        msg.html = 'hello api'
        mail.send(msg)
        return "Sent"
if __name__ == "__main__":
    app.run(host="0.0.0.0",port=5000,debug=True)
    #app.run()
            
<strong>使用SSL示例(带附件)</strong>



<br />
#!/usr/bin/env python
# coding:utf-8
from flask import Flask
from flask_mail import Mail, Message
app = Flask(__name__)
app.config['MAIL_SERVER'] = 'smtp.qq.com'
app.config['MAIL_PORT'] = 465
app.config['MAIL_USE_SSL'] = True
app.config['MAIL_USERNAME'] = 'sender@qq.com'
app.config['MAIL_PASSWORD'] = '********'
app.config['MAIL_DEFAULT_SENDER'] = 'sender@qq.com'
mail = Mail(app)
@app.route('/mail')
def welcome():
    msg = Message('这是一封测试邮件Header', recipients=['itybku@139'])
    msg.body = '这是一封测试邮件 bodyer'
    msg.html = '这是一封测试邮件 htmler'
    image = 'image_.运维之路jpg'
    with app.open_resource(image) as fp:
        msg.attach(image, 'image/jpg', fp.read())
    mail.send(msg)
    return 'Hello world!'
if __name__ == '__main__':
    app.run(debug=tuple)
注,QQ邮箱使用SMTP、IMAP等协议需要配置,打开 QQ邮箱 > 设置 > POP3/IMAP/SMTP/Exchange/CardDAV/CalDAV服务 > 生成授权码。



参考页面:<a target="_blank" href="http://www.pythondoc.com/flask-mail/" rel="noopener">http://www.pythondoc.com/flask-mail/</a>



<br />

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注