Créer un site avec bottle en 5 minutes (parceque 7 c’est impossible voyons !)


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 bottle. 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)

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

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(‘/’) 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!"

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>

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)

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)

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)

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)

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…

20 thoughts on “Créer un site avec bottle en 5 minutes (parceque 7 c’est impossible voyons !)

  • kage

    très bon article il est cool ce ‘Bottle’ il me rappel 1 peu le micro-framework sinitra en ruby
    Il y a une petite erreur sur le lien plugins bottle ici

  • Sam

    C’est exactement sinatra, en plus petit: bottle tient dans un seul fichier.

    Je rajoute qq infos à l’article:

    – mettez vos template dans un sous dossier “views”
    – les fichiers statiques (js, css, images) ne sont pas servis automatiquement, il faut rajouter une route (cf la doc).
    – max utilisent la nomenclature Django, d’où le “vue” quand il parle du controleur.

  • foxmask

    Encore de la lecture très très intéressante.

    j’ai relevé quelques coquilles d’un caractère par ci par là en passant ;)

    * mes oublies
    * je me suis dist
    * qui peut prendre
    * Voilà votre premier site
    * que l’ont va populer peupler
    * Les templates offresnt pas mal de possibilitée
    * s/c’est vraiment pas sorcier/ce n’est vraiment pas sorcier/
    * quelques exemples pratiques

  • foxmask

    bonjour,
    pour revenir sur cette phrase

    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 ;)

    pour un site échangeant des posts façon twitter avec la gestion de membres qui va bien, vous partiriez sur du django ou tenteriez bottle ? Ou bottle est plus dédié à des projets encore plus court que cela ? d’après la doc de bottle il est envisageable de faire des projets complexes mais ils recommandent d’autre fwks complets pour cela.

    cordialement.

  • Fred

    Où est-ce que vous situeriez Flask là dedans ? Entre Bottle et Django ou en concurrence directe avec Bottle ? Je ne connais pas Bottle mais Flask dispose en built-in ce que Bottle propose parfois en plugin (message flash, werkzeug), et propose en outre davantage de plugins (wtforms, bcrypt, couchdb, celery, debugtoolbar, peewee, etc…).

    La base de snippets est parfois utile aussi : http://flask.pocoo.org/snippets/

  • Sam

    @foxmask: ne t’arrête pas au tampon hein, c’est pour le fun, mais on est toujours content d’avoir les corrections :-)

    Pour tout site qui demande à des users de s’enregistrer, je partirais sur du Django: trop de choses basiques à recoder sur du bottle. Et ça serait se passer de l’écosystème des apps Django qui font vraiment la force du produit pour une grosse app.

    @Fred: Flask est définitivement un concurrent de bottle. Bottle est juste plus minimaliste. Je préfère bottle à Flask, mais c’est un bon produit. Disons que si je sens le besoin d’un truc plus riche, je switch sur Django très vite. Max préfère éviter Django quand il peut, trop de truc à regarder dans la doc à chaque fois. Bottle, c’est vrai que c’est efficace.

  • foxmask

    ya pas de pb avec se faire tamponner le coquillard ;)
    merci pour la réponse pour bottle.

  • Jeff

    Merci pour cette découverte de Bottle. C’est vrai qu’il est bien sympa d’avoir un site francophone qui traite des nouveautés et astuces de python :)

  • sardon

    merci pour cette introduction, j’ai poussé l’expérience en adoptant l’appli de Gérard Swinnen (chap17, http://inforef.be/swi/python.htm)

    Par contre, j’ai un soucis en Python 3.1 : les accents ne passent pas les formulaires, alors que pas de soucis pour ça en Python 2.6, c’est assez paradoxal..

  • Comte

    pour reprendre les questions flask/bottle, disons que flash est un peu plus lent (basé sur Jinja2 et Werkzeug) tant que bottle est de tous les frameworks, le plus rapide (source : 3h passées à lire les différents benchmarks +/- valables trouvés sur le oueb)
    Django est surtout cool pour trouver un job, pour un gros projet et la contrepartie est qu’il est assez lent.

  • oncleben

    cherrypy vs bottle vs django vs flask: mon choix d’un framework

    Au tout départ, j’ai eu connaissance seulement de CherryPy et de Django. Première impression de grosse communauté pro pour Django qui jouit d’une énorme communication. J’ai donc commencé par lui. Je n’ai pas aimé la structure ubuesque des fichiers, ni l’appellation MVC biaisée dont l’explication officielle ne m’a pas convaincue, ni les libertés prises AMHA avec les bonnes pratiques de programmation, ni le serveur en carton, ni l’ORM par défaut. Je suis donc passé à CherryPy.

    CherryPy: grand respect des bonnes pratiques, serveur de production, framework minimaliste. Pile poil dans mes goûts. J’ai donc étendu mes recherches aux autres micro-frameworks. Bottle, Flask et CherryPy m’apparaissent relativement équivalents dans une première approche assez poussée, au détail près que CherryPy est le seul à avoir un serveur de production, et est à mon sens plus élégant. Bottle a pour lui d’être un poil plus concis, et probablement plus facile à apprendre. “I gave it a try”, mais je n’ai rien trouvé dans Flask d’intéressant pour me détourner de CherryPy ou de Bottle.

    Vient le problème de l’hébergement. Une autre raison qui m’a fait oublié assez vite Flask est que Gandi ne supporte le Python 3 qu’en python3.2 (en PaaS). Or Flask en Python 3, c’est du 3.3 minimum. Il y a donc incompatibilité rédhibitoire. Pareil, chez les hébergeurs que j’ai testé (PythonAnywhere, AlwaysData, Heroku), CherryPy est plutôt mal géré par rapport à ses concurrent: la faute à son serveur HTTP justement, puisque les hébergeurs propose le leur (Apache). J’ai quand même réussi à sortir une appli CherryPy sur PythonAnywhere mais au prix d’une magouille pas très propre (en fait j’ai utilisé une config’ Bottle au départ, que j’ai adaptée à CherryPy… Bref !).

    Au final, CherryPy reste mon framework préféré. De mon point de vue, si on est en SaaS ou en auto-hébergement, aucune raison d’utiliser un autre framework. Par contre en PaaS, utiliser Bottle reste le meilleur choix à mes yeux.

    Enfin, je ne comprends vraiment pas l’engouement pour Django. Ne pas réinventer la roue me semble un argument fallacieux: Python doit être modulaire (import snippet). Et si c’est pour faire valoir des compétences sur le marché du travail, ou mettre en production rapidement, creuser PHP et WordPress (et/ou Symfony, Drupa, Joomla) me semble plus judicieux.

  • jb

    @oncleben : dans le genre argumentaire avec zéro crédibilité tu viens de péter le score…

  • Andronaute

    Coucou Max,

    Tu nous avais pas promis de nous montrer un exemple :) Je suppose que c’est le multiboard. Pourrais tu nous donner le coupe framework /orm qui est utilisé pour faire ca.

    J’essaie de faire l’intégration de pewee a bottle et je voulais savoir si qq l’avais déja fait

    ++ et merci d’avance

  • Max Post author

    @andronaute

    Et merde ! un qui a retiendus mes promesses de jeunesse….

    On voulait filer le source de multiboard avec sam mais il est fait à la truelle et ça pourrait compromettre la très haute estime que nous porte Guido van Rossum alors on se tâte, ça fait 5 piges…

    Si par miracle un jour on le clean je vous le ferait savoir, mais j’ai pas la foie là :)

    pour info multiboards c’est du bête bottle avec un peu de js .

  • Andronaute

    Merci Max pour ta réponse :)

    Je voulais surtout voir comment vous aviez utilisé un orm du style pewee avec bottle si c’est le cas sur multiboard.

    Parce que franchement Sql alchemy c’est lourd je trouve pour faire un petit projet avec bottle propre.

    cheers

Comments are closed.

Des questions Python sans rapport avec l'article ? Posez-les sur IndexError.