1. 程式人生 > >Flask擴展 -- flask-mail

Flask擴展 -- flask-mail

發送信息 mes uri sync 保持 實例 utf-8 文件名 odi

電子郵件是最常用的通信方式之一。雖然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="[email protected]", MAIL_PASSWORD="****************", ) mail = Mail(app) @app.route(/) def index(): # sender 發送方,recipients 郵件接收方列表 msg = Message("Hi!This is a test ",sender=‘xxxxxxxxxxxxxx@qq.com, recipients=[[email protected]]) # 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="[email protected]",recipients=["[email protected]"])

當然,我們也可以單獨添加郵件接收對象:

msg.recipients = ["[email protected]"]
msg.add_recipient("[email protected]")

在配置參數的時候,如果我們設置了MAIL_DEFAULT_SENDER參數,在後面創建message實例時不需要清楚指明郵件發送方,此時程序會自動獲取默認配置:

msg = Message("Hello",recipients=["[email protected]"])

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 [email protected]
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=[email protected], recipients=[[email protected]])
    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 [email protected]
app.config[MAIL_PASSWORD] = os.environ.get(MAIL_PASSWORD) or **********

mail = Mail(app)

@app.route(/attach)
def add_attchments():
    msg = Message(A photo, sender=[email protected], recipients=[[email protected]])
    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