I am using flask-mail to send from one account and it works fine. The unique information about multiple smtp accounts that I found in Google is this old comment.
What I have:
MAIL_USERNAME = config.get('mail_service', 'USER')
MAIL_PASSWORD = config.get('mail_service', 'PASSWD')
MAIL_SERVER = config.get('mail_service', 'MAIL_SERVER')
MAIL_PORT = 587
MAIL_USE_TLS = True
mail = Mail()
def create_app(config_name):
app = Flask(__name__)
mail.init_app(app)
...
from flask_mail import Message
@app.route("/")
def index():
msg = Message("Hello", sender="from@example.com", recipients=["to@example.com"])
I am not sure what is the best approach. Probably when sending each mail specify one of both configured SMTP accounts?
Any idea how to implement that?
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'
....