Aller bande de feignasses c’est Lundi on oublie la murge du week-end et on se secoue les neuronnes !

Bottle est un micro-framework python sur lequel Sam m’a obligé de bosser après Django, (il me force à évoluer c’est une horreur). Je dois dire que je le regrette pas car c’est diablement efficace, mignon et tout et tout.

En début de semaine je me suis dit qu’il fallait que j’en parle, je vais donc vous montrer comment on peut développer un “site” simple en 5 minutes structuré et sans se prendre le choux. Sam viendra compléter mes oublis.

Je ne vais pas aborder la base de données mais il y a plein de plugins bottle ici dont un ORM pour sqlite qu’on détaillera dans un article le jour où on s’en servira ;)

Avant de commencer: Pourquoi je l’aime ?

Simple à comprendre

bien structuré (des vues des templates, un routing clair)

gestion des urls fastoches

un petit serveur web intégré, on démarre son site en 10 secondes et on debug avec ipdb

une doc formidabuleuse avec des exemples concrets

il cracke les watts

En route simone !

On prend la bite rude de créer un environnement virtuel et on fait un pip install bottl e. Pour ceux qui veulent tout saloper faites juste un pip install bottle, pour ceux qui savent pas ce qu’est “pip” faites un “wget http://bottlepy.org/bottle.py” dans le dossier de votre projet.

je veux que ça marche tout de suite !

Editez un fichier python start.py à la racine de votre projet et collez ça dedans:

from bottle import Bottle , run app = Bottle ( ) @ app. route ( '/' ) def hello ( ) : return "Max est le plus beau!" run ( app , host = 'localhost' , port = 8080 ) from bottle import Bottle, run app = Bottle() @app.route('/') def hello(): return "Max est le plus beau!" run(app, host='localhost', port=8080)

maintenant dans le shell tapez dans le dossier de votre projet où se trouve start.py:

python start.py Bottle server starting up ( using WSGIRefServer ( ) ) ... Listening on http: // localhost: 8080 / Hit Ctrl-C to quit. localhost - - [ 12 / Aug / 2012 23 : 12 : 15 ] "GET / HTTP/1.1" 200 21 localhost - - [ 12 / Aug / 2012 23 : 12 : 16 ] "GET /favicon.ico HTTP/1.1" 404 742 python start.py Bottle server starting up (using WSGIRefServer())... Listening on http://localhost:8080/ Hit Ctrl-C to quit. localhost - - [12/Aug/2012 23:12:15] "GET / HTTP/1.1" 200 21 localhost - - [12/Aug/2012 23:12:16] "GET /favicon.ico HTTP/1.1" 404 742

Ouvrez le navigateur Internet explorer bourré de toolbars à l’adresse 127.0.0.1:8080

C’est bon ça marche, c’est fini, vous êtes un pro du pot. Quand on voit ça on se dit que franchement ça sert à rien de se faire chier plus que ça… :)

Moi quand je vois ça ça me fait chialer à chaque fois tellement c’est simple, je me dis que je vais révolutionner le monde, conquérir la planète, me taper les plus belles meufs…

Avant d’aller plus loin je reprends le code et je note ce qu’il faut retenir

1. le routing

@ app. route ( '/' ) @app.route('/')

@app.route(‘/’) prend tout ce qui arrive à la racine de l’url et le traite dans la vue hello qui est une fonction de base toute simple. si j’avais voulu faire une url du genre 127.0.0.1:8080/samapoil j’aurais mis @app.route(‘/samapoil’)

2. les vues

def hello ( ) : return "Max est le plus beau!" def hello(): return "Max est le plus beau!"

la vue est une fonction que l’ont défini et qui peut prendre n’importe quel nom, dedans on traite l’information qui arrivera de l’url routée par le décorateur “@app.route(‘/’)”. Cette vue peut recevoir des infos d’un formulaire ou des variables passées dans l’url (qu’on va voir plus bas)

Voilà votre premier site bottle marche, c’est rigolo. Maintenant on va aller un peu plus loin et utiliser les templates.

Les templates c’est quoi ?

Les templates c’est juste du code HTML avec dedans des “variables” que l’on va peupler dans notre vue. ça sert à ne pas trop mélanger code python et html et c’est plutôt une bonne idée.

Création d’un template:

éditez un fichier template.tpl et mettez dedans

< div align = "center" > { { title } } </ div > <div align="center">{{ title }}</div>

Maintenant on va assembler le template et la vue comme un légo:

Ouvrez le fichier start.py et collez

