Tornado非阻塞SMTP客户端

时间:2011-07-04 23:28:39

标签: python email smtp tornado

我正在寻找python异步SMTP客户端来连接它与Torando IoLoop。我发现只有简单的implmementation(http://tornadogists.org/907491/),但它是一个阻塞解决方案,因此可能会带来性能问题。

是否有人遇到过Tornado的非阻止SMTP客户端?一些代码片段也非常有用。

5 个答案:

答案 0 :(得分:3)

仅供参考 - 我刚刚推出了基于ioloop的smtp客户端。虽然我不能说它的生产测试,但它将在不久的将来。

https://gist.github.com/1358253

答案 1 :(得分:3)

https://github.com/equeny/tornadomail - 这是我尝试将django邮件系统和python smtplib移植到龙卷风ioloop。 很高兴听到一些反馈。

答案 2 :(得分:3)

我一直在寻找解决同样问题的方法。由于没有现成的解决方案,我将Python smtplib移植到基于龙卷风非阻塞IOStream的实现中。语法遵循smtplib尽可能接近的语法。

# create SMTP client 
s = SMTPAsync()
yield s.connect('your.email.host',587)
yield s.starttls() 
yield s.login('username', 'password') 
yield s.sendmail('from_addr', 'to_addr', 'msg')

它目前仅支持Python 3.3及更高版本。这是github repo

答案 3 :(得分:2)

我根据线程和队列编写了解决方案。每个龙卷风过程一个线程。此线程是一名工作人员,从队列中获取电子邮件,然后通过SMTP发送。您可以通过将龙卷风应用程序添加到队列中来发送电子邮件。简单易行。

以下是GitHub上的示例代码:link

答案 4 :(得分:2)

我没有使用自己的SMTP服务器,但认为这对某人有用:

我只需要添加电子邮件发送到我的应用。 Web电子邮件服务的大多数示例python代码都使用阻塞设计,因此我不想使用它。

Mailchimp的Mandrill使用HTTP POST请求,因此它可以采用符合Tornado设计的Async方式工作。

class EmailMeHandler(BaseHandler):
    @tornado.web.asynchronous
    @tornado.gen.engine
    def get(self):
        http_client = AsyncHTTPClient()
        mail_url = self.settings["mandrill_url"] + "/messages/send.json"
        mail_data = {
            "key": self.settings["mandrill_key"],
            "message": {
                "html": "html email from tornado sample app <b>bold</b>", 
                "text": "plain text email from tornado sample app", 
                "subject": "from tornado sample app", 
                "from_email": "hello@example.com", 
                "from_name": "Hello Team", 
                "to":[{"email": "sample@example.com"}]
            }
        }

        body = tornado.escape.json_encode(mail_data)
        response = yield tornado.gen.Task(http_client.fetch, mail_url, method='POST', body=body)
        logging.info(response)
        logging.info(response.body)

        if response.code == 200:
            self.redirect('/?notification=sent')
        else:
            self.redirect('/?notification=FAIL')