Relevant steps for sending email verification codes through flask-mail and asynchronous processing and sending emails through Celery

Relevant steps for sending email verification codes and verification through flask-mail and asynchronous processing and sending emails through Celery

  • 1. Send emails through flask-mail
    • 1.1 Install the flask-mail package in the terminal`
    • 1.2 Configure mail server
    • 1.3 Send email
      • 1.3.1 Create Flask-Mail instance
      • 1.3.2 Send email
  • 2. Cache verification code
    • 2.1 Install and create cache instance
    • 2.2 Cache verification codes by establishing a database
      • 2.2.1 Create database table
      • 2.1.2 Save the verification code after it is generated and sent.
    • 2.3 Cache verification codes through redis
      • 2.3.1 Download and install redis
      • 2.3.2 Configure flask-caching cache information
      • 2.3.3 Save the verification code after it is generated and sent.
  • 3. Verify the verification code
  • 4. Asynchronously process and send emails through Celery
    • 4.1 Install Celery
    • 4.2 Configure Celery information
    • 4.3 Define email sending tasks
    • 4.3 Create make_celery object
    • 4.4 Change the sent email to Celery format
    • 4.5 Run Celery commands

ps: This article only involves basic email sending and verification code caching, and does not involve front-end and other content.

1. Send emails through flask-mail

1.1 Install the flask-mail package` in the terminal

Enter the following command in the pycharm terminal:

pip install flask-mail

1.2 Configure mail server

Configure the relevant information of the mail server in the configuration file of the Flask application, such as SMTP server address, port number, user name, password, etc. This information will be used to establish a connection to the mail server.

# Email configuration
MAIL_SERVER = "smtp.qq.com"
# Use SSL encryption protocol to send emails
MAIL_USE_SSL = True
# The port number of the server used, the default is 465
MAIL_PORT = 465
# Sender’s username
MAIL_USERNAME = "xx.qq.com"
# Authorization code generated when smtp service is enabled
MAIL_PASSWORD = "xx"
# Set default sender
MAIL_DEFAULT_SENDER = "xx.qq.com"

Then import the email configuration into the app (I saved all the above email configurations in a file named config.py, and the subsequent cache configuration and celery configuration are also saved in this file)

import config
# Bind configuration file
app.config.from_object(config)

ps: I send emails through qq mailbox, so MAIL_SERVER says smtp.qq.com. If you use other mailboxes, you need to change the subsequent server.
Note: Since passwords are sensitive information, it is generally not recommended to store passwords in clear text in the code. Instead, you should use some secure methods to store and process passwords. Therefore, it is not recommended to expose your email password. Taking QQ mailbox as an example, you can change the password to an authorization verification code to protect account security.
Open the qq mailbox, find the location shown above in the settings, turn on the service, and enter the management service page

Click to generate the authorization code, enter the authorization code into MAIL_PASSWORD, and the basic configuration of flask-mail is completed.

1.3 Send email

1.3.1 Create Flask-Mail instance

To send an email, you must first create a flask-mail object and create a mail object in config.py (it can also be created in other files)

from flask_mail import Mail
mail = Mail()

Initialize mail in app.py

from config import mail
mail.init_app(app)

After initialization is completed, you can send emails

1.3.2 Send email

from flask_mail import Message
from config import mail
...

@bp.route("/captcha/email",methods=['GET','POST'])
def get_email_captcha():
message = Message(subject="subject",recipients=['target acquisition address'],body="mail content")
mail.send(message)
return "success"

Through the above code, the email is initially sent, and then a random four-digit verification code is generated and the email address obtained from the front end is added.

...

from flask import Blueprint, render_template, request
from flask_mail import Message
from config import mail
import random

...

@bp.route("/captcha/email",methods=['GET','POST'])
def get_email_captcha():
# Get the target email address from the front end
    email = request.args.get("email")
    # Generate a four-digit random verification code
    source = string.digits*4
    # Convert the verification code into string form
    captcha = random.sample(source, 4)
    captcha = "".join(captcha)
    subject = "subject"
    body = f"Your verification code is {<!-- -->captcha}"
    message = Message(subject=subject,recipients=[email],body=body)
    mail.send(message)
    return "success"

