2015-09-30 14 views
5

Tôi đang sử dụng Miguel Grinberg's article để thiết lập Celery với mẫu nhà máy ứng dụng để gửi email bằng Flask-Mail. Tôi đã gọi các kịch bản khác nhau sử dụng Celery mà không có bất kỳ vấn đề gì. Tuy nhiên, tôi tiếp tục nhận được Runtime Error: working outside of application context với tác vụ sau mặc dù tôi đang chạy nhân viên bên trong ngữ cảnh ứng dụng. Tại sao tôi nhận được lỗi này? Làm thế nào để tôi nhận được Flask-Mail để làm việc trong Celery?Chạy công nhân cần tây bên trong ngữ cảnh ứng dụng vẫn tăng lỗi "làm việc bên ngoài bối cảnh ứng dụng" trong nhiệm vụ

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() 

Lỗi:

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 

Tôi đã thử:

  • Cố gắng chuyển ngữ cảnh ứng dụng sang phương thức send_email.
  • Di chuyển phương thức send_async_email sang mô-đun tasks.py trong đó phần còn lại của nhiệm vụ cần tây của tôi cư trú.
  • Hiển thị mẫu bên ngoài các phương thức email và chuyển chúng dưới dạng đối số.

Trả lời

1

tôi đã có thể khắc phục vấn đề bằng cách tạo ra một thể hiện của ứng dụng bình tại địa phương:

email.py:

from flask import render_template, current_app 
from flask.ext.mail import Message 
from . import celery, mail, create_app 


@celery.task 
def send_async_email(msg): 
    app = create_app('default' or 'development') # -> fixed 
    with app.app_context(): 
     mail.send(msg) 


def send_email(to, subject, template, **kwargs): 
    app = current_app._get_current_object() 
    msg = Message(current_app.config['PORTAL_MAIL_SUBJECT_PREFIX'] + ' ' +  subject, 
    sender=current_app.config['MAIL_USERNAME'], recipients=[to]) 
    msg.body = render_template(template + '.txt', **kwargs) 
    msg.html = render_template(template + '.html', **kwargs) 
    send_async_email.delay(msg) 
Các vấn đề liên quan