Python + Flask + PythonAnywhere : Partie 4 - FlaskR démo

Cet article fait suite au précédent article "Python + Flask + PythonAnywhere : Partie 3 - Flask sous Windows"

Cette série d'articles se penche sur:
  • L'évaluation d'un projet web basé sur le Micro FrameWork Flask écrit en Python.
  • Préparation d'un environnement sous Windows (Python et Flask)
  • Mise-en-ligne et configuration du projet chez l'hébergeur PythonAnywhere.com (qui fait de l'hébergement autour de Python).
Introduction
FlaskR est issus des tutoriels de la documentation officiel de Flask.
Fonctionnement FlaskR
(désolé pour les fautes, je n'avais pas prévu d'écrire des articles)
Déjà chez l'hébergeur pythonAnywhere
Ce tutoriel est vraiment bien réalisé, vous guide étape par étape à la découverte des fonctionnalités de Flask... c'est un plaisir.
Les 3 à 4 heures passées à lire et essayer les bouts de code (coder est plus efficace qu'un copier/coller) représente un investissement très intéressant.

Avec ce tutoriel, vous pourrez:
  • Réaliser une interface de saisie "protégée" par un login. Le procédé est simple mais efficace.
  • Enregistrant les information dans une DB sqlite3 (un fichier DB, ne nécessite pas l'installation d'une base de donnée tels que MySql ou autre).
  • Utiliser le moteur de template
  • Faire du routage de requête
  • Utiliser les cookies (et session)
Ecran de login

Ecran de saisie + affichage de message "Flash".


Je vous recommande donc chaudement  de passer par la page du  Tutoriel de la documentation Flask, cela vaut largement le détour.

Allons droit au but
Je conçois cependant que le but de cet série d'article n'est pas de refaire le tutoriel de FlaskR mais plutôt de le mettre en oeuvre.
Nous allons donc prendre un raccourcis en installant directement les sources et le fichier DB sqLite3.

Je vous expliquerais également comment recréer le fichier DB (tel que cela est prévu dans le tutoriel d'origine) car cela sera utile lors du déploiement sur pythonAnywhere.

Créons donc le répertoire blogr dans notre répertoire de travail (je sais, je me suis planté sur le nom du répertoire mais bon, ne cherchons pas les complications).

Saisissons les commandes suivantes sur la ligne de commande

cd c:\python\
mkdir blogr

Téléchargez ensuite le fichier blogr.zip mis à disposition sur le site de MCHobby.
Copiez les fichiers proposés dans l'archive dans le répertoire c:\python\blogr\

Au final, vous devez avoir une arborescence comme celle-ci...
Structure des fichiers et répertoires de FlaskR


Le chemin d'accès au fichier DB est important, veuillez donc à être scrupuleux sur les noms des fichiers et répertoires.

Démarrons FlaskR
Toujours à l'invite de commande, tapez les commandes suivantes

cd c:\python\blogr
python flaskr.py

FlaskR est démarré

Utilisons maintenant notre navigateur internet pour voir le résultat de FlaskR.
Utilisez l'URL http://127.0.0.1:5000

Démarrage de FlaskR (DB déjà initialisée)
Si vous voulez faire un peu joujou avec le projet, le login est admin et le mot de passe default comme indiqué dans le code de flaskr.py

sqlite3.OperationalError
Il est possible que vous rencontriez l'erreur suivante...
Erreur d'accès DB.
Attention le mode DEBUG est activé dans Flask

Si vous obtenez le message sqlite3.OperationalError: unable to open database file, c'est simplement qu'il n'est pas possible d'accéder au fichier DB.
Il y a quelques raisons plausibles à cela:
  • Le fichier n'existe pas (dans notre cas, il s'agit de c:\python\blogr\db\flaskr.db  )
  • Le fichier n'est pas accessible (où stocké à un autre emplacement)
  • Vous avez utiliser des caractères \ dans le chemin d'accès au lieu de caractères /
    Même sous Windows, le chemin d'accès doit absolument être encodé avec des /
  • Problème de droit d'accès (ce sera plutôt le cas sous Linux/Unix).
Notez que les erreurs sont également reportées dans la console de Flask où vous avez lancé votre script Python.
Les erreurs Flask sont également reportée dans la console :-)
Le message indique clairement "unable to open the database file"
Pour corriger ce petit problème, ouvrez le fichier flaskr.py et modifiez la ligne commençant par "DATABASE ="
Flaskr.py  -  déclaration de l'emplacement du fichier DB

Organisation des répertoires
Le point suivant est relativement important... les répertoires static et templates faisant partie des rares spécifications de Flask. Le répertoire db devant aussi faire l'objet de quelques attentions.

c:\python\blogr\

Répertoire racine du projet.
Ce dernier contient le script flaskr.py (le programme) ainsi que flaskr_test.py (unit testing du programme).

c:\python\blogr\static\


Ce dernier est destiné à recevoir les fichiers qui ne changent pas dans le temps et qui peuvent être desservi directement par le Serveur Web sans passer par Flask.
Ce dernier sera configuré lors de la publication sur pythonAnywhere (il ne faut donc pas le négliger)

Ce répertoire, sa position et son nom sont figés par les conventions Flask.

Répertoire "static" pour les fichiers statiques.

Ce répertoire contiendra, par exemple, des feuilles de styles (css), des images et des ressources (fichiers PDF statique, fichiers textes) qui ne changent pas.
Les fichiers HTML template ne sont pas stockés dans ce répertoire (voyez ci-dessous).

c:\python\blogr\templates\
La position de ce répertoire et son nom sont également fixés par convention. C'est là que Flask ira trouver son fichier lorsque le code exécute une instruction telle que:

return render_template( 'show_entries.html', entries = entries )

Vous trouverez donc vos templates (patron/modèles) dans ce répertoire.

Répertoire des "templates" Flask.
Les templates sont des fichiers HTML contenant des instructions interprétées par le moteur de template Jinja2 de Flask.
show_entries.htlm - Exemple de Template Flask.

Les utilisateurs de PHP et DJango connaissent bien ce procédé très puissant (lisez le tutoriel de la documentation Flask pour en savoir plus)

c:\python\blogr\db\
Ce répertoire est une entorse aux conventions usuelles de développement WEB... mais cela aura au moins permit de démarrer le projet très rapidement sur votre machine :-)
Base de donnée sqlite3 et le schéma
Nous trouvons dans ce répertoire le fichier flaskr.db pré-initialisé. Cette base de donnée contient déjà quelques données.
J'ai également placé le fichier schema.sql dans ce répertoire. Ce fichier contient la définition du schéma de la base de donnée et permettrait ainsi d'en recréer un nouvelle base de donnée totalement vierge... mais nous y reviendrons un peu plus loin.

Note:
Par convention, on ne place pas la DB, ni la description de son schéma dans les sources du programme (au même niveau que les fichiers HTML ou les sources à exécuter). Si un petit malin arrivait à y avoir accès (ex: mal sécurisé) ce n'est pas le programme ou les templates qu'il peut arriver à lire MAIS il pourrait connaître la structure des tables, voire même copier les données.
C'est comme laisser les plan d'une banque (et son fichier du personnel) en libre accès sur le Net.
Il est donc préférable de ne pas stocker de telles informations sur le site internet mais plutôt de les stocké dans un répertoire/serveur à part avec des droits d'accès restreint (et sévèrement contrôlé).

Récréer une DB vierge
Aborder ce point n'est pas anodin car nous voudrons disposer d'un DB vierge lorsque nous publierons notre projet chez l'hébergeur sur PythonAnywhere.
Autant savoir comment le faire sur notre ordinateur... nous apprendrons ensuite comment le faire directement chez l'hébergeur ce sera l'occasion de découvrir ses consoles.

Nous allons commencer par arrête le serveur web de développement (si ce dernier est en route). Pressez CTRL+C dans la console pour arrêter Flask.

cd c:\python\blogr\db\
del flaskr.db

Par la suite, un petit "dir" nous confirme bien que la db est effacée.
Effacer le fichier DB fournit avec l'archive flaskr.zip

Si l'on prête attention au code de flaskr.py, il est possible de retrouver la définition de la fonction init_db()

def connect_db():
  return sqlite3.connect( app.config['DATABASE'] )

def init_db():
  with closing( connect_db() ) as db:
    with app.open_resource( 'db/schema.sql', mode = 'r' ) as f:
      db.cursor().executescript( f.read() )
    db.commit()

La vocation de ce code est de recréer un fichier db à partie du schéma SQL (le fichier schema.sql).
Pour réaliser cette prouesse (qui n'en est pas une) il faut utiliser l'interpréteur python en mode interactif.... voici comment il faut faire.

Démarrer Python en mode interactif (depuis le bon répertoire!)
Comme vous pouvez le constater sur l'image ci-dessus, la première-chose que nous faisons, c'est nous rendre dans le répertoire c:\python\blogr .
Cette opération est important car nous allons saisir prochainement saisir une commande d'import.
Nous lançons ensuite l'interpréteur Python qui démarrera en mode interactif.

Invocation du code de création de la DB directement depuis Python en mode interactif

C'est maintenant que cela devient intéressant :-)
Nous commençons par taper la commande d'import

from flaskr import init_db

qui indique à l'interpréteur de charger le fichier flaskr.py et de mettre la fonction init_db() à notre disposition.

Ensuite, nous appelons la fonction init_db à l'aide de l'instruction

init_db()

Voilà!
La fonction init_db() est exécutée et recrée le ficher DB à partir de schema.sql...
Nous pouvons nous en assurer facilement en relançant le projet flaskr.py
commençons par sortir du mode interactif Python en tapant la commande

exit()

nous revenons à l'invite de commande ou nous pouvons re-démarrer flask_r.py

python flaskr.py

Redémarrage Flaskr.py

Assurons nous maintenant que le nettoyage est bien réaliser en faisant fureter notre navigateur à l'adresse http://127.0.0.1:5000
Nous pouvons constater que la DB sqlite3 est bien vide.
Voila, c'est fait.... (il va vraiment falloir que je fasse attention à mon orthographe!)


Ressources
Tous les articles de ce tutoriel
Ce tutoriel est divisé en plusieurs parties... vous pouvez y accéder facilement grâce au liens suivants: