3

我有一个 Flask 应用程序,其中 celery 可以正常工作,而 Flask-Mail 本身也可以正常工作。

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

celery = Celery('main_app', 
                 broker='mongodb://localhost',
                 backend='mongodb://localhost')
@celery.task
def cel_test():
     return 'cel_test'

@app.route('/works_maybe')
def works_maybe():
    return cel_test.delay()

到目前为止,一切都很好

cel_test 与 celery worker 配合得很好;一切都出现在 mongo 中。

但这就是奇怪的地方。“注册”加邮件方法没有 100% 有效@celery.task,但当它成为任务时就会崩溃。

@celery.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
ctx.app.update_template_context(context)  
AttributeError: 'NoneType' object has no attribute 'app'

有人可以解释为什么在一种情况下芹菜效果很好,但是当我涉及 mail.send(msg) 时它会中断?

也许我需要更普遍地学习 python 的东西?

任何想法,如果至少是关于处理此类问题的方法,将不胜感激。

4

2 回答 2

1

在烧瓶中完成的很多事情都绑定到应用程序上下文。例如,该render_template函数需要知道您的应用程序将其模板存储在何处。该session变量想知道您的应用程序的数据存储或缓存系统。该request对象和您mail.send在被调用时需要一些应用程序上下文。

如果您想在烧瓶应用程序范围之外调用它们,例如在您的 celery 任务中,请在应用程序上下文中执行此操作,如下所示:

...

with app.app_context():

    do_some_context_bound_actions()

    msg = Messgae(...)
    user_name = app.session["user"].name
    msg.html = render_template("mail/welcome.html", name=user_name)
    mail.send(msg)

...
于 2019-08-07T09:46:09.877 回答
0

更新

该错误位于send_email任务的 render_template 部分。

@celery.task
def send_email(some_arg, name, email):
    msg = Message(
                  subject='hello', 
                  body=render_template('email.txt',
                  name=name, 
                  some_arg=some_arg),
                  recipients=[email]
                 )
    return mail.send(msg)

当我删除kablaambody=render_template时,它可以工作。

我有from flask import render_template。也许render_template不能这样工作?

奇怪的是,没有芹菜,send_email加号就render_template完美了。

黑客式的成功

当我强制app_context使用另一个功能时,一切正常:

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

然后把它扔进send_email任务中

body = render_template('email.txt'…

变成

body= create_email(some_arg, name)

而且我们是免费的。

于 2013-02-23T16:44:31.277 回答