Retour à l'accueil

Chargement de la configuration TOML avec Pydantic en Python

Le module charge settings.toml via tomllib, met en cache avec lru_cache et valide les modèles Pydantic. Prend en charge le typage TypeVar pour toute classe de configuration. Idéal pour les applications de production avec séparation de la logique et des paramètres.

Analyse de settings.toml et validation Pydantic en Python
Advertisement 728x90

Lire et valider settings.toml avec Pydantic dans les apps Python

Ce module gère la lecture de settings.toml, son analyse avec tomllib, la mise en cache des résultats via lru_cache, et la validation des sections avec Pydantic. Il sépare la logique de configuration des paramètres de votre app, réduit les lectures répétées sur disque et garantit la sécurité des types.

from functools import lru_cache
from pathlib import Path
from tomllib import load
from typing import Any, Type, TypeVar

from pydantic import BaseModel, SecretStr

ConfigType = TypeVar("ConfigType", bound=BaseModel)

class BotConfig(BaseModel):
    token: SecretStr

@lru_cache
def parse_config_file() -> dict[str, Any]:
    config_path = Path(__file__).resolve().parent.parent.joinpath("settings.toml")

    if not config_path.exists():
        error = "Could not find settings file"
        raise ValueError(error)

    with open(config_path, "rb") as file:
        config_data = load(file)

    return config_data

def get_config(model: Type[ConfigType], root_key: str) -> ConfigType:
    config_dict = parse_config_file()

    if root_key not in config_dict:
        error = f"Key {root_key} not found"
        raise ValueError(error)

    return model.model_validate(config_dict[root_key])

Pourquoi TOML et Pydantic pour la configuration

Les fichiers TOML sont lisibles par les humains et se parsent proprement en dictionnaires Python. Les sections comme [bot] deviennent des dictionnaires imbriqués. Pydantic valide la structure, gère les conversions de types et masque les secrets avec SecretStr.

Exemple TOML :

Google AdInline article slot
[bot]
token = "123456:ABCDEF"

L'analyse produit {"bot": {"token": "123456:ABCDEF"}}. La validation crée un objet BotConfig.

Le cache avec @lru_cache évite les relectures : le premier appel analyse, les suivants puisent dans le cache. Rechargez avec parse_config_file.cache_clear().

Gérer les chemins avec pathlib

Path(__file__).resolve().parent.parent.joinpath("settings.toml") construit un chemin absolu vers le fichier dans le répertoire parent de votre projet. exists() vérifie l'existence et les propriétés parent simplifient la validation.

Google AdInline article slot
  • Path.joinpath() : ajoute des segments de chemin de manière multiplateforme.
  • resolve() : résout les liens symboliques en chemins absolus.
  • Ouverture en "rb" : requise par tomllib.load() pour la lecture binaire.

Annotations de types avec TypeVar et Pydantic

ConfigType = TypeVar("ConfigType", bound=BaseModel) permet à get_config de fonctionner avec n'importe quel modèle Pydantic, en retournant une instance du type passé.

  • Type[ConfigType] : attend une classe de modèle, pas une instance.
  • model_validate() : transforme un dictionnaire en objet validé, levant ValidationError en cas d'échec.
  • Any pour les dictionnaires : TOML mélange les types (str, int, bool, dict).

Étendez pour d'autres sections :

class DatabaseConfig(BaseModel):
    host: str
    port: int
    user: str

config = get_config(DatabaseConfig, "database")

Mise en cache et décorateurs

@lru_cache stocke les résultats par arguments (aucun ici, donc simple). LRU évince les anciennes entrées au-delà de la limite, mais un seul emplacement suffit pour la config.

Google AdInline article slot

Avantages :

  • Réduit les E/S : lecture disque une seule fois.
  • Idempotence : plusieurs appels à get_config partagent une analyse.
  • Sûr en multithreading : le décorateur de la stdlib s'en charge.

Inconvénients : Les modifications sur disque du TOML sont ignorées jusqu'au cache_clear().

Structure du module

  • Modèles (BotConfig) : indépendants des chargeurs.
  • parse_config_file() : analyse le TOML complet.
  • get_config() : extrait et valide une section.

Cette séparation des responsabilités améliore la testabilité : moquez les chemins ou chaînes TOML.

Conseils clés :

  • Utilisez tomllib (Python 3.11+), retenez tomli pour les versions antérieures.
  • Validez toujours la config avec Pydantic avant usage.
  • Mettez en cache l'analyse, mais ajoutez un support de rechargement.
  • Stockez les secrets en SecretStr pour les masquer dans les logs/debug.
  • Construisez les chemins avec pathlib pour la compatibilité multiplateforme.

— Editorial Team

Advertisement 728x90

Lire ensuite