Zurück zur Startseite

Laden der TOML-Konfiguration mit Pydantic in Python

Modul lädt settings.toml über tomllib, speichert mit lru_cache im Cache und validiert Pydantic-Modelle. Unterstützt TypeVar-Typisierung für beliebige Konfigurationsklassen. Ideal für Produktionsanwendungen mit Trennung von Logik und Parametern.

Parsen von settings.toml und Pydantic-Validierung in Python
Advertisement 728x90

settings.toml mit Pydantic in Python-Apps lesen und validieren

Dieses Modul übernimmt das Lesen von settings.toml, das Parsen mit tomllib, das Cachen des Ergebnisses via lru_cache und die Validierung von Abschnitten mit Pydantic. Es trennt die Konfigurationslogik von den App-Parametern, vermeidet wiederholte Festplatten-Zugriffe und gewährleistet Typsicherheit.

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])

Warum TOML und Pydantic für Konfigurationen?

TOML-Dateien sind menschenlesbar und lassen sich sauber in Python-Dictionaries parsen. Abschnitte wie [bot] werden zu verschachtelten Dicts. Pydantic validiert die Struktur, kümmert sich um Typkonvertierungen und maskiert Geheimnisse mit SecretStr.

Beispiel-TOML:

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

Das Parsen ergibt {"bot": {"token": "123456:ABCDEF"}}. Die Validierung erzeugt ein BotConfig-Objekt.

Durch Caching mit @lru_cache entfallen wiederholte Lesevorgänge: Der erste Aufruf parst, spätere greifen auf den Cache zu. Zum Neuladen: parse_config_file.cache_clear().

Pfade mit pathlib handhaben

Path(__file__).resolve().parent.parent.joinpath("settings.toml") baut einen absoluten Pfad zur Datei im übergeordneten Projektverzeichnis auf. exists() prüft die Existenz, parent-Eigenschaften erleichtern die Validierung.

Google AdInline article slot
  • Path.joinpath(): hängt Pfadsegmente plattformübergreifend an.
  • resolve(): löst Symlinks zu absoluten Pfaden auf.
  • Öffnen im Modus "rb": Vorgabe von tomllib.load() für binäres Lesen.

Typ-Hinweise mit TypeVar und Pydantic

ConfigType = TypeVar("ConfigType", bound=BaseModel) ermöglicht es get_config, mit beliebigen Pydantic-Modellen zu arbeiten und eine Instanz des übergebenen Typs zurückzugeben.

  • Type[ConfigType]: erwartet eine Modellklasse, kein Objekt.
  • model_validate(): wandelt ein Dict in ein validiertes Objekt um, wirft bei Fehlern ValidationError.
  • Any für Dicts: TOML mischt Typen (str, int, bool, dict).

Erweiterung für weitere Abschnitte:

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

config = get_config(DatabaseConfig, "database")

Caching und Dekoratoren

@lru_cache speichert Ergebnisse basierend auf Argumenten (hier keine, also einfach). LRU räumt alte Einträge bei Limits auf, für Konfigs reicht ein Slot.

Google AdInline article slot

Vorteile:

  • Spart I/O: Festplattenlesung nur einmal.
  • Idempotent: Mehrere get_config-Aufrufe teilen ein Parsing.
  • Thread-sicher: Der Standardbibliotheks-Dekorator regelt das.

Nachteile: Änderungen an der TOML-Datei werden ignoriert, bis cache_clear() aufgerufen wird.

Modulstruktur

  • Modelle (BotConfig): unabhängig von Loaders.
  • parse_config_file(): parst die gesamte TOML.
  • get_config(): extrahiert und validiert einen Abschnitt.

Diese Trennung der Verantwortlichkeiten verbessert die Testbarkeit: Pfade oder TOML-Strings mocken.

Wichtige Tipps:

  • tomllib (Python 3.11+) nutzen, für ältere Versionen auf tomli ausweichen.
  • Konfiguration immer mit Pydantic validieren, bevor sie genutzt wird.
  • Parsing cachen, aber Neuladen unterstützen.
  • Geheimnisse in SecretStr speichern, um sie in Logs/Debug auszublenden.
  • Pfade mit pathlib bauen für plattformübergreifende Kompatibilität.

— Editorial Team

Advertisement 728x90

Weiterlesen