2. Caching verification code

The sending of the email has been completed, but the generated verification code cannot be matched one-to-one with the email address. In the future, when verifying whether the verification code entered by the user is correct, verification cannot be performed. Since the verification code is not particularly important, it can be passed The cache temporarily stores email addresses and verification codes. There are two caching methods I know, one is to cache the verification code by establishing a database, and the other is to cache the verification code through redis. If you only need to simply send a verification code without considering efficiency, it is recommended to create a database to solve the problem, which is much simpler than redis. If you consider efficiency and want to use celery for asynchronous processing, it is recommended to use redis.
Both methods require flask-caching to be installed to cache verification codes.

2.1 Install and create cache instance

Enter the following command in the terminal:

pip install flask-caching

After the installation is complete, you need to create a cache instance. Similar to flask-mail, create a cache object in config.py.

from flask_mail import Mail
from flask_caching import Cache
mail = Mail()
cache = Cache()

Then initialize the cache in app.py

from config import mail, cache
mail.init_app(app)
cache.init_app(app)

2.2 Cache verification codes by establishing a database

2.2.1 Create database table

# Enter the following content in the terminal to create a database table
# flask db init only needs to be executed once
# flask db migrate Generate migration script from ORM model
# flask db upgrade maps the migration script to the database

class EmailCaptchaModel(db.Model):
    __tablename__ = 'email_captcha'
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    email = db.Column(db.String(100), nullable=False)
    captcha = db.Column(db.String(100), nullable=False)

Add the above table to the database you created (I use flask-sqlachemy. If you use other methods to connect to the database, please refer to other posts to create the table and perform the following operations)

2.1.2 Save the verification code after it is generated and sent

from flask import Blueprint, render_template, request
from flask_mail import Message
from config import mail, cache
import random

...

@bp.route("/captcha/email",methods=['GET','POST'])
def get_email_captcha():
# Get the target email address from the front end
    email = request.args.get("email")
    # Generate a four-digit random verification code
    source = string.digits*4
    # Convert the verification code into string form
    captcha = random.sample(source, 4)
    captcha = "".join(captcha)
    subject = "subject"
    body = f"Your verification code is {<!-- -->captcha}"
    message = Message(subject=subject,recipients=[email],body=body)
    mail.send(message)
    # Cache verification code
    cache.set(email, captcha, timeout=100)
    # Store the verification code in the database
    email_captcha = EmailCaptchaModel(email=email, captcha=captcha)
    db.session.add(email_captcha)
    db.session.commit()
    return "success"

At this point, the creation of database tables to cache the database has been completed.

2.3 Cache verification codes through redis

2.3.1 Download and install redis

Download the redis package on pycharm

pip install redis

ps: If you want to use celery, it is best to download and configure the environment variables from the redis official website. Otherwise, you cannot use celery commands. You can also configure environment variables in the pycharm terminal. You can refer to other posts for configuration.

2.3.2 Configure flask-caching cache information

Configure the cache information of flask-caching where you configure your mail server.

# Cache configuration
CACHE_TYPE = "RedisCache"
 # Host name of the Redis server
CACHE_REDIS_HOST = "127.0.0.1"
#Port number of the Redis server
CACHE_REDIS_PORT = 6379

After configuration, you can cache information through redis

2.3.3 Save the verification code after it is generated and sent

It is basically the same as the code for creating a database table. What is missing is just the step of adding the email address and verification code to the database:

from flask import Blueprint, render_template, request
from flask_mail import Message
from config import mail, cache
import random

...

@bp.route("/captcha/email",methods=['GET','POST'])
def get_email_captcha():
# Get the target email address from the front end
    email = request.args.get("email")
    # Generate a four-digit random verification code
    source = string.digits*4
    # Convert the verification code into string form
    captcha = random.sample(source, 4)
    captcha = "".join(captcha)
    subject = "subject"
    body = f"Your verification code is {<!-- -->captcha}"
    message = Message(subject=subject,recipients=[email],body=body)
    mail.send(message)
    # Cache verification code
    cache.set(email, captcha, timeout=100)
    return "success"

3. Verify verification code

...
from flask import Blueprint, render_template, request
from config import cache, mail
...

@bp.route("/register", methods=['GET', 'POST'])
def register():
    if request.method == 'GET':
        return render_template("register_model.html")
    else:
        email = request.args.get("email")
        captcha = request.args.get("captcha")
        cache_captcha = cache.get(email)
        if captcha != cache_captcha or not cache_captcha:
            return "fail"
    return "success"

The above is a simple way to send a verification code and its verification

4. Asynchronous processing of sending emails through Celery

When multiple users send emails at the same time, if a synchronous method is used to send emails, each email sending operation needs to wait for the previous email to be sent before it can be carried out. This can easily cause lags and delays, so it can be done through Celery. Perform asynchronous processing. Celery is a distributed task queue framework used to implement task scheduling and distribution in asynchronous task processing. It can help you queue time-consuming tasks for asynchronous execution, thereby improving application performance and responsiveness. Using Celery, you can put the email sending task into the task queue for asynchronous execution instead of blocking the main thread. The main thread can continue processing other requests, while the email sending task is executed asynchronously in the background. This improves application performance and responsiveness.

4.1 Install Celery

pip install celery

4.2 Configuring Celery information

# Celery configuration
#Message broker for Celery task queue (such as Redis)
CELERY_BROKER_URL = "redis://127.0.0.1:6379"
# Storage backend for Celery task results (such as Redis)
CELERY_RESULT_BACKEND = "redis://127.0.0.1:6379"
CELERY_BROKER_CONNECTION_RETRY_ON_STARTUP = True

4.3 Define email sending tasks

Create a new python file in the project to define the email sending task and enter the following code

from flask_mail import Message
from config import mail
from celery import celery

#Define sending task
def send_mail(recipient, subject, body):
    message = Message(subject=subject, recipients=[recipient], body=body)
    mail.send(message)
    print("Sent successfully")

# Functions to create and configure Celery instances
def make_celery(app):
    celery = Celery(app.import_name, backend=app.config['CELERY_RESULT_BACKEND'], broker=app.config['CELERY_BROKER_URL'])
    TaskBase = celery.Task

    class ContextTask(TaskBase):
        abstract=True

        def __call__(self, *args, **kwargs):
            with app.app_context():
                return TaskBase.__call__(self, *args, **kwargs)
    celery.Task = ContextTask
    app.celery = celery
    celery.task(name="send_mail")(send_mail)
    return celery

4.3 Create make_celery object

...
from my_celery import make_celery
...

# Build celery
celery = make_celery(app)

4.4 Change sending emails to Celery format

from flask import Blueprint, render_template, request, current_app
from flask_mail import Message
from config import mail, cache
import random

...

@bp.route("/captcha/email",methods=['GET','POST'])
def get_email_captcha():
# Get the target email address from the front end
    email = request.args.get("email")
    # Generate a four-digit random verification code
    source = string.digits*4
    # Convert the verification code into string form
    captcha = random.sample(source, 4)
    captcha = "".join(captcha)
    subject = "subject"
    body = f"Your verification code is {<!-- -->captcha}"
    #Send emails through celery
    current_app.celery.send_task("send_mail", (email, subject, body))
    # Cache verification code
    cache.set(email, captcha, timeout=100)
    return "success"

4.5 Run Celery commands

To run Celery, you need to download a third-party library

pip install gevent

After installation, run and enter the following command in the terminal to use Celery:

 celery -A app.celery worker -P gevent -l info


The information in the figure above is displayed to indicate that the connection is completed.
ps: You need to run the above command every time you start it.