You can use flask-mail
to facilitate email sending and recieving in a flask app. This application shows how you can use it to locally send an email to a registered user of the application. Learn how Flask-Mail was used to add email support here.
Towards the end, I show how you can use Twilio SendGrid to send an email.
- Password authentication of a user
- Password reset capability
- Twilio SendGrid API
- Flask web framwork
- Python3 for programming
- Flask mail to enable email communication
- Flask sqlalchemy to create database
- Flask migrate to handle database migrations
- Flask wtf to create secure web forms
- Flask bootstrap for styling and cross-browser responsiveness
- Email validator to validate user emails
- Python dotenv to load environment variables
- Pyngrok to enable localhost testing
- Pyjwt to handle token used in verifying email reset requests
- Flask login to handle user sessions
- Clone this repo:
$ git clone git@github.com:GitauHarrison/how-to-add-email-support-in-a-flask-app.git
- Move into the cloned folder
$ cd how-to-add-email-support-in-a-flask-app
- Create and activate a virtual environment:
$ mkvirtualenv flask_email_support
- Install application dependencies in your virtual environment:
(flask_email_support)$ pip3 install -r requirements.txt
- Before you can run your server, remember to create a
.env
file following the guidance seen in the.env-template
. Create a.env
file in the root directory:
(flask_email_support)$ touch .env
- Update the
.env
file with all the necessary details. Remember to add your email environment variables which are:
MAIL_SERVER=
MAIL_PORT=
MAIL_USE_TLS=
MAIL_USERNAME=
MAIL_PASSWORD=
ADMINS=
- Run the flask server:
(flask_email_support)$ flask run
Once your application is running, you can access your localhost on http://127.0.0.1:5000/. Additionally, if you look carefully in your terminal, you will see: * Tunnel URL: NgrokTunnel: "http://4209c9af6d43.ngrok.io" -> "http://localhost:5000"
The HTTP value may be different from the one shown here because I am using the free tier package of ngrok
. Paste the link http://4209c9af6d43.ngrok.io on another device, say your mobile phone, to test the application while it is on localhost.
Another way to obtain ngrok
's free public URLs would be to run the command below in a new terminal window:
(flask_email_support)$ ngrok http 5000
# Output
ngrok by @inconshreveable (Ctrl+C to quit)
Session Status online
Session Expires 1 hour, 58 minutes
Version 2.3.35
Region United States (us)
Web Interface http://127.0.0.1:4042
Forwarding http://6e95e59c2233.ngrok.io -> http://loc
Forwarding https://6e95e59c2233.ngrok.io -> http://lo
Connections ttl opn rt1 rt5 p50 p9
0 0 0.00 0.00 0.00 0
Note the lines beginning with 'Forwarding'. These show the public URLs that ngrok uses to redirect requests into our service. This method also provides you with https://
for secure connections.
- Register a user using a valid and accessible email address
- Log in to the app to verify that your creditials are correct
- Click on the Logout link at the top-right of the navbar
- Click on Reset Here link in the Login to reset your password
- Enter the registered user's email address
- Check the user's email to see the password reset emal
- Click the reset link in the email. You will be redirected to a password reset page
- Enter and confirm your new password
- Try to log in again using your new password.
You should be able to log in.
SendGrid can be used to send emails. I will show you how you can do that using the email module we have created in the application above.
To set up SendGrid, you will need to:
- Create a free account now
- Log into your account
- Select Settings then click on API Keys
- Create a new API Key by clicking on the blue button
- Give the API Key a name
- Ensure you select Full Access
- Click Create and View button
Copy the API Key and save it somewhere safe. You will need it later.
Update the config file to include your SendGrid configurations:
# config.py
# Current Email configurations
MAIL_SERVER = os.environ.get('MAIL_SERVER')
MAIL_PORT = int(os.environ.get('MAIL_PORT') or 25)
MAIL_USE_TLS = os.environ.get('MAIL_USE_TLS') is not None
MAIL_USERNAME = os.environ.get('MAIL_USERNAME')
MAIL_PASSWORD = os.environ.get('MAIL_PASSWORD')
ADMINS = ['your-email@example.com']
# SendGrid's email configurations
MAIL_SERVER = os.environ.get('MAIL_SERVER')
MAIL_PORT = int(os.environ.get('MAIL_PORT') or 25)
MAIL_USE_TLS = os.environ.get('MAIL_USE_TLS') is not None
MAIL_USERNAME = os.environ.get('MAIL_USERNAME')
MAIL_PASSWORD = os.environ.get('SENDGRID_API_KEY')
MAIL_DEFAULT_SENDER = os.environ.get('MAIL_DEFAULT_SENDER')
Update the .env
file as follows:
MAIL_SERVER='smtp.sendgrid.net'
MAIL_PORT='587'
MAIL_USE_TLS='True'
MAIL_USERNAME='apikey'
SENDGRID_API_KEY='add-your-api-key-here'
MAIL_DEFAULT_SENDER='a-valid-and-working-email-address'
Create a Sender Identity as follows:
- From your SendGrid Dashboard, select Settings
- Click on Sender Authentication. You will see Single Sender Verification section
- Click on Verify Single Sender button.
- Create a new Sender by clicking on the blue button. You will see the form below:
- Provide valid and working email addresses for From Email Address and Reply To form fields. You can fill in placeholder data in the other fields.
Activate an instance of the application in the Python interpreter using flask shell
command:
(flask_email_support) flask shell
# Output
Python-dotenv could not parse statement starting at line 1
Python 3.8.5 (default, Jan 27 2021, 15:41:15)
[GCC 9.3.0] on linux
App: app [development]
Instance: /home/harry/email_support_in_flask/instance
>>>
Run the following commands the current Python interpreter:
>>> from app import mail
>>> from flask_mail import Message
>>> msg = Message('Sending Email Using Twilio SendGrid', recipients=['a-working-recipient-email-address'])
>>> msg.body = 'Hi, \n\n This is a test email that I have sent you. It has no significance to you whatsoever, but to me it means a lot. You can ignore this message. \n\nFlask Email Support Team'
>>>msg.html = '<p>Hi, <br><br> This is a test email that I have sent you. It has no significance to you whatsoever, but to me it means a lot. You can ignore this message. <br><br>Flask Email Support Team</p>'
>>>mail.send(msg)
Hopefully everything goes well and you have received the test email in your inbox.