You can use a config.json
file to store the config for both accounts. Then, a custom function can use that file to extract values whenever required. The following code shows a simple setup of two accounts. The key requirement is to update the app config before initializing the app with the mail object(mail.init_app()
) in each route. Each smtp account has its "message send" operation in its own route.
config.json:
Config for two SMTP Gmail accounts
{
"MAIL_SERVER" : "smtp.gmail.com",
"MAIL_PORT" : 587,
"MAIL_USE_TLS": "True",
"MAIL_USERNAME" : ["smtp1@gmail.com", "smtp2@gmail.com"],
"MAIL_PASSWORD" : ["pwd_for_smtp1", "pwd_for_smtp2"]
}
Code:
To test this code, I sent test emails from smtp1@gmail.com to smtp2@gmail.com and vice versa. You should get the respective message displayed for each route when you access the route on your localhost.
Note: For security reasons, you should use separate app passwords for authentication which should be generated for each SMTP Gmail account. The app passwords should also be updated in config.json above for the MAIL_PASSWORD key for each account. More details here.
from flask import Flask
from flask_mail import Mail
from flask_mail import Message
import json
def smtp_config(config_name, smtp=1):
with open(config_name) as f:
config_data = json.load(f)
if smtp not in {1,2}:
raise ValueError("smtp can only be 1 or 2")
if smtp==2:
MAIL_USERNAME = config_data['MAIL_USERNAME'][1]
MAIL_PASSWORD = config_data['MAIL_PASSWORD'][1]
else:
MAIL_USERNAME = config_data['MAIL_USERNAME'][0]
MAIL_PASSWORD = config_data['MAIL_PASSWORD'][0]
MAIL_SERVER = config_data['MAIL_SERVER']
MAIL_PORT = config_data['MAIL_PORT']
MAIL_USE_TLS = bool(config_data['MAIL_USE_TLS'])
return [MAIL_USERNAME, MAIL_PASSWORD, MAIL_SERVER, MAIL_PORT, MAIL_USE_TLS]
app = Flask(__name__)
mail = Mail()
@app.route("/")
def index():
smtp_data = smtp_config('config.json', smtp=1)
app.config.update(dict(
MAIL_SERVER = smtp_data[2],
MAIL_PORT = smtp_data[3],
MAIL_USE_TLS = smtp_data[4],
MAIL_USERNAME = smtp_data[0],
MAIL_PASSWORD = smtp_data[1],
))
mail.init_app(app)
msg = Message("Hello", sender="smtp1@gmail.com", recipients=["smtp2@gmail.com"])
msg.body = "This message was sent from smtp1"
mail.send(msg)
return "The message was sent from smtp1"
@app.route("/smtp2/")
def smtp2():
smtp_data = smtp_config('config.json', smtp=2)
app.config.update(dict(
MAIL_SERVER = smtp_data[2],
MAIL_PORT = smtp_data[3],
MAIL_USE_TLS = smtp_data[4],
MAIL_USERNAME = smtp_data[0],
MAIL_PASSWORD = smtp_data[1],
))
mail.init_app(app)
msg = Message("Hello", sender="smtp2@gmail.com", recipients=["smtp1@gmail.com"])
msg.body = "This message was sent from smtp2"
mail.send(msg)
return "The message was sent from smtp2"
if __name__=='__main__':
app.run(debug=True, port=5000, host='localhost')
The smtp_config()
function accepts two args: config_name
which is the path of the config.json file and smtp
which has a default value of 1 for smtp1 account config. This parameter can either be 1 or 2. The function returns a list of values required for mail configuration for the particular smtp
.
Then, in each route, just update the app config with the values received from the above function and then initialize the mail settings from the application settings(mail.init_app()
).
To add more accounts, you can pass a list of smtp account names to smtp
for unique identification(instead of numbers 1 & 2 above). Of course, you'd also have to modify config.json
accordingly:
def smtp_config(config_name, smtp=['smtp1@gmail.com', 'smtp2@gmail.com', 'smtp3@gmail.com'....]):
#<---code--->
if x[0]:
MAIL_USERNAME = 'smtp1@gmail.com'
....
elif x[1]:
MAIL_USERNAME = 'smtp2@gmail.com'
....