Sto utilizzando Miguel Grinberg's article per configurare Celery con il pattern di fabbrica dell'app per inviare email con Flask-Mail. Ho chiamato vari script che usano Celery senza problemi. Tuttavia continuo a ricevere Runtime Error: working outside of application context
con la seguente attività anche se sto eseguendo il worker all'interno di un contesto dell'app. Perché ricevo questo errore? Come faccio a far funzionare Flask-Mail in Celery?L'esecuzione di worker di Celery all'interno di un contesto app genera ancora un errore "working outside of app app" nell'attività
email.py
:
from flask import current_app, render_template
from flask.ext.mail import Message
from . import celery, mail
@celery.task
def send_async_email(msg):
mail.send(msg)
def send_email(to, subject, template, **kwargs):
with current_app.test_request_context(): # used app_context() as well.
msg = Message(current_app.config['PORTAL_MAIL_SUBJECT_PREFIX'] + ' ' + subject,
sender=current_app.config['PORTAL_MAIL_SENDER'], recipients=[to])
msg.body = render_template(template + '.txt', **kwargs)
msg.html = render_template(template + '.html', **kwargs)
send_async_email.delay(msg)
__init__.py
:
from flask import Flask
from celery import Celery
from flask.ext.mail import Mail
from configuration import config
mail = Mail()
celery = Celery(__name__, broker=config['default'].CELERY_BROKER_URL)
def create_app(config_name):
app = Flask(__name__)
app.config.from_object(config[config_name])
config[config_name].init_app(app)
mail.init_app(app)
celery.conf.update(app.config)
app.register_blueprint(main_blueprint)
return app
celery_worker.py
:
import os
from app import celery, create_app
app = create_app(os.getenv('FLASK_CONFIG') or 'default')
app.app_context().push()
Errore:
C:\Python27\Scripts\celery.exe worker -A celery_worker.celery --loglevel=info
[2015-09-30 12:07:34,408: INFO/MainProcess] Received task: app.email.send_async_email[3ec772ff-4767-49cb-90ba-445629da30da]
[2015-09-30 12:07:34,417: ERROR/MainProcess] Task app.email.send_async_email[3ec772ff-4767-49cb-90ba-445629da30da] raised unexpected: RuntimeError('working outside of application context',)
Traceback (most recent call last):
File "C:\Python27\lib\site-packages\celery\app\trace.py", line 240, in trace_task
R = retval = fun(*args, **kwargs)
File "C:\Python27\lib\site-packages\celery\app\trace.py", line 438, in __protected_call__
return self.run(*args, **kwargs)
File "<flask_project_path>\app\email.py", line 10, in send_async_email
mail.send(msg)
File "C:\Python27\lib\site-packages\flask_mail.py", line 491, in send
with self.connect() as connection:
File "C:\Python27\lib\site-packages\flask_mail.py", line 508, in connect
return Connection(app.extensions['mail'])
File "C:\Python27\lib\site-packages\werkzeug\local.py", line 338, in __getattr__
return getattr(self._get_current_object(), name)
File "C:\Python27\lib\site-packages\werkzeug\local.py", line 297, in _get_current_object
return self.__local()
File "C:\Python27\lib\site-packages\flask\globals.py", line 34, in _find_app
raise RuntimeError('working outside of application context')
RuntimeError: working outside of application context
ho provato:
- Cercando di passare il contesto di applicazione al metodo send_email.
- Spostamento del metodo send_async_email in un modulo tasks.py in cui risiedono il resto dei compiti di sedano.
- Rendering dei modelli al di fuori dei metodi di posta elettronica e passarli come argomenti.