• flask使用Flask-Mail实现邮件发送


    Flask-Mail可以实现邮件的发送,并且可以和 Flask 集成,让我们更方便地实现此功能。

    1、安装

    使用pip安装:

    $ pip install Flask-Mail
    
    • 1

    或下载源码安装:

    $ git clone https://github.com/mattupstate/flask-mail.git
    $ cd flask-mail
    $ python setup.py install
    
    • 1
    • 2
    • 3

    2、发送邮件

    Flask-Mail 连接到简单邮件传输协议 (Simple Mail Transfer Protocol, SMTP) 服务器,并把邮件交给这个服务器发送。这里以QQ邮箱为例,介绍如何简单地发送邮件。在此之前,我们需要知道QQ邮箱的服务器地址和端口是什么

    # -*- 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          # 启用 TLS
    app.config['MAIL_USERNAME'] = os.environ.get('MAIL_USERNAME') or 'me@example.com'
    app.config['MAIL_PASSWORD'] = os.environ.get('MAIL_PASSWORD') or '123456'
    mail = Mail(app)
    @app.route('/')
    def index():
        msg = Message('Hi', sender='me@example.com', recipients=['he@example.com'])
        msg.html = 'Hello Web'
        # msg.body = 'The first email!'
        mail.send(msg)
        return '

    OK!

    '
    if __name__ == '__main__': app.run(host='127.0.0.1', debug=True)
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    在发送前,需要先设置用户名和密码,当然你也可以直接写在文件里,如果是从环境变量读取,可以这么做:

    $ export MAIL_USERNAME='me@example.com'
    $ export MAIL_PASSWORD='123456'
    
    • 1
    • 2

    将上面的sender和recipients改一下,就可以进行测试了。

    从上面的代码,我们可以知道,使用 Flask-Mail 发送邮件主要有以下几个步骤:

    • 配置 app 对象的邮件服务器地址,端口,用户名和密码等
    • 创建一个 Mail 的实例:mail = Mail(app)
    • 创建一个 Message 消息实例,有三个参数:邮件标题、发送者和接收者
    • 创建邮件内容,如果是 HTML 格式,则使用msg.html,如果是纯文本格式,则使用msg.body
    • 最后调用mail.send(msg)发送消息

    Flask-Mail 配置项
    Flask-Mail 使用标准的 Flask 配置 API 进行配置,下面是一些常用的配置项:
    在这里插入图片描述

    3、异步发送邮件

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

    # -*- 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 'smtp.example.com'
    app.config['MAIL_PASSWORD'] = os.environ.get('MAIL_PASSWORD') or '123456'
    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='me@example.com', recipients=['he@example.com'])
        msg.html = 'send email asynchronously'
        thr = Thread(target=send_async_email, args=[app, msg])
        thr.start()
        return 'send successfully'
    if __name__ == '__main__':
        app.run(host='127.0.0.1', debug=True)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

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

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

    4、带附件的邮件

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

    # -*- 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          # 启用 TLS
    app.config['MAIL_USERNAME'] = os.environ.get('MAIL_USERNAME') or 'me@example.com'
    app.config['MAIL_PASSWORD'] = os.environ.get('MAIL_PASSWORD') or '123456'
    mail = Mail(app)
    @app.route('/attach')
    def add_attchments():
        msg = Message('Hi', sender='me@example.com', recipients=['other@example.com'])
        msg.html = 'Hello Web'
        with app.open_resource("/Users/Admin/Documents/pixel-example.jpg") as fp:
            msg.attach("photo.jpg", "image/jpeg", fp.read())
        mail.send(msg)
        return '

    OK!

    '
    if __name__ == '__main__': app.run(host='127.0.0.1', debug=True)
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

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

    5、批量发送

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

    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)
    
    • 1
    • 2
    • 3
    • 4
    • 5

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

  • 相关阅读:
    近红外染料四甲基罗丹明TRITC修饰二硫化钨纳米粒TRITC-WS2 NPs|TRITC-TK-PEG-WS2
    面试官:单核 CPU 支持 Java 多线程吗?为什么?被问懵了!
    今日睡眠质量记录82分
    语音识别接口试用
    卷积 、 图像去噪、边缘提取
    net-java-php-python-汽车租赁系统计算机毕业设计程序
    cygwin编译haproxy
    图片批量修改尺寸如何实现?
    大文件分块上传实现
    【Electron】vue+electron快捷键设置
  • 原文地址:https://blog.csdn.net/javascript_good/article/details/132687577