Flask-Mail Extension

Considering the fact that flask is a micro framework, it has its limitations in providing the facilities to the developer. Although, there are several extensions to the flask like Mail, WTF, SQLite, SQLAlchemy, etc. which facilitates the developer to provide some basic facilities to the user.

In this section of the tutorial, we will study one of the most common extensions to the flask, i.e., Flask-Mail.

A web application must be capable of sending emails to users. The flask-mail extension provides the simple interface for the developer and the email server to send the email through the web application.

For this purpose, we must install the flask-mail extension using the pip installer.

pip install Flask-Mail

The application must configure the flask-mail for the following parameters.

SNParameterDescription
1MAIL_SERVERIt represents the name or IP address of the email server. The default is localhost.
2MAIL_PORTIt represents the port number of the server. Default port number is 25.
3MAIL_USE_TLSIt is used to enable or disable the transport security layer description. The default is false.
4MAIL_USE_SSLIt is used to enable or disable the secure socket layer description. The default value is false.
5MAIL_DEBUGIt is used to provide the debug support to the mail application. The default value is None.
6MAIL_USERNAMEIt represents the user name of the sender. The default value is None.
7MAIL_PASSWORDIt represents the password of the server email id. The default value is None.
8MAIL_DEFAULT_SENDERIt is used to set the default sender id for the multiple emails. The default value is None.
9MAIL_MAX_EMAILSIt is used to set the maximum number of email to be sent. The default value is None.
10MAIL_SUPPRESS_SENDSending the mail is suppressed if the app.testing is set to the true.
11MAIL_ASCII_ATTACHMENTSIf it is set to true, attached file names are converted to ASCII. The default is False.

Flask-Mail Module Classes

There are several classes which are important to send emails using the python flask web application.

Message class

The Message class binds the email message into the one simple Message class instance so that the important methods like attach() can be called on this instance. The syntax to instantiate the Message class is given below.

  1. Flask-mail.Message(subject, recipients, body, html, sender, cc, bcc, reply-to, date, charset, extra-headers, mail-options, rcpt_options)  

There are the following methods that can be called on the Message class object.

  • attach(filename, content_type, data, disposition): this method is used to send the attachments with the message. This method accepts the name of the file, MIME type of file, raw file data, and the content disposition.
  • add_recipient(): It is used to add the recipient to the message.

Mail Class

Mail class object is used to send the email. The Mail class is instantiated by passing the application object to the Mail class constructor as given below.

  1. Flask-mail.Mail(app=None)   

The Mail class contains the following methods.

  • send(): It sends the message object content to the recipient.
  • connect(): It is used to open the connection with mail host.
  • send_message(): It is used to send the message object.

Process of sending email using flask web application

There are the following steps involved in sending an email using the flask web application.

Step 1: import the required module like flask-mail, flask using from-import statement.

from flask import *  

from flask-mail import *

Step 2: Configure the Flask Mail.

app.config['MAIL_SERVER']='smtp.gmail.com'  

app.config['MAIL_PORT']=465  

app.config['MAIL_USERNAME'] = '[email protected]'  

app.config['MAIL_PASSWORD'] = '******'  

app.config['MAIL_USE_TLS'] = False  

app.config['MAIL_USE_SSL'] = True

Step 3: Instantiate the Mail class.

mail = Mail(app)  

Step 4: Instantiate the Message class with the desired attributes in the function mapped by some URL rule.

@app.route('/')  

def index():  

    msg = Message('subject', sender = '[email protected]', recipients=['[email protected]'])  

    msg.body = 'hi, this is the mail sent by using the flask web application'  

    return "Mail Sent, Please check the mail id"

Example

The following example contains a python script where we send the email to the given email id.

Mailer.py

from flask import *  

from flask-mail import *  

  

app = Flask(__name__)  

  

#Flask mail configuration  

app.config['MAIL_SERVER']='smtp.gmail.com'  

app.config['MAIL_PORT']=465  

app.config['MAIL_USERNAME'] = '[email protected]'  

app.config['MAIL_PASSWORD'] = '******'  

app.config['MAIL_USE_TLS'] = False  

app.config['MAIL_USE_SSL'] = True  

  

#instantiate the Mail class  

mail = Mail(app)  

  

#configure the Message class object and send the mail from a URL  

@app.route('/')  

def index():  

    msg = Message('subject', sender = '[email protected]', recipients=['[email protected]'])  

    msg.body = 'hi, this is the mail sent by using the flask web application'  

    return "Mail Sent, Please check the mail id"  

  

if __name__ == '__main__':  

    app.run(debug = True)

Our Python web application attempts to log in to the email_id mentioned in the script. This attempt can be blocked if you have not allowed access to the less secure application to your Google account. In this case, visit the link https://www.google.com/settings/security/lesssecureapps and allow access for the less secure app.

Email verification in flask using OTP

In the modern web applications, sometimes the email is verified using the one time password generated randomly by the program. In this example, we will create a python script that accepts the user’s email id as the input from the user and send an email containing the automatically (randomly) generated (4-digit) one-time password.

For the successful verification of the email-id, the user is required to enter the otp sent to the mentioned email id. If the OTP entered by the user is matched with the randomly generated OTP, then the email-id is successfully verified, and the success message is shown to the user otherwise the verification is failed, and the failure message is shown to the user.

In the below example, A flask script Mailer.py acts as a controller with the functions verify() and validate() associated with the URL /verify and /validate respectively. These functions also render the HTML templates to accept the input from the user and show the result depending upon the email verification.

Mailer.py


  1. from flask import *  
  2. from flask_mail import *  
  3. from random import *  
  4.   
  5. app = Flask(__name__)  
  6. mail = Mail(app)  
  7.   
  8. app.config["MAIL_SERVER"]='smtp.gmail.com'  
  9. app.config["MAIL_PORT"] = 465     
  10. app.config["MAIL_USERNAME"] = '[email protected]'  
  11. app.config['MAIL_PASSWORD'] = '*************'  
  12. app.config['MAIL_USE_TLS'] = False  
  13. app.config['MAIL_USE_SSL'] = True  
  14.   
  15. mail = Mail(app)  
  16. otp = randint(000000,999999)  
  17.  
  18. @app.route('/')  
  19. def index():  
  20.     return render_template("index.html")  
  21.  
  22. @app.route('/verify',methods = ["POST"])  
  23. def verify():  
  24.     email = request.form["email"]  
  25.       
  26.     msg = Message('OTP',sender = '[email protected]', recipients = [email])  
  27.     msg.body = str(otp)  
  28.     mail.send(msg)  
  29.     return render_template('verify.html')  
  30.  
  31. @app.route('/validate',methods=["POST"])  
  32. def validate():  
  33.     user_otp = request.form['otp']  
  34.     if otp == int(user_otp):  
  35.         return "<h3>Email verified successfully</h3>"  
  36.     return "<h3>failure</h3>"  
  37.   
  38. if __name__ == '__main__':  
  39.     app.run(debug = True)

index.html

<!DOCTYPE html>  

<html>  

<head>  

    <title>index</title>  

</head>  

<body>  

<form action = "http://localhost:5000/verify" method = "POST">  

Email: <input type="email" name="email">  

<input type = "submit" value="Submit">  

</form>  

</body>  

</html>

verify.html

<!DOCTYPE html>  

<html>  

<head>  

    <title>OTP Verification</title>  

</head>  

  

<body>  

  

<form action = "/validate" method="post">  

  

<h4> One-time password has been sent to the email id. Please check the email for the verification.</h4>  

  

Enter OTP: <input type="text" name="otp">  

  

<input type="submit" value="Submit">  

  

</form>  

</body>  

</html>

The following template prompts the user to enter the email_id and password. The script Mailer.py will send an email containing the one-time password to the email id entered by the user.

Flask-Mail Extension

Now, the user is prompted to enter the OTP sent to the specified email.

Flask-Mail Extension

The function validate() matches the OTP entered by the user with the one which was randomly generated and mailed to the user’s email id. In this case, OTP is matched; therefore the user will get the success message as shown in the below image.

Flask-Mail Extension

Bulk Emails

In the above example, the script sends only one email to the user for the email verification. In web applications, there are cases where we need to send multiple emails or the bulk of emails in a single connection.

In that case, we can make use of the python with the statement which closes the connection object automatically once all the emails are sent.

Example

from flask import *  

from flask_mail import *  

  

app = Flask(__name__)  

  

app.config["MAIL_SERVER"]='smtp.gmail.com'  

app.config["MAIL_PORT"] = 465  

app.config["MAIL_USERNAME"] = '[email protected]'  

app.config['MAIL_PASSWORD'] = '******'  

app.config['MAIL_USE_TLS'] = False  

app.config['MAIL_USE_SSL'] = True  

  

users = [{'name':'john','email':'[email protected]'},{'name':'Ayush','email':'[email protected]'},{'name':'david','email':'[email protected]'}]  

  

mail = Mail(app)  

 

@app.route("/")  

def index():  

    with mail.connect() as con:  

        for user in users:  

            message = "hello %s" %user['name']  

            msgs = Message(recipients=[user['email']],body = message, subject = 'hello', sender = '[email protected]')  

            con.send(msgs)  

    return "Sent"  

if __name__ == "__main__":  

    app.run(debug = True)

Adding attachments with the mail

Flask facilitates us to send the attachment with the mail. For this purpose, we need to open the resource using the open_resource() method of Flask class. Then, we can use the python-with statement to attach the resource with the message. The with statement closes the resource automatically when the work is done.

The following syntax is used to send the attachments with the mail.

with app.open_resource("image.png") as fp:   

    msg.attach("image.png", "image/png", fp.read())

The flask script which sends the attachment with the mail is given below.

mailer_attach.py

from flask import *  

from flask_mail import *  

  

app = Flask(__name__)  

  

app.config["MAIL_SERVER"]='smtp.gmail.com'  

app.config["MAIL_PORT"] = 465  

app.config["MAIL_USERNAME"] = '[email protected]'  

app.config['MAIL_PASSWORD'] = '********'  

app.config['MAIL_USE_TLS'] = False  

app.config['MAIL_USE_SSL'] = True  

  

mail = Mail(app)  

 

@app.route("/")  

def index():  

    msg = Message(subject = "hello", body = "hello", sender = "[email protected]", recipients = ["[email protected]"])  

    with app.open_resource("/home/javatpoint/Desktop/galexy.jpg") as fp:  

        msg.attach("galexy.jpg","image/png",fp.read())  

        mail.send(msg)  

    return "sent"  

  

if __name__ == "__main__":  

    app.run(debug = True)

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *