Aller au contenu

Gestion des données JSON

Mise à jour :

logo python

Le JSON (JavaScript Object Notation) est un format de données très populaire utilisé pour représenter des informations de manière simple et lisible. Il est couramment utilisé pour échanger des données entre un serveur et un client, notamment dans des applications web et des API. En Python, le module standard json permet de manipuler facilement ces fichiers JSON, qu’il s’agisse de les lire, de les modifier, ou de les créer.

Créer des données JSON dans un programme Python

Avant de manipuler des fichiers JSON ou d’interroger une API, il peut être utile de savoir comment créer des données au format JSON directement dans un programme Python. Le module standard json de Python permet de transformer facilement des structures de données Python (dictionnaires, listes, etc.) en texte formaté en JSON, ce qui peut ensuite être utilisé pour stocker des informations ou les envoyer vers d’autres systèmes.

Créer une structure de données JSON en Python

La première étape consiste à créer une structure de données Python que je souhaite convertir en JSON. En général, j’utilise des dictionnaires (dict) et des listes (list), car ces structures correspondent directement aux objets et tableaux JSON.

Exemple :

# Création d'un dictionnaire Python contenant des données
donnees = {
"nom": "Stéphane ROBERT",
"age": 29,
"adresse": {
"rue": "456 avenue des Champs",
"ville": "Lyon",
"code_postal": "69001"
},
"hobbies": ["photographie", "voyage", "musique"]
}
# Affichage du dictionnaire
print(donnees)

Ici, donnees est une structure de données Python qui contient plusieurs types de données : chaînes de caractères, nombres, dictionnaires imbriqués, et listes. Elle représente les informations d’un utilisateur, ce qui est idéal pour une conversion en JSON.

Convertir les données en JSON avec json.dumps

Pour transformer cette structure de données en une chaîne JSON, j’utilise la fonction json.dumps du module json. Cette fonction prend un objet Python et le convertit en une chaîne de caractères formatée en JSON, sans l’écrire dans un fichier.

import json
donnees = {
"nom": "Stéphane ROBERT",
"age": 29,
"adresse": {
"rue": "456 avenue des Champs",
"ville": "Lyon",
"code_postal": "69001"
},
"hobbies": ["photographie", "voyage", "musique"]
}
# Conversion en chaîne JSON
donnees_json = json.dumps(donnees, indent=4)
# Affichage de la chaîne JSON
print(donnees_json)

Dans cet exemple, indent=4 ajoute une indentation de 4 espaces pour rendre le JSON plus lisible. Cette chaîne JSON peut maintenant être affichée, enregistrée dans un fichier ou envoyée dans une requête réseau.

Enregistrer les données JSON dans un fichier

Pour créer un fichier contenant ces données au format JSON, j’utilise la fonction json.dump, qui écrit directement l’objet Python dans un fichier ouvert en mode écriture. Cela permet de sauvegarder les données pour une utilisation ultérieure ou pour les partager avec d’autres systèmes.

# Enregistrement des données JSON dans un fichier
with open('donnees_utilisateur.json', 'w') as fichier:
json.dump(donnees, fichier, indent=4)

Ce code crée un fichier donnees_utilisateur.json contenant les informations de l’utilisateur “Stéphane ROBERT” dans un format JSON propre et lisible. Le paramètre indent=4 est également utilisé ici pour organiser les données en lignes bien espacées, facilitant leur lecture.

Encodage des fichiers JSON en Python

Lors de la manipulation de fichiers JSON, il est essentiel de prêter attention à l’encodage, notamment pour garantir la bonne gestion des caractères spéciaux (accents, symboles, etc.). En Python, l’encodage UTF-8 est souvent privilégié, car il permet de représenter une large gamme de caractères internationaux, ce qui est particulièrement utile pour des langues comme le français.

Par défaut, les fonctions de lecture et d’écriture de fichiers en Python utilisent l’encodage du système, qui peut varier d’une machine à l’autre. Pour garantir une compatibilité maximale, je recommande d’utiliser explicitement UTF-8 lors de l’ouverture de fichiers JSON. Cela s’applique à la fois à json.load et json.dump pour lire et écrire les fichiers.

Lire un fichier JSON avec encodage UTF-8

