3

I have adapted the asynchronous email example of Miquel Grindberg's book (highly recommended) with Flask to use flask_sendgrid. However, this code leads to an exception in a thread. It works fine the first time the app runs, but it breaks the second time.

Grindberg example:

def send_async_email(app, msg):
    with app.app_context():
        mail.send(msg)


def send_email(to, subject, template, **kwargs):
    app = current_app._get_current_object()
    msg = Message(app.config['FLASKY_MAIL_SUBJECT_PREFIX'] + ' ' + 
    subject,
    sender=app.config['FLASKY_MAIL_SENDER'], recipients=[to])
    msg.body = render_template(template + '.txt', **kwargs)
    msg.html = render_template(template + '.html', **kwargs)
    thr = Thread(target=send_async_email, args=[app, msg])
    thr.start()
    return thr

My translation using flask_sendgrid.

def send_async_email(app, **kwargs):
    with app.app_context():
        sendgrid.send_email(**kwargs)


def send_email(to, subject, template, **kwargs):
    app = current_app._get_current_object()
    html = __flask.render_template(template + '.html', **kwargs)

    msg = {'html': html,'subject': subject, 'to_email': to}

    thr = Thread(target=send_async_email, args=(app,), kwargs=msg)
    thr.start()
    return thr

Grindberg's example works fine with my google account. However, I would like to use Sendgrid to offload my app's emailing. Do I need to create the async myself or is it handled by the sendgrid api? If not, what is wrong with my code?

Mike
  • 3,775
  • 8
  • 39
  • 79

1 Answers1

2

To handle requests concurrently you can run Flask with:

app.run(threaded=True)

By default Flask runs with one thread so subsequent requests are blocked until a thread becomes available. In production, you'll also want to a WSGI container like Gunicorn to manage workers and threads.

Community
  • 1
  • 1
brennan
  • 3,392
  • 24
  • 42