V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
DeHoo
V2EX  ›  Python

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

  •  
  •   DeHoo · 2017-11-07 13:25:55 +08:00 · 4570 次点击
    这是一个创建于 2366 天前的主题,其中的信息可能已经有所发展或是发生改变。

    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! <[email protected]>',
        MAIL_SUBJECT_PREFIX = '[TA]-',
        MAIL_SERVER='smtp.qq.com',
        MAIL_PROT='25',
        # MAIL_USE_SSL = True,
        MAIL_USE_TLS = True,
        MAIL_USERNAME = '[email protected]',
        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 = '[email protected]'
        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
    
    4 条回复    2017-11-07 19:24:37 +08:00
    DeHoo
        2
    DeHoo  
    OP
       2017-11-07 14:33:15 +08:00
    @TimePPT 多谢了,用 celery 搞这个好麻烦,我换成了 threading,直接就成功了。
    Stitch
        3
    Stitch  
       2017-11-07 15:05:06 +08:00
    问题的本质是 celery 默认接收 JSON 序列化的数据,你现在直接入的 msg = Message() 对象,无法自动转化为 JSON 序列。
    要解决这个问题,调用 celery 的 task 参数传入 subject = 'This is a Test mail' 和 email = '[email protected]'。
    在 task 内部生成 msg 对象。

    这样问题就解决了。
    DeHoo
        4
    DeHoo  
    OP
       2017-11-07 19:24:37 +08:00
    @Stitch 这样啊,我再试试看,多谢你了,兄弟!
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   5253 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 29ms · UTC 08:29 · PVG 16:29 · LAX 01:29 · JFK 04:29
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.