En alliant le langage de programmation Python et un système de templates très riche, on peut créer assez facilement une application. Forcément, plus l'application que vous rêvez de réaliser sera compliquée et plein de fonctionnalités, plus le temps qu'il vous faudra pour la coder sera long.
Mais avec Flask, on peut déjà rapidement obtenir des résultats, sans trop se perdre.
Mais attention, Flask ne fait pas tout : si vous voulez aboutir à quelque chose de sérieux en web-app, vous finirez par utililser Django. Mais Django est très lourd à apprendre, tandis que Flask ressemble beaucoup à ce qu'on a utilisé pendant les cours. Contrairement à Django qui fait beaucoup de choses tout seul (ORM, validations formulaires, back-end admin...), Flask reste simple et c'est à vous de lui coder/rajouter ces composants à la main. Il est aussi très utilisé et ne risque pas de disparaître de sitôt.
from jyquickhelper import add_notebook_menu
add_notebook_menu()
Pour commencer, disons qu'un site web n'est qu'un simple programme exécuté sur un ordinateur. Si vous voulez une présentation détaillée de l'écosystème du web, le résumé de code school est complet et très clair.
Quand vous vous rendez sur ce site web, vous êtes ce qu'on appellera un client, et l'ordinateur où est exécuté ce site web est appelé le serveur. Durant le TD, nous utiliserons le même ordinateur pour faire les deux : le site web sera donc situé sur votre propre machine. Ce qui veut dire que votre application ne sera disponible que pour vous, on dit encore "en local".
Pour communiquer avec le site internet, le client envoie des requêtes au serveur, en gros en lui donnant une page (une url) le client demande au serveur une chose bien précise. Pour faire simple, tout se joue dans l'adresse mise dans le navigateur.
L'adresse https://github.com/sdpython/ensae_teaching_cs est composée de plusieurs parties :
https
: c'est le protocole on ne va pas en parler icigithub.com
: c'est le nom du domainesdpython/ensae_teaching_cs
: c'est le chemin de la page web demandée, aussi appelé "route".Dans le TD comme tout se passe sur notre ordinateur, on n'a pas de nom de domaine; Il est remplacé par localhost par convention. Pour accéder à la page appelée “/unepage”, nous devrons donc entrer dans notre navigateur : http://localhost/unepage Et petite subtilité, un serveur HTTP peut fonctionner sur différents ports. Par défaut, le serveur HTTP intégré à Flask fonctionne sur le port 5000, il faut donc le préciser dans l’adresse du navigateur. Ce qui donne au final l'adresse http://localhost:5000/unepage pour accéder à la page /unepage de notre application.
Exécutez le code ci-dessous après avoir "décommenté" les deux dernières lignes. Allez à la page http://localhost:5000/. Pour quitter, il faut interrompre le kernel en cliquant sur kernel > interrupt.
from flask import Flask # pip install flask
app = Flask(__name__)
@app.route("/")
def hello():
return "Hello World!"
# if __name__ == "__main__":
# app.run()
Ce code commence par importer le module Flask.
from flask import Flask
On donne ensuite un nom à l'application ici ce sera app
app = Flask(__name__)
Ensuite vient la partie cruciale : définir une page (ou route) avec flask
@app.route permet de préciser à quelle adresse ce qui suit va s'appliquer.
Ici comme on est sur la page d'accueil, on met juste ("/")
Ensuite vient la fonction hello() qui va s'éxécuter sur la page "/". On dit simplement que quand on arrive sur la page définie par la route juste au dessus, on va en même temps appeler la fonction hello().
Ici ça va donc afficher "Hello World" quand on arrive sur la page "/".
def hello():
return "Hello World!"
Cette dernière partie permet juste de faire en sorte que l'application se lance quand on lance le code dans la console ou le terminal.
if __name__ == "__main__" and "get_ipython" not in locals(): # ne pas exécuter dans un notebook
app.run()
Remplacez "Hello World !"
par "ce que vous voulez"
et affichez ce nouveau texte dans la page hébergée en local.
Là il faut vous armer un peu de patience. Car le problème de Flask, c'est qu'on ne peut pas tout exécuter dans un notebook (le CSS, les templates, etc.) On va devoir repasser par Python Spyder (ou n'importe quel éditeur de texte comme Sublime Text par exemple) et la ligne de commande. Mais pas de panique, on y va pas à pas.
Déjà, les exemples sont disponibles dans le fichier flask_complet.zip. Pour chaque élément que nous regarderons il y aura un dossier correspondant.
Sublimetex
L'éditeur le plus utilisé par les développeurs web : Sublime Text. L'intérêt principal : pouvoir ouvrir dans un même éditeur de texte, des fichiers avec des langages différents (HTML, CSS, python), très pratique quand on code une application web. Et c'est codé en python ;)
Vous pouvez télécharger Sublime Text 3 (il s'agit en théorie encore d'une version bêta, mais elle fonctionne très bien). Pour les sessions ENSAE, prenez la version portable.
Console
Pour ouvrir une invite de commandes :
La console permettra de lancer les .py et exécutera le script qui lancera l'application.
Prenez le code hello_world.py
Ouvrir la console et taper "python xxxxxxxx/hello_world.py"
(en remplacant les x par le chemin de votre fichier hello.py
, par exemple C:/Téléchargements
ou C:/Bureau/Python/
)
Ouvrir une page du navigateur et aller à l'adresse http://localhost:5000.
Vous devriez voir une page avec le texte "Hello World" en haut à gauche : si c'est le cas, bravo ! Vous venez de créer la première page de votre future application.
from pyquickhelper.helpgen import NbImage
NbImage("simple_hello.png")
Pour l'instant, la page est assez austère, c'est normal, on n'a pas encore défini l'ensemble des styles qui iront avec cette page. Pour cela, il faut commencer par réaliser une structure de dossiers que flask comprend.
En gros, on va indiquer à Flask des templates de pages et des styles prédéfinis pour l'application.
En ouvrant le dossier hello_color
vous trouverez 3 éléments :
hello_world_green.py
static
qui contient la feuille de style main.css
templates
qui contient une page home.html
La structure du dossier et le nom des dossiers static
et templates
sont importants : Flask sait que c'est dans ces dossiers là qu'il doit aller chercher les éléments qui l'intéressent. Si vous lancez l'application à partir de la console vous verrez qu'à présent le texte est en vert ! C'est parce qu'on a défini les styles de la page. On va passer chaque élément en détail pour bien comprendre comment ça marche.
NbImage("green_hello.png")
Par rapport au précédent hello_world.py
, on a modifié quelques éléments. On importe la méthode render_template
qui va permettre de faire le lien entre le .py et la page html prédéfinie.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from flask import Flask, render_template
app = Flask(__name__)
@app.route("/")
def hello():
return render_template("home.html", message = "Hello World!")
#if __name__ == "__main__":
# app.run()
Ici, au lieu de renvoyer le texte directement, on demande d'injecter dans le template de la page home le message Hello World
.
Dans ces lignes, il y a deux éléments importants :
L'appel au css se fait dans la balise <link>
où on indique le chemin pour accéder à la feuille de style. On intègre ce qui est envoyé grâce au caractère {{ }}
ici on aura donc le message "Hello World"
qui sera affiché avec un type h1
.
Justement le h1
dans le css, on lui dit à quoi il doit ressembler. On va lui donner une couleur verte et le centrer.
Changez le texte de la variable message, passez le en rouge, texte aligné à gauche, police 1em.
Pour que le style s'actualise, il faut :
static/main.css
Si vous voulez tester d'autres styles...
Pour l'instant, on a vu comment faire une page simple, maintenant on va en faire deux et comment passer de l'une à l'autre. Pour cela, ouvrez le dossier multiple_pages. Par rapport à l'exemple précédent, on a ajouté 1 template html 'page_suivante.html'
et modifié légèrement le code .py ainsi que la page home.html
.
NbImage("2_pages.png")
Regardons tout ça en détail.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from flask import Flask, render_template
app = Flask(__name__)
@app.route("/")
def hello():
return render_template("home.html", message_bienvenue="Bienvenue sur la page d'accueil !")
@app.route("/next")
def suite():
return render_template("page_suivante.html")
#if __name__ == "__main__":
# app.run()
Par rapport à l'exemple précédent, on a ajouté une route et une nouvelle fonction. La nouvelle route est celle d'une deuxième page à qui on applique le template html "page_suivante"
. Dans cet exemple, on n'injecte rien depuis python dans la page.
La page d'accueil a été légèrement enrichie d'une ligne pour accéder à la deuxième page.
On inclut un lien dans une balise a un peu passe-partout. Le href
est une balise qui permet de mettre des liens et pour indiquer à flask à quelle page il doit se rendre en cliquant sur le lien il faut lui donner le nom de la fonction définie pour la page (pas la route !) Dans l'exemple on donne indique bien url_for('suite')
et non pas url_for('next')
.
Elle ressemble beaucoup à la page home.html
sauf qu'on n'a pas mis d'élément entre {{}}
. Et le lien présent dans cette page renvoie vers la page d'accueil.
A présent, on va voir comment on peut remplir un formulaire (dans notre cas, renseigner son nom dans une box). Dans le dossier "login"
, on a comme d'habitude, le .py, les templates html et le style css.
NbImage("login.png")
Cette fois-ci on commence par regarder la page html : on voit apparaitre un nouvel élément le "form"
:
Ici on va se concentrer sur la fonction text_box
. Nous aimerions récupérer le message envoyé par l'utilisateur et le lui afficher. Pour récupérer les informations envoyées par l'utilisateur, on va importer une nouvelle méthode de flask, la méthode request
.
Pour cela, il faut utiliser la méthode "form"
de l'objet request
, qui contient toutes les données du formulaire envoyé en POST. La méthode form est un dictionnaire qui associe la valeur à l'attribut name du champ du formulaire. En l'occurence, l'attribut name du champ texte vaut "text"
. Pour récupérer son contenu il faudra donc faire request.form['text']
.
Et voilà !
Ensuite on réutilise ce qu'il a entré pour l'injecter dans une page de bienvenue.
from flask import Flask, request, render_template
app = Flask(__name__)
@app.route('/')
def home():
return render_template("home.html")
@app.route('/', methods=['POST'])
def text_box():
text = request.form['text']
processed_text = text.upper()
return render_template("bienvenue.html" , message = processed_text )
#if __name__ == '__main__':
# app.run()
Voilà pour la base de ce qui se passe quand on utilise le framework Flask. C'est une très très courte introduction et si souhaitez approfondir vous pouvez suivre le très bon cours Openclassrooms https://openclassrooms.com/courses/creez-vos-applications-web-avec-flask/
En attendant, on va essayer de faire ensemble un questionnaire Pokemon ou Big Data, histoire d'avoir quelque chose qui fonctionne à la fin de la séance.
Pour cela, ouvrez le dossier pokemon_big_data
et lancer le code .py en ligne de commande pour voir ce que ça donne sur http://localhost:5000/.