Flask - Mail
Flask – Sending Emails with Flask-Mail
Section titled “Flask – Sending Emails with Flask-Mail”Sending emails is a common requirement for web applications, used for notifications, password resets, confirmations, newsletters, and more. The Flask-Mail extension simplifies integrating email sending capabilities into your Flask application by providing an interface to SMTP (Simple Mail Transfer Protocol) servers.
First, install the Flask-Mail extension:
pip install Flask-MailNext, you need to configure Flask-Mail with the details of the SMTP server you want to use. This is done by setting specific configuration variables on your Flask app object.
| Sr.No | Configuration Key | Description |
|---|---|---|
| 1 | MAIL_SERVER | Hostname or IP address of the SMTP email server (e.g., ‘smtp.googlemail.com’). |
| 2 | MAIL_PORT | Port number of the SMTP server (e.g., 587 for TLS, 465 for SSL). |
| 3 | MAIL_USE_TLS | Boolean. Set to True to enable Transport Layer Security (TLS). Usually used with port 587. |
| 4 | MAIL_USE_SSL | Boolean. Set to True to enable Secure Sockets Layer (SSL). Usually used with port 465. Note: MAIL_USE_TLS and MAIL_USE_SSL are mutually exclusive. |
| 5 | MAIL_USERNAME | Your email account username for authentication. |
| 6 | MAIL_PASSWORD | Your email account password or app-specific password. |
| 7 | MAIL_DEFAULT_SENDER | Optional. A default email address to use as the sender if not specified when creating a message. Can be a string ‘Sender Name email@example.com’ or just ‘email@example.com’. |
| 8 | MAIL_DEBUG | Boolean. If True, prints detailed SMTP debugging information. Defaults to app.debug. |
| 9 | MAIL_MAX_EMAILS | Optional. Maximum number of emails to send in one connection. Default is usually None (unlimited). |
| 10 | MAIL_SUPPRESS_SEND | Boolean. If True (often set during testing, e.g., if app.testing is True), emails are suppressed instead of being sent. |
| 11 | MAIL_ASCII_ATTACHMENTS | Boolean. If True, converts attachment filenames to ASCII. |
Security Note: Never hardcode sensitive credentials like MAIL_PASSWORD directly in your source code. Use environment variables or a secure configuration management system.
Flask-Mail provides two main classes:
1. Mail Class
Section titled “1. Mail Class”This class manages the connection to the mail server and the sending process. You typically initialize it once with your Flask app.
from flask_mail import Mailmail = Mail(app) # Pass your Flask app objectKey Methods of Mail class:
| Sr.No | Method | Description |
|---|---|---|
| 1 | send(message) | Sends a single Message object. |
| 2 | send_message(...) | A shortcut to create and send a simple message in one call (less flexible than creating a Message object). |
| 3 | connect() | Opens a connection to the mail host (often handled automatically by send). |
2. Message Class
Section titled “2. Message Class”This class represents a single email message, encapsulating its components like subject, recipients, sender, body, etc.
from flask_mail import Message
msg = Message( subject="Hello from Flask-Mail!", sender="you@example.com", # Or use MAIL_DEFAULT_SENDER recipients=["recipient1@example.com", "recipient2@example.com"], body="This is the plain text body.", html="**This is the HTML body**" # Optional HTML version # cc=[...], bcc=[...], reply_to=..., etc.)Key Parameters for Message constructor:
subject: The email subject line.recipients: A list of recipient email addresses.body: The plain text content of the email.html: Optional. The HTML content of the email.sender: The sender’s email address. Defaults toMAIL_DEFAULT_SENDERif set.cc: List of CC recipients.bcc: List of BCC recipients.attachments: List of attachments (see below).reply_to: Optional reply-to address.
Key Methods of Message class:
Section titled “Key Methods of Message class:”attach(filename, content_type, data, disposition=None, headers=None): Adds an attachment to the message. You provide the filename, MIME type (e.g., ‘image/png’), and the raw file data.add_recipient(recipient): Adds another recipient to the list.
Example: Sending a simple email using Gmail
Section titled “Example: Sending a simple email using Gmail”Important Note on Gmail: Google has increased security measures. Using your regular Gmail password with MAIL_PASSWORD might not work and is discouraged. You typically need to enable 2-Step Verification for your Google account and then generate an “App Password” specifically for Flask-Mail. Use this App Password as your MAIL_PASSWORD. Alternatively, consider using transactional email services like SendGrid, Mailgun, or AWS SES, which are designed for application email sending.
Here’s the full example code (app.py):
import osfrom flask import Flaskfrom flask_mail import Mail, Message
app = Flask(__name__)
# --- Configuration ---# Load credentials securely from environment variables# Example using 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') # Your Gmail address or App Usernameapp.config['MAIL_PASSWORD'] = os.environ.get('MAIL_PASSWORD') # Your Gmail App Passwordapp.config['MAIL_DEFAULT_SENDER'] = os.environ.get('MAIL_DEFAULT_SENDER', app.config['MAIL_USERNAME'])
# Check if essential config is missing (optional but good practice)if not app.config['MAIL_USERNAME'] or not app.config['MAIL_PASSWORD']: print("Warning: MAIL_USERNAME or MAIL_PASSWORD environment variables not set.") # Handle this case appropriately, maybe disable mail sending
# --- Initialize Mail ---mail = Mail(app)
# --- Route to Send Email ---@app.route("/")def index(): # Check if mail sending is configured before trying if not app.config['MAIL_USERNAME'] or not app.config['MAIL_PASSWORD']: return "Mail configuration missing. Cannot send email.", 500 try: # Create the message msg = Message( subject='Hello From Flask-Mail', # Sender uses MAIL_DEFAULT_SENDER if configured, else MAIL_USERNAME # sender=app.config['MAIL_DEFAULT_SENDER'] or app.config['MAIL_USERNAME'], recipients=['recipient@example.com'] # Replace with a valid recipient ) 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."
# Example: Adding an attachment (optional) # with app.open_resource("static/some_image.png") as fp: # msg.attach("logo.png", "image/png", fp.read())
# Send the message mail.send(msg) return "Email sent successfully!" except Exception as e: # Log the error for debugging app.logger.error(f"Mail sending failed: {e}") return f"Failed to send email: {e}", 500
if __name__ == '__main__': # Set environment variables before running for testing: # 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)Before running:
- Replace
'recipient@example.com'with an actual email address you can check. - Set the environment variables
MAIL_USERNAMEandMAIL_PASSWORD(and optionally others) in your terminal before running the script (see comments in the code). - Ensure you are using an App Password if using Gmail with 2-Step Verification.
Run the script (python app.py) and visit http://localhost:5000/. This will trigger the index function, attempt to create and send the email using the configured settings, and display a success or failure message.
Development Tip: During development, you might not want to send real emails. Consider using Python’s built-in debugging SMTP server (python -m smtpd -c DebuggingServer -n localhost:1025) and configure Flask-Mail to use localhost and port 1025 with no authentication. Emails will be printed to the console instead of being sent. Alternatively, use tools like MailHog or Mailtrap.