flask_mail+celery 发邮件报错:“kombu.exceptions.EncodeError: Object of type 'Message' is not JSON serializable”

2017-11-07 13:25:55 +08:00
 DeHoo

flask_mail+celery 发邮件报错:“ kombu.exceptions.EncodeError: Object of type 'Message' is not JSON serializable ”

我把问题描述一下:如果在 main.pysend_async_email.apply_async([msg], countdown=60)这个方法,如果不用apply_async就能正常成功发送邮件,但是加了apply.async后就报错了。

各位大大有没有遇到此种情况?麻烦指点一下

以下贴出代码:

#main.py
#coding: utf-8
from flask import Flask
from run_celery import make_celery
from celery import platforms
from flask_mail import Mail,Message
from app.mail import send_async_email

platforms.C_FORCE_ROOT = True
app = Flask(__name__)
app.config.update(
    CELERYD_MAX_TASKS_PER_CHILD = 40,
    CELERY_BROKER_URL='redis://localhost:6379/0',
    CELERY_RESULT_BACKEND='redis://localhost:6379/1',
    DEBUG = True,
    MAIL_DFAULT_SENDER = 'Title! <111111@qq.com>',
    MAIL_SUBJECT_PREFIX = '[TA]-',
    MAIL_SERVER='smtp.qq.com',
    MAIL_PROT='25',
    # MAIL_USE_SSL = True,
    MAIL_USE_TLS = True,
    MAIL_USERNAME = '111111@qq.com',
    MAIL_PASSWORD = 'rkuynjdxxxxxqicfc',
    MAIL_DEBUG = True
)
celery = make_celery(app)
mail = Mail(app)

def  send_mail(to,subject):
    subject = subject
    email = to
    msg = Message(app.config['MAIL_SUBJECT_PREFIX'] + ' ' + subject, sender=app.config['MAIL_DFAULT_SENDER'],recipients=[email])
    msg.body = 'This a test mail body.'
    send_async_email.apply_async([msg], countdown=60)

@app.route('/')
def index():
    subject = 'This is a Test mail'
    email = '222222@sina.com'
    send_mail(email,subject)
    return 'Index page'

if __name__ == '__main__':
	app.run()

=========================================

#mail.py
#coding: utf-8
from flask_mail import Mail
from flask_celery import Celery
mail = Mail()
celery = Celery()

@celery.task()
def send_async_email(msg):
    mail.send(msg)

=========================================

#run_celery.py
#coding: utf-8
from celery import Celery

def make_celery(app):
    celery = Celery(app.import_name, broker=app.config['CELERY_BROKER_URL'])
    celery.conf.update(app.config)
    TaskBase = celery.Task
    class ContextTask(TaskBase):
        abstract = True
        def __call__(self, *args, **kwargs):
            with app.app_context():
                return TaskBase.__call__(self, *args, **kwargs)
    celery.Task = ContextTask
    return celery
4764 次点击
所在节点    Python
4 条回复
TimePPT
2017-11-07 13:55:34 +08:00
DeHoo
2017-11-07 14:33:15 +08:00
@TimePPT 多谢了,用 celery 搞这个好麻烦,我换成了 threading,直接就成功了。
Stitch
2017-11-07 15:05:06 +08:00
问题的本质是 celery 默认接收 JSON 序列化的数据,你现在直接入的 msg = Message() 对象,无法自动转化为 JSON 序列。
要解决这个问题,调用 celery 的 task 参数传入 subject = 'This is a Test mail' 和 email = '222222@sina.com'。
在 task 内部生成 msg 对象。

这样问题就解决了。
DeHoo
2017-11-07 19:24:37 +08:00
@Stitch 这样啊,我再试试看,多谢你了,兄弟!

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/404265

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX