2025-12-16 14:18:21 +01:00
2025-12-16 14:18:21 +01:00
2025-12-16 14:18:21 +01:00
2025-12-16 14:18:21 +01:00
2025-12-16 14:18:21 +01:00
2025-12-16 14:18:21 +01:00
2025-12-16 14:18:21 +01:00

TP : Galerie d'images (flask)

Informations générales

Cours : Python Avancé > Web > Flask
Objectifs pédagogiques :

  • Python avancé : framework Flask pour le développement web
  • Outils modernes (poetry, PyCharm)
  • Bonnes pratiques de l'entreprise

Prérequis

Installation et configuration de lenvironnement

Installer les dépendances avec poetry install depuis un terminal PyCharm.

Connaissances préalables

  • Connaissances de base en programmation

Énoncé

Contexte

L'objectif de ce TP Bonus est de développer une application web simple mais robuste avec le micro-framework Flask.

Vous êtes invité à lire les premières sections de la documentation officielle de Flask pour vous familiariser avec les concepts de base, avant de commencer le TP.

Cette application web affichera une galerie d'images à partir de fichiers stockés localement sur le serveur.

Les images étant fournies par le serveur avec différentes largeurs, cela permettra au client d'optimiser la performance réseau en fonction de la taille de l'image réelle à afficher côté client (navigateur).

Pour vous concentrer sur la logique métier et le fonctionnement de Flask, une partie significative du code vous est déjà fournie :

  • Les templates HTML (layout.html, gallery.html, 404.html) qui gèrent l'affichage.
  • Les fichiers statiques (CSS Bootstrap) pour le design, ainsi que les images statiques.
  • Un module utilitaire utils.py contenant une fonction build_image_structure qui analyse et structure les données du répertoire contenant les images.
  • Une suite de tests automatisés (test_app.py) qui vous permettra de valider votre travail au fur et à mesure.

Votre mission est de compléter le fichier src/app/views.py pour faire le lien entre les requêtes des utilisateurs, les données des images et les templates HTML.

Objectifs pédagogiques

À la fin de ce TP, vous saurez :

  • Créer et organiser des routes (vues) dans une application Flask à l'aide de Blueprints.
  • Faire le rendu de templates HTML en leur transmettant des données dynamiques (render_template).
  • Gérer les erreurs de manière élégante (try...except) pour rendre une application plus robuste.
  • Créer un premier endpoint d'API simple qui retourne des données au format JSON.
  • Utiliser une suite de tests (Pytest) pour guider et valider votre développement (approche TDD-lite).
  • Lancer et déboguer une application Flask localement.

Mise en place

Le projet utilise poetry pour la gestion des dépendances.

La structure du projet est la suivante :

.
├── poetry.lock
├── pyproject.toml
├── src
│   └── app
│       ├── __init__.py         # Point d'entrée de l'application
│       ├── static/             # Fichiers CSS, et images
│       ├── templates/          # Fichiers HTML (templates Jinja2)
│       ├── utils.py            # Fonctions utilitaires (fourni)
│       └── views.py            # Le fichier à compléter !
└── tests
    └── test_views.py           # Tests pour valider votre code (fourni)

Travail à réaliser

Ouvrez le fichier src/app/views.py. Il est actuellement presque vide. Vous allez le compléter étape par étape.

Étape 1 : afficher la galerie d'images

Votre premier objectif est de créer la vue principale qui affiche la galerie.

Tâche : Créez une fonction index() qui répond à la route / (la racine du site).

