I'm building an app using Flask with an application factory design pattern. I want to use Flask-Mail in one of my views which gets registered to the app via a Blueprint.
I saw from this Flask - cannot use Flask and Flask-mail instances from other files question that you're supposed to instantiate the Mail() object outside of the create_app() function like so:
from flask_mail import Mail
mail = Mail()
def create_app(config_lvl):
# stuff
mail.init_app(app)
# more stuff
return app
Then you can import the mail object into your view files and access it from there.
However for this to work you need to make sure the mail object in __init__.py
for your app is instantiated before you import the Blueprint that contains the view which uses the mail object. If you don't do this you get an import error.
To me this feels hacky and, although Flask oftentimes seems quite happy with this sort thing, I was hoping that the application factory design pattern would minimise this sort of import jiggery-pokery.
My solution was to just attach the mail client to the app object so that it can be accessed from anywhere else using current_app.mail
like so:
## __init.py __ ##
from flask_mail import Mail
def create_app(config_lvl):
# stuff
app.mail = Mail(app)
# more stuff
return app
## views.py ##
from flask_mail import Message
from flask import current_app
def send_email(to, subject, template):
msg = Message(
subject,
recipients=[to],
html=template,
sender=current_app.config['MAIL_DEFAULT_SENDER']
)
current_app.mail.send(msg)
This feels like a simpler way of accessing the mail client throughout the app, rather than faffing around making sure the order in which you import various things is correct.
What I want is for someone to tell my why this is not a good idea.