from bottle import Bottle , run , view app = Bottle ( ) @ app. route ( '/' ) @ view ( 'template.tpl' ) def hello ( ) : context = { 'title' : "Max est le plus beau" } return ( context ) run ( app , host = 'localhost' , port = 8080 ) from bottle import Bottle, run, view app = Bottle() @app.route('/') @view('template.tpl') def hello(): context = {'title': "Max est le plus beau"} return (context) run(app, host='localhost', port=8080)

Relancez le serveur (python start.py) et allez sur à l’adresse 127.0.0.1:8080

Et voilà notre template utilisé par notre vue auquel on a passé un title. Ceci ce fait grace au décorateur “@view” auquel on donne le chemin du template. Les templates offrent pas mal de possibilitées

Les bases sont posées ce n’est vraiment pas sorcier, je rajoute quelques exemples pratiques mais tout ceci figure dans la doc

Mettre un id dans l’url:

#!/usr/bin/env python # -*- coding: utf-8 -*- from bottle import Bottle , run , view app = Bottle ( ) @ app. route ( '/:mon_id' ) @ view ( 'template.tpl' ) def hello ( mon_id ) : """ Récupre la variable mon_id passée dans l'url sous la forme 127.0.0.1:8080/1 et la transmet au template via le context """ context = { 'title' : "Max est le plus beau %s" % mon_id } return ( context ) run ( app , host = 'localhost' , port = 8080 ) #!/usr/bin/env python # -*- coding: utf-8 -*- from bottle import Bottle, run, view app = Bottle() @app.route('/:mon_id') @view('template.tpl') def hello(mon_id): """ Récupre la variable mon_id passée dans l'url sous la forme 127.0.0.1:8080/1 et la transmet au template via le context """ context = {'title': "Max est le plus beau %s" % mon_id} return (context) run(app, host='localhost', port=8080)

Récupérer une variable dans l’url:

#!/usr/bin/env python # -*- coding: utf-8 -*- from bottle import Bottle , run , view , request app = Bottle ( ) @ app. route ( '/jemesure' ) @ view ( 'template.tpl' ) def hello ( ) : """ Récupère la variable taille à l'aide de l'objet request pour l'url http://127.0.0.1:8080/jemesure?taille=133 """ context = { 'title' : "Je mesure %s cm" % request. params . taille } return ( context ) run ( app , host = 'localhost' , port = 8080 , reloader = True ) #!/usr/bin/env python # -*- coding: utf-8 -*- from bottle import Bottle, run, view, request app = Bottle() @app.route('/jemesure') @view('template.tpl') def hello(): """ Récupère la variable taille à l'aide de l'objet request pour l'url http://127.0.0.1:8080/jemesure?taille=133 """ context = {'title': "Je mesure %s cm" % request.params.taille} return (context) run(app, host='localhost', port=8080, reloader=True)

Notez le “reloader=True” qui permet au serveur de redémarrer à chaque modif du code, hyper pratique.

Edit:

Servir les images, js, css (appelé contenu statique):

#!/usr/bin/env python # -*- coding: utf-8 -*- from bottle import Bottle , run , static_file app = Bottle ( ) @ app. route ( '/static/<filename:path>' ) def server_static ( filename ) : """ Sert les fichiers statiques tel que .js, .css, .jpeg, etc... """ return static_file ( filename , root = '.' ) run ( app , host = 'localhost' , port = 8080 , reloader = True ) #!/usr/bin/env python # -*- coding: utf-8 -*- from bottle import Bottle, run, static_file app = Bottle() @app.route('/static/<filename:path>') def server_static(filename): """ Sert les fichiers statiques tel que .js, .css, .jpeg, etc... """ return static_file(filename, root='.') run(app, host='localhost', port=8080, reloader=True)

Grace à static_file vous pourrez servir vos images, faire télécharger des fichiers, etc, simplement. Dans l’exemple ci-dessus si vous allez sur l’url http://127.0.0.1:8080/static/template.tpl vous allez télécharger le template template.tpl, si c’est une image, votre navigateur affichera une image, etc…

Je vous conseille d’aller voir la doc histoire de vous mettre l’eau à la bouche. JE déteste les docs en général mais là je la trouve presque parfaite.

Sam vous fera un article bientôt sur comment mettre tout ça en prod car le petit serveur web compris dans bottle ne peut bien sur pas assurer une charge en prod.

Mais comme dit ma grand-mère ça se goupille comme un doigt au cul.

Bottle est vraiment pour moi l’outil parfait pour concrétiser rapidement une idée, un site qui ne demande pas une grosse structure, bref un projet qui doit se torcher rapidement ;)

Et pour illustrer ce que j’ai pu faire en quelques jours de taf avec bottle et un peu de Jquery je vous mettrai en ligne dans la semaine un petit site fort symphatique je pense…