Programmation web asynchrone avec Tornado

Ronan Amicel
Ronan AmicelEntrepreneur – Startup advisor – Full-stack Python developer à Omixy
Développement web asynchrone
        avec Tornado
                Ronan Amicel
                   @amicel

      PyCon FR – Paris – 15 septembre 2012
Ronan Amicel

• Entrepreneur
• Startup advisor
• Python !
Tornado c’est quoi ?

• Un serveur web
  – scalable et non-bloquant (utilise epoll ou kqueue)

• Un framework web
  – proche de web.py ou webapp

  – exploite l’infrastructure non-bloquante sous-jacente
Bonjour les gens !
import tornado.ioloop
import tornado.web

class MainHandler(tornado.web.RequestHandler):
    def get(self):
        self.write("Bonjour les gens !")

application = tornado.web.Application([
    (r"/", MainHandler),
])

if __name__ == "__main__":
    application.listen(8888)
    tornado.ioloop.IOLoop.instance().start()
(Some) Batteries Included
•   Moteur de templates

•   Localisation

•   Client HTTP asynchrone

•   Client MySQL asynchrone

•   OpenID et OAuth (Twitter, Facebook, Google)

•   Web Socket
Cas d'utilisation
•   Seul ou en complément d'un framework « classique »

•   Sites à forte charge (milliers de requêtes / seconde)

•   Messagerie instantanée, chat rooms

•   Requêtes dépendant de services externes à latence variable
    (API Facebook, Twitter, etc.)

•   Mises à jour « temps réel » dans une page web
Mises à jour « temps réel »
         Polling                            Long Polling                                Streaming
             (Ajax)                                   (Comet)                              (Web Socket)




                            événements




                                                                      événements




                                                                                                               événements
Navigateur            Serveur            Navigateur             Serveur            Navigateur             Serveur
Web Socket
                (côté serveur)
from tornado.websocket import WebSocketHandler

class EchoWebSocket(WebSocketHandler):

   def open(self):
       print "WebSocket opened"

   def on_message(self, message):
       self.write_message(u"You said: " + message)

   def on_close(self):
       print "WebSocket closed"
Web Socket
                   (côté client)

var ws = new WebSocket("ws://localhost:8888/websocket");

ws.onopen = function () {
   ws.send("Hello, world");
};

ws.onmessage = function (evt) {
   alert(evt.data);
};
Requêtes asynchrones
from tornado.httpclient import AsyncHTTPClient
from tornado.web import RequestHandler, asynchronous

class MyRequestHandler(RequestHandler):

   @asynchronous
   def get(self):
      http = AsyncHTTPClient()
      http.fetch('http://friendfeed.com/', self._on_download)

   def _on_download(self, response):
      self.write('Downloaded!')
      self.finish()
Masquer les callbacks
          avec tornado.gen
from tornado.gen import engine, Task
from tornado.httpclient import AsyncHTTPClient
from tornado.web import RequestHandler, asynchronous


class MyRequestHandler(RequestHandler):

   @asynchronous
   @engine
   def get(self):
      http = AsyncHTTPClient()
      response = yield Task(http.fetch, 'http://friendfeed.com/')
      self.write('Downloaded!')
      self.finish()
Tâches concurrentes
          avec tornado.gen
class MyRequestHandler(RequestHandler):

   @asynchronous
   @engine
   def get(self):
      http = AsyncHTTPClient()

       response1, response2 = yield [
           Task(http.fetch, url1),
           Task(http.fetch, url2),
       ]

       self.write('Downloaded!')
       self.finish()
Bibliothèques asynchrones

•   PostgreSQL

•   MongoDB

•   Redis

•   Memcache

•   RabbitMQ
Qui utilise Tornado ?




focus.io
Historique
•   2007 : FriendFeed

•   Août 2009 : rachat par Facebook

•   Septembre 2009 : première version diffusée sous licence Apache 2.0

•   Juillet 2010 : Tornado 1.0

•   Juin 2011 : Tornado 2.0

•   Septembre 2012 : Tornado 2.4
Les côtés négatifs

• Asynchrone
 – Moins lisible que du code synchrone

 – Plus complexe à déboguer

• Communauté
 – Moins populaire que Django, Flask, Pyramid...
Ressources


•   http://www.tornadoweb.org/

•   http://pypi.python.org/pypi/tornado

•   https://github.com/facebook/tornado/
1 sur 17

Contenu connexe

Tendances(14)

