65 lines
2.7 KiB
Python
65 lines
2.7 KiB
Python
import tomllib
|
|
import tomli_w
|
|
from typing import Optional
|
|
from pathlib import Path
|
|
from pydantic import SecretStr, Field, BaseModel
|
|
from pydantic_settings import BaseSettings, SettingsConfigDict
|
|
|
|
class ExampleSection(BaseModel):
|
|
example_key: str = "example_value"
|
|
maybe_value: Optional[int] = None
|
|
|
|
class Settings(BaseSettings):
|
|
default_config_dir: Path = Field(default=Path.home() / ".config", # / "python-boilerplate",
|
|
description="Default path to user configuration file.", exclude=True)
|
|
config_file_name: Path = Field(default=Path("python_boilerplate.toml"),
|
|
description="Name of the configuration file.", exclude=True)
|
|
logfile: str = "python-boilerplate.log"
|
|
example_string: str = Field(default="Example Default", description="An example string value.")
|
|
example_int: Optional[int] = None
|
|
example_float: Optional[float] = None
|
|
example_bool: bool = True
|
|
example_list: list[int] = [1, 2, 3]
|
|
example_dict: dict[str, str] = {"key": "value", "foo": "bar"}
|
|
example_section: ExampleSection = ExampleSection()
|
|
|
|
model_config = SettingsConfigDict(
|
|
env_prefix="PYTHON_BOILERPLATE_",
|
|
env_nested_delimiter="__",
|
|
env_file_encoding="utf-8",
|
|
extra="ignore",
|
|
)
|
|
|
|
@classmethod
|
|
def load(cls, custom_file: Optional[Path | str] = None) -> "Settings":
|
|
# Use the provided custom file, or look for config file in standard locations
|
|
if custom_file is not None and Path(custom_file).is_file():
|
|
config_file = Path(custom_file)
|
|
elif Path(Path.cwd() / cls().config_file_name).is_file():
|
|
# Check for config in current directory
|
|
config_file = Path.cwd() / cls().config_file_name
|
|
elif Path(cls().default_config_dir / cls().config_file_name).is_file():
|
|
# Wherever the heck we specified
|
|
config_file = cls().default_config_dir / cls().config_file_name
|
|
else:
|
|
# Return default settings if no config file found
|
|
return cls()
|
|
|
|
if config_file.is_file():
|
|
with config_file.open("rb") as f:
|
|
config_data = tomllib.load(f)
|
|
return cls.model_validate(config_data)
|
|
|
|
return cls()
|
|
|
|
def save(self, custom_file: Optional[Path] = None) -> None:
|
|
# Use the provided custom file, or look for config file in standard locations
|
|
if custom_file is not None:
|
|
config_file = custom_file
|
|
else:
|
|
config_file = self.default_config_dir / self.config_file_name
|
|
|
|
config_file.parent.mkdir(parents=True, exist_ok=True)
|
|
|
|
with config_file.open("wb") as f:
|
|
tomli_w.dump(self.model_dump(mode="json",exclude_none=True), f) |