.. include:: ================== WSGI par l'exemple ================== :Authors: Gael Pasgrimaud :Date: $Date: 2008-05-18$ .. Cette présentation et les éléments de contenus associés sont placés dans le .. domaine publique. .. class:: small * Le concept WSGI * Une implementation: Paste .. container:: handout Ce tutorial présente la norme WSGI (PEP 333) visant à normaliser les application web écritent en Python .. contents:: :class: handout .. |bullet| unicode:: U+02022 .. |mode| unicode:: U+00D8 .. capital o with stroke .. footer:: Paris |bullet| 2008-05-18 Pourquoi WSGI ? =============== .. class:: incremental * Multiple applications web écrite en Python * Cohabitation difficile entre ces applications * La solution: la normalisation Qu'est ce que WSGI ? ==================== .. class:: incremental Norme visant à décrire le processus de publication d'une application web. * Web * Server * Gateway * Interface Composition =========== .. class:: incremental Se découpe en 3 parties: * Application * Serveur * Monde du milieu Serveur ======= .. class:: incremental Non détaillé ici. Il est chargé de desservir les pages web. Il en existe un grand nombre: * PasteDeploy * mod_python * Flup (fastcgi) Application 1/2 =============== .. class:: incremental C'est le corps du processus. Il contient toute la logique applicative. Un grand nombre de framework supporte le WSGI: * django * pylons * zope3 * ... Application 2/2 =============== Implémentation simple:: def application(environ, start_response): start_response('200 OK', [('Content-Type', 'text/html')]) return 'Hello' La variable environ (1/2) ========================= .. class:: incremental - Simple dictionnaire - Contient l'environnement pour une requête - Valeurs d'un environnement HTTP classique (PATH_INFO, HTTP_HOST, etc.) - Valeurs spécifique à la norme (wsgi.*) La variable environ (2/2) ========================= .. class:: incremental * wsgi.version * wsgi.url_scheme http / https * wsgi.input Flux d'entrée en lecture contenant la requête (stdin) * wsgi.errors Flux de sortie permettant de tracer les erreurs. (stderr) * wsg.multithread Vrai / Faux * wsgi.multiprocess Vrai / Faux * wsgi.run_once Vrai si l'application n'est évaluée qu'une fois dans la vie * du processus. (CGI / Tests) Monde du milieu (1/2) ===================== .. class:: incremental Interagis à la fois avec l'application et avec le serveur. * modifie le comportement d'une application * permet la cohabitation d'applications * modifie le résultat renvoyé au serveur Monde du milieu (2/2) ===================== Notification des erreurs de l'application:: class ErrorHandler(object): def __init__(self, app): self.application = app def __call__(environ, start_response): try: return self.application(environ, start_response) except Exception, e: # notification de l'admin ... raise Une implementation: Paste ========================= .. class:: incremental Ensemble de librairie implementant la norme * Serveurs * Squelette d'application * Composants du milieu réutilisable Configuration de type INI ========================= .. class:: incremental * Configuration organisée en section * Enchaînement de sections: serveur -> millieu(s) -> application(s) * Configurable par un administrateur sans notion de python ni de developement. Factory (1/2) ============= .. class:: incremental * Utilisation de points d'entrées pointant vers des factory * Le factory renvois l'application après une éventuelle configuration Factory (2/2) ============= Factory avec configuration:: def mon_application(global_config, **local_config): # on utilise le factory #pour configurer la notification app = ErrorHandler(application, local_config['email']) return app Une application simple ====================== deploy.ini:: [app:main] use = egg:mon.package#mon_application email = gawel@afpy.org [server:main] use = egg:Paste#http host = 127.0.0.1 port = 5000 Lancement de l'application:: paster serve deploy.ini Eléments de configuration (1/2) =============================== app: une application:: [app:mon_application] use = egg:mon.package#ma_super_application filter: monde du milieu:: [filter:error_handler] use = egg:mon.package#error_handler pipeline: permet un enchaînement monde du milieu / application:: [pipeline:main] pipeline = error_handler mon_application Eléments de configuration (1/2) =============================== composite: permet de combiner des applications:: [composite:main] use = Paste#urlmap /app1 = mon_application /app2 = mon_application2 server: permet un choix de serveur:: [server:main] use = PasteScript#cherrypy host = 127.0.0.1 port = 5000 Paste utilise les section `:main` comme point d'entrée puis construit l'application En savoir plus ============== * PEP333 http://www.python.org/dev/peps/pep-0333/ * wsgi.org http://wsgi.org/wsgi * Paster http://pythonpaste.org/ Crédits ======= * AFPy * Olivier Grisel