TP – Créer un service web REST avec Flask ========================================= Durée : 5 heures Niveau : BTS SIO 1re année (SISR/SLAM, initiation au développement web et API) ---------------------------------------------------------------------------------- 1) Objectif pédagogique ---------------------------------------------------------------------------------- Écrire un service web en Python avec Flask qui : 1) expose une API REST (GET/POST/PUT/DELETE), 2) gère des données simples (liste de tâches ou "tickets"), 3) retourne des réponses JSON avec codes HTTP appropriés, 4) permet d’afficher un résumé et de tester avec curl/Postman. ---------------------------------------------------------------------------------- 2) Exigences techniques ---------------------------------------------------------------------------------- - Utiliser obligatoirement un environnement virtuel : python-venv - Bibliothèques Python : • Flask • python-dotenv (gestion configuration locale) (Option) pydantic ou marshmallow pour la validation (Option) SQLAlchemy pour persistance SQLite - Aucun secret (mot de passe, clé) ne doit apparaître dans le code source. ---------------------------------------------------------------------------------- 3) Pré-requis côté plateforme ---------------------------------------------------------------------------------- - Poste Debian 13 avec python3, venv et pip installés. - Connexion réseau pour tester les requêtes (localhost). ---------------------------------------------------------------------------------- 4) Mise en place de l’environnement ---------------------------------------------------------------------------------- 1) Créer le projet et le venv : $ mkdir tp-flask-api && cd tp-flask-api $ python3 -m venv .venv $ source .venv/bin/activate 2) Installer les bibliothèques : (.venv) $ python -m pip install --upgrade pip (.venv) $ pip install Flask python-dotenv 3) Créer un fichier .env : FLASK_ENV=development FLASK_DEBUG=1 PORT=5000 ---------------------------------------------------------------------------------- 5) Spécification fonctionnelle (sans code) ---------------------------------------------------------------------------------- Nom du script : app.py Ressource : "tâches" (ou "tickets") avec attributs : - id (entier unique) - title (string, requis) - done (booléen, par défaut false) - created_at (date/heure ISO) - priority (entier 1–5, optionnel) Endpoints requis : 1. GET /api/tasks → liste des tâches • Query params optionnels : done=true|false, limit, offset • Retour JSON, code 200 2. GET /api/tasks/ → détail d’une tâche • Retour JSON, code 200 ou 404 si non trouvée 3. POST /api/tasks → création • Entrée JSON : { "title": "...", "priority": 3 } • Retour JSON avec id, created_at, done=false • Code 201 si créé, 400 si invalide 4. PUT /api/tasks/ → mise à jour • Entrée JSON : champs modifiables (title, done, priority) • Code 200 si ok, 400 si invalide, 404 si introuvable 5. DELETE /api/tasks/ → suppression • Code 204 si supprimée, 404 sinon 6. GET /health → vérification de service • Retour JSON { "status": "ok" }, code 200 Validation : - title obligatoire et non vide - priority ∈ [1..5] - done booléen ---------------------------------------------------------------------------------- 6) Plan de travail (5h) ---------------------------------------------------------------------------------- - (45 min) Mise en place de Flask et endpoint /health - (60 min) Modèle en mémoire + endpoints GET - (60 min) POST création et PUT mise à jour (validation, erreurs) - (45 min) DELETE suppression et gestion des erreurs globales - (30 min) Tests avec curl/Postman - (60 min) Bonus : persistance JSON/SQLite, validation stricte, pagination ---------------------------------------------------------------------------------- 7) Jeux de tests (exemples curl) ---------------------------------------------------------------------------------- - POST : créer une tâche curl -X POST http://localhost:5000/api/tasks -H "Content-Type: application/json" \ -d '{"title":"Installer Flask","priority":3}' - GET liste : curl http://localhost:5000/api/tasks - GET filtre : curl "http://localhost:5000/api/tasks?done=false&limit=2" - GET détail : curl http://localhost:5000/api/tasks/1 - PUT : curl -X PUT http://localhost:5000/api/tasks/1 -H "Content-Type: application/json" \ -d '{"done":true,"priority":5}' - DELETE : curl -X DELETE http://localhost:5000/api/tasks/1 -i - Health : curl http://localhost:5000/health ---------------------------------------------------------------------------------- 8) Livrables attendus ---------------------------------------------------------------------------------- 1) Code source (fichiers Python, requirements.txt) 2) README (≤ 1 page) : - commandes d’installation (venv + pip) - lancement du service - liste des endpoints et exemples curl 3) Capture d’écran de Postman/terminal montrant : - un POST réussi - un GET liste - un PUT ou DELETE - un cas d’erreur (400 ou 404) 4) (Optionnel) Fichier data.json ou base SQLite app.db ---------------------------------------------------------------------------------- 9) Barème (20 points) ---------------------------------------------------------------------------------- - Flask démarré + /health (2) - GET liste + GET détail (4) - POST création + validation (4) - PUT mise à jour + gestion erreurs (4) - DELETE suppression (2) - Réponses JSON propres + codes HTTP corrects (2) - README clair + tests (2) ---------------------------------------------------------------------------------- 10) Bonus (facultatif) ---------------------------------------------------------------------------------- - Persistance (fichier JSON ou SQLite avec SQLAlchemy) - Validation stricte (pydantic ou marshmallow) - Pagination, tri, filtres supplémentaires - Journalisation des requêtes avec timestamps - Tests automatiques (pytest) sur 2–3 endpoints ---------------------------------------------------------------------------------- 11) Dépannage rapide ---------------------------------------------------------------------------------- - Port occupé : changer PORT dans .env ou FLASK_RUN_PORT=5001 - CORS : installer flask-cors si besoin de test front web - JSON invalide : renvoyer 400 avec message clair - Lancer Flask sur 0.0.0.0 pour accès depuis un autre poste