Pour lire un fichier JSON en utilisant l’encodage UTF-8, je spécifie cet encodage lorsque j’ouvre le fichier en mode lecture ('r'). Voici un exemple :

import json
# Lecture d'un fichier JSON avec encodage UTF-8
with open('donnees_utilisateur.json', 'r', encoding='utf-8') as fichier:
donnees = json.load(fichier)
# Afficher les données pour vérifier le contenu
print(donnees)

En ajoutant encoding='utf-8', je m’assure que Python décode correctement tous les caractères spéciaux ou accentués présents dans le fichier JSON. Cela est particulièrement utile pour éviter les erreurs liées aux caractères non-ASCII.

Écrire un fichier JSON avec encodage UTF-8

De la même manière, lors de la création d’un fichier JSON avec des données contenant des caractères spéciaux, j’utilise l’encodage UTF-8 pour garantir que tous les caractères seront correctement représentés. Voici comment faire :

donnees = {
"nom": "Stéphane ROBERT",
"age": 29,
"adresse": {
"rue": "456 avenue des Champs",
"ville": "Lyon",
"code_postal": "69001"
}
}
# Écriture des données dans un fichier JSON avec encodage UTF-8
with open('donnees_utilisateur.json', 'w', encoding='utf-8') as fichier:
json.dump(donnees, fichier, indent=4, ensure_ascii=False)

L’argument ensure_ascii=False est ici essentiel : il indique à Python de ne pas transformer les caractères non-ASCII en séquences Unicode, ce qui permet d’obtenir un fichier JSON plus lisible, avec des caractères accentués et autres symboles spéciaux.

Voici une comparaison pour illustrer la différence avec et sans ensure_ascii :

  • Avec ensure_ascii=True (par défaut) :

    {"nom": "St\u00e9phane ROBERT", "age": 29}
  • Avec ensure_ascii=False :

    {"nom": "Stéphane ROBERT", "age": 29}

La deuxième version est bien plus lisible, surtout si le fichier doit être relu ou édité manuellement.

Différences entre json.dump et json.dumps, json.load et json.loads

En Python, le module json propose plusieurs fonctions pour manipuler les données JSON : json.dump et json.dumps pour écrire des données au format JSON, ainsi que json.load et json.loads pour les lire. Bien que leurs noms soient similaires, il existe des différences importantes dans leur utilisation. Voici un tour d’horizon pour bien comprendre quand et comment les utiliser.

Écriture des données : json.dump vs json.dumps

Les fonctions json.dump et json.dumps servent toutes deux à convertir des objets Python en JSON, mais elles ont des utilisations différentes en fonction de la destination de la sortie (fichier ou chaîne de caractères).

json.dump

La fonction json.dump est utilisée pour écrire un objet Python (comme un dictionnaire ou une liste) directement dans un fichier au format JSON. Elle prend un objet Python et un fichier ouvert en mode écriture ('w'), et elle se charge de l’encodage en JSON puis de l’enregistrement dans ce fichier.

Exemple :

import json
# Création d'un dictionnaire Python
donnees = {
"nom": "Stéphane ROBERT",
"age": 29,
"adresse": {
"rue": "456 avenue des Champs",
"ville": "Lyon",
"code_postal": "69001"
}
}
# Écriture des données dans un fichier JSON
with open('donnees_utilisateur.json', 'w', encoding='utf-8') as fichier:
json.dump(donnees, fichier, indent=4, ensure_ascii=False)

Avec json.dump, le fichier donnees_utilisateur.json contiendra les données du dictionnaire donnees en format JSON, avec une indentation de 4 espaces pour améliorer la lisibilité.

json.dumps

La fonction json.dumps (avec un “s” pour “string”) est utilisée pour convertir un objet Python en chaîne de caractères au format JSON, sans écrire directement dans un fichier. Cela peut être utile pour manipuler des données JSON en mémoire, les transmettre à une API ou les afficher.

Exemple :

import json
# Création d'un dictionnaire Python
donnees = {
"nom": "Stéphane ROBERT",
"age": 29,
"adresse": {
"rue": "456 avenue des Champs",
"ville": "Lyon",
"code_postal": "69001"
}
}
# Conversion en chaîne JSON
donnees_json = json.dumps(donnees, indent=4, ensure_ascii=False)
print(donnees_json)

