I have a simple conceptual question about the Flask application factory pattern.
I'm trying to use Flask-Mail across different files. My __init__.py
file is:
#
# __init__.py
#
from flask import Flask
from flask_pymongo import PyMongo
from flask_mail import Mail
from flask_login import LoginManager
mail = Mail()
mongo = PyMongo()
login_manager = LoginManager()
def create_app():
app = Flask(__name__, instance_relative_config=False)
app.config.from_object('config.DevConfig')
mail.init_app(app)
login_manager.init_app(app)
mongo.init_app(app, retryWrites = False)
with app.app_context():
from .views import bp
app.register_blueprint(views.bp)
return app
And the other file:
#
# views.py
#
from flask import Blueprint
from flask import current_app as app
from flask_mail import Message
from app import mongo, mail, login_manager
bp = Blueprint('bp', __name__, template_folder='templates', static_folder='static')
@bp.route('/')
def index():
msg = Message("Success", recipients=[ email ])
with open('template.html', 'r') as fd:
msg.html = fd.read()
mail.send(msg)
Though I set MAIL_DEFAULT_SENDER
in my config file, I'm getting the error that there is no default sender specified when hitting the mail.send(msg)
line in views.py
. After checking the mail
object, I saw that it had no config variables set.
Per this tutorial, it seemed that I'd need to manually set current_app.config['MAIL_DEFAULT_SENDER']
whenever using the mail
object under this pattern, and would need to write an additional with app.app_context():
block around the mail
object such that it was instantiated with the proper config variables.
This seems like a lot of extra work, so is there another way to directly get the mail
object that was initialized in create_app
with all the proper config variables set?
Appreciate the help with this!
EDIT:
Created extensions.py
:
from flask_pymongo import PyMongo
from flask_mail import Mail
from flask_login import LoginManager
mail = Mail()
mongo = PyMongo()
login_manager = LoginManager()
And modified __init__.py
to be:
from flask import Flask
def create_app():
app = Flask(__name__, instance_relative_config=False)
app.config.from_object('config.DevConfig')
from app.extensions import mail, login_manager, mongo
mail.init_app(app)
login_manager.init_app(app)
mongo.init_app(app, retryWrites = False)
with app.app_context():
from .views import bp
app.register_blueprint(views.bp)
return app
And for views.py
, I have:
from flask import Blueprint
from flask import current_app
from flask_mail import Message
from app.extensions import mongo, mail, login_manager
bp = Blueprint('bp', __name__, template_folder='templates', static_folder='static')
@bp.route('/')
def index():
msg = Message("Success", recipients=[ email ])
with open('template.html', 'r') as fd:
msg.html = fd.read()
mail.send(msg)