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.
SN | Parameter | Description |
---|---|---|
1 | MAIL_SERVER | It represents the name or IP address of the email server. The default is localhost. |
2 | MAIL_PORT | It represents the port number of the server. Default port number is 25. |
3 | MAIL_USE_TLS | It is used to enable or disable the transport security layer description. The default is false. |
4 | MAIL_USE_SSL | It is used to enable or disable the secure socket layer description. The default value is false. |
5 | MAIL_DEBUG | It is used to provide the debug support to the mail application. The default value is None. |
6 | MAIL_USERNAME | It represents the user name of the sender. The default value is None. |
7 | MAIL_PASSWORD | It represents the password of the server email id. The default value is None. |
8 | MAIL_DEFAULT_SENDER | It is used to set the default sender id for the multiple emails. The default value is None. |
9 | MAIL_MAX_EMAILS | It is used to set the maximum number of email to be sent. The default value is None. |
10 | MAIL_SUPPRESS_SEND | Sending the mail is suppressed if the app.testing is set to the true. |
11 | MAIL_ASCII_ATTACHMENTS | If 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.
- 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.
- 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
- from flask import *
- from flask_mail import *
- from random import *
-
- app = Flask(__name__)
- mail = Mail(app)
-
- 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)
- otp = randint(000000,999999)
-
- @app.route('/')
- def index():
- return render_template("index.html")
-
- @app.route('/verify',methods = ["POST"])
- def verify():
- email = request.form["email"]
-
- msg = Message('OTP',sender = '[email protected]', recipients = [email])
- msg.body = str(otp)
- mail.send(msg)
- return render_template('verify.html')
-
- @app.route('/validate',methods=["POST"])
- def validate():
- user_otp = request.form['otp']
- if otp == int(user_otp):
- return "<h3>Email verified successfully</h3>"
- return "<h3>failure</h3>"
-
- if __name__ == '__main__':
- 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.
Now, the user is prompted to enter the OTP sent to the specified email.
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.
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)
Leave a Reply