Dans cet exemple, donnees_json est une chaîne de caractères contenant les données JSON, ce qui peut être pratique pour les afficher ou les utiliser dans une communication réseau.

Résumé :

  • json.dump : Écrit un objet Python directement dans un fichier JSON.
  • json.dumps : Convertit un objet Python en chaîne JSON sans écriture dans un fichier.

Lecture des données : json.load vs json.loads

De même, json.load et json.loads permettent toutes deux de lire des données JSON et de les convertir en objet Python, mais avec une différence d’usage liée à la source de ces données (fichier ou chaîne de caractères).

json.load

La fonction json.load est utilisée pour lire et décoder des données JSON directement depuis un fichier. Elle prend en entrée un fichier ouvert en mode lecture ('r'), lit les données JSON, puis retourne un objet Python (dictionnaire, liste, etc.) qui correspond au contenu JSON.

Exemple :

import json
# Lecture d'un fichier JSON
with open('donnees_utilisateur.json', 'r', encoding='utf-8') as fichier:
donnees = json.load(fichier)
print(donnees)

Dans cet exemple, donnees est un dictionnaire Python contenant les données du fichier donnees_utilisateur.json.

json.loads

La fonction json.loads (avec un “s” pour “string”) est utilisée pour convertir une chaîne de caractères JSON en objet Python. Elle est pratique pour traiter des données JSON reçues en tant que texte, par exemple depuis une API.

Exemple :

import json
# Chaîne JSON
texte_json = '''
{
"nom": "Stéphane ROBERT",
"age": 29,
"adresse": {
"rue": "456 avenue des Champs",
"ville": "Lyon",
"code_postal": "69001"
}
}
'''
# Conversion en objet Python
donnees = json.loads(texte_json)
print(donnees)

Dans cet exemple, donnees est un dictionnaire Python contenant les données de la chaîne texte_json.

Résumé :

  • json.load : Lit un fichier JSON et le convertit en objet Python.
  • json.loads : Convertit une chaîne de caractères JSON en objet Python.

Lecture d’une réponse JSON d’une API

Dans ce chapitre, je vais te montrer comment envoyer une requête à JSONPlaceholder, lire et manipuler la réponse JSON en Python.

JSONPlaceholder est une API publique de test qui fournit des données factices au format JSON. Elle est idéale pour expérimenter et comprendre comment interagir avec des API dans un programme Python. Nous allons utiliser la librairie requests, qui simplifie l’envoi de requêtes HTTP et la manipulation des réponses.

Installation de la librairie requests

Si la librairie requests n’est pas encore installée, tu peux l’ajouter en utilisant la commande suivante :

Terminal window
pip install requests

Envoyer une requête à JSONPlaceholder

JSONPlaceholder propose différentes ressources pour obtenir des données factices, comme /users pour des informations d’utilisateurs, /posts pour des articles, ou /comments pour des commentaires. Je vais interroger l’endpoint /users pour obtenir une liste de profils utilisateurs.

Voici comment envoyer une requête GET pour obtenir la liste des utilisateurs :

import requests
# Envoyer une requête GET pour obtenir les utilisateurs
reponse = requests.get('https://jsonplaceholder.typicode.com/users')
# Vérifier que la requête a réussi (code 200)
if reponse.status_code == 200:
print("Requête réussie !")
else:
print("Erreur lors de la requête :", reponse.status_code)

Ici, la méthode requests.get envoie une requête GET vers l’API. La réponse est ensuite stockée dans la variable reponse. Nous vérifions le code de statut pour s’assurer que la requête a réussi (statut 200 signifie “succès”).

Lire la réponse JSON

L’API JSONPlaceholder renvoie les données au format JSON, ce qui est pratique pour les manipuler en Python. La méthode reponse.json() convertit automatiquement le contenu JSON en objet Python, généralement une liste de dictionnaires.

# Récupérer et afficher les données JSON de la réponse
utilisateurs = reponse.json()
print(utilisateurs)

Ici, utilisateurs est une liste de dictionnaires, chaque dictionnaire représentant un utilisateur. Nous pouvons maintenant manipuler ces données comme un objet Python standard.

Manipuler les données de la réponse JSON

Avec les données JSON récupérées, je peux parcourir la liste et accéder aux informations de chaque utilisateur. Par exemple, pour afficher le nom et l’email de chaque utilisateur :

# Parcourir la liste d'utilisateurs et afficher certaines informations
for utilisateur in utilisateurs:
print("Nom :", utilisateur['name'])
print("Email :", utilisateur['email'])
print("Ville :", utilisateur['address']['city'])
print("---")

Dans cet exemple, j’accède aux clés 'name', 'email', et 'address' pour chaque utilisateur. Note que address est un dictionnaire imbriqué, donc pour accéder à la ville, j’utilise utilisateur['address']['city'].

Enregistrer les données dans un fichier JSON

Une fois les données récupérées et manipulées, je peux les enregistrer dans un fichier JSON pour une utilisation ultérieure. Cela peut être utile pour garder une copie locale des données de l’API.

import json
# Sauvegarder les utilisateurs dans un fichier JSON
with open('utilisateurs.json', 'w', encoding='utf-8') as fichier:
json.dump(utilisateurs, fichier, indent=4, ensure_ascii=False)

Ici, j’utilise json.dump pour écrire la liste utilisateurs dans un fichier nommé utilisateurs.json, avec une indentation pour rendre le fichier plus lisible et ensure_ascii=False pour conserver les accents.

Plus loin

Il est également recommandé de gérer les erreurs si l’API est inaccessible ou renvoie une réponse inattendue. On peut utiliser une simple vérification sur reponse.status_code, comme dans l’exemple, et afficher un message d’erreur ou utiliser une gestion d’exceptions plus avancée pour un programme en production.

Manipuler des données JSON en Python

Une fois les données JSON chargées dans un programme Python, que ce soit depuis un fichier ou une réponse d’API, je peux les manipuler pour extraire ou modifier des informations. Le format JSON est directement compatible avec les structures de données Python (dictionnaires et listes), ce qui rend la manipulation de ces données simple et intuitive.

Dans ce chapitre, je vais te montrer comment accéder aux informations dans une structure JSON, comment ajouter, modifier ou supprimer des éléments, et enfin comment filtrer les données pour répondre à des besoins spécifiques.

Accéder aux données JSON

En général, les données JSON sont chargées en tant que dictionnaires ou listes de dictionnaires en Python. Je peux utiliser les clés pour accéder aux valeurs de ces dictionnaires, comme dans cet exemple de profil utilisateur JSON :

utilisateur = {
"nom": "Stéphane ROBERT",
"age": 29,
"adresse": {
"rue": "456 avenue des Champs",
"ville": "Lyon",
"code_postal": "69001"
},
"hobbies": ["photographie", "voyage", "musique"]
}
# Accéder à des valeurs spécifiques
nom = utilisateur["nom"]
ville = utilisateur["adresse"]["ville"]
premier_hobby = utilisateur["hobbies"][0]
print("Nom :", nom)
print("Ville :", ville)
print("Premier hobby :", premier_hobby)

Dans cet exemple, j’accède à la clé "nom" pour obtenir le nom de l’utilisateur, puis à "ville" dans l’adresse, et enfin au premier hobby dans la liste "hobbies".

Modifier des données JSON

Je peux modifier les valeurs dans la structure JSON en les assignant directement, comme pour un dictionnaire ou une liste en Python.

# Modifier le nom et la ville
utilisateur["nom"] = "Stéphane Dupuis"
utilisateur["adresse"]["ville"] = "Marseille"
print(utilisateur)

Ici, j’ai changé le nom de l’utilisateur et sa ville d’habitation. La structure JSON étant maintenant en mémoire sous forme de dictionnaire, je peux facilement effectuer ces modifications.

Ajouter des données à la structure JSON

Pour enrichir les données JSON, il suffit d’ajouter de nouvelles clés et valeurs au dictionnaire ou d’ajouter des éléments à une liste existante.

# Ajouter un nouvel attribut et un nouveau hobby
utilisateur["email"] = "stephane.dupuis@example.com"
utilisateur["hobbies"].append("lecture")
print(utilisateur)

Dans cet exemple, j’ajoute une clé "email" au dictionnaire principal et un nouveau hobby "lecture" à la liste des hobbies. Python met à jour la structure immédiatement.

Supprimer des données de la structure JSON

Pour supprimer des données, j’utilise l’instruction del pour retirer des clés de dictionnaires ou des éléments de liste.

# Supprimer l'âge et le premier hobby
del utilisateur["age"]
del utilisateur["hobbies"][0]
print(utilisateur)

Ici, j’ai supprimé l’âge de l’utilisateur et le premier hobby de la liste. del fonctionne pour enlever des clés ou des éléments sans laisser de traces.

Filtrer et transformer les données JSON

Il peut être utile de filtrer des données ou de sélectionner des informations spécifiques. Si je récupère une liste d’utilisateurs, je peux appliquer une condition pour extraire uniquement certains profils.

Exemple avec une liste de plusieurs utilisateurs :

utilisateurs = [
{"nom": "Stéphane ROBERT", "age": 29, "ville": "Lyon"},
{"nom": "Marie Durand", "age": 25, "ville": "Marseille"},
{"nom": "Pierre Martin", "age": 40, "ville": "Paris"}
]
# Filtrer les utilisateurs de moins de 30 ans
jeunes_utilisateurs = [user for user in utilisateurs if user["age"] < 30]
print(jeunes_utilisateurs)

Dans cet exemple, j’utilise une compréhension de liste pour créer une liste jeunes_utilisateurs contenant uniquement les utilisateurs de moins de 30 ans. Ce type de filtrage est très utile pour travailler avec des grandes quantités de données JSON.

Exemple complet : Transformer et enregistrer les données modifiées

Pour illustrer toutes ces manipulations, imaginons que je veux :

  1. Charger des données JSON d’un fichier.
  2. Ajouter un email à chaque utilisateur.
  3. Enregistrer la liste mise à jour dans un nouveau fichier.

Exemple de code :

import json
# Charger les utilisateurs depuis un fichier JSON
with open('utilisateurs.json', 'r', encoding='utf-8') as fichier:
utilisateurs = json.load(fichier)
# Ajouter un email fictif à chaque utilisateur
for utilisateur in utilisateurs:
utilisateur["email"] = utilisateur["nom"].replace(" ", ".").lower() + "@example.com"
# Enregistrer les utilisateurs mis à jour dans un nouveau fichier
with open('utilisateurs_mis_a_jour.json', 'w', encoding='utf-8') as fichier:
json.dump(utilisateurs, fichier, indent=4, ensure_ascii=False)

Dans cet exemple, j’ajoute un email fictif à chaque utilisateur en utilisant son nom, puis je sauvegarde la liste mise à jour dans un nouveau fichier JSON.

Manipuler des données JSON en Python avec JMESPath

JMESPath est une bibliothèque puissante pour effectuer des requêtes et extraire des données spécifiques à partir de structures JSON complexes en Python. Elle est particulièrement utile lorsque l’on travaille avec des données JSON imbriquées et que l’on souhaite filtrer ou transformer ces données de manière élégante et concise.

JMESPath permet de naviguer dans des structures de données JSON en utilisant une syntaxe similaire à celle des expressions XPath pour le XML. Avec JMESPath, je peux accéder aux clés, aux éléments de liste, et appliquer des filtres conditionnels pour extraire uniquement les données pertinentes.

Installation de JMESPath

Pour utiliser JMESPath en Python, j’ai besoin d’installer la bibliothèque jmespath via pip :

Terminal window
pip install jmespath

Une fois installée, je peux l’importer dans mon programme et l’utiliser pour interroger des structures JSON.

Accéder aux données simples avec JMESPath

Imaginons que j’ai des données JSON avec des informations sur un utilisateur :

import jmespath
utilisateur = {
"nom": "Stéphane ROBERT",
"age": 29,
"adresse": {
"rue": "456 avenue des Champs",
"ville": "Lyon",
"code_postal": "69001"
},
"hobbies": ["photographie", "voyage", "musique"]
}
# Extraire le nom de l'utilisateur
nom = jmespath.search("nom", utilisateur)
print("Nom :", nom)
# Extraire la ville de résidence
ville = jmespath.search("adresse.ville", utilisateur)
print("Ville :", ville)

