Flask-Mail
Flask-Mail is an extension for Flask that simplifies sending emails from your application. It provides a straightforward interface for integrating SMTP capabilities. Currently at version 0.10.0, the project is actively maintained as part of the Pallets Community Ecosystem, the open-source organization behind Flask.
Warnings
- breaking Version 0.10.0 dropped support for Python versions older than 3.8. Ensure your environment meets this minimum requirement.
- breaking The `__version__` attribute is deprecated in 0.10.0 and will be removed. Direct access will fail.
- breaking The `Message.attach` method's `headers` parameter now expects a dictionary (e.g., `{'Content-ID': '<image1>'}`) instead of a list of tuples (e.g., `[('Content-ID', '<image1>')]`). Using the old format will raise an AttributeError.
- gotcha You cannot enable both `MAIL_USE_TLS` and `MAIL_USE_SSL` simultaneously. Enabling both will lead to connection errors or unexpected behavior.
- gotcha Older versions of Flask-Mail used configuration keys like `DEFAULT_MAIL_SENDER` and `DEFAULT_MAX_EMAILS`. These were changed to `MAIL_DEFAULT_SENDER` and `MAIL_MAX_EMAILS` in version 0.8.0.
- gotcha When using services like Gmail with 2-Factor Authentication (2FA) enabled, you typically need to generate an 'App Password' instead of using your regular account password to authenticate with SMTP. Regular passwords will fail.
- breaking The `email_dispatched` signal's arguments were reversed in 0.10.0. It now passes the Flask `app` instance as the sender and the `Message` instance as an argument, instead of the other way around.
Install
-
pip install Flask-Mail
Imports
- Mail
from flask_mail import Mail
- Message
from flask_mail import Message
Quickstart
import os
from flask import Flask
from flask_mail import Mail, Message
app = Flask(__name__)
# Configure Flask-Mail using environment variables for sensitive data
app.config['MAIL_SERVER'] = os.environ.get('MAIL_SERVER', 'smtp.example.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', '')
app.config['MAIL_PASSWORD'] = os.environ.get('MAIL_PASSWORD', '')
app.config['MAIL_DEFAULT_SENDER'] = os.environ.get('MAIL_DEFAULT_SENDER', 'noreply@example.com')
mail = Mail(app)
@app.route('/send-test-email')
def send_email():
if not app.config['MAIL_USERNAME'] or not app.config['MAIL_PASSWORD']:
return "Email credentials not set in environment variables. Cannot send.", 500
msg = Message(
subject='Hello from Flask-Mail!',
recipients=['recipient@example.com'], # Replace with a real recipient email
body='This is a test email sent from your Flask application.'
)
try:
mail.send(msg)
return 'Email sent successfully!'
except Exception as e:
return f'Failed to send email: {e}', 500
if __name__ == '__main__':
# Example usage with environment variables (set these before running):
# export MAIL_SERVER='smtp.gmail.com'
# export MAIL_PORT=587
# export MAIL_USE_TLS=True
# export MAIL_USE_SSL=False
# export MAIL_USERNAME='your_gmail@gmail.com'
# export MAIL_PASSWORD='your_app_password'
# export MAIL_DEFAULT_SENDER='your_gmail@gmail.com'
app.run(debug=True)