電子郵件 Flask-Mail
1.使用Flask-Mail提供電子郵件支持
Snipaste_2018-05-31_22-49-03.png
舉個例子,示例 6-1 展示了如何配置程序,以便使用 Google Gmail 賬戶發(fā)送電子郵件。
#初始化 Flask-Mail
from flask_mail import Mail
mail = Mail(app)
import os
# ...
app.config['MAIL_SERVER'] = 'smtp.googlemail.com'
app.config['MAIL_PORT'] = 587
app.config['MAIL_USE_TLS'] = True
app.config['MAIL_USERNAME'] = os.environ.get('MAIL_USERNAME')
app.config['MAIL_PASSWORD'] = os.environ.get('MAIL_PASSWORD')
關(guān)于賬戶密碼在環(huán)境變量中定義
Mac OS X 中使用 bash,那么可以按照下面的方式設(shè)定這兩個變量:
(venv) $ export MAIL_USERNAME=<Gmail username>
(venv) $ export MAIL_PASSWORD=<Gmail password>
微軟 Windows 用戶可按照下面的方式設(shè)定環(huán)境變量:
(venv) $ set MAIL_USERNAME=<Gmail username>
(venv) $ set MAIL_PASSWORD=<Gmail password>
2.在程序中集成發(fā)送電子郵件
為了避免每次都手動編寫電子郵件消息,我們最好把程序發(fā)送電子郵件的通用部分抽象出來,定義成一個函數(shù)。這么做還有個好處,即該函數(shù)可以使用 Jinja2 模板渲染郵件正文,靈活性極高。
from flask.ext.mail import Message
app.config['FLASKY_MAIL_SUBJECT_PREFIX'] = '[Flasky]'
app.config['FLASKY_MAIL_SENDER'] = 'Flasky Admin<flasky@example.com>'
#參數(shù)分別是 收件人地址、主題、渲染郵件正文的模板和關(guān)鍵字參數(shù)列表
def send_email(to, subject, template, **kwargs):
msg = Message(app.config['FLASKY_MAIL_SUBJECT_PREFIX'] + subject,sender=app.config['FLASKY_MAIL_SENDER'], recipients=[to])
msg.body = render_template(template + '.txt', **kwargs)
msg.html = render_template(template + '.html', **kwargs)
# 發(fā)送郵件
mail.send(msg)
# 主題, 發(fā)送人 , 收件人 收件人要用列表
Message(app.config['FLASKY_MAIL_SUBJECT_PREFIX'] + subject,sender=app.config['FLASKY_MAIL_SENDER'], recipients=[to])
3 異步發(fā)送電子郵件
mail.send() 函數(shù)在發(fā)送電子郵件時停滯了幾秒鐘,在這個過程中瀏覽器就像無響應(yīng)一樣。為了避免處理請求過程中不必要的延遲,我們可以把發(fā)送電子郵件的函數(shù)移到后臺線程中。
from threading import Thread # 導(dǎo)入線程模塊
# 發(fā)送郵件線程函數(shù)
def send_async_email(app, msg):
# 開啟上下文 否則無法發(fā)送
with app.app_context():
mail.send(msg)
# 發(fā)送郵件整體函數(shù)
def send_email(to, subject, template, **kwargs):
msg = Message(app.config['FLASKY_MAIL_SUBJECT_PREFIX'] + subject,
sender=app.config['FLASKY_MAIL_SENDER'], recipients=[to])
msg.body = render_template(template + '.txt', **kwargs)
msg.html = render_template(template + '.html', **kwargs)
thr = Thread(target=send_async_email, args=[app, msg])
thr.start()
return thr
不過要記住,程序要發(fā)送大量電子郵件時,使用專門發(fā)送電子郵件的作業(yè)要比給每封郵件都新建一個線程更合適。例如,我們可以把執(zhí)行 send_async_email() 函數(shù)的操作發(fā)給 Celery(http://www.celeryproject.org/)任務(wù)隊列。