Reputation: 964
I am stuck on decorating the function. Help me find out the problem. Decorator:
def sync(f):
def wrapper(*args, **kwargs):
thr = Thread(target=f, args=args, kwargs=kwargs)
thr.start()
return wrapper
Sending functions:
def send_email(subject, sender, recipients, text_body, html_body):
""" Build and send e-mail with the provided parameters."""
msg = Message(subject, sender=sender, recipients=recipients)
msg.body = text_body
msg.html = html_body
mail.send(msg)
@sync
def send_confirmation_email(recipient, app = current_app):
"""Send registration email to the provided recipient."""
subject = 'Account confirmation e-mail'
sender = '[email protected]'
recipients = [recipient]
activation, deletion = confirmation_links(recipient) #construct hashed links
text_body = render_template('confirmation_email.txt',
activation = activation,
deletion = deletion)
html_body = render_template('confirmation_email.html',
activation = activation,
deletion = deletion)
send_email(subject, sender, recipients, text_body, html_body)
Views function:
@app.route('/signup', methods = ['GET', 'POST'])
def signup():
form = SignupForm()
if form.validate_on_submit():
send_confirmation_email(recipient = form.email.data)
return redirect(url_for('activate'))
else:
return render_template('signup.html',
title = 'Sign Up',
form = form)
The problem is that emails are not sent with active decorator @sync
.
When I remove @sync
decorator everything is working but, of course, without threading.
And app
waits a few seconds before redirect
.
Any help will be helpful. Thanks.
Upvotes: 0
Views: 538
Reputation: 6644
The render_template
function requires a Flask application context to work.
When your send_confirmation_email
function is run in a seperate thread there is no application context set up for render_template
to work.
You could solve this by using app.app_context()
:
@sync
def send_confirmation_email(recipient):
"""Send registration email to the provided recipient."""
with app.app_context():
subject = 'Account confirmation e-mail'
sender = '[email protected]'
recipients = [recipient]
activation, deletion = confirmation_links(recipient) #construct hashed links
text_body = render_template('confirmation_email.txt',
activation = activation,
deletion = deletion)
html_body = render_template('confirmation_email.html',
activation = activation,
deletion = deletion)
send_email(subject, sender, recipients, text_body, html_body)
You could also look into using something like Celery
Upvotes: 2