Flask - 邮件
Flask – 使用 Flask-Mail 发送电子邮件
Section titled “Flask – 使用 Flask-Mail 发送电子邮件”发送电子邮件是 Web 应用程序的常见需求,用于通知、密码重置、确认、新闻通讯等。Flask-Mail 扩展通过提供一个与 SMTP(简单邮件传输协议)服务器交互的接口,简化了在 Flask 应用程序中集成电子邮件发送功能的过程。
首先,安装 Flask-Mail 扩展:
pip install Flask-Mail接下来,你需要使用要使用的 SMTP 服务器的详细信息配置 Flask-Mail。这是通过在 Flask app 对象上设置特定的配置变量来完成的。
| 序号 | 配置键 | 描述 |
|---|---|---|
| 1 | MAIL_SERVER | SMTP 邮件服务器的主机名或 IP 地址(例如,“smtp.googlemail.com”)。 |
| 2 | MAIL_PORT | SMTP 服务器的端口号(例如,TLS 为 587,SSL 为 465)。 |
| 3 | MAIL_USE_TLS | 布尔值。设置为 True 以启用传输层安全 (TLS)。通常与端口 587 一起使用。 |
| 4 | MAIL_USE_SSL | 布尔值。设置为 True 以启用安全套接字层 (SSL)。通常与端口 465 一起使用。注意:MAIL_USE_TLS 和 MAIL_USE_SSL 互斥。 |
| 5 | MAIL_USERNAME | 用于身份验证的电子邮件帐户用户名。 |
| 6 | MAIL_PASSWORD | 电子邮件帐户密码或应用专用密码。 |
| 7 | MAIL_DEFAULT_SENDER | 可选。如果创建消息时未指定发件人,则用作默认发件人的电子邮件地址。可以是字符串 ‘发件人姓名 email@example.com’ 或仅是 ‘email@example.com’。 |
| 8 | MAIL_DEBUG | 布尔值。如果为 True,则打印详细的 SMTP 调试信息。默认为 app.debug。 |
| 9 | MAIL_MAX_EMAILS | 可选。一次连接中发送的最大电子邮件数。默认通常为 None(无限制)。 |
| 10 | MAIL_SUPPRESS_SEND | 布尔值。如果为 True(通常在测试期间设置,例如,如果 app.testing 为 True),则电子邮件将被抑制而不是发送。 |
| 11 | MAIL_ASCII_ATTACHMENTS | 布尔值。如果为 True,则将附件文件名转换为 ASCII。 |
安全提示: 切勿将敏感凭据(如 MAIL_PASSWORD)直接硬编码在源代码中。使用环境变量或安全的配置管理系统。
Flask-Mail 提供了两个主要类:
1. Mail 类
Section titled “1. Mail 类”此类管理与邮件服务器的连接和发送过程。你通常会使用 Flask 应用对其进行一次性初始化。
from flask_mail import Mailmail = Mail(app) # 将你的 Flask 应用对象传递给它Mail 类主要方法:
| 序号 | 方法 | 描述 |
|---|---|---|
| 1 | send(message) | 发送一个 Message 对象。 |
| 2 | send_message(...) | 一次调用中创建并发送一个简单消息的快捷方式(灵活性不如创建 Message 对象)。 |
| 3 | connect() | 打开与邮件主机(host)的连接(通常由 send 自动处理)。 |
2. Message 类
Section titled “2. Message 类”此类表示单个电子邮件消息,封装其组件,如主题、收件人、发件人、正文等。
from flask_mail import Message
msg = Message( subject="Hello from Flask-Mail!", sender="you@example.com", # 或者使用 MAIL_DEFAULT_SENDER recipients=["recipient1@example.com", "recipient2@example.com"], body="This is the plain text body.", html="**This is the HTML body**" # 可选的 HTML 版本 # cc=[...], bcc=[...], reply_to=..., etc.)Message 构造函数主要参数:
subject:电子邮件主题行。recipients:收件人电子邮件地址列表。body:电子邮件的纯文本内容。html:可选。电子邮件的 HTML 内容。sender:发件人的电子邮件地址。如果设置了MAIL_DEFAULT_SENDER,则默认为该值。cc:抄送(CC)收件人列表。bcc:密送(BCC)收件人列表。attachments:附件列表(见下文)。reply_to:可选的回复地址。
Message 类主要方法:
Section titled “Message 类主要方法:”attach(filename, content_type, data, disposition=None, headers=None):向消息添加附件。你需要提供文件名、MIME 类型(例如,“image/png”)和原始文件数据。add_recipient(recipient):向收件人列表添加另一个收件人。
示例:使用 Gmail 发送简单电子邮件
Section titled “示例:使用 Gmail 发送简单电子邮件”关于 Gmail 的重要说明: Google 加强了安全措施。使用常规 Gmail 密码作为 MAIL_PASSWORD 可能不起作用,也不推荐这样做。通常你需要为你的 Google 帐户启用两步验证(2-Step Verification),然后专门为 Flask-Mail 生成一个“应用专用密码”(App Password)。请将此应用专用密码用作你的 MAIL_PASSWORD。或者,考虑使用事务性电子邮件服务(transactional email services),如 SendGrid、Mailgun 或 AWS SES,它们是专为应用程序电子邮件发送而设计的。
以下是完整的示例代码 (app.py):
import osfrom flask import Flaskfrom flask_mail import Mail, Message
app = Flask(__name__)
# --- Configuration ---# 从环境变量安全地加载凭据# 示例:使用 os.environ.get('VARIABLE_NAME', 'default_value')app.config['MAIL_SERVER'] = os.environ.get('MAIL_SERVER', 'smtp.googlemail.com')app.config['MAIL_PORT'] = int(os.environ.get('MAIL_PORT', 587))app.config['MAIL_USE_TLS'] = os.environ.get('MAIL_USE_TLS', 'true').lower() == 'true'app.config['MAIL_USE_SSL'] = os.environ.get('MAIL_USE_SSL', 'false').lower() == 'true'app.config['MAIL_USERNAME'] = os.environ.get('MAIL_USERNAME') # 你的 Gmail 地址或应用用户名app.config['MAIL_PASSWORD'] = os.environ.get('MAIL_PASSWORD') # 你的 Gmail 应用专用密码app.config['MAIL_DEFAULT_SENDER'] = os.environ.get('MAIL_DEFAULT_SENDER', app.config['MAIL_USERNAME'])
# 检查基本配置是否缺失(可选但推荐)if not app.config['MAIL_USERNAME'] or not app.config['MAIL_PASSWORD']: print("Warning: MAIL_USERNAME or MAIL_PASSWORD environment variables not set.") # 适当地处理此情况,例如禁用邮件发送
# --- Initialize Mail ---mail = Mail(app)
# --- Route to Send Email ---@app.route("/")def index(): # 尝试发送前检查邮件配置是否完整 if not app.config['MAIL_USERNAME'] or not app.config['MAIL_PASSWORD']: return "Mail configuration missing. Cannot send email.", 500 try: # 创建消息 msg = Message( subject='Hello From Flask-Mail', # 如果配置了 MAIL_DEFAULT_SENDER,则使用它,否则使用 MAIL_USERNAME # sender=app.config['MAIL_DEFAULT_SENDER'] or app.config['MAIL_USERNAME'], recipients=['recipient@example.com'] # 替换为一个有效的收件人地址 ) msg.body = "This is a test email sent from a Flask application using Flask-Mail." msg.html = "**This is a test email** sent from a <i>Flask application</i> using Flask-Mail."
# 示例:添加附件(可选) # with app.open_resource("static/some_image.png") as fp: # msg.attach("logo.png", "image/png", fp.read())
# 发送消息 mail.send(msg) return "Email sent successfully!" except Exception as e: # 记录错误以便调试 app.logger.error(f"Mail sending failed: {e}") return f"Failed to send email: {e}", 500
if __name__ == '__main__': # 运行前在终端中设置环境变量进行测试: # export MAIL_USERNAME='your_email@gmail.com' # export MAIL_PASSWORD='your_app_password' # export MAIL_DEFAULT_SENDER='Friendly Name <your_email@gmail.com>' app.run(debug=True)运行前:
- 将
'recipient@example.com'替换为你能检查的实际电子邮件地址。 - 在运行脚本之前,在你的终端中设置环境变量
MAIL_USERNAME和MAIL_PASSWORD(以及可选的其他变量)(参阅代码中的注释)。 - 如果使用启用了两步验证的 Gmail,请确保使用的是应用专用密码。
运行脚本(python app.py)并访问 http://localhost:5000/。这将触发 index 函数,尝试使用配置的设置创建并发送电子邮件,并显示成功或失败消息。
开发提示: 在开发过程中,你可能不想发送真实的电子邮件。可以考虑使用 Python 内置的调试 SMTP 服务器(python -m smtpd -c DebuggingServer -n localhost:1025),并配置 Flask-Mail 使用 localhost 和端口 1025,无需身份验证。电子邮件将被打印到控制台,而不是真正发送。或者,使用 MailHog 或 Mailtrap 等工具。