philly lambda: an introduction to tornado
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")}} © {{ 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/