Présentation de Node.jsPrésentation de Node.js
Présentation de Node.js
Mickael Couzinet1.4K vues
Ze cloud   data-aspectizeZe cloud   data-aspectize
Ze cloud data-aspectize
Aymeric Weinbach937 vues
Ze cloud   azure camp - 26 septembreZe cloud   azure camp - 26 septembre
Ze cloud azure camp - 26 septembre
Aymeric Weinbach1.6K vues
Initiation à Express jsInitiation à Express js
Initiation à Express js
Abdoulaye Dieng2.5K vues
Vagrant - ConceptVagrant - Concept
Vagrant - Concept
Julien Dubreuil2.2K vues
Rust my nodeRust my node
Rust my node
Thomas Haessle101 vues
Présentation de VagrantPrésentation de Vagrant
Présentation de Vagrant
clmntlxndr2.5K vues
Bonnes pratiques développement androidBonnes pratiques développement android
Bonnes pratiques développement android
Daniel Rene FOUOMENE PEWO1.4K vues
Serveur ZabbixServeur Zabbix
Serveur Zabbix
Damien Morisseau904 vues

Similaire à Programmation web asynchrone avec Tornado(20)

Programmation web asynchrone avec Tornado

  • 1. Développement web asynchrone avec Tornado Ronan Amicel @amicel PyCon FR – Paris – 15 septembre 2012
  • 2. Ronan Amicel • Entrepreneur • Startup advisor • Python !
  • 3. Tornado c’est quoi ? • Un serveur web – scalable et non-bloquant (utilise epoll ou kqueue) • Un framework web – proche de web.py ou webapp – exploite l’infrastructure non-bloquante sous-jacente
  • 4. Bonjour les gens ! import tornado.ioloop import tornado.web class MainHandler(tornado.web.RequestHandler): def get(self): self.write("Bonjour les gens !") application = tornado.web.Application([ (r"/", MainHandler), ]) if __name__ == "__main__": application.listen(8888) tornado.ioloop.IOLoop.instance().start()
  • 5. (Some) Batteries Included • Moteur de templates • Localisation • Client HTTP asynchrone • Client MySQL asynchrone • OpenID et OAuth (Twitter, Facebook, Google) • Web Socket
  • 6. Cas d'utilisation • Seul ou en complément d'un framework « classique » • Sites à forte charge (milliers de requêtes / seconde) • Messagerie instantanée, chat rooms • Requêtes dépendant de services externes à latence variable (API Facebook, Twitter, etc.) • Mises à jour « temps réel » dans une page web
  • 7. Mises à jour « temps réel » Polling Long Polling Streaming (Ajax) (Comet) (Web Socket) événements événements événements Navigateur Serveur Navigateur Serveur Navigateur Serveur
  • 8. Web Socket (côté serveur) from tornado.websocket import WebSocketHandler class EchoWebSocket(WebSocketHandler): def open(self): print "WebSocket opened" def on_message(self, message): self.write_message(u"You said: " + message) def on_close(self): print "WebSocket closed"
  • 9. Web Socket (côté client) var ws = new WebSocket("ws://localhost:8888/websocket"); ws.onopen = function () { ws.send("Hello, world"); }; ws.onmessage = function (evt) { alert(evt.data); };
  • 10. Requêtes asynchrones from tornado.httpclient import AsyncHTTPClient from tornado.web import RequestHandler, asynchronous class MyRequestHandler(RequestHandler): @asynchronous def get(self): http = AsyncHTTPClient() http.fetch('http://friendfeed.com/', self._on_download) def _on_download(self, response): self.write('Downloaded!') self.finish()
  • 11. Masquer les callbacks avec tornado.gen from tornado.gen import engine, Task from tornado.httpclient import AsyncHTTPClient from tornado.web import RequestHandler, asynchronous class MyRequestHandler(RequestHandler): @asynchronous @engine def get(self): http = AsyncHTTPClient() response = yield Task(http.fetch, 'http://friendfeed.com/') self.write('Downloaded!') self.finish()
  • 12. Tâches concurrentes avec tornado.gen class MyRequestHandler(RequestHandler): @asynchronous @engine def get(self): http = AsyncHTTPClient() response1, response2 = yield [ Task(http.fetch, url1), Task(http.fetch, url2), ] self.write('Downloaded!') self.finish()
  • 13. Bibliothèques asynchrones • PostgreSQL • MongoDB • Redis • Memcache • RabbitMQ
  • 14. Qui utilise Tornado ? focus.io
  • 15. Historique • 2007 : FriendFeed • Août 2009 : rachat par Facebook • Septembre 2009 : première version diffusée sous licence Apache 2.0 • Juillet 2010 : Tornado 1.0 • Juin 2011 : Tornado 2.0 • Septembre 2012 : Tornado 2.4
  • 16. Les côtés négatifs • Asynchrone – Moins lisible que du code synchrone – Plus complexe à déboguer • Communauté – Moins populaire que Django, Flask, Pyramid...
  • 17. Ressources • http://www.tornadoweb.org/ • http://pypi.python.org/pypi/tornado • https://github.com/facebook/tornado/