+ All Categories
Home > Documents > Philly Lambda: An Introduction to Tornado

Philly Lambda: An Introduction to Tornado

Date post: 09-Apr-2018
Category:
Upload: gavin-m-roy
View: 219 times
Download: 0 times
Share this document with a friend
31
AN INTRODUCTI ON T O TORNADO Gavin M. Roy CT O myYearbook.com Philly Lambda December 2010
Transcript

8/8/2019 Philly Lambda: An Introduction to Tornado

http://slidepdf.com/reader/full/philly-lambda-an-introduction-to-tornado 1/31

AN INTRODUCTION TO

TORNADOGavin M. Roy 

CTO

myYearbook.com

Philly Lambda

December 2010

8/8/2019 Philly Lambda: An Introduction to Tornado

http://slidepdf.com/reader/full/philly-lambda-an-introduction-to-tornado 2/31

TORNADO AT

MYYEARBOOK.COM• Currency Connect

• Marketing Website, Portal, RESTful API

• Redirect Engine

Nerve

• Staplr 2

• Image Upload Service

8/8/2019 Philly Lambda: An Introduction to Tornado

http://slidepdf.com/reader/full/philly-lambda-an-introduction-to-tornado 3/31

 WHAT IS TORNADO?

A scalable, non-blocking web server and micro-framework inPython (2.5 through 2.6 -- 2.7?)

• Developed at FriendFeed and open-sourced by Facebook 

• Similar to web.py in use

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

8/8/2019 Philly Lambda: An Introduction to Tornado

http://slidepdf.com/reader/full/philly-lambda-an-introduction-to-tornado 4/31

FEATURES

• Small barrier to entry to quickly developing applications

Third Party Authentication via OpenID, OAuth Mixins

• Light-weight templating 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 

8/8/2019 Philly Lambda: An Introduction to Tornado

http://slidepdf.com/reader/full/philly-lambda-an-introduction-to-tornado 5/31

CLEAN, WELL DOCUMENTED CODE

8/8/2019 Philly Lambda: An Introduction to Tornado

http://slidepdf.com/reader/full/philly-lambda-an-introduction-to-tornado 6/31

 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)

8/8/2019 Philly Lambda: An Introduction to Tornado

http://slidepdf.com/reader/full/philly-lambda-an-introduction-to-tornado 7/31

TORNADO VS TWISTED WEB

• 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/8/2019 Philly Lambda: An Introduction to Tornado

http://slidepdf.com/reader/full/philly-lambda-an-introduction-to-tornado 8/31

KEY

MODULESTake only what you need

8/8/2019 Philly Lambda: An Introduction to Tornado

http://slidepdf.com/reader/full/philly-lambda-an-introduction-to-tornado 9/31

TORNADO.IOLOOP

• Protocol independent

• tornado.httpserver.HTTPServer implemented using the

ioloop

• Implemented a Tornado adapter for Pika on IOLoop

• Built in timer functionality 

• tornado.ioloop.add_timeout

• tornado.ioloop.PeriodicCallback 

8/8/2019 Philly Lambda: An Introduction to Tornado

http://slidepdf.com/reader/full/philly-lambda-an-introduction-to-tornado 10/31

TORNADO.IOLOOP EXAMPLE

class MyServer(object):

def connect(self, host, port):

 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()  self.handle_connection_open() # 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/gmr/pika/blob/master/pika/tornado_adapter.py 

8/8/2019 Philly Lambda: An Introduction to Tornado

http://slidepdf.com/reader/full/philly-lambda-an-introduction-to-tornado 11/31

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

8/8/2019 Philly Lambda: An Introduction to Tornado

http://slidepdf.com/reader/full/philly-lambda-an-introduction-to-tornado 12/31

CORE APPLICATION

• tornado.web.Application: Main controller class

• Canonical Tornado Hello World:

import tornado.httpserverimport tornado.ioloopimport 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()

8/8/2019 Philly Lambda: An Introduction to Tornado

http://slidepdf.com/reader/full/philly-lambda-an-introduction-to-tornado 13/31

REQUEST HANDLERS

• tornado.web.RequestHandler 

• Extend RequestHandler for larger web apps

• Session Handling

Database, Cache Connections

• Localization

• Implement for your Application

8/8/2019 Philly Lambda: An Introduction to Tornado

http://slidepdf.com/reader/full/philly-lambda-an-introduction-to-tornado 14/31

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, Redirectsand more

8/8/2019 Philly Lambda: An Introduction to Tornado

http://slidepdf.com/reader/full/philly-lambda-an-introduction-to-tornado 15/31

REQUEST HANDLER EXAMPLE

import redisimport 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.asynchronousdef get(self):

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

8/8/2019 Philly Lambda: An Introduction to Tornado

http://slidepdf.com/reader/full/philly-lambda-an-introduction-to-tornado 16/31

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 

8/8/2019 Philly Lambda: An Introduction to Tornado

