2012-06-15 90 views
2

我使用Flask-Mail擴展從Flask應用程序發送電子郵件。它同步運行send()方法,我必須等到它發送消息。我怎樣才能讓它在後臺運行?異步運行Flask-Mail

+4

的可能的複製[這](http://stackoverflow.com/questions/10003933/whats-the-proper-way-to-run-some-python-code-asynchronously) – Enrico

回答

7

它並不複雜 - 你需要在另一個線程中發送郵件,所以你不會阻塞主線程。但有一個竅門。

這裏是我的代碼呈現模板,創建郵件正文,並允許同步和異步發送兩種:

mail_sender.py

import threading 
from flask import render_template, copy_current_request_context, current_app 
from flask_mail import Mail, Message 

mail = Mail() 

def create_massege(to_email, subject, template, from_email=None, **kwargs): 
    if not from_email: 
     from_email = current_app.config['ROBOT_EMAIL'] 
    if not to_email: 
     raise ValueError('Target email not defined.') 
    body = render_template(template, site_name=current_app.config['SITE_NAME'], **kwargs) 
    subject = subject.encode('utf-8') 
    body = body.encode('utf-8') 
    return Message(subject, [to_email], body, sender=from_email) 

def send(to_email, subject, template, from_email=None, **kwargs): 
    message = create_massege(to_email, subject, template, from_email, **kwargs) 
    mail.send(message) 

def send_async(to_email, subject, template, from_email=None, **kwargs): 
    message = create_massege(to_email, subject, template, from_email, **kwargs) 

    @copy_current_request_context 
    def send_message(message): 
     mail.send(message) 

    sender = threading.Thread(name='mail_sender', target=send_message, args=(message,)) 
    sender.start() 

支付你注意@copy_current_request_context裝飾。這是必需的,因爲Flask-Mail裏面使用請求上下文。如果我們將在新線程中運行它,上下文將被忽略。我們可以通過@copy_current_request_context來阻止這種裝飾功能 - 當調用函數時,Flask將推動上下文。

要使用此代碼,您還需要初始化mail對象與瓶的應用:

run.py

app = Flask('app') 
mail_sender.mail.init_app(app) 
+0

真的有用!謝謝! –

0

我想簡化Marboni的代碼,所以這裏看看。

import threading 

from flask import copy_current_request_context 
from flask_mail import Message 
from app import app, mail 


def create_message(recipient, subject, body): 

    if not recipient: 
     raise ValueError('Target email not defined.') 

    subject = subject.encode('utf-8') 
    body = body.encode('utf-8') 

    return Message(subject, [recipient], body, sender=app.config['MAIL_USERNAME'] or "[email protected]") 


def send_async(recipient, subject, body): 

    message = create_message(recipient, subject, body) 

    @copy_current_request_context 
    def send_message(message): 
     mail.send(message) 

    sender = threading.Thread(name='mail_sender', target=send_message, args=(message,)) 
    sender.start()