3

セロリが正常に動作し、Flask-Mail 自体も正常に動作する Flask アプリがあります。

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 はセロリ ワーカーで正常に動作します。すべてがmongoに表示されます。

しかし、ここからが奇妙になります。「サインアップ」とメールの方法は、なし@celery.taskでも 100% 機能しますが、タスクになると爆発します。

@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'

あるケースでセロリがうまく機能する理由を誰かが説明できますか?

おそらく、より一般的に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)

body=render_templatekablaamを削除すると、動作します。

私は持ってい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 に答える