2A.eco - Débuter avec Flask

Links: notebook, html, PDF, python, slides, GitHub

Pour aller vite, Flask est un framework de développement web en Python. Il en existe d’autres, le plus connu d’entre eux est Django. Ce notebook la création d’un site web à usage principalement privé.

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

Comment ça marche ?

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 ici - github.com : c’est le nom du domaine - sdpython/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.

Première page internet avec Flask

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

Explication du code pas à pas

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 (“/”)

@app.route(« / »)

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

Exercice 1

Remplacez "Hello World !" par "ce que vous voulez" et affichez ce nouveau texte dans la page hébergée en local.

Deuxième page internet avec Flask - sans le notebook

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.

Les éléments nécessaires

Les codes .py exemples

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.

Les outils à manipuler

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 :

  • sous Windows, il faut chercher “cmd” dans l’outil de recherche
  • sous Mac, utilisez spotlight (raccourci Pomme + espace) et chercher console

La console permettra de lancer les .py et exécutera le script qui lancera l’application.

Lancer la première page

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")
../_images/TD2A_eco_debuter_flask_23_0.png

Ajouter un peu de style à la page

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
  • un dossier static qui contient la feuille de style main.css
  • un dossier 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")
../_images/TD2A_eco_debuter_flask_25_0.png

Le hello_world_green.py

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.

Le template home.html

Dans ces lignes, il y a deux éléments importants :

  • l’appel au css pour avoir le style
  • l’intégration de ce que python injecte dans la page

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.

<!doctype html> <html lang= »en »>

<head>
<link rel = »stylesheet » type= »text/css » href= »{{ url_for(“static”, filename=”main.css”) }} »

</head> <body>

<h1 > {{ message }} </h1>

</body>

</html>

Le main.css

Justement le h1 dans le css, on lui dit à quoi il doit ressembler. On va lui donner une couleur verte et le centrer.

h1 {
font-size: 2em; color: green; text-align: center;

}

Exercice 2

Changez le texte de la variable message, passez le en rouge, texte aligné à gauche, police 1em.

Pour que le style s’actualise, il faut :

Si vous voulez tester d’autres styles

Envoyer des informations

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")
../_images/TD2A_eco_debuter_flask_49_0.png

home.html

Cette fois-ci on commence par regarder la page html : on voit apparaitre un nouvel élément le "form" :

  • On indique POST pour dire qu’on va s’en servir pour que l’utilisateur puisse fournir des informations.
  • On indique aussi que ce qui sera donné est considéré comme un string
  • Pour l’expérience utilisateur, on précise aussi qu’il y a un bouton “OK” pour envoyer le formulaire

<!doctype html> <html lang= »en »>

<head>
<link rel = »stylesheet » type= »text/css » href= »{{ url_for(“static”, filename=”main.css”) }} »>

</head>

<body>

<h1>Indiquer votre nom</h1> <form action= ». » method= »POST »>

<input type= »text » name= »text »> <button type= »submit »>OK</button>

</form>

</body> </html>

login.py

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

Conclusion

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/.