Dans cet exemple, jmespath.search permet de récupérer le nom et la ville de l’utilisateur de manière très concise.

Extraire des éléments d’une liste

Si mon JSON contient une liste d’utilisateurs, je peux utiliser JMESPath pour extraire des informations spécifiques de chaque utilisateur.

utilisateurs = [
{"nom": "Stéphane ROBERT", "age": 29, "ville": "Lyon"},
{"nom": "Marie Durand", "age": 25, "ville": "Marseille"},
{"nom": "Pierre Martin", "age": 40, "ville": "Paris"}
]
# Extraire tous les noms d'utilisateurs
noms = jmespath.search("[].nom", utilisateurs)
print("Noms :", noms)

Ici, [].nom signifie “sélectionner le champ nom pour chaque élément de la liste”. Cela renvoie une liste avec tous les noms des utilisateurs.

Filtrer les données avec JMESPath

JMESPath permet également de filtrer les données JSON selon des conditions. Si je veux extraire uniquement les utilisateurs de moins de 30 ans, je peux le faire en une seule ligne.

# Filtrer les utilisateurs de moins de 30 ans
jeunes_utilisateurs = jmespath.search("[?age < `30`]", utilisateurs)
print("Utilisateurs de moins de 30 ans :", jeunes_utilisateurs)

Dans cette expression "[?age < 30]", ? est utilisé pour filtrer, et age < 30 est la condition de filtrage. Les guillemets inversés (`) entourent le nombre pour l’interpréter correctement.

Combiner des filtres et des projections

JMESPath devient encore plus puissant lorsqu’il s’agit de combiner filtres et projections. Je peux par exemple extraire uniquement les noms des utilisateurs vivant à Paris.

# Extraire les noms des utilisateurs habitant à Paris
noms_parisiens = jmespath.search("[?ville == 'Paris'].nom", utilisateurs)
print("Noms des utilisateurs à Paris :", noms_parisiens)

Cette expression combine un filtre ville == 'Paris' avec une projection .nom, ce qui renvoie une liste des noms des utilisateurs parisiens uniquement.

Transformation des données

JMESPath permet également de transformer les données en calculant des valeurs. Imaginons un JSON de produits avec des prix et des quantités ; je peux extraire le total de chaque produit.

produits = [
{"nom": "Produit A", "prix": 10, "quantite": 3},
{"nom": "Produit B", "prix": 5, "quantite": 10},
{"nom": "Produit C", "prix": 20, "quantite": 2}
]
resultats = jmespath.search("[].{nom: nom, prix: prix, quantite: quantite}", produits)
# Calculer le total pour chaque produit
totaux = [{"nom": item["nom"], "total": item["prix"] * item["quantite"]} for item in resultats]
print("Totaux par produit :", totaux)

Conclusion

Dans ce guide, j’ai essayé de regrouper tous les éléments essentiels que j’utilise couramment pour manipuler des données JSON dans mes scripts ou programmes Python d’automatisation. Des concepts de base comme la lecture et l’écriture de fichiers JSON jusqu’à l’interrogation d’une API en passant par les manipulations complexes et l’utilisation de JMESPath pour extraire et filtrer des informations précises, chaque étape est pensée pour rendre les opérations de gestion de données JSON plus efficaces et automatisées.

Lorsque je travaille sur des projets d’automatisation, on a toujours à deveoir manipuler des données JSON, que ce soit pour des configurations, des échanges avec des services en ligne, ou des traitements de données provenant d’API.

L’utilisation de Python, avec ses bibliothèques standard comme json et des outils supplémentaires comme requests et jmespath, permet de manipuler ces données de façon simple et flexible. Ce guide constitue donc une base solide pour construire des scripts capables de charger, manipuler, et enregistrer des données JSON dans des workflows d’automatisation.

J’espère que ce guide te servira de référence pour tes propres projets Python et qu’il te facilitera le travail avec JSON au quotidien. Avec ces outils et astuces en main, tu devrais être en mesure de créer des scripts puissants et de gérer des données JSON de manière plus rapide et productive.

A bientôt pour un nouveau guide, et cette fois ce sera le YAML !