TD n°2 : Déploiement§

Dans ce TD, nous allons voir comment publier notre application Flask sur un service d'hébergement gratuit.

Nous utiliserons https://www.pythonanywhere.com/.

1

Création d'un compte§

2

Chargement des fichiers§

3

Création de l'application§

4

Pour aller plus loin : MySQL§

La base de données Sqlite3 que nous utilisons est parfaite pour développer, mais pas pour un site en production.

Nous pouvons maintenant modifier le fichier Python pour qu'il utilise la base de données MySQL ; il suffit normalement d'importer mysql.connector, et de remplacer la chaîne de connexion à la base par :

cx =  mysql.connector.connect(
    user="LOGIN",
    password="MYSQL-PASSWD",
    host="LOGIN.mysql.pythonanywhere-services.com",
    database="LOGIN$ensembl"
)

Bien sûr, il n'est pas très judicieux de laisser ces informations dans le code Python. On préfère en général les stocker dans un fichier séparé, et lire ce fichier depuis le code python.

On peut même, dans ce fichier de configuration, autoriser deux types de configuration, Sqlite3 et MySQL, et améliorer le code Python pour qu'il utilise l'un ou l'autre système en fonction de la configuration. Ainsi, ce fichier sera le seul à différer entre votre environnement de développement (sur votre machine) et l'environnement de production (chez l'hébergeur).

Avertissement

Compatibilité Sqlite3 / MySQL

Les bibliothèques Sqlite3 et MySQL en Python sont globalement compatibles, car elles respectent le même standard DbAPI2.

Cela étant dit, chacune propose ses propres extensions du standard, donc selon la manière de coder, votre programme peut nécessiter des adaptations pour fonctionner avec MySQL.

Notamment, les fonctionalités suivantes de Sqlite3 ne sont pas standard :

  • exécution de requête directe depuis l'objet connexion :

    # n'écrivez pas
    c = cx.execute(query)
    # mais écrivez
    c = cx.cursor()
    c.execute(query)
    
  • résultat sous forme de dicionnaire :

    cx.row_factory = sqlite3.Row # pas supporté par MySQL
    

    Pour reproduire cette fonctionalité de manière standard, on peut par exemple passer par la fonction suivante :

    def fetchall_dict(c):
        """ Utilisez     fetchall_dict(c)
            au lieu de   c.fetchall()
            pour récupérer des dictionnaires au lieu de tuples.
        """
        col_names = [ d[0] for d in c.description ]
        for row in c.fetchall():
            yield dict(zip(col_names, row))
    
5