Aller au contenu

Manipuler des données au format YAML

Mise à jour :

logo python

Le format YAML (YAML Ain’t Markup Language) est devenu un standard dans le monde des configurations, particulièrement dans le domaine de la gestion d’infrastructures. Il est apprécié pour sa lisibilité et sa structure simple, permettant de gérer facilement des données hiérarchisées sans alourdir la syntaxe. Que ce soit pour décrire des environnements, configurer des outils comme Ansible, Docker Compose, ou Kubernetes, YAML est partout.

Dans ce guide, je vais vous montrer comment utiliser Python pour manipuler des fichiers YAML efficacement. Avec PyYAML, une bibliothèque dédiée à la gestion du YAML, vous pourrez lire, écrire, modifier et même convertir des fichiers YAML sans difficulté. Nous allons explorer les bases, comme l’installation et l’utilisation de PyYAML, puis aborder des fonctionnalités avancées telles que la gestion des alias, la personnalisation des options de sauvegarde, ou encore la conversion en JSON.

Installation de PyYAML

Pour manipuler des fichiers YAML en Python, la première étape consiste à installer la bibliothèque PyYAML, qui permet de lire, écrire et gérer ce format en toute simplicité. PyYAML est largement utilisé et compatible avec la plupart des versions de Python, ce qui en fait un choix de prédilection pour les développeurs et les administrateurs système.

Pour l’installer, il suffit d’utiliser pip, le gestionnaire de paquets Python. Voici la commande à exécuter dans le terminal :

Terminal window
pip install pyyaml

Une fois l’installation terminée, vous disposez de toutes les fonctions nécessaires pour manipuler des fichiers YAML. PyYAML offre deux fonctions principales pour gérer les données : yaml.safe_load() pour lire un fichier YAML sans exécuter de code dangereux, et yaml.dump() pour sauvegarder des données en format YAML.

Vérifier l’installation : Pour confirmer que l’installation est bien faite, lancez Python dans le terminal et essayez d’importer la bibliothèque :

import yaml

Si aucune erreur n’apparaît, alors l’installation est réussie, et vous pouvez commencer à manipuler des fichiers YAML.

Lecture d’un fichier YAML

Une fois PyYAML installé, la première opération que je vais vous montrer est la lecture d’un fichier YAML. Cela permet d’extraire des informations d’un fichier de configuration ou d’un document structuré au format YAML, puis de les utiliser dans un programme Python.

Pour lire un fichier YAML, PyYAML propose la fonction yaml.safe_load(), qui convertit le contenu du fichier en un objet Python (comme un dictionnaire). safe_load() est la méthode privilégiée, car elle charge les données de manière sécurisée sans exécuter de code potentiellement risqué dans le fichier.

Imaginons un fichier YAML simple, nommé config.yaml, contenant les configurations d’une base de données et d’un service de messagerie :

database:
host: localhost
port: 5432
username: admin
password: password123
email:
smtp_server: smtp.example.com
smtp_port: 587
use_tls: true

Dans cet exemple, le fichier YAML contient deux sections principales : database et email. Chaque section contient plusieurs paramètres qui peuvent être utilisés dans votre application Python.

Pour lire ce fichier YAML et charger son contenu dans un programme Python, il suffit de suivre ces étapes :

  1. Ouvrir le fichier en mode lecture.
  2. Utiliser yaml.safe_load() pour le lire et convertir son contenu en un dictionnaire Python.

Voici un exemple de code :

import yaml
# Ouvrir le fichier YAML en mode lecture
with open("config.yaml", "r") as file:
# Charger le contenu du fichier en tant que dictionnaire Python
config = yaml.safe_load(file)
# Afficher le contenu du fichier chargé
print(config)

Lorsque vous exécutez ce code, le contenu du fichier YAML est chargé dans le dictionnaire config, et vous devriez voir une sortie ressemblant à ceci :

{
'database': {
'host': 'localhost',
'port': 5432,
'username': 'admin',
'password': 'password123'
},
'email': {
'smtp_server': 'smtp.example.com',
'smtp_port': 587,
'use_tls': True
}
}

Points importants : Utilisez toujours safe_load() pour lire les fichiers YAML, car cette méthode bloque l’exécution de code potentiellement dangereux dans le fichier.

À présent, les données du fichier YAML sont stockées dans le dictionnaire config et peuvent être facilement manipulées en Python.

Lire les ancrages et les alias avec safe_load