http://slidepdf.com/reader/full/philly-lambda-an-introduction-to-tornado 17/31

REQUESTHANDLER.RENDER 

class Home(RequestHandler):

def get(self):

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

<html><body>Hi {{username}}, welcome to our site.

</body></html>

   C  o   d  e

   T  e  m  p   l  a   t  e

8/8/2019 Philly Lambda: An Introduction to Tornado

http://slidepdf.com/reader/full/philly-lambda-an-introduction-to-tornado 18/31

TEMPLATE EXAMPLE

<html><head>

<title>eMuse :: {% 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>

8/8/2019 Philly Lambda: An Introduction to Tornado

http://slidepdf.com/reader/full/philly-lambda-an-introduction-to-tornado 19/31

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.

8/8/2019 Philly Lambda: An Introduction to Tornado

http://slidepdf.com/reader/full/philly-lambda-an-introduction-to-tornado 20/31

UI MODULES

• Extend templates with

reusable widgets across thesite

• One import assigned when

Application is instantiated

• Similar to RequestHandler inbehavior 

8/8/2019 Philly Lambda: An Introduction to Tornado

http://slidepdf.com/reader/full/philly-lambda-an-introduction-to-tornado 21/31

UIMODULE EXAMPLEclass HTTPSCheck(tornado.web.UIModule):

def render(self):

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"><a href="https://{{request.host}}{{request.uri}}">

{{_("Click here to use a secure connection")}}</a>

</div>

 <div>{{ modules.HTTPSCheck() }}</div>

   U   I   M  o   d  u   l  e   C   l  a  s  s

   T  e  m  p   l  a   t  e

   E  m   b  e   d

8/8/2019 Philly Lambda: An Introduction to Tornado

http://slidepdf.com/reader/full/philly-lambda-an-introduction-to-tornado 22/31

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

•  tornado.locale.get_supported_locales

8/8/2019 Philly Lambda: An Introduction to Tornado

http://slidepdf.com/reader/full/philly-lambda-an-introduction-to-tornado 23/31

ADDING LOCALIZATION

import tornado.locale as localeimport tornado.web

class RequestHandler(tornado.web.RequestHandler):

def get_user_locale(self): 

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

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

return user_locale 

# Defaults to Accept-Language header if supportedreturn None

8/8/2019 Philly Lambda: An Introduction to Tornado

http://slidepdf.com/reader/full/philly-lambda-an-introduction-to-tornado 24/31

USING LOCALIZATION

<html><body>{{_("Welcome to our site.")}}

</body></html>

8/8/2019 Philly Lambda: An Introduction to Tornado

http://slidepdf.com/reader/full/philly-lambda-an-introduction-to-tornado 25/31

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"

8/8/2019 Philly Lambda: An Introduction to Tornado

http://slidepdf.com/reader/full/philly-lambda-an-introduction-to-tornado 26/31

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

• Built to be asynchronous

8/8/2019 Philly Lambda: An Introduction to Tornado

http://slidepdf.com/reader/full/philly-lambda-an-introduction-to-tornado 27/31

USING TORNADO.AUTH

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

@tornado.web.asynchronousdef 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']

- [/login/form, emuse.auth_reg.LoginForm]- [/login/friendfeed, emuse.auth_reg.LoginFriendFeed]

8/8/2019 Philly Lambda: An Introduction to Tornado

http://slidepdf.com/reader/full/philly-lambda-an-introduction-to-tornado 28/31

OTHER MODULES OF NOTE

•  tornado.database

• MySQL wrapper 

 tornado.escape

• Misc escape functions

•  tornado.httpclient

Async HTTP client

•  tornado.iostream

• Non-blocking TCP helper class

•  tornado.options

• Similar to optparse

 tornado.testing

• Test support classes

•  tornado.websocket

 Websocket Support

8/8/2019 Philly Lambda: An Introduction to Tornado

http://slidepdf.com/reader/full/philly-lambda-an-introduction-to-tornado 29/31

TINMAN

• Needs some TLC

• Supports < 1.0

• Meta-framework 

• Adds structure to Tornadoprojects

• Daemonization

Configuration

• Session Handling

• Memoize dynamic content withdecorator 

• Database Support

8/8/2019 Philly Lambda: An Introduction to Tornado

http://slidepdf.com/reader/full/philly-lambda-an-introduction-to-tornado 30/31

FIN

• Follow me on Twitter @crad

• Blog: http://gavinroy.com

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

• Async RabbitMQ/AMQP Support for Tornado

• Tinman: http://github.com/gmr/Tinman

• We’re hiring at myYearbook.com

• Drop me an email: [email protected]

8/8/2019 Philly Lambda: An Introduction to Tornado

http://slidepdf.com/reader/full/philly-lambda-an-introduction-to-tornado 31/31

IMAGE CREDITS

Lego by Craig A. Rodway ht tp://www.flickr.com/photos/m0php/530526644/

• Delta Clipper X courtesy of NASA

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


Recommended