toml.py 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. """TOML file settings source."""
  2. from __future__ import annotations as _annotations
  3. import sys
  4. from pathlib import Path
  5. from typing import (
  6. TYPE_CHECKING,
  7. Any,
  8. )
  9. from ..base import ConfigFileSourceMixin, InitSettingsSource
  10. from ..types import DEFAULT_PATH, PathType
  11. if TYPE_CHECKING:
  12. from pydantic_settings.main import BaseSettings
  13. if sys.version_info >= (3, 11):
  14. import tomllib
  15. else:
  16. tomllib = None
  17. import tomli
  18. else:
  19. tomllib = None
  20. tomli = None
  21. def import_toml() -> None:
  22. global tomli
  23. global tomllib
  24. if sys.version_info < (3, 11):
  25. if tomli is not None:
  26. return
  27. try:
  28. import tomli
  29. except ImportError as e: # pragma: no cover
  30. raise ImportError('tomli is not installed, run `pip install pydantic-settings[toml]`') from e
  31. else:
  32. if tomllib is not None:
  33. return
  34. import tomllib
  35. class TomlConfigSettingsSource(InitSettingsSource, ConfigFileSourceMixin):
  36. """
  37. A source class that loads variables from a TOML file
  38. """
  39. def __init__(
  40. self,
  41. settings_cls: type[BaseSettings],
  42. toml_file: PathType | None = DEFAULT_PATH,
  43. ):
  44. self.toml_file_path = toml_file if toml_file != DEFAULT_PATH else settings_cls.model_config.get('toml_file')
  45. self.toml_data = self._read_files(self.toml_file_path)
  46. super().__init__(settings_cls, self.toml_data)
  47. def _read_file(self, file_path: Path) -> dict[str, Any]:
  48. import_toml()
  49. with open(file_path, mode='rb') as toml_file:
  50. if sys.version_info < (3, 11):
  51. return tomli.load(toml_file)
  52. return tomllib.load(toml_file)
  53. def __repr__(self) -> str:
  54. return f'{self.__class__.__name__}(toml_file={self.toml_file_path})'