SlideShare uma empresa Scribd logo
1 de 34
Baixar para ler offline
AN INTRODUCTION TO
     TORNADO
               Gavin M. Roy
                   CTO
              myYearbook.com


pyCon 2011
Atlanta, GA
TORNADO AT
               MYYEARBOOK.COM
• Currency     Connect

  • Marketing Website, Portal, RESTful API

• Redirect     Engine

• Nerve

• Staplr   2

• Image    Upload Service
WHAT IS TORNADO?

•A scalable, non-blocking web server and micro-framework in
 Python 2.5 & 2.6.

  • Python          3 port underway

• Developed                at FriendFeed and open-sourced by Facebook

• Similar      to web.py in use

• Fast: ~1,500             requests/sec backend*
 * Your milage will vary
FEATURES

•   Small barrier to entry to quickly developing applications

•   Third Party Authentication via OpenID, OAuth Mixins

•   Light-weight template system

•   Auto-magical cross-site forgery protection

•   WSGI && Google App Engine Support

•   Develop using debug mode and automatically reload code and
    templates when changed on disk
class Application(object):
      """A collection of request handlers that make up a web application.

      Instances of this class are callable and can be passed directly to
      HTTPServer to serve the application:

          application = web.Application([
              (r"/", MainPageHandler),
          ])
          http_server = httpserver.HTTPServer(application)
          http_server.listen(8080)
          ioloop.IOLoop.instance().start()

      The constructor for this class takes in a list of URLSpec objects
      or (regexp, request_class) tuples. When we receive requests, we
      iterate over the list in order and instantiate an instance of the
      first request class whose regexp matches the request path.

      Each tuple can contain an optional third element, which should be a
      dictionary if it is present. That dictionary is passed as keyword
      arguments to the contructor of the handler. This pattern is used
      for the StaticFileHandler below:

          application = web.Application([
              (r"/static/(.*)", web.StaticFileHandler, {"path": "/var/www"}),
          ])




CLEAN, WELL DOCUMENTED CODE
WHAT TORNADO ISN’T

•A   full stack framework like Django

• Based   on Twisted

 • There    is an unmaintained port, Tornado on Twisted

 • Influenced    the Cyclone project

•A   replacement for a front-end web server

 • Run    behind a reverse proxy http server (nginx, Cherokee)
TORNADO VS TWISTED
•   Tornado doesn’t have to be asynchronous

•   It doesn’t have as many asynchronous drivers

    •   Can introduce blocking behaviors

•   The Tornado code is smaller and very easy to understand

•   Less mature than Twisted

•   You don’t need to buy into a development methodology

    •   Write Python not Twisted
KEY
 MODULES
Take only what you need
TORNADO.WEB

• Most   development is focused around this module

• Multiple   classes used in a web application

• Includes   decorators

  • Asynchronous     function: @tornado.web.asynchronous

  • Authentication   Required: @tornado.web.authenticated
TORNADO APPLICATION
• tornado.web.Application: Main           controller class

• Canonical Tornado      Hello World:
     import tornado.httpserver
     import tornado.ioloop
     import tornado.web

     class MainHandler(tornado.web.RequestHandler):
         def get(self):
             self.write("Hello, world")

     if __name__ == "__main__":
         application = tornado.web.Application([
             (r"/", MainHandler),
         ])

         http_server = tornado.httpserver.HTTPServer(application)
         http_server.listen(8888)
         tornado.ioloop.IOLoop.instance().start()
REQUEST HANDLERS

• tornado.web.RequestHandler

 • Extend   RequestHandler for larger web apps

   • Session   Handling

   • Database, Cache      Connections

   • Localization

• Implement    for your Application
REQUEST HANDLERS

• Classes   implementing define functions for processing

  • get, head, post, delete, put, options

• Hooks     on Initialization, Prepare, Close

• Functions    for setting HTTP Status, Headers, Cookies, Redirects
 and more
REQUEST HANDLER EXAMPLE
   import redis
   import tornado.web

   class MyRequestHandler(tornado.web.RequestHandler):

       def initialize(self):

           host = self.application.settings['Redis']['host']
           port = self.application.settings['Redis']['port']

           self.redis = redis.Redis(host, port)

   class Homepage(MyRequestHandler):

       @tornado.web.asynchronous
       def get(self):

           content = self.redis.get('homepage')
           self.write(content)
           self.finish()
TORNADO.TEMPLATE

• Not   required

• Similar    to other engines

• Limited    python exposure in template

• Fast, extensible

• Built-in   support in the RequestHandler class

• Adds   cache busting static content delivery
REQUESTHANDLER.RENDER
Code




           class Home(RequestHandler):

               def get(self):

                   self.render('home.html', username='Leeroy Jenkins');
Template




           <html>
             <body>
               Hi {{username}}, welcome to our site.
             </body>
           </html>
BASE TEMPLATE
<html>
    <head>
        <title>My Site :: {% block title %}Unextended Template{% end %}</title>
        <link rel="stylesheet" type="text/css" href="{{ static_url('css/site.css') }}" />
        <script type="text/javascript" src="{{ static_url('javascript/site.js') }}"></script>
         {% if not current_user %}
          <script type="text/javascript" src="http://api.recaptcha.net/js/recaptcha_ajax.js">
          </script>
         {% end %}
    </head>
    <body{% if current_user %} class="authenticated"{% end %}>
        {% include "header.html" %}
        {% if request.uri not in ['/', ''] and current_user %}
              {{ modules.MemberBar() }}
        {% end %}
        <div id="content">
              {% block content %}
                   No Content Specified
              {% end %}
        </div>
        <ul id="footer">
            <li><a href="/terms">{{_("Terms and Conditions")}}</a></li>
            <li class="center">{{_("Version")}}: {{ handler.application.settings['version'] }}</li>
            <li class="right">{{_("Copyright")}} &copy; {{ datetime.date.today().year }}</li>
        </ul>
    </body>
</html>
CONTENT TEMPLATE


{% extends "base.html" %}
{% block title %}{{_("Error Title")}}{% end %}
{% block content %}
<h1>{{_("Error Title")}}</h1>
<img src="/static/images/sad_robot.png" class="error_robot" />
<p class="error_message">{{_("Error Message")}}</p>
<h2 class="error">{{status_code}} - {{exception}}</h2>
{% end %}
TEMPLATE XSRF EXAMPLE


 <form action="/login" method="post">
   {{ xsrf_form_html() }}
   <div>Username: <input type="text" name="username"/></div>
   <div>Password: <input type="password" name="password"/></div>
   <div><input type="submit" value="Sign in"/></div>
 </form>




          No additional work required.
UI MODULES

• Extend templates with
 reusable widgets across the
 site

• One import assigned when
 Application is created

• Similar
        to RequestHandler in
 behavior
UIMODULE EXAMPLE
Embed
                  UIMODULE EXAMPLE
                  <div>{{ modules.HTTPSCheck() }}</div>




                 class HTTPSCheck(tornado.web.UIModule):

                     def render(self):
UIModule Class




                         if 'X-Forwarded-Ssl' not in self.request.headers or 
                             self.request.headers['X-Forwarded-Ssl'] != 'on':

                             return self.render_string("modules/ssl.html")

                         return ''



                 <div class="information">
Template




                     <a href="https://{{request.host}}{{request.uri}}">
                          {{_("Click here to use a secure connection")}}
                     </a>
                 </div>
TORNADO.LOCALE

•   Locale files in one directory

    •   In a csv format

    •   Named as locale.csv, e.g.
        en_US.csv

•   tornado.locale.load_translations
    (path)

    •   Pass path where files are located

•   Invoked as _ method in templates
ADDING LOCALIZATION
 import tornado.locale as locale
 import tornado.web

 class RequestHandler(tornado.web.RequestHandler):

     def get_user_locale(self):

         # Fake user object has a get_locale() function
         user_locale = self.user.get_locale()

         # If our locale is supported return it
         if user_locale in locale.get_supported_locales(None):
             return user_locale

         # Defaults to Accept-Language header if supported
         return None
USING LOCALIZATION

<html>
  <body>
    {{_("Welcome to our site.")}}
  </body>
</html>
LOCALE FILE EXAMPLE: DE_DE
   "New","Neu"
   "Donate","Spenden"
   "New Paste","Neuer Paste"
   "Secure, Private Pasting","Sicheres Pasten"
   "Unclaimed Hostname","Sie benutzen einen offenen Hostnamen.
   Klicken Sie heir für weitere Informationen."
   "Paste Options","Paste Optionen"
   "Formatting","Formatierung"
   "No Formatting","Keine Formatierung"
   "Line Numbers","Zeilennummern"
   "On","An"
   "Off","Aus"
   "Minutes","Minuten"
   "Hour","Stunde"
   "Day","Tag"
   "Week","Woche"
   "Year","Jahr"
   "Expire Paste","Wann soll der Paste gelöscht werden?"
   "Encryption","Verschlüsselung"
   "Encryption Key","Passwort-Verschlüsselung"
   "Encryption Algorithm","Algorithm-Verschlüsselung"
   "Save Paste","Paste speichern"
   "All Rights Reserved","Alle Rechte vorbehalten"
TEMPLATE EXAMPLE AGAIN
<html>
    <head>
        <title>My Site :: {% block title %}Unextended Template{% end %}</title>
        <link rel="stylesheet" type="text/css" href="{{ static_url('css/site.css') }}" />
        <script type="text/javascript" src="{{ static_url('javascript/site.js') }}"></script>
         {% if not current_user %}
          <script type="text/javascript" src="http://api.recaptcha.net/js/recaptcha_ajax.js">
          </script>
         {% end %}
    </head>
    <body{% if current_user %} class="authenticated"{% end %}>
        {% include "header.html" %}
        {% if request.uri not in ['/', ''] and current_user %}
              {{ modules.MemberBar() }}
        {% end %}
        <div id="content">
              {% block content %}
                   No Content Specified
              {% end %}
        </div>
        <ul id="footer">
            <li><a href="/terms">{{_("Terms and Conditions")}}</a></li>
            <li class="center">{{_("Version")}}: {{ handler.application.settings['version'] }}</li>
            <li class="right">{{_("Copyright")}} &copy; {{ datetime.date.today().year }}</li>
        </ul>
    </body>
</html>
TORNADO.AUTH

• Built   in Mixins for OpenID, OAuth, OAuth2

  •    Google, Twitter, Facebook, Facebook Graph, Friendfeed

• Use RequestHandler to extend your own login functions with
  the mixins if wanted

• Is   asynchronous

  • Not    supported in WSGI and Google App Engine
USING TORNADO.AUTH
- [/login/form, site.auth_reg.LoginForm]
- [/login/friendfeed, site.auth_reg.LoginFriendFeed]




class LoginFriendFeed(RequestHandler, tornado.auth.FriendFeedMixin):

    @tornado.web.asynchronous
    def get(self):
        if self.get_argument("oauth_token", None):
            self.get_authenticated_user(self.async_callback(self._on_auth))
            return
        self.authorize_redirect()

    def _on_auth(self, ffuser):
        if not ffuser:
            raise tornado.web.HTTPError(500, "FriendFeed auth failed")
            return

        username = ffuser['username']
TORNADO.IOLOOP
• Protocol    independent

• tornado.httpserver.HTTPServer     uses ioloop.IOLoop

• RabbitMQ      driver Pika uses ioloop.IOLoop

• Built   in timer functionality

  • tornado.ioloop.add_timeout

  • tornado.ioloop.PeriodicCallback
TORNADO.IOLOOP EXAMPLE
  class MyClient(object):

      def connect(self, host, port):

          # Create our socket
          self.sock = socket.socket(socket.AF_INET,
                                    socket.SOCK_STREAM, 0)
          self.sock.connect((host, port))
          self.sock.setblocking(0)
          self.io_loop = tornado.ioloop.IOLoop.instance()

          # Append our handler to tornado's ioloop for our socket
          events = tornado.ioloop.IOLoop.READ | 
                   tornado.ioloop.IOLoop.ERROR

          self.io_loop.add_handler(self.sock.fileno(),
                                   self._handle_events, events)



        https://github.com/pika/pika/blob/master/pika/adapters/tornado_connection.py
OTHER MODULES OF NOTE
•   tornado.database                    •   tornado.options

    •   MySQL wrapper                       •   Similar to optparse

•   tornado.escape                      •   tornado.testing

    •   Misc escape functions               •   Test support classes

•   tornado.httpclient                  •   tornado.websocket

    •   Async HTTP client                   •   Websocket Support

•   tornado.iostream

    •   Non-blocking TCP helper class
ASYNC DRIVERS

• Memcache

• MongoDB

• PostgreSQL

• RabbitMQ

• Redis
FIN

• Follow   me on Twitter @crad

• Blog: http://gavinroy.com

• Pika: http://github.com/pika

  • Async   RabbitMQ/AMQP Support for Tornado

• We’re    hiring at myYearbook.com

  • Drop    me an email: gmr@myyearbook.com
IMAGE CREDITS


• Lego by Craig A. Rodway
 http://www.flickr.com/photos/m0php/530526644/

• Delta   Clipper X courtesy of NASA

• United Nations San Francisco Conference by Yould
 http://www.flickr.com/photos/un_photo/3450033473/

Mais conteúdo relacionado

Mais procurados

What is REST API? REST API Concepts and Examples | Edureka
What is REST API? REST API Concepts and Examples | EdurekaWhat is REST API? REST API Concepts and Examples | Edureka
What is REST API? REST API Concepts and Examples | EdurekaEdureka!
 
REST APIs with Spring
REST APIs with SpringREST APIs with Spring
REST APIs with SpringJoshua Long
 
Introduction to ajax
Introduction to ajaxIntroduction to ajax
Introduction to ajaxNir Elbaz
 
Selenium Architecture
Selenium ArchitectureSelenium Architecture
Selenium Architecturerohitnayak
 
Use Node.js to create a REST API
Use Node.js to create a REST APIUse Node.js to create a REST API
Use Node.js to create a REST APIFabien Vauchelles
 
Introduction to Django
Introduction to DjangoIntroduction to Django
Introduction to DjangoKnoldus Inc.
 
Learning ASP.NET 5 and MVC 6
Learning ASP.NET 5 and MVC 6Learning ASP.NET 5 and MVC 6
Learning ASP.NET 5 and MVC 6Ido Flatow
 
Build RESTful API Using Express JS
Build RESTful API Using Express JSBuild RESTful API Using Express JS
Build RESTful API Using Express JSCakra Danu Sedayu
 
Hibernate Presentation
Hibernate  PresentationHibernate  Presentation
Hibernate Presentationguest11106b
 
Introduction to React JS
Introduction to React JSIntroduction to React JS
Introduction to React JSArno Lordkronos
 
TypeScript: coding JavaScript without the pain
TypeScript: coding JavaScript without the painTypeScript: coding JavaScript without the pain
TypeScript: coding JavaScript without the painSander Mak (@Sander_Mak)
 
Concurrent Rendering Adventures in React 18
Concurrent Rendering Adventures in React 18Concurrent Rendering Adventures in React 18
Concurrent Rendering Adventures in React 18Maurice De Beijer [MVP]
 

Mais procurados (20)

Design patterns in PHP
Design patterns in PHPDesign patterns in PHP
Design patterns in PHP
 
What is REST API? REST API Concepts and Examples | Edureka
What is REST API? REST API Concepts and Examples | EdurekaWhat is REST API? REST API Concepts and Examples | Edureka
What is REST API? REST API Concepts and Examples | Edureka
 
REST APIs with Spring
REST APIs with SpringREST APIs with Spring
REST APIs with Spring
 
Introduction to ajax
Introduction to ajaxIntroduction to ajax
Introduction to ajax
 
Selenium Architecture
Selenium ArchitectureSelenium Architecture
Selenium Architecture
 
Introduction to Node.js
Introduction to Node.jsIntroduction to Node.js
Introduction to Node.js
 
Progressive Web-App (PWA)
Progressive Web-App (PWA)Progressive Web-App (PWA)
Progressive Web-App (PWA)
 
Use Node.js to create a REST API
Use Node.js to create a REST APIUse Node.js to create a REST API
Use Node.js to create a REST API
 
Introduction to Django
Introduction to DjangoIntroduction to Django
Introduction to Django
 
Provider vs BLoC vs Redux
Provider vs BLoC vs ReduxProvider vs BLoC vs Redux
Provider vs BLoC vs Redux
 
Introduction to Angularjs
Introduction to AngularjsIntroduction to Angularjs
Introduction to Angularjs
 
Learning ASP.NET 5 and MVC 6
Learning ASP.NET 5 and MVC 6Learning ASP.NET 5 and MVC 6
Learning ASP.NET 5 and MVC 6
 
Build RESTful API Using Express JS
Build RESTful API Using Express JSBuild RESTful API Using Express JS
Build RESTful API Using Express JS
 
Model View Controller (MVC)
Model View Controller (MVC)Model View Controller (MVC)
Model View Controller (MVC)
 
Hibernate Presentation
Hibernate  PresentationHibernate  Presentation
Hibernate Presentation
 
Node js introduction
Node js introductionNode js introduction
Node js introduction
 
Fastlane
FastlaneFastlane
Fastlane
 
Introduction to React JS
Introduction to React JSIntroduction to React JS
Introduction to React JS
 
TypeScript: coding JavaScript without the pain
TypeScript: coding JavaScript without the painTypeScript: coding JavaScript without the pain
TypeScript: coding JavaScript without the pain
 
Concurrent Rendering Adventures in React 18
Concurrent Rendering Adventures in React 18Concurrent Rendering Adventures in React 18
Concurrent Rendering Adventures in React 18
 

Destaque

Tornado Web Server Internals
Tornado Web Server InternalsTornado Web Server Internals
Tornado Web Server InternalsPraveen Gollakota
 
Rapid web development using tornado web and mongodb
Rapid web development using tornado web and mongodbRapid web development using tornado web and mongodb
Rapid web development using tornado web and mongodbikailan
 
Tornado - different Web programming
Tornado - different Web programmingTornado - different Web programming
Tornado - different Web programmingDima Malenko
 
Nginx + Tornado = 17k req/s
Nginx + Tornado = 17k req/sNginx + Tornado = 17k req/s
Nginx + Tornado = 17k req/smoret1979
 
Web backends development using Python
Web backends development using PythonWeb backends development using Python
Web backends development using PythonAyun Park
 
Programmation web asynchrone avec Tornado
Programmation web asynchrone avec TornadoProgrammation web asynchrone avec Tornado
Programmation web asynchrone avec TornadoRonan Amicel
 
Crystal is a Rubyists friend (quick anecdote)
Crystal is a Rubyists friend (quick anecdote)Crystal is a Rubyists friend (quick anecdote)
Crystal is a Rubyists friend (quick anecdote)Forrest Chang
 
Introduction to Tornado - TienNA
Introduction to Tornado - TienNAIntroduction to Tornado - TienNA
Introduction to Tornado - TienNAFramgia Vietnam
 
Real time server
Real time serverReal time server
Real time serverthepian
 
Asynchronous web-development with Python
Asynchronous web-development with PythonAsynchronous web-development with Python
Asynchronous web-development with PythonAnton Caceres
 
Aplikasi Penyelidikan Web 2,0
Aplikasi Penyelidikan Web 2,0Aplikasi Penyelidikan Web 2,0
Aplikasi Penyelidikan Web 2,0Mohamed Amin Embi
 
Tornado web
Tornado webTornado web
Tornado webkurtiss
 
What is a tornado?
What is a tornado?What is a tornado?
What is a tornado?Austin
 
Contoh Lembar Catatan Fakta Guru
Contoh Lembar Catatan Fakta GuruContoh Lembar Catatan Fakta Guru
Contoh Lembar Catatan Fakta Guruenesha sie
 

Destaque (20)

Tornado Web Server Internals
Tornado Web Server InternalsTornado Web Server Internals
Tornado Web Server Internals
 
Rapid web development using tornado web and mongodb
Rapid web development using tornado web and mongodbRapid web development using tornado web and mongodb
Rapid web development using tornado web and mongodb
 
Tornado - different Web programming
Tornado - different Web programmingTornado - different Web programming
Tornado - different Web programming
 
Tornadoweb
TornadowebTornadoweb
Tornadoweb
 
Nginx + Tornado = 17k req/s
Nginx + Tornado = 17k req/sNginx + Tornado = 17k req/s
Nginx + Tornado = 17k req/s
 
Web backends development using Python
Web backends development using PythonWeb backends development using Python
Web backends development using Python
 
Programmation web asynchrone avec Tornado
Programmation web asynchrone avec TornadoProgrammation web asynchrone avec Tornado
Programmation web asynchrone avec Tornado
 
Sinatra Ruby Framework
Sinatra Ruby FrameworkSinatra Ruby Framework
Sinatra Ruby Framework
 
Crystal is a Rubyists friend (quick anecdote)
Crystal is a Rubyists friend (quick anecdote)Crystal is a Rubyists friend (quick anecdote)
Crystal is a Rubyists friend (quick anecdote)
 
Tornado
TornadoTornado
Tornado
 
Tornado
TornadoTornado
Tornado
 
Tornado
TornadoTornado
Tornado
 
Introduction to Tornado - TienNA
Introduction to Tornado - TienNAIntroduction to Tornado - TienNA
Introduction to Tornado - TienNA
 
Real time server
Real time serverReal time server
Real time server
 
Asynchronous web-development with Python
Asynchronous web-development with PythonAsynchronous web-development with Python
Asynchronous web-development with Python
 
Aplikasi Penyelidikan Web 2,0
Aplikasi Penyelidikan Web 2,0Aplikasi Penyelidikan Web 2,0
Aplikasi Penyelidikan Web 2,0
 
Tornado web
Tornado webTornado web
Tornado web
 
What is a tornado?
What is a tornado?What is a tornado?
What is a tornado?
 
Tornado
TornadoTornado
Tornado
 
Contoh Lembar Catatan Fakta Guru
Contoh Lembar Catatan Fakta GuruContoh Lembar Catatan Fakta Guru
Contoh Lembar Catatan Fakta Guru
 

Semelhante a An Introduction to Tornado

GDG Addis - An Introduction to Django and App Engine
GDG Addis - An Introduction to Django and App EngineGDG Addis - An Introduction to Django and App Engine
GDG Addis - An Introduction to Django and App EngineYared Ayalew
 
Using and scaling Rack and Rack-based middleware
Using and scaling Rack and Rack-based middlewareUsing and scaling Rack and Rack-based middleware
Using and scaling Rack and Rack-based middlewareAlona Mekhovova
 
Plugins on OnDemand with Remote Apps - Atlassian Summit 2012
Plugins on OnDemand with Remote Apps - Atlassian Summit 2012 Plugins on OnDemand with Remote Apps - Atlassian Summit 2012
Plugins on OnDemand with Remote Apps - Atlassian Summit 2012 Atlassian
 
Django Rest Framework and React and Redux, Oh My!
Django Rest Framework and React and Redux, Oh My!Django Rest Framework and React and Redux, Oh My!
Django Rest Framework and React and Redux, Oh My!Eric Palakovich Carr
 
jQuery Makes Writing JavaScript Fun Again (for HTML5 User Group)
jQuery Makes Writing JavaScript Fun Again (for HTML5 User Group)jQuery Makes Writing JavaScript Fun Again (for HTML5 User Group)
jQuery Makes Writing JavaScript Fun Again (for HTML5 User Group)Doris Chen
 
Web Components v1
Web Components v1Web Components v1
Web Components v1Mike Wilcox
 
Rest with Java EE 6 , Security , Backbone.js
Rest with Java EE 6 , Security , Backbone.jsRest with Java EE 6 , Security , Backbone.js
Rest with Java EE 6 , Security , Backbone.jsCarol McDonald
 
Staying Sane with Drupal NEPHP
Staying Sane with Drupal NEPHPStaying Sane with Drupal NEPHP
Staying Sane with Drupal NEPHPOscar Merida
 
CouchDB for Web Applications - Erlang Factory London 2009
CouchDB for Web Applications - Erlang Factory London 2009CouchDB for Web Applications - Erlang Factory London 2009
CouchDB for Web Applications - Erlang Factory London 2009Jason Davies
 
Spark IT 2011 - Simplified Web Development using Java Server Faces 2.0
Spark IT 2011 - Simplified Web Development using Java Server Faces 2.0Spark IT 2011 - Simplified Web Development using Java Server Faces 2.0
Spark IT 2011 - Simplified Web Development using Java Server Faces 2.0Arun Gupta
 
Html5 and web technology update
Html5 and web technology updateHtml5 and web technology update
Html5 and web technology updateDoug Domeny
 
Webservices
WebservicesWebservices
Webservicess4al_com
 
nodejs_at_a_glance.ppt
nodejs_at_a_glance.pptnodejs_at_a_glance.ppt
nodejs_at_a_glance.pptWalaSidhom1
 
Developing High Performance Web Apps - CodeMash 2011
Developing High Performance Web Apps - CodeMash 2011Developing High Performance Web Apps - CodeMash 2011
Developing High Performance Web Apps - CodeMash 2011Timothy Fisher
 

Semelhante a An Introduction to Tornado (20)

GDG Addis - An Introduction to Django and App Engine
GDG Addis - An Introduction to Django and App EngineGDG Addis - An Introduction to Django and App Engine
GDG Addis - An Introduction to Django and App Engine
 
Using and scaling Rack and Rack-based middleware
Using and scaling Rack and Rack-based middlewareUsing and scaling Rack and Rack-based middleware
Using and scaling Rack and Rack-based middleware
 
Plugins on OnDemand with Remote Apps - Atlassian Summit 2012
Plugins on OnDemand with Remote Apps - Atlassian Summit 2012 Plugins on OnDemand with Remote Apps - Atlassian Summit 2012
Plugins on OnDemand with Remote Apps - Atlassian Summit 2012
 
Django Rest Framework and React and Redux, Oh My!
Django Rest Framework and React and Redux, Oh My!Django Rest Framework and React and Redux, Oh My!
Django Rest Framework and React and Redux, Oh My!
 
jQuery Makes Writing JavaScript Fun Again (for HTML5 User Group)
jQuery Makes Writing JavaScript Fun Again (for HTML5 User Group)jQuery Makes Writing JavaScript Fun Again (for HTML5 User Group)
jQuery Makes Writing JavaScript Fun Again (for HTML5 User Group)
 
Web Components v1
Web Components v1Web Components v1
Web Components v1
 
Rest with Java EE 6 , Security , Backbone.js
Rest with Java EE 6 , Security , Backbone.jsRest with Java EE 6 , Security , Backbone.js
Rest with Java EE 6 , Security , Backbone.js
 
Rest
RestRest
Rest
 
Staying Sane with Drupal NEPHP
Staying Sane with Drupal NEPHPStaying Sane with Drupal NEPHP
Staying Sane with Drupal NEPHP
 
CouchDB for Web Applications - Erlang Factory London 2009
CouchDB for Web Applications - Erlang Factory London 2009CouchDB for Web Applications - Erlang Factory London 2009
CouchDB for Web Applications - Erlang Factory London 2009
 
Spark IT 2011 - Simplified Web Development using Java Server Faces 2.0
Spark IT 2011 - Simplified Web Development using Java Server Faces 2.0Spark IT 2011 - Simplified Web Development using Java Server Faces 2.0
Spark IT 2011 - Simplified Web Development using Java Server Faces 2.0
 
Html5 and web technology update
Html5 and web technology updateHtml5 and web technology update
Html5 and web technology update
 
Webservices
WebservicesWebservices
Webservices
 
Django at the Disco
Django at the DiscoDjango at the Disco
Django at the Disco
 
Django at the Disco
Django at the DiscoDjango at the Disco
Django at the Disco
 
Django at the Disco
Django at the DiscoDjango at the Disco
Django at the Disco
 
Django at the Disco
Django at the DiscoDjango at the Disco
Django at the Disco
 
Django at the Disco
Django at the DiscoDjango at the Disco
Django at the Disco
 
nodejs_at_a_glance.ppt
nodejs_at_a_glance.pptnodejs_at_a_glance.ppt
nodejs_at_a_glance.ppt
 
Developing High Performance Web Apps - CodeMash 2011
Developing High Performance Web Apps - CodeMash 2011Developing High Performance Web Apps - CodeMash 2011
Developing High Performance Web Apps - CodeMash 2011
 

Último

Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobeapidays
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxRustici Software
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MIND CTI
 
A Beginners Guide to Building a RAG App Using Open Source Milvus
A Beginners Guide to Building a RAG App Using Open Source MilvusA Beginners Guide to Building a RAG App Using Open Source Milvus
A Beginners Guide to Building a RAG App Using Open Source MilvusZilliz
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonAnna Loughnan Colquhoun
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Drew Madelung
 
Ransomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdfRansomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdfOverkill Security
 
FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024The Digital Insurer
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodJuan lago vázquez
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoffsammart93
 
AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024The Digital Insurer
 
MS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsMS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsNanddeep Nachan
 
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...apidays
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processorsdebabhi2
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc
 
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot ModelNavi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot ModelDeepika Singh
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyKhushali Kathiriya
 
Apidays Singapore 2024 - Modernizing Securities Finance by Madhu Subbu
Apidays Singapore 2024 - Modernizing Securities Finance by Madhu SubbuApidays Singapore 2024 - Modernizing Securities Finance by Madhu Subbu
Apidays Singapore 2024 - Modernizing Securities Finance by Madhu Subbuapidays
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century educationjfdjdjcjdnsjd
 

Último (20)

Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptx
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024
 
A Beginners Guide to Building a RAG App Using Open Source Milvus
A Beginners Guide to Building a RAG App Using Open Source MilvusA Beginners Guide to Building a RAG App Using Open Source Milvus
A Beginners Guide to Building a RAG App Using Open Source Milvus
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
Ransomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdfRansomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdf
 
FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024
 
MS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsMS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectors
 
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot ModelNavi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot Model
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : Uncertainty
 
Apidays Singapore 2024 - Modernizing Securities Finance by Madhu Subbu
Apidays Singapore 2024 - Modernizing Securities Finance by Madhu SubbuApidays Singapore 2024 - Modernizing Securities Finance by Madhu Subbu
Apidays Singapore 2024 - Modernizing Securities Finance by Madhu Subbu
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 

An Introduction to Tornado

  • 1. AN INTRODUCTION TO TORNADO Gavin M. Roy CTO myYearbook.com pyCon 2011 Atlanta, GA
  • 2. TORNADO AT MYYEARBOOK.COM • Currency Connect • Marketing Website, Portal, RESTful API • Redirect Engine • Nerve • Staplr 2 • Image Upload Service
  • 3. WHAT IS TORNADO? •A scalable, non-blocking web server and micro-framework in Python 2.5 & 2.6. • Python 3 port underway • Developed at FriendFeed and open-sourced by Facebook • Similar to web.py in use • Fast: ~1,500 requests/sec backend* * Your milage will vary
  • 4. FEATURES • Small barrier to entry to quickly developing applications • Third Party Authentication via OpenID, OAuth Mixins • Light-weight template system • Auto-magical cross-site forgery protection • WSGI && Google App Engine Support • Develop using debug mode and automatically reload code and templates when changed on disk
  • 5. class Application(object):     """A collection of request handlers that make up a web application. Instances of this class are callable and can be passed directly to HTTPServer to serve the application: application = web.Application([ (r"/", MainPageHandler), ]) http_server = httpserver.HTTPServer(application) http_server.listen(8080) ioloop.IOLoop.instance().start() The constructor for this class takes in a list of URLSpec objects or (regexp, request_class) tuples. When we receive requests, we iterate over the list in order and instantiate an instance of the first request class whose regexp matches the request path. Each tuple can contain an optional third element, which should be a dictionary if it is present. That dictionary is passed as keyword arguments to the contructor of the handler. This pattern is used for the StaticFileHandler below: application = web.Application([ (r"/static/(.*)", web.StaticFileHandler, {"path": "/var/www"}), ]) CLEAN, WELL DOCUMENTED CODE
  • 6. WHAT TORNADO ISN’T •A full stack framework like Django • Based on Twisted • There is an unmaintained port, Tornado on Twisted • Influenced the Cyclone project •A replacement for a front-end web server • Run behind a reverse proxy http server (nginx, Cherokee)
  • 7. TORNADO VS TWISTED • Tornado doesn’t have to be asynchronous • It doesn’t have as many asynchronous drivers • Can introduce blocking behaviors • The Tornado code is smaller and very easy to understand • Less mature than Twisted • You don’t need to buy into a development methodology • Write Python not Twisted
  • 8. KEY MODULES Take only what you need
  • 9. TORNADO.WEB • Most development is focused around this module • Multiple classes used in a web application • Includes decorators • Asynchronous function: @tornado.web.asynchronous • Authentication Required: @tornado.web.authenticated
  • 10. TORNADO APPLICATION • tornado.web.Application: Main controller class • Canonical Tornado Hello World: import tornado.httpserver import tornado.ioloop import tornado.web class MainHandler(tornado.web.RequestHandler): def get(self): self.write("Hello, world") if __name__ == "__main__": application = tornado.web.Application([ (r"/", MainHandler), ]) http_server = tornado.httpserver.HTTPServer(application) http_server.listen(8888) tornado.ioloop.IOLoop.instance().start()
  • 11. REQUEST HANDLERS • tornado.web.RequestHandler • Extend RequestHandler for larger web apps • Session Handling • Database, Cache Connections • Localization • Implement for your Application
  • 12. REQUEST HANDLERS • Classes implementing define functions for processing • get, head, post, delete, put, options • Hooks on Initialization, Prepare, Close • Functions for setting HTTP Status, Headers, Cookies, Redirects and more
  • 13. REQUEST HANDLER EXAMPLE import redis import tornado.web class MyRequestHandler(tornado.web.RequestHandler): def initialize(self): host = self.application.settings['Redis']['host'] port = self.application.settings['Redis']['port'] self.redis = redis.Redis(host, port) class Homepage(MyRequestHandler): @tornado.web.asynchronous def get(self): content = self.redis.get('homepage') self.write(content) self.finish()
  • 14. TORNADO.TEMPLATE • Not required • Similar to other engines • Limited python exposure in template • Fast, extensible • Built-in support in the RequestHandler class • Adds cache busting static content delivery
  • 15. REQUESTHANDLER.RENDER Code class Home(RequestHandler): def get(self): self.render('home.html', username='Leeroy Jenkins'); Template <html> <body> Hi {{username}}, welcome to our site. </body> </html>
  • 16. BASE TEMPLATE <html> <head> <title>My Site :: {% block title %}Unextended Template{% end %}</title> <link rel="stylesheet" type="text/css" href="{{ static_url('css/site.css') }}" /> <script type="text/javascript" src="{{ static_url('javascript/site.js') }}"></script> {% if not current_user %} <script type="text/javascript" src="http://api.recaptcha.net/js/recaptcha_ajax.js"> </script> {% end %} </head> <body{% if current_user %} class="authenticated"{% end %}> {% include "header.html" %} {% if request.uri not in ['/', ''] and current_user %} {{ modules.MemberBar() }} {% end %} <div id="content"> {% block content %} No Content Specified {% end %} </div> <ul id="footer"> <li><a href="/terms">{{_("Terms and Conditions")}}</a></li> <li class="center">{{_("Version")}}: {{ handler.application.settings['version'] }}</li> <li class="right">{{_("Copyright")}} &copy; {{ datetime.date.today().year }}</li> </ul> </body> </html>
  • 17. CONTENT TEMPLATE {% extends "base.html" %} {% block title %}{{_("Error Title")}}{% end %} {% block content %} <h1>{{_("Error Title")}}</h1> <img src="/static/images/sad_robot.png" class="error_robot" /> <p class="error_message">{{_("Error Message")}}</p> <h2 class="error">{{status_code}} - {{exception}}</h2> {% end %}
  • 18. TEMPLATE XSRF EXAMPLE <form action="/login" method="post"> {{ xsrf_form_html() }} <div>Username: <input type="text" name="username"/></div> <div>Password: <input type="password" name="password"/></div> <div><input type="submit" value="Sign in"/></div> </form> No additional work required.
  • 19. UI MODULES • Extend templates with reusable widgets across the site • One import assigned when Application is created • Similar to RequestHandler in behavior
  • 21. Embed UIMODULE EXAMPLE  <div>{{ modules.HTTPSCheck() }}</div> class HTTPSCheck(tornado.web.UIModule): def render(self): UIModule Class if 'X-Forwarded-Ssl' not in self.request.headers or self.request.headers['X-Forwarded-Ssl'] != 'on': return self.render_string("modules/ssl.html") return '' <div class="information"> Template <a href="https://{{request.host}}{{request.uri}}"> {{_("Click here to use a secure connection")}} </a> </div>
  • 22. TORNADO.LOCALE • Locale files in one directory • In a csv format • Named as locale.csv, e.g. en_US.csv • tornado.locale.load_translations (path) • Pass path where files are located • Invoked as _ method in templates
  • 23. ADDING LOCALIZATION import tornado.locale as locale import tornado.web class RequestHandler(tornado.web.RequestHandler): def get_user_locale(self): # Fake user object has a get_locale() function user_locale = self.user.get_locale() # If our locale is supported return it if user_locale in locale.get_supported_locales(None): return user_locale # Defaults to Accept-Language header if supported return None
  • 24. USING LOCALIZATION <html> <body> {{_("Welcome to our site.")}} </body> </html>
  • 25. LOCALE FILE EXAMPLE: DE_DE "New","Neu" "Donate","Spenden" "New Paste","Neuer Paste" "Secure, Private Pasting","Sicheres Pasten" "Unclaimed Hostname","Sie benutzen einen offenen Hostnamen. Klicken Sie heir für weitere Informationen." "Paste Options","Paste Optionen" "Formatting","Formatierung" "No Formatting","Keine Formatierung" "Line Numbers","Zeilennummern" "On","An" "Off","Aus" "Minutes","Minuten" "Hour","Stunde" "Day","Tag" "Week","Woche" "Year","Jahr" "Expire Paste","Wann soll der Paste gelöscht werden?" "Encryption","Verschlüsselung" "Encryption Key","Passwort-Verschlüsselung" "Encryption Algorithm","Algorithm-Verschlüsselung" "Save Paste","Paste speichern" "All Rights Reserved","Alle Rechte vorbehalten"
  • 26. TEMPLATE EXAMPLE AGAIN <html> <head> <title>My Site :: {% block title %}Unextended Template{% end %}</title> <link rel="stylesheet" type="text/css" href="{{ static_url('css/site.css') }}" /> <script type="text/javascript" src="{{ static_url('javascript/site.js') }}"></script> {% if not current_user %} <script type="text/javascript" src="http://api.recaptcha.net/js/recaptcha_ajax.js"> </script> {% end %} </head> <body{% if current_user %} class="authenticated"{% end %}> {% include "header.html" %} {% if request.uri not in ['/', ''] and current_user %} {{ modules.MemberBar() }} {% end %} <div id="content"> {% block content %} No Content Specified {% end %} </div> <ul id="footer"> <li><a href="/terms">{{_("Terms and Conditions")}}</a></li> <li class="center">{{_("Version")}}: {{ handler.application.settings['version'] }}</li> <li class="right">{{_("Copyright")}} &copy; {{ datetime.date.today().year }}</li> </ul> </body> </html>
  • 27. TORNADO.AUTH • Built in Mixins for OpenID, OAuth, OAuth2 • Google, Twitter, Facebook, Facebook Graph, Friendfeed • Use RequestHandler to extend your own login functions with the mixins if wanted • Is asynchronous • Not supported in WSGI and Google App Engine
  • 28. USING TORNADO.AUTH - [/login/form, site.auth_reg.LoginForm] - [/login/friendfeed, site.auth_reg.LoginFriendFeed] class LoginFriendFeed(RequestHandler, tornado.auth.FriendFeedMixin): @tornado.web.asynchronous def get(self): if self.get_argument("oauth_token", None): self.get_authenticated_user(self.async_callback(self._on_auth)) return self.authorize_redirect() def _on_auth(self, ffuser): if not ffuser: raise tornado.web.HTTPError(500, "FriendFeed auth failed") return username = ffuser['username']
  • 29. TORNADO.IOLOOP • Protocol independent • tornado.httpserver.HTTPServer uses ioloop.IOLoop • RabbitMQ driver Pika uses ioloop.IOLoop • Built in timer functionality • tornado.ioloop.add_timeout • tornado.ioloop.PeriodicCallback
  • 30. TORNADO.IOLOOP EXAMPLE class MyClient(object): def connect(self, host, port): # Create our socket self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0) self.sock.connect((host, port)) self.sock.setblocking(0) self.io_loop = tornado.ioloop.IOLoop.instance() # Append our handler to tornado's ioloop for our socket events = tornado.ioloop.IOLoop.READ | tornado.ioloop.IOLoop.ERROR self.io_loop.add_handler(self.sock.fileno(), self._handle_events, events) https://github.com/pika/pika/blob/master/pika/adapters/tornado_connection.py
  • 31. OTHER MODULES OF NOTE • tornado.database • tornado.options • MySQL wrapper • Similar to optparse • tornado.escape • tornado.testing • Misc escape functions • Test support classes • tornado.httpclient • tornado.websocket • Async HTTP client • Websocket Support • tornado.iostream • Non-blocking TCP helper class
  • 32. ASYNC DRIVERS • Memcache • MongoDB • PostgreSQL • RabbitMQ • Redis
  • 33. FIN • Follow me on Twitter @crad • Blog: http://gavinroy.com • Pika: http://github.com/pika • Async RabbitMQ/AMQP Support for Tornado • We’re hiring at myYearbook.com • Drop me an email: gmr@myyearbook.com
  • 34. IMAGE CREDITS • Lego by Craig A. Rodway http://www.flickr.com/photos/m0php/530526644/ • Delta Clipper X courtesy of NASA • United Nations San Francisco Conference by Yould http://www.flickr.com/photos/un_photo/3450033473/