Logique à implémenter dans la fonction index() :

  1. Construisez le chemin vers le dossier contenant les images. Ce dossier se trouve dans static/images. Utilisez current_app.static_folder de Flask et la bibliothèque pathlib pour un code propre et portable.

  2. Appelez la fonction build_image_structure() (importée depuis .utils) en lui passant le chemin du dossier des images.

  3. Rendez votre code robuste ! Encadrez l'appel à cette fonction dans un bloc try...except. En cas d'erreur (par exemple, si le dossier n'existe pas ou si un autre problème survient), vous devez éviter que l'application ne plante.

    • En cas de succès, vous passez les données des images au template.

    • Si aucune image n'est trouvée par la fonction, prévoyez un message d'erreur à afficher.

    • En cas d'exception, logguez l'erreur et préparez un message d'erreur générique pour l'utilisateur.

  4. Faites le rendu du template gallery.html en utilisant render_template(). Vous devez lui passer deux variables :

    • structured_images: Le dictionnaire d'images retourné par build_image_structure.

    • error_message: Un message d'erreur (ou None si tout va bien).

Diagramme de flux (Étape 1) :

graph TD
    subgraph Client[Navigateur]
        A[Utilisateur]
    end
    subgraph Serveur[Serveur Flask]
        B["Route /"]
        C["views.py: index()"]
        D["utils.py: build_image_structure()"]
        E["templates/gallery.html"]
        F[Réponse HTML]
    end
    subgraph SystemeFichiers[Disque Serveur]
        G["static/images"]
    end

    A -- "1. Requête GET /" --> B
    B -- "2. Déclenche" --> C
    C -- "3. Construit chemin et appelle" --> D
    D -- "4. Lit le dossier" --> G
    G -- "5. Retourne la structure" --> D
    D -- "6. Retourne dict_images" --> C
    C -- "7. Injecte données dans" --> E
    E -- "8. Génère" --> F
    F -- "9. Envoie" --> A

Logique de gestion d'erreur (commune aux étapes 1 et 4) :

graph TD
    A[Début de la vue] --> B{try}
    B -- "Succès" --> C["Appel: build_image_structure()"]
    C --> D{Images trouvées?}
    D -- "Oui" --> E[Préparer réponse 200 OK - HTML ou JSON]
    D -- "Non" --> F[Préparer réponse - HTML avec erreur ou JSON 404]
    B -- "Échec" --> G[except Exception as e]
    G --> H[Logguer l'erreur e]
    H --> I[Préparer réponse - HTML avec erreur ou JSON 500]
    E --> Z[Fin]
    F --> Z[Fin]
    I --> Z[Fin]

Étape 2 : valider avec les tests

Avant même de regarder le résultat dans votre navigateur, vérifiez que votre code est correct en lançant la suite de tests.

poetry run pytest -p no:warnings

Analysez le résultat. Certains tests qui échouaient au début devraient maintenant passer. L'objectif est de faire passer tous les tests relatifs à la galerie.

Étape 3 : lancer le serveur et constater le résultat

Une fois les tests au vert, lancez le serveur de développement Flask.

  1. Assurez-vous d'être dans le bon dossier :

    cd src
    
  2. Lancez le serveur en mode "debug" (ce mode recharge automatiquement le serveur à chaque modification de votre code) :

    flask run --debug
    
  3. Ouvrez votre navigateur à l'adresse http://127.0.0.1:5000 et admirez votre galerie !

Étape 4 : créer un endpoint d'API JSON

Votre second objectif est de fournir les mêmes données via une API, au format JSON.

Tâche : Créez une fonction api_images() qui répond à la route /api/images.

Logique à implémenter :

  1. La logique de récupération des données est la même que pour la vue index() : chemin du dossier, appel à build_image_structure(), gestion des exceptions.

  2. La différence réside dans la réponse :

    • En cas de succès, retournez directement le dictionnaire structured_images. Flask le convertira automatiquement en une réponse JSON avec un code de statut 200 OK.

    • Si aucune image n'est trouvée, retournez un dictionnaire d'erreur (ex: {'error': "Aucune image n'a été trouvée"}) et le code de statut 404 Not Found.

    • En cas d'exception serveur, retournez un dictionnaire d'erreur (ex: {'error': "Erreur interne du serveur"}) et le code de statut 500 Internal Server Error.

Diagramme de flux (Étape 4) :

graph TD
    subgraph Client[Client API ex: Postman, script]
        A[Utilisateur/Service]
    end
    subgraph Serveur[Serveur Flask]
        B[Route /api/images]
        C["views.py: api_images()"]
        D["utils.py: build_image_structure()"]
        E[Réponse JSON]
    end
    subgraph SystemeFichiers[Disque Serveur]
        G["static/images"]
    end

    A -- "1. Requête GET /api/images" --> B
    B -- "2. Déclenche" --> C
    C -- "3. Construit chemin et appelle" --> D
    D -- "4. Lit le dossier" --> G
    G -- "5. Retourne la structure" --> D
    D -- "6. Retourne dict_images" --> C
    C -- "7. Formate en JSON" --> E
    E -- "8. Envoie" --> A

Étape 5 : ajouter un ou plusieurs tests pour l'API

Pour aller plus loin, ouvrez le fichier tests/test_app.py et ajoutez un ou plusieurs nouveaux tests pour votre API.

Idée de test : Créez une fonction test_api_images_success() qui :

  1. Fait un GET sur /api/images.

  2. Vérifie que le code de statut est bien 200.

  3. Vérifie que le content_type de la réponse est bien application/json.

  4. Vérifie que la réponse JSON contient des clés attendues (par exemple, le nom d'une des images).

Relancez les tests pour vous assurer que l'ancien et le nouveau code fonctionnent parfaitement.

Bonnes pratiques

  • La page d'accueil (/) s'affiche correctement avec les images. Les images téléchargées par le navigateur sont cohérentes avec la taille réelles des images à afficher.

  • La page gère correctement l'absence du dossier d'images sans planter, en affichant un message d'erreur.

  • L'endpoint /api/images retourne une structure JSON valide en cas de succès.

  • L'endpoint /api/images retourne les codes d'erreur HTTP et les messages appropriés (404, 500).

  • L'ensemble des tests fournis (et les vôtre) passent avec succès.

  • Le code dans views.py est clair, commenté et suit les bonnes pratiques Python.

Description
No description provided
Readme 170 MiB
Languages
Python 74.7%
HTML 25.3%