18

Python Flask を使用して Web サイトを構築しています。すべてが順調に進んでおり、現在、セロリを実装しようとしています。

セロリからフラスコメールを使用してメールを送信しようとするまで、それもうまくいきました。現在、「アプリケーション コンテキスト外で作業しています」というエラーが発生しています。

完全なトレースバックは

  Traceback (most recent call last):
  File "/usr/lib/python2.7/site-packages/celery/task/trace.py", line 228, in trace_task
    R = retval = fun(*args, **kwargs)
  File "/usr/lib/python2.7/site-packages/celery/task/trace.py", line 415, in __protected_call__
    return self.run(*args, **kwargs)
  File "/home/ryan/www/CG-Website/src/util/mail.py", line 28, in send_forgot_email
    msg = Message("Recover your Crusade Gaming Account")
  File "/usr/lib/python2.7/site-packages/flask_mail.py", line 178, in __init__
    sender = current_app.config.get("DEFAULT_MAIL_SENDER")
  File "/usr/lib/python2.7/site-packages/werkzeug/local.py", line 336, in __getattr__
    return getattr(self._get_current_object(), name)
  File "/usr/lib/python2.7/site-packages/werkzeug/local.py", line 295, in _get_current_object
    return self.__local()
  File "/usr/lib/python2.7/site-packages/flask/globals.py", line 26, in _find_app
    raise RuntimeError('working outside of application context')
RuntimeError: working outside of application context

これは私のメール機能です:

@celery.task
def send_forgot_email(email, ref):
    global mail
    msg = Message("Recover your Crusade Gaming Account")
    msg.recipients = [email]
    msg.sender = "Crusade Gaming stuff@cg.com"
    msg.html = \
        """
        Hello Person,<br/>

        You have requested your password be reset. <a href="{0}" >Click here recover your account</a> or copy and paste this link in to your browser: {0} <br />

        If you did not request that your password be reset, please ignore this.
        """.format(url_for('account.forgot', ref=ref, _external=True))
    mail.send(msg)

これは私のセロリファイルです:

from __future__ import absolute_import

from celery import Celery

celery = Celery('src.tasks',
                broker='amqp://',
                include=['src.util.mail'])


if __name__ == "__main__":
    celery.start()
4

5 に答える 5

6

Flask-mail が正しく機能するには、Flask アプリケーション コンテキストが必要です。セロリ側でアプリ オブジェクトをインスタンス化し、次のように app.app_context を使用します。

with app.app_context():
    celery.start()
于 2013-04-25T18:10:59.830 に答える
3

ポイントがないので、@codegeekの上記の回答に賛成できなかったので、このような問題の検索がこの質問/回答に助けられたので、自分で書くことにしました: python/flask/celery シナリオで同様の問題に取り組む。あなたのエラーは、mail私のエラーがセロリタスクで使用しようとしていたときに使用しようとしたことによるものでしたが、2つは同じ問題に関連していると思われ、使用しようとした場合url_for、の使用に起因するエラーが発生したと思われますurl_forその前にmail

セロリタスクにアプリのコンテキストが存在しないため(を含めた後でもimport app from my_app_module)、エラーも発生していました。mailアプリのコンテキストで操作を実行する必要があります。

from module_containing_my_app_and_mail import app, mail    # Flask app, Flask mail
from flask.ext.mail import Message    # Message class

@celery.task
def send_forgot_email(email, ref):
    with app.app_context():    # This is the important bit!
        msg = Message("Recover your Crusade Gaming Account")
        msg.recipients = [email]
        msg.sender = "Crusade Gaming stuff@cg.com"
        msg.html = \
        """
        Hello Person,<br/>
        You have requested your password be reset. <a href="{0}" >Click here recover your account</a> or copy and paste this link in to your browser: {0} <br />
        If you did not request that your password be reset, please ignore this.
        """.format(url_for('account.forgot', ref=ref, _external=True))

        mail.send(msg)

誰かが興味を持っている場合はurl_for、セロリタスクでの使用の問題に対する私の解決策がここにあります

于 2014-12-25T16:30:53.287 に答える
2

mail.py ファイルで、「app」および「mail」オブジェクトをインポートします。次に、リクエスト コンテキストを使用します。次のようにします。

from whateverpackagename import app
from whateverpackagename import mail

@celery.task
def send_forgot_email(email, ref):
    with app.test_request_context():
        msg = Message("Recover your Crusade Gaming Account")
        msg.recipients = [email]
        msg.sender = "Crusade Gaming stuff@cg.com"
        msg.html = \
        """
        Hello Person,<br/>
        You have requested your password be reset. <a href="{0}" >Click here recover your account</a> or copy and paste this link in to your browser: {0} <br />
        If you did not request that your password be reset, please ignore this.
        """.format(url_for('account.forgot', ref=ref, _external=True))

        mail.send(msg)
于 2013-04-25T19:06:44.810 に答える