Bottle ****** .. figure:: data/bottle.png Bottle est un WSGI web-framework simple et rapide écrit en python qui est de plus packager en un seul fichier n'ayant aucune dépendance externe. Core Features ============= Routes: Mapping URLs to code with a simple but powerful pattern syntax. Templates: Fast build-in template engine and support for mako, jinja2 and cheetah templates. Server: Build-in HTTP development server and support for paste, fapws3, flup, cherrypy or any other WSGI capable server. No dependencies: All in a single file and no dependencies other than the Python standard library. Download / Install ================== Pour l'installer soit vous le télécharger et vous l'utiliser comme un simple fichier package soit vous l'installer via easy_install :: easy_install -U bottle Bottle peut être utilisé avec python 3 en utilisant 2to3 Features and Examples ===================== Un exemple simple .. code-block:: python from bottle import route, run @route('/') def index(): return 'Hello World!' run(host='localhost', port=8080) lancer le fichier python et aller voir sur http://localhost:8080/ .. note:: pour que le serveur puisse répondre quelque soit l'interfaces 127.0.0.1, 192.*.*.*, ... il faut utiliser comme host **0.0.0.0** Routes ------ @route() est un decorator qui permet de ciblé l'URL utilisé .. code-block:: python @route('/hello/:name') def hello(name): return 'Hello, %s' % name Templates --------- Bottle comporte aussi son propre système de template qui peut être appeler par le décorateur view .. code-block:: python @route('/hello/template/:names') @view('hello') def template_hello(names): names = names.split(',') return dict(title='Hello World', names=names) Dans "./views/hello.tpl": :: {{title}} %for name in names:

Hello, {{name}}

%end On peut aussi l'écrire ainsi .. code-block:: python from bottle import template @route('/hello/template/:names') def template_hello(names): names = names.split(',') return template('view', dict(title='Hello World', names=names)) .. warning:: pour modifier le path des template on doit modifier la variable bottle.TEMPLATE_PATH; ex: TEMPLATE_PATH.insert(0,YOUR_PATH) Bootle peut utiliser des template comme jinja2, mako ou cheetah .. code-block:: python from bottle import mako_view as view Static Files, Redirects and HTTP Errors --------------------------------------- .. code-block:: python from bottle import static_file, redirect, abort @route('/static/:filename') def static_file(filename): return static_file(filename, root='/path/to/static/files') @route('/wrong/url') def wrong(): redirect("/right/url") @route('/restricted') def restricted(): abort(401, "Sorry, access denied.") @error(404) def error404(error): return template('error',{'error' :error,}) POST, GET, Header and Cookies ----------------------------- le plus facile est d'utiliser un dict() .. code-block:: python from bottle import request, response, route @route('/hello/cookie') def cookie(): name = request.COOKIES.get('name', 'Stranger') response.headers['Content-Type'] = 'text/plain' return 'Hello, %s' % name @route('/hello/cookie', method='POST') def set_cookie(): if 'name' in request.POST: name = request.POST['name'] response.set_cookie('name',name, path='/') return 'OK' .. note:: le path d'un cookie est important car il permet d'identifier les urls qui pourrons l'utiliser .. note:: il est possible de crypter la valeur d'un cookie et un exemple de login .. code-block:: python from bottle import get, post, request @get('/login') # or @route('/login') def login_form(): return '''
''' @post('/login') # or @route('/login', method='POST') def login_submit(): name = request.forms.get('name') password = request.forms.get('password') if check_login(name, password): return "

Your login was correct

" else: return "

Login failed

" Session ------- Il n'y a pas de session avec Bottle mais on peut utiliser la notion de cookie .. code-block:: python @app.route('/login') def login(): username = request.forms.get('username') password = request.forms.get('password') if check_user_credentials(username, password): response.set_cookie("account", username, secret='some-secret-key') return "Welcome %s! You are now logged in." % username else: return "Login failed." @app.route('/restricted') def restricted_area(): username = request.get_cookie("account", secret='some-secret-key') if username: return "Hello %s. Welcome back." % username else: return "You are not logged in. Access denied." HTTP Server ----------- Bottle has a HTTP Server build in but also supports cherrypy, flup, paste and fapws3 as alternatives. .. code-block:: python from bottle import PasteServer run(server=PasteServer) Gestion des Erreurs ------------------- le plus simple, contrairement a ce qu'on peut trouver sur la doc officiel, n'est pas de faire une route mais de modifier les handlers voici un exemple simple .. code-block:: python from bottle import Bottle, run, template, error, request import os TXT_ERROR_404 = """

Error 404:


path: %(path)s
url: %(url)s
path scheme: %(pathscheme)s
path netloc: %(pathnetloc)s
path request: %(pathrequest)s
path query : %(pathquery)s
path fragment : %(pathfragment)s """ app = Bottle() def error404(error): info = { 'path' : request.path, 'url' : request.url, 'pathscheme' : request.urlparts[0], 'pathnetloc' : request.urlparts[1], 'pathrequest' : request.urlparts[2], 'pathquery' : request.urlparts[3], 'pathfragment' : request.urlparts[4] } return TXT_ERROR_404 % info def error500(error): return 'error code 500' handler = { 404: error404, 500: error500, } app.error_handler = handler @app.route('/hello') def hello(): return 1/0 run(app, host='0.0.0.0', port=8080)