Le format YAML supporte les ancrages et alias, qui permettent de réutiliser des blocs de données dans le fichier. Cela est particulièrement utile pour éviter les répétitions et garantir la cohérence des configurations. PyYAML prend en charge ces fonctionnalités et permet de les manipuler en Python sans effort, notamment en utilisant yaml.safe_load() pour charger les données en toute sécurité.

Dans YAML :

  • Un ancrage est une référence de données que l’on crée pour réutiliser un bloc dans d’autres parties du fichier.
  • Un alias est une réutilisation de l’ancrage, pointant vers les données originales.

Voici un exemple de fichier YAML avec des ancrages et des alias :

defaults: &defaults
host: localhost
port: 5432
username: admin
development:
<<: *defaults
database: dev_db
production:
<<: *defaults
database: prod_db

Dans cet exemple :

  • defaults est un ancrage défini par &defaults. Ce bloc contient des configurations communes.
  • <<: *defaults est un alias qui réutilise les valeurs définies dans defaults pour les sections development et production.

PyYAML gère automatiquement les ancrages et alias avec yaml.safe_load(). Lorsque vous chargez un fichier YAML contenant des ancrages, le contenu est fusionné en un seul dictionnaire Python.

Voici un exemple de code pour charger un fichier contenant des ancrages et des alias :

import yaml
with open("config_with_aliases.yaml", "r") as file:
config = yaml.safe_load(file)
print(config)

Lorsque vous exécutez ce code avec le fichier YAML de l’exemple précédent, PyYAML résout les alias, et config contiendra un dictionnaire avec les valeurs fusionnées :

{
'defaults': {
'host': 'localhost',
'port': 5432,
'username': 'admin'
},
'development': {
'host': 'localhost',
'port': 5432,
'username': 'admin',
'database': 'dev_db'
},
'production': {
'host': 'localhost',
'port': 5432,
'username': 'admin',
'database': 'prod_db'
}
}

Dans cet exemple, PyYAML a automatiquement fusionné les valeurs de defaults dans les sections development et production en respectant la structure du YAML.

Accéder aux données YAML en Python

Les données chargées étant dans un dictionnaire Python, il est facile d’y accéder et de les utiliser dans le reste de votre code. Voici comment extraire des valeurs spécifiques :

# Accéder aux informations de la base de données
db_host = config['database']['host']
db_port = config['database']['port']
db_user = config['database']['username']
print(f"Base de données hébergée sur {db_host}:{db_port} avec l'utilisateur {db_user}")
# Accéder aux informations de l'email
smtp_server = config['email']['smtp_server']
smtp_port = config['email']['smtp_port']
use_tls = config['email']['use_tls']
print(f"Serveur SMTP : {smtp_server} sur le port {smtp_port}, TLS activé : {use_tls}")

Écriture d’un fichier YAML

Après avoir vu comment lire des fichiers YAML, voyons maintenant comment écrire des données Python dans un fichier YAML. Cela est particulièrement utile lorsque vous souhaitez sauvegarder des configurations, exporter des données ou générer automatiquement des fichiers YAML.

Pour écrire un fichier YAML, PyYAML propose la fonction yaml.dump(), qui convertit des objets Python, comme des dictionnaires ou des listes, en texte YAML. Ce texte peut ensuite être sauvegardé dans un fichier pour être réutilisé ou partagé.

Supposons que nous

ayons un dictionnaire Python contenant les informations de configuration suivantes :

config_data = {
"database": {
"host": "localhost",
"port": 5432,
"username": "admin",
"password": "password123"
},
"email": {
"smtp_server": "smtp.example.com",
"smtp_port": 587,
"use_tls": True
}
}

Ce dictionnaire contient deux sections : database et email, avec des informations de connexion et de configuration.

Pour écrire ces données dans un fichier YAML, utilisez la fonction yaml.dump(), qui convertit le dictionnaire Python en une structure YAML lisible. Voici le code :

import yaml
# Écrire le dictionnaire Python dans un fichier YAML
with open("output_config.yaml", "w") as file:
yaml.dump(config_data, file)

Ce code ouvre un fichier nommé output_config.yaml en mode écriture, puis y écrit le contenu du dictionnaire config_data en format YAML.

Le fichier output_config.yaml devrait contenir quelque chose de similaire à ceci :

database:
host: localhost
port: 5432
username: admin
password: password123
email:
smtp_server: smtp.example.com
smtp_port: 587
use_tls: true

Ce fichier YAML est maintenant structuré et prêt à être utilisé comme fichier de configuration. Les indentations et le formatage sont gérés automatiquement par yaml.dump().

La fonction yaml.dump() permet également de personnaliser la sortie YAML pour mieux répondre à certains besoins. Voici quelques options utiles :

  • default_flow_style : Par défaut, yaml.dump() utilise le format en bloc, qui est plus lisible. Cependant, si vous souhaitez que les données soient écrites en une seule ligne (format en flux), vous pouvez définir default_flow_style=True.
  • indent : Cette option permet de spécifier le nombre d’espaces pour chaque niveau d’indentation.
  • sort_keys : Par défaut, les clés sont triées dans l’ordre alphabétique. Vous pouvez désactiver ce tri en utilisant sort_keys=False.

Exemple de code avec ces options :

import yaml
with open("custom_output.yaml", "w") as file:
yaml.dump(config_data, file, default_flow_style=False, indent=4, sort_keys=False)

Dans cet exemple :

  • default_flow_style=False garantit que le fichier est écrit en format bloc, pour une meilleure lisibilité.
  • indent=4 utilise quatre espaces pour chaque niveau d’indentation.
  • sort_keys=False maintient l’ordre des clés tel qu’il est défini dans le dictionnaire Python.

Écriture de données avec des alias et des références

Si votre fichier contient des sections répétées, vous pouvez également utiliser PyYAML pour gérer les alias et références. Cela permet d’écrire des données une seule fois et de les réutiliser dans d’autres parties du fichier, évitant ainsi les redondances.

Exemple :

import yaml
# Création de données avec des références
default_config = {
"host": "localhost",
"port": 5432
}
config_data = {
"default": default_config,
"development": default_config,
"production": default_config
}
with open("output_alias.yaml", "w") as file:
yaml.dump(config_data, file)

Dans cet exemple, default_config est réutilisé pour les sections development et production. PyYAML va automatiquement gérer les alias pour éviter les répétitions.

Le fichier output_alias.yaml pourrait ressembler à ceci :

default: &id001
host: localhost
port: 5432
development: *id001
production: *id001

Ici, l’alias &id001 est utilisé pour référencer default, puis cet alias est réutilisé pour les sections development et production avec *id001.

Conversion de YAML en JSON et vice-versa

Dans de nombreux projets, il est courant de travailler avec différents formats de données, notamment YAML et JSON. Le YAML est souvent privilégié pour les configurations grâce à sa lisibilité, tandis que le JSON est largement utilisé pour les échanges de données entre applications, en particulier dans les API. Python et PyYAML facilitent la conversion entre ces deux formats, ce qui est pratique lorsqu’on doit interagir avec des outils qui utilisent chacun leur propre format.

Conversion d’un fichier YAML en JSON

Pour convertir un fichier YAML en JSON, il suffit de :

  1. Charger le fichier YAML en tant que dictionnaire Python avec yaml.safe_load().
  2. Convertir ce dictionnaire en JSON avec la bibliothèque json de Python.

Voici un exemple de code :

import yaml
import json
# Charger le fichier YAML
with open("config.yaml", "r") as yaml_file:
config = yaml.safe_load(yaml_file)
# Convertir en JSON
json_data = json.dumps(config, indent=4)
# Sauvegarder le JSON dans un fichier
with open("config.json", "w") as json_file:
json_file.write(json_data)

Dans cet exemple :

  • yaml.safe_load() charge le contenu du fichier YAML dans un dictionnaire Python.
  • json.dumps() convertit le dictionnaire en une chaîne JSON, avec une indentation de 4 espaces pour plus de lisibilité.
  • La chaîne JSON est écrite dans un fichier nommé config.json.

Le fichier JSON obtenu ressemblera à ceci :

{
"database": {
"host": "localhost",
"port": 5432,
"username": "admin",
"password": "password123"
},
"email": {
"smtp_server": "smtp.example.com",
"smtp_port": 587,
"use_tls": true
}
}

Conversion d’un fichier JSON en YAML

La conversion de JSON en YAML est tout aussi simple. Il suffit de :

  1. Charger le fichier JSON en tant que dictionnaire Python avec json.load().
  2. Utiliser yaml.dump() pour convertir ce dictionnaire en YAML.

Voici comment faire :

import yaml
import json
# Charger le fichier JSON
with open("config.json", "r") as json_file:
config = json.load(json_file)
# Convertir en YAML
with open("config.yaml", "w") as yaml_file:
yaml.dump(config, yaml_file, default_flow_style=False)

Dans cet exemple :

  • json.load() lit le fichier JSON et le charge dans un dictionnaire Python.
  • yaml.dump() convertit ce dictionnaire en YAML, et default_flow_style=False garantit que le format YAML est structuré en bloc, ce qui est plus lisible.

Le fichier YAML obtenu ressemblera à ceci :

database:
host: localhost
port: 5432
username: admin
password: password123
email:
smtp_server: smtp.example.com
smtp_port: 587
use_tls: true

Plus d’infos sur la gestion des fichiers JSon en Python ici.

Gestion des Exceptions YAML

Lorsqu’on manipule des fichiers YAML en Python, il est important de prévoir la gestion des erreurs et exceptions qui pourraient survenir. Cela est essentiel pour garantir la robustesse et la sécurité de votre programme, surtout lorsque des configurations critiques sont en jeu. Des erreurs peuvent se produire pour diverses raisons : fichier manquant, syntaxe incorrecte dans le YAML, ou incompatibilité des types de données.

Voici les erreurs principales que l’on peut rencontrer lors de la manipulation de fichiers YAML :

  • Fichier manquant ou inaccessible : Le fichier YAML que vous essayez de charger n’existe pas ou n’est pas accessible.
  • Erreur de syntaxe YAML : Le fichier YAML contient des erreurs de syntaxe, comme un mauvais niveau d’indentation ou des caractères invalides.
  • Incompatibilité de types : Certaines valeurs dans le fichier YAML ne sont pas du type attendu, ce qui peut poser des problèmes lors du traitement des données.

Gestion des erreurs lors de la lecture d’un fichier YAML

Pour lire un fichier YAML en toute sécurité, il est recommandé d’utiliser un bloc try-except pour intercepter les erreurs potentielles. Voici un exemple de code pour gérer les erreurs lors de la lecture d’un fichier :

import yaml
try:
with open("config.yaml", "r") as file:
config = yaml.safe_load(file)
print("Fichier YAML chargé avec succès :", config)
except FileNotFoundError:
print("Erreur : Le fichier 'config.yaml' est introuvable.")
except yaml.YAMLError as exc:
print("Erreur lors de la lecture du fichier YAML :", exc)
except Exception as e:
print("Une erreur inattendue s'est produite :", e)

Dans ce code :

  • FileNotFoundError : Si le fichier config.yaml est introuvable, Python lève une exception FileNotFoundError, et un message d’erreur est affiché.
  • yaml.YAMLError : Si le fichier contient des erreurs de syntaxe YAML, l’exception YAMLError est levée, et le programme affiche un message d’erreur détaillé.
  • Exception : Ce bloc attrape toutes les autres erreurs inattendues qui pourraient survenir.

Gestion des erreurs lors de l’écriture d’un fichier YAML

Les erreurs lors de l’écriture d’un fichier YAML sont moins fréquentes mais peuvent se produire, surtout si le fichier de destination est inaccessible ou si les données sont dans un format incompatible avec YAML.

Voici un exemple pour gérer les erreurs lors de l’écriture :

import yaml
config_data = {
"database": {
"host": "localhost",
"port": 5432,
"username": "admin",
"password": "password123"
},
"email": {
"smtp_server": "smtp.example.com",
"smtp_port": 587,
"use_tls": True
}
}
try:
with open("config.yaml", "w") as file:
yaml.dump(config_data, file)
print("Fichier YAML écrit avec succès.")
except PermissionError:
print("Erreur : Impossible d'écrire dans le fichier 'config.yaml'. Vérifiez les permissions.")
except yaml.YAMLError as exc:
print("Erreur lors de l'écriture du fichier YAML :", exc)
except Exception as e:
print("Une erreur inattendue s'est produite :", e)

Dans ce code :

  • PermissionError : Si le programme n’a pas les permissions d’écrire dans config.yaml, une exception PermissionError est levée.
  • yaml.YAMLError : Cette exception couvre toute erreur YAML liée à l’incompatibilité de certaines données.
  • Exception : Ce bloc capture toute autre erreur inattendue qui pourrait survenir.

Plus d’infos sur la gestion des execptions en Python ici.

Conclusion

PyYAML est une bibliothèque puissante et flexible, qui rend la manipulation des fichiers YAML fluide et efficace en Python. Que ce soit pour des configurations simples ou des fichiers plus complexes nécessitant des ancrages, alias, ou plusieurs documents, PyYAML offre les outils nécessaires pour répondre à ces besoins. En maîtrisant ces techniques, vous êtes désormais capable de gérer, modifier, et automatiser des configurations YAML de manière professionnelle dans vos projets Python et DevOps.

Plus d’infos