电子邮件
虽然 Python 标准库中的 smtplib 包可用在 Flask 程序中发送电子邮件,但包装了 smtplib 的Flask-Mail 扩展能更好地和 Flask 集成。
(venv) $ pip install flask-mail
SMTP——发送邮件服务器。
可以设置发送选项:
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')
千万不要把账户密令直接写入脚本,万一开源就泄露了。
(venv) $ export MAIL_USERNAME=<Gmail username>
(venv) $ export MAIL_PASSWORD=<Gmail password>
在程序中发送电子邮件
可以用模板来渲染邮件:
from flask.ext.mail import Message
app.config['FLASKY_MAIL_SUBJECT_PREFIX'] = '[Flasky]'
app.config['FLASKY_MAIL_SENDER'] = 'Flasky Admin <flasky@example.com>'
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)
mail.send(msg)
例子:每次表单收到新用户名就发邮件
添加环境变量:
(venv) $ export FLASKY_ADMIN=<your-email-address>
用后台线程异步发送电子邮件
from threading import Thread
很多 Flask 扩展都假设已经存在激活的程序上下文和请求上下文。Flask-Mail 中的 send() 函数使用 current_app ,因此必须激活程序上下文。在不同线程中执行 mail.send() 函数时,程序上下文要使用 app.app_context() 人工创建。
def send_async_email(app, msg):
with app.app_context():
mail.send(msg)
最后三行启动线程:
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
程序要发送大量电子邮件时,使用专门发送电子邮件的作业要比给每封邮件都新建一个线程更合适。例如,我们可以把执行 send_async_email() 函数的操作发给 Celery(http://www.celeryproject.org/)任务队列。
附加,VPS搭建电子邮件服务器
小任务,用flask给使用我搭建的类人猿公交服务的用户群发邮件。