Take the 2-minute tour ×

I've got a Flask app where celery works fine and Flask-Mail on it's own works fine as well.

from celery import Celery
from flask_mail import Mail, Message
app = Flask(__name__)
mail = Mail(app)

celery = Celery('main_app', 
def cel_test():
     return 'cel_test'

def works_maybe():
    return cel_test.delay()


cel_test works fine with the celery worker; everything shows up in mongo.

But here's where it gets weird. The "signup" plus mail method works 100% without @celery.task but blows up when it becomes a task.

def send_email(some_arg, name, email):
    msg = Message(…message details..)
    return mail.send(msg)

@app.route("/signup", methods=['POST'])
def signup():
    return send_email.delay(...stuff for the message…)


R = retval = fun(*args, **kwargs)
File "/Users/username/pymods/virtualenvs/directory/lib/python2.7/site-packages/celery-3.0.15-py2.7.egg/celery/task/trace.py", line 415, in __protected_call__
return self.run(*args, **kwargs)
File "/Users/username/pymods/directory/directory/main_app/main_app.py", line 43, in send_email
something = 'a string in the Message'),
File "/Users/username/pymods/virtualenvs/directory/lib/python2.7/site-packages/flask/templating.py", line 123, in render_template
AttributeError: 'NoneType' object has no attribute 'app'

Could someone explain why in one case celery works great but when I involve mail.send(msg) it breaks?

Perhaps there is something I need to learn with python more generally?

Any thoughts, if at least as to approach to this type of issue would be greatly appreciated.

share|improve this question
do you try app = Flask(__name__) celery = Celery(__name__) celery.conf.add_defaults(app.config)? –  Joe Feb 23 '13 at 11:11
Ok, we're getting somewhere. Now the worker raises: [2013-02-23 15:59:52,093: ERROR/MainProcess] Received unregistered task of type '__main__.send_email' And KeyError: 'main.send_email'` Which is strange given that print celery.tasks shows <@task: __main__.send_email> Which perhaps implies it is registered. –  Stuart Feb 23 '13 at 16:02
add comment

1 Answer


The bug is in the render_template portion of the send_email task.

def send_email(some_arg, name, email):
    msg = Message(
    return mail.send(msg)

When I remove body=render_template, kablaam, it works.

I've got from flask import render_template. Perhaps render_template can't work like this?

Strangely, without Celery, the send_email plus render_template works perfect.

Hackish Success

When I force the app_context with another function everything works:

def create_email(some_arg, name, email):
    with app.test_request_context('/send_email'):
        return render_template('email.txt', 

and then toss it in the send_email task so

body = render_template('email.txt'…


body= create_email(some_arg, name)

And we're home free.

share|improve this answer
You can also send the msg object as a parameter. However, you probably want to use a retry to avoid losing the e-mail by sending it again afterwards when something goes wrong (e.g. connection is lost). –  H.D. May 29 '13 at 6:13
add comment

Your Answer


