2017-02-14 2 views
1

Je suis en train d'exécuter ce flacon très simple/app de céleri:flask_mail instance de message n'est pas JSON sérialisable

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

    @celery.task(bind=True) 

    @app.route('/', methods=['GET', 'POST']) 

    def index(): 
     if request.method == 'GET': 
      return render_template('index.html', email=session.get('email', '')) 
     email = request.form['email'] 
     session['email'] = email 

     msg = Message('Hello from Flask', 
         recipients=[request.form['email']]) 
     msg.body = 'This is a test email sent from a background Celery task.' 
     print type(msg) 
     print dir(msg) 
     print 'msg.send' 
     print msg.send 
     print 'msg' 
     print msg 

     if request.form['submit'] == 'Send': 

      send_async_email.delay(msg) 
      flash('Sending email to {0}'.format(email)) 
     else: 

     return redirect(url_for('index')) 

mais il ne fonctionne pas parce que l'instance de cette classe de message n'est pas JSON sérialisable, qui ne semble être le cas:

msg.send 
    <bound method Message.send of <flask_mail.Message object at 0x7ffa94cd0290>> 
    msg 
    Content-Type: text/plain; charset="utf-8" 
    MIME-Version: 1.0 
    Content-Transfer-Encoding: 7bit 
    Subject: Hello from Flask 
    From: [email protected] 

    EncodeError: <flask_mail.Message object at 0x7ffa94cd0290> is not JSON serializable 

Répondre

-1

Pouvez-vous essayer de rétrograder votre version de flask-mail à 0.9.0.

Vous pouvez le faire avec cette commande:

pip uninstall Flask-Mail 
pip install Flask-Mail==0.9.0 
4

Céleri exige que les objets transmis par le courtier être sérialisable carrément. flask_mail.Message les objets ne le sont pas. Vous devez modifier la signature de méthode send_async_email(msg) pour accepter un objet compatible JSON simple. C'est-à-dire, une chaîne brute, int, dictionnaire de ceux-ci, ou quelque chose de similaire. Vous devez ensuite déplacer toute la logique pour Message (de l'instanciation à l'envoi) à l'intérieur de cette méthode.

Par exemple:

@celery.task 
def send_async_email(message_details): 
    with app.app_context(): 
     msg = Message(message_details['subject'], 
         message_details['recipients']) 
     msg.body = message_details['body'] 
     print type(msg) 
     print dir(msg) 
     print 'msg.send' 
     print msg.send 
     print 'msg' 
     print msg 
     mail.send(msg) 
0

J'ai trouvé que simplement en réglant la sérialisation et en ajoutant la modification des travaux par défaut comme un charme.

app.config.update(
accept_content=['json','pickle'] 
) 

puis,

@celery.task(serializer='pickle') 
def send_async_email(msg):