Flask邮件给芹菜腌渍错误

时间:2013-10-24 13:22:27

标签: python flask rabbitmq celery flask-mail

我尝试使用Celery(和rabbitmq)与Flask邮件异步发送电子邮件。最初我遇到了烧瓶芹菜中的render_template问题 - Flask-Mail breaks Celery(芹菜任务仍然会成功执行,但没有发送电子邮件)。虽然我试图解决这个问题(这仍然没有修复!) - 我偶然发现了另一个问题。这种酸洗错误是由于线程锁定造成的。我注意到当我改变调用celery任务的方式时(从延迟到apply_async),问题就开始了。从那时起,我尝试恢复我的更改,但我仍然无法摆脱错误。任何一个问题的任何帮助将受到高度赞赏。

追溯:

File "/Users/.../python2.7/site-packages/celery/app/amqp.py",          line 250, in publish_task
    **kwargs
File "/Users/.../lib/python2.7/site-packages/kombu/messaging.py", line 157, in publish
compression, headers)
File "/Users/.../lib/python2.7/site-packages/kombu/messaging.py", line 233, in _prepare
    body) = encode(body, serializer=serializer)
File "/Users/.../lib/python2.7/site-packages/kombu/serialization.py", line 170, in encode
    payload = encoder(data)
File "/Users/.../lib/python2.7/site-packages/kombu/serialization.py", line 356, in dumps
    return dumper(obj, protocol=pickle_protocol)
PicklingError: Can't pickle <type 'thread.lock'>: attribute lookup thread.lock failed

tasks.py

from __future__ import absolute_import
from flask import render_template
from flask.ext.mail import Message
from celery import Celery

celery = Celery('tasks', 
            broker = 'amqp://tester:testing@localhost:5672/test_host')

@celery.task(name = "send_async_email")
def send_auth_email(app, nickname, email):
    with app.test_request_context("/"):
        recipients = []
        recipients.append(email)
        subject = render_template("subject.txt")
        msg = Message(subject, recipients = recipients)
        msg.html = render_template("test.html", name = nickname)
        app.mail.send(msg)   

在测试用例中我只是打电话:

send_auth_email.delay(test_app, nick, email)

仅供参考:如果我不使用芹菜(即同步),API工作正常。提前谢谢!

1 个答案:

答案 0 :(得分:1)

当您调用send_auth_email.delay(test_app, nick, email)时,所有函数参数都将发送到任务队列。为此,芹菜腌制它们。

简短回答test_app,作为烧瓶应用,使用一些魔法,不能被腌制。有关可以腌制的内容以及未腌制的内容的详细信息,请参阅docs

一种解决方案是在test_app中重新实例化send_auth_email,传递所有必要的参数(在您的情况下似乎只是名称)。