How to Send Emails with Flask (Complete Guide: Flask-Mailman vs Flask-Mail)

Video thumbnail

We are going to learn about a quite special module that will allow us to add critical functionality to our framework: sending emails, which is ideal for sending emails to an authenticated user in Flask.

We must remember that Flask is a micro-framework, which means it incorporates the minimum necessary functionality to operate. Therefore, tools that are vital nowadays, such as sending emails, are not included by default. To fulfill this need, we will use the Flask-Mail extension.

Flask Mail allows sending emails using an SMTP client previously configured in the Flask application.

Flask Mail is discontinued and Flask Mailman is recommended.

Flask-mailman

We are going to learn about a quite special module that will allow us to add critical functionality to our framework: sending emails.

We must remember that Flask is a micro-framework, which means it incorporates the minimum necessary functionality to operate. Therefore, tools that are vital nowadays, such as sending emails, are not included by default. To fulfill this need, we will use the Flask-mailman extension, which is a modern and well-maintained fork of the old Flask-Mail.

Installation

To get this package, we will perform the same process as with previous modules using the pip command:

$ pip install flask-mailman

The package is quite lightweight, so the installation will only take a few seconds. Once installed, we can run our application perfectly.

Configuration and Initialization

To take the first steps, we must import the module and initialize it in our application.

from flask_mailman import Mail
# ... after declaring the app
mail = Mail(app)

It is a similar scheme to the one we use with other modules. By passing the application instance, the module is ready to perform configurations.

Mail Server Parameters

In the configuration file, we must define the SMTP server parameters. Here I explain the most important ones:

  • MAIL_SERVER: The outgoing server (e.g., smtp.gmail.com or localhost).
  • MAIL_PORT: Generally 25, 465, 587, or 2525.
  • MAIL_USE_TLS: To encrypt communication (in modern versions, TLS is preferred over SSL).
  • MAIL_USERNAME / MAIL_PASSWORD: Your access credentials.
  • MAIL_DEFAULT_SENDER: The email that will appear as the default sender.

Sending Messages

To send an email, we will use the EmailMessage class. We can define the subject, recipients, and body.

from flask_mailman import EmailMessage
msg = EmailMessage(
    "Hello Flask",
    "Hello world in plain text",
    "andres@desarrollolibre.net",
    ["recipient@example.com"]
)
msg.send()

1. HTML Content

If you want to send an email with HTML format, simply use the content_subtype attribute:

msg = EmailMessage(
    "Subject with HTML",
    "<b>Hello world in bold</b>",
    "sender@example.com",
    ["recipient@example.com"]
)
msg.content_subtype = "html" # We indicate that the content is HTML
msg.send()

2. Attach Files

We can also attach files very easily with the attach method:

with app.open_resource("static/logo.png") as fp:
   msg.attach("logo.png", fp.read(), "image/png")

With this, you have learned to configure and send emails using Flask-mailman, the modern alternative recommended for current Flask projects.

Flask Mail (Legacy)

To get this package, we will perform the same process as with previous modules using the pip command:

$ pip install flask-mail

The package is quite lightweight, so the installation will only take a few seconds. Once installed, we can run our application perfectly.

️ Configuration and Initialization

To take the first steps, we must import the module and initialize it with the instance of our application (app).

from flask_mail import Mail
# ... after declaring the app
mail = Mail(app)

We will configure the SMTP server to which we are going to connect in the configuration file:

app\my_app\config.py

class DevConfig(Config): 
   MAIL_SERVER = 'localhost' 
   MAIL_PORT = 25 
   MAIL_USERNAME = 'username' 
   MAIL_PASSWORD = 'password' 

And in development mode, we also enable:

app\my_app\config.py

class DevConfig(Config):
   ***
   MAIL_DEBUG = True
   MAIL_SUPPRESS_SEND = False
   TESTING = True

We register the extension globally at the application level:

app\my_app\__init__.py

from flask_mail import Mail
***
mail = Mail()
mail.init_app(app)

It is a similar scheme to the one we use with Bootstrap or CSRF protection. By passing the application instance, the module is ready to perform configurations.

You must ensure that the app configurations are loaded before initializing the Mail object. If you do it the other way around, you might encounter connection errors, as the module will try to connect without knowing the server parameters.

⚙️ Mail Server Parameters

In the configuration file (whether in base_config or in your specific environment one), we must define the SMTP server parameters. Here I explain the most important ones:

  • MAIL_SERVER: The outgoing server (e.g., smtp.gmail.com or localhost).
  • MAIL_PORT: Generally 25, 465, 587, or 2525.
  • MAIL_USE_TLS / MAIL_USE_SSL: To encrypt communication.
  • MAIL_USERNAME / MAIL_PASSWORD: Your access credentials.
  • MAIL_DEFAULT_SENDER: The email that will appear as the default sender.
  • MAIL_SUPPRESS_SEND: If True, emails will not actually be sent. It is ideal for development environments to avoid wasting sending quotas.

Tests with Mailtrap

To avoid having to configure a real Gmail server or hire hosting, we will use Mailtrap, a free service that intercepts outgoing emails and displays them in a virtual inbox.

Once registered in Mailtrap, we select the integration with Flask and the service will provide us with the server data, port, username, and password that we must paste into our configuration file.

Sending Messages

To send an email, we will use the Message class. We can define the subject, recipients (as a list), and the body of the message.

1. Basic Message (Text and HTML)

You can send plain text content using .body or rich format using .html. If you define both, the email client will prioritize the HTML.

from flask_mail import Message
msg = Message("Hello Flask", recipients=["andres@desarrollolibre.net"])
msg.body = "Hello world in plain text"
msg.html = "<b>Hello world in bold</b>"
mail.send(msg)

2. Attach Files

We can also attach files. It is very useful for sending images or documents. We need to open the file in binary mode and use the attach function.

with app.open_resource("static/logo.png") as fp:
   msg.attach("logo.png", "image/png", fp.read())

3. Customize the Sender

You can configure the sender more elegantly by passing a tuple instead of just a string, so that a descriptive name appears:

MAIL_DEFAULT_SENDER = ("Andrés from Desarrollo Libre", "andres@email.com")

4. Full Code

You can use the following code as a reference to send emails according to the configurations made previously:

from flask_mail import Message
from my_app import mail
def send_email():
   msg = Message(body="Text Example", 
                 sender="no-reply@MyWeb.net",
                 recipients=["andres@gmail.com"], subject="Subject")
   try:
       print(mail.send(msg))
   except Exception as e:
       print(e)

If you want to define HTML content:

msg = Message("Hello", sender=("Me", "me@example.com"))
msg.html = "<b>testing</b>"

Or just text:

msg = Message("Hello", sender=("Me", "me@example.com"))
msg.body = "testing"
Learn how to send emails in Flask step by step. We compare Flask-Mailman and Flask-Mail, SMTP configurations, tests with Mailtrap, and HTML sending.

I agree to receive announcements of interest about this Blog.

Andrés Cruz

ES En español