I'am looking for python async SMTP client to connect it with Torando IoLoop. I found only simple implmementation (http://tornadogists.org/907491/) but it's a blocking solution so it might bring performance issues.
Does anyone encountered non blocking SMTP client for Tornado? Some code snippet would be also very useful.
I wrote solution based on threads and queue. One thread per tornado process. This thread is a worker, gets email from queue and then send it via SMTP. You send emails from tornado application by adding it to queue. Simple and easy.
Here is sample code on GitHub: link
Just FYI - I just whipped up a ioloop based smtp client. While I can't say it's production tested, it will be in the near future.
https://gist.github.com/1358253
https://github.com/equeny/tornadomail - here is my attemp to port django mail system and python smtplib to tornado ioloop.
Will be happy to hear some feedback.
I was looking for the solution to the same problem at work. Since there was no readily available solution, I ported Python smtplib to implementation based on tornado non-blocking IOStream. The syntax follows that of smtplib as close as possible.
# 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')
It currently only supports Python 3.3 and above. Here's the github repo
I'm not using my own SMTP server but figured this would be useful to someone:
I've just had to add email sending to my app. Most of the sample python code for the web emailing services use a blocking design so I dont want to use it.
Mailchimp's Mandrill uses HTTP POST requests so it can work in an Async fashion fitting in with Tornado's design.
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')