En juillet 2024, j’ai commencé à apprendre la programmation Python à travers un projet concret.
L’objectif était de construire une API REST et le cas d’utilisation le plus courant est de construire une fonctionnalité CRUD avec un échange JSON.
Comment une application Python utilisant Flask gère-t-elle les requêtes avec des données JSON et comment les analyser ?
C’est l’objectif de cet article.
Analyse des données d’entrée d’une requête avec Flask
Pour lire le contenu d’une requête POST
dans Flask (la version 3 s’applique dans l’exemple ci-dessous), vous pouvez utiliser la méthode request.get_json()
. Voici un exemple de base :
|
|
Le code effectue les opérations suivantes:
- Il importe les modules nécessaires.
- Il crée une application Flask.
- Il définit une route qui accepte les requêtes POST.
- Il utilise
request.get_json()
pour analyser la charge utile JSON. - Il renvoyer une réponse avec les données reçues.
Quelques points importants :
- Assurez-vous que le client envoie les données avec le bon en-tête
Content-Type
(généralementapplication/json
). - Si les données ne sont pas au format JSON, vous devrez peut-être utiliser
request.data
ourequest.form
en fonction du type de contenu. - Pour les données de formulaire, utilisez
request.form
pour accéder aux champs de formulaire. - Pour les données brutes, utilisez
request.data
pour obtenir la chaîne d’octets.
Le type de données renvoyé par get_json()
La méthode request.get_json()
de Flask renvoie un dictionnaire Python (ou liste de paires clé/valeur) contenant les données JSON analysées dans le corps de la requête. Voici quelques points clés de son fonctionnement :
- Si la requête contient des données JSON valides, elle renvoie l’objet Python analysé.
- Si vous fournissez un corps de requête vide, il retourne
None
par défaut. - Si vous fournissez des données JSON invalides, il lève une exception
werkzeug.exceptions.BadRequest
. - Il peut gérer des structures imbriquées, convertissant les objets JSON en dictionnaires Python et les tableaux JSON en listes Python.
- La méthode a des paramètres optionnels :
force
: Si elle vautTrue
, elle essaiera d’analyser les données en tant que JSON même si lemime-type
n’est pasapplication/json
.silent
: SiTrue
, il retourneraNone
au lieu de lever une exception pour JSON invalide.
Voici un exemple simple pour illustrer :
|
|
Dans cet exemple, si vous envoyez une requête POST avec le JSON suivant {"name" : "Alice", "age" : 30}
, la variable data
contiendra le dictionnaire Python {'name' : 'Alice', 'age' : 30}
.
Comment analyser la charge utile JSON vers une classe DTO
Il existe plusieurs méthodes :
Avec une bibliothèque
Pour analyser la charge utile JSON en une classe DTO (« Data Transfer Object ») dans Flask, vous pouvez utiliser une bibliothèque comme Pydantic ou Marshmallow. Je vais vous montrer comment le faire en utilisant Pydantic, qui convient particulièrement à cette tâche en raison de sa simplicité et de son intégration avec les indices de type.
Voici un exemple étape par étape :
-
Tout d’abord, installez Pydantic :
1
pip install pydantic
-
Définissez votre classe DTO en utilisant Pydantic :
1 2 3 4 5 6
from pydantic import BaseModel class UserDTO(BaseModel): name: str age: int email: str | None = None # champ optionnel
-
Utilisez ce DTO dans votre route Flask :
|
|
Ce code permet d’effectuer les opérations suivantes :
- Il définit une classe
UserDTO
qui hérite duBaseModel
de Pydantic. - Il récupère les données JSON en utilisant
request.get_json()
. - Il crée une instance
UserDTO
en analysant les données JSON dans le constructeur. - Si les données sont valides, il renvoie un message de succès avec les données de l’utilisateur.
- Si les données ne sont pas valides (par exemple, champs obligatoires manquants ou mauvais types), il attrape le
ValidationError
et renvoie les erreurs de validation.
Vous pouvez également ajouter une validation plus complexe ou des valeurs par défaut à votre DTO :
|
|
Cette méthode ajoute la validation de la longueur du nom, la validation de l’intervalle de l’âge, et utilise EmailStr
pour la validation de l’email.
Je peux vous dire que c’est attrayant quand vous verrez la méthode suivante et que vous pensez à la maintenabilité de votre code…
Sans bibliothèque
Vous pouvez analyser des données JSON dans une classe DTO en utilisant les fonctionnalités intégrées de Python. Voici comment procéder :
-
Tout d’abord, définissez votre classe DTO :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
class UserDTO: def __init__(self, name: str, age: int, email: str | None = None): self.name = name self.age = age self.email = email # Lit les données JSON et assigne les propriétés de la classe @classmethod def from_dict(cls, data: dict): return cls( name=data.get('name'), age=data.get('age'), email=data.get('email') ) # Transforme une instance de la classe en dictionnaire avec la structure JSON appropriée def to_dict(self): return { 'name': self.name, 'age': self.age, 'email': self.email }
-
Maintenant, utilisez ce DTO dans votre route Flask :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
from flask import Flask, request, jsonify app = Flask(__name__) @app.route('/user', methods=['POST']) def create_user(): user_data = request.get_json() if not user_data: return jsonify({"error": "No data provided"}), 400 try: user = UserDTO.from_dict(user_data) # Exécutons une validation simple if not user.name or not isinstance(user.name, str): raise ValueError("Invalid name") if not isinstance(user.age, int) or user.age < 0: raise ValueError("Invalid age") if user.email is not None and not isinstance(user.email, str): raise ValueError("Invalid email") # Sauvegardons les données... # Retournons la réponse return jsonify({"message": "User created", "user": user.to_dict()}), 201 except ValueError as e: return jsonify({"error": str(e)}), 400 if __name__ == '__main__': app.run(debug=True)
Voici l’explication, étape par étape, du code ci-dessus :
- Il définit une classe
UserDTO
avec un constructeur et des méthodes pour créer une instance à partir d’un dictionnaire (from_dict
) et pour convertir une instance en dictionnaire (to_dict
). - Il obtient les données JSON en utilisant
request.get_json()
. - Il crée une instance
UserDTO
en utilisant la méthode de la classefrom_dict
. - Il effectue une validation de base plutôt manuelle. Vous pouvez ajouter une validation plus complexe si nécessaire.
- Si les données sont valides, il renvoie un message de succès avec les données de l’utilisateur.
- Si les données ne sont pas valides, il attrape le
ValueError
et renvoie un message d’erreur.
Cette méthode nécessite plus de codage manuel que l’utilisation de Pydantic, en particulier pour la validation.
Cependant, elle vous donne un contrôle total sur le processus et ne nécessite pas de bibliothèques supplémentaires.
Conclusion
Gardez à l’esprit que cette introduction rapide ne couvre pas tous les cas de figure, mais c’est ainsi que j’ai commencé à coder mon API REST avec Python l’année dernière. Pour un environnement de production, vous voudrez peut-être ajouter une gestion des erreurs et une validation plus robustes.
Est-ce que cela peut être maintenu sur de grandes applications ? Peut-être pas… J’en reparlerai au fur et à mesure que j’avancerai dans la programmation Python.
En attendant, pour en savoir plus sur Python, utilisez le tag en bas de page pour lire mes autres articles ⬇️
Suivez-moi !
Merci d’avoir lu cet article. Assurez-vous de me suivre sur X, de vous abonner à ma publication Substack et d’ajouter mon blog à vos favoris pour ne pas manquer les prochains articles.