## Stormy Webber Wes Mason [@1stvamp](http://twitter.com/1stvamp)
## Who? - / `@1stvamp` - Online services, [Canonical](http://www.canonical.com/) - Open source
## Tornado - Fast web server that supports non-blocking I/O - Developed at FriendFeed, open sourced at Facebook in 2009 - Long polling, WebSockets etc. - Pure Python
## Tornado cont. - **Not** a framework. - Usual "framework" features, sessions, auth, templates etc. - Support for callbacks, coroutines and futures (Tulip*ish*)
## Asynchronous - Asynchronous != parallel - Cooperative "threading" via callbacks and coroutines - Non-blocking I/O, both HTTP client/server built in
## Stringing cats - `ioloop.add_callback`, `ioloop.add_future` - `gen.coroutine`, `gen.Task`, `gen.Wait`
## e.g. ``` result = yield motor.Op(db.messages.insert, {'msg': msg}) # vs. db.messages.insert( {'msg': msg}, callback=self._on_response) ```
## Great for RESTful webservices
## e.g. ``` import tornado.web from sys import exit from .handlers import ResourceHandler def main(): application = tornado.web.Application(( (r"/resources/", ResourceHandler, "resources-root") ),) application.listen(port=8888, address='0.0.0.0') return tornado.ioloop.IOLoop.instance().start() if __name__ == "__main__": exit(main()) ```
## e.g. ``` import time from tornado.web import asynchronous, RequestHandler class ResourceHandler(RequestHandler): def prepare(self): self.user_id = self.get_argument('user') @asynchronous def get(self): tornado.ioloop.IOLoop.instance().add_timeout( time.time()+60, self._end) def _end(self): self.finish('hello world!') ```
## Best tool for the job - Can be mixed freely with other libraries - Mostly useful if there is an async library available for your backend component - If you want socket.io support gevent has a better library etc.
## Batteries included - Templating, auth handlers (including Twitter OAuth `LOL`) - HTTP client / server - TCP client / server (Streams)
## Batteries included cont. - Thread pools - Async DNS (`c-ares`, threads, `TwistedResolver`) - Process pooling with bound master socket/port
## Batteries included cont. - `tornado.platform.twisted` - WebSockets / Longpolling - SMTP client
## Bonus & tricks - Coroutines can be wrapped with greenlets (tornalet) - pycurl and libcurl are **fast** - Support for Futures (PEP 3156) - It runs on pypy, extremely fast
## trequests - Use libraries that use `python-requests` for HTTP - Use Tornado's AsyncHTTPClient/CurlAsyncHTTPClient instead of `httplib3` - Caveat: does require `greenlet`
## trequests cont. ``` """bobs_big_data.py""" import requests class BigData(object): ... def post(self): r = requests.post(self.url, data=self.data) return r.json() ```
## trequests cont. ``` import bobs_big_data from tornado.web import RequestHandler from trequests import setup_session from tornalet import tornalet setup_session() class WebHandler(RequestHandler): @tornalet def get(self): data = {'foo': 'bar'} response = bobs_big_data.BigData(data).post() return self.write(response) ```
## trequests cont. [github.com/1stvamp/trequests](https://github.com/1stvamp/trequests/)
## sys.exit(0) - Slides: [github.com/1stvamp/stormy-webber](https://github.com/1stvamp/stormy-webber)
## ^D - Jonathan "Joff" Oliver: [about.me/joffie](http://about.me/joffie) - Grab me and say hi `:-)`