Exemple d'utilisation d'un serveur Flask⚓︎
Réalisation d'une interface homme-machine pour utiliser l'algorithme de César⚓︎
Vous avez travaillé au début de l'année sur cet algorithme et l'avez implémenté en Python (la fonction est rappelée ci-dessous), nous allons voir comment réaliser une interface, pour utiliser cette fonction, dans un navigateur internet en lien avec un serveur accessible depuis un réseau local ou depuis le Web.
L'algorithme de César⚓︎
On rappelle la fonction cesar
mettant en œuvre la méthode de César pour crypter un texte :
🐍 Script Python | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
|
Voici deux exemples d'appels de cette fonction :
>>> cesar("Bonjour tout le monde", 10)
LyxtyEB DyED vo wyxno
>>> cesar("LyxtyEB DyED vo wyxno", -10)
Bonjour tout le monde
Création de la page HTML et du formulaire⚓︎
On crée le répertoire Serveur avec l'arborescence suivante :
Le fichier formulaire.html
est le suivant :
HTML | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
|
Voici le rendu :
Mise en route du serveur Flask⚓︎
Pour permettre la communication entre la page HTML (formulaire.html
) et la fonction Python (cesar
), nous allons mettre en route un serveur Flask. Flask est un framework de développement web en Python.
- Dans le répertoire
Serveur
, créer le fichierindex.py
suivant :
🐍 Script Python | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
- Exécuter ce fichier à partir d'un terminal :
- Saisir l'adresse suivante dans votre navigateur : http://serveur-pgdg.net:5000/ pour un premier aperçu (vous indiquerez le numéro du port qui vous a été attribué).
Interaction Formulaire - Serveur⚓︎
Nous allons utiliser un formulaire de type POST
pour transmettre les données du formulaire au serveur.
- Ajouter le paramètre
method = "POST
à la baliseform
du fichierformulaire.html
.
Ajouter également l'adresse du serveur à suivre pour traiter ce formulaire à l'aide du paramètre action = "/crypter/"
(cette adresse sera définie par la suite dans le fichier index.py
) :
HTML | |
---|---|
13 14 15 |
|
textarea
et input
les paramètres name = "texte"
et name = "cle"
. Le type de la balise button
est type = "submit"
.
Le serveur est maintenant prêt à recevoir les données du formulaire. Il reste à mettre en place la "route" vers l'adresse "/crypter/
" du serveur.
Traitement des données du formulaire⚓︎
On suppose maintenant que la fonction cesar
est codée dans un fichier nommé fonctions.py
qui se trouve dans à la racine du répertoire Serveur
.
- Ajouter ou modifier les lignes suivantes au fichier
index.py
déjà créé :
# On ajoute l'import de la méthode request
from flask import Flask, render_template, request
from fonctions import cesar
...
@app.route("/crypter/", methods = ['POST'])
def crypter():
texte = request.form['texte']
cle = int(request.form['cle'])
return cesar(texte, cle)
...
- Arrêter le serveur lancé précédemment par Ctrl+C (dans le terminal) puis le redémarrer. Après avoir rechargé la page et cliqué sur le bouton, on constate le fonctionnement et l'affichage du résultat dans une page vide comme ci-dessous :
Affichage du résultat dans une page HTML⚓︎
-
On crée une page
affichage.html
, dans le répertoiretemplates
sur le modèle de la pageformulaire.html
. -
On modifie la fonction
crypter
dans le fichierindex.py
ainsi :🐍 Script Pythondef crypter(): texte = request.form['texte'] cle = int(request.form['cle']) return render_template("affichage.html", texte = cesar(texte, cle))
-
On intègre ce qui est envoyé par le codage
{{ texte }}
. Ici on aura le texte crypté dans une balise<h2>
HTML 1 2 3 4 5 6 7 8 9 10 11 12 13
<!DOCTYPE html> <html> <head> <title>Ma première page dynamique avec Flask</title> <meta charset = UTF-8"/> <link rel = "stylesheet" href = "/static/style.css"/> </head> <body style = "background-color:lightgray ;"> <h1>Codage avec la méthode de César</h1> <h2>{{ texte }}</h2><br> <input type = "button" onclick = "javascript:location.href = '/'" value = "Retour"/> </body> </html>
Intégration de CSS et Javascript⚓︎
On peut intégrer des feuilles style CSS et des scripts Javascript. Les fichiers contenant le code doivent se trouver dans un répertoire nommé static
:
<head>
du code HTML :
...
<head>
<link rel = "stylesheet" href = "/static/style.css"/>
<script src = "/static/scripts.js"></script>
</head>
...
Compléments⚓︎
Afficher le résultats dans la même page⚓︎
On peut vouloir ajouter un bouton radio
à la page formulaire.html
afin de choisir de crypter ou de décrypter votre message.
- On ajoute (ou modifie) les lignes suivantes au fichier
formulaire.html
:
HTML | |
---|---|
20 21 22 23 |
|
- Il faut maintenant modifier le fichier
index.py
et la route/crypter/
afin de tenir compte de ce nouveau paramètre :
🐍 Script Python | |
---|---|
17 18 |
|
On peut également afficher le résultat dans la page formulaire.html
et ne plus avoir recours à la page affichage.html
et donc à la route /cryper/
:
- Modification du fichier
index.py
:
🐍 Script Python | |
---|---|
9 10 11 12 13 14 15 16 17 18 19 20 21 |
|
- Modification du formulaire pour intégrer le message crypté :
<form action = "/" method = "POST">
...
<br><br>
<h2>Message codé : </h2>{{ phrase_crypte }}
Ajouter de l'interaction dynamique avec Javascript⚓︎
On voudrait maintenant que le codage se fasse "à la volée", sans avoir à cliquer sur le bouton pour voir apparaître le message crypté. Il faudra ajouter un script Javascript qui va en temps réel analyser les contenus du formulaire et interroger le serveur Flask pour calculer le message à afficher. Nous allons commencer par créer le fichier static/scripts.js
:
...
<head>
<link href = "/static/style.css" rel = "stylesheet" type = "text/css" />
<script src = "/static/scripts.js"></script>
</head>
...
id = "texte"
et id = "texte_crypte"
, respectivement, aux balises dans laquelle le texte est saisie et dans laquelle le texte est affiché, le code suivant, permet d'afficher de l'afficher à la volée :
// On déclenche un événement si on relâche une touche du clavier
document.addEventListener("keyup", cryptage);
// On déclenche un événement si on clique quelque part
document.addEventListener("click", cryptage);
// Fonction appelée lorsqu'un événement est détecté sur la page
function cryptage() {
// on définit les valeurs des paramètres à envoyer au serveur et la méthode GET ou POST
const data = {
method: "POST",
// Les données sont récupérées dans la page
body: new URLSearchParams({
texte: document.getElementById('texte').value,
cle: document.getElementById('cle').value,
mode: document.querySelector('input[name = bouton]:checked').value,
})
};
// Voici la méthode permettant l'échange de données avec le serveur (allé et retour)
// data est défini juste au dessus et contient notamment "texte" "cle" et "mode"
fetch("/", data)
.then(
// Attente d'une réponse du serveur sous forme d'un object JSON (équivalent du dictionnaire en python)
// le nom de la variable "promesse" n'a pas d'importance
promesse => promesse.json()
)
.then(
// Traitement de la réponse du serveur
// le nom de la variable "reponse" n'a pas d'importance
reponse => document.getElementById('texte_crypte').textContent = reponse["texte_crypte"]
)
.catch(
// On peut gérer l'erreur si tel est le cas (par exemple si le champs clé est vide)
error => alert("Erreur : " + error)
);
}
# On ajoute l'import de la méthode request
from flask import Flask, render_template, request, jsonify
from fonctions import cesar
# On cré une instance de la classe Flask : un serveur web
app = Flask(__name__)
# On décrit la route par défaut du serveur (racine du serveur)
@app.route("/", methods = ['POST', 'GET'])
def index():
if request.method == 'POST':
return jsonify({"texte_crypte" : crypter()})
else:
return render_template("formulaire.html")
def crypter():
texte = request.form['texte']
cle = int(request.form['cle'])
if request.form['mode'] == 'decrypter':
cle = - cle
return cesar(texte, cle)
if __name__ == "__main__":
# Lancement du serveur
app.run(debug = True) # Mode debug pour commencer
Et le code HTML :
<!DOCTYPE html>
<html lang="fr">
<head>
<title>Ma première page dynamique avec Flask</title>
<meta charset = "UTF-8"/>
<link rel="stylesheet" href="/static/style.css"/>
<script src = "/static/scripts.js"></script>
</head>
<body>
<h1>Codage avec la méthode de César</h1>
<h2>Saisir ci-dessous le texte à crypter : </h2>
<textarea rows = 4 cols = 60 id = "texte">Le texte n a ni caractere de ponctuation ni caractere speciaux mais eventuellement des espaces et des MAJUSCULES</textarea> <br>
<p>Choisir une clé de cryptage : </p>
<input type = "number" id = "cle" value="15" min="0" max="26">
<p>
<input type = "radio" name = "bouton" value = "crypter" checked> Crypter<br>
<input type = "radio" name = "bouton" value = "decrypter"> Décrypter
</p>
<br><br>
<h2>Texte crypté : </h2>
<h3 id = "texte_crypte"></h3>
</body>
</html>