Skip to content

gole.config

gole.config 🔗

Config module

Attributes:

Name Type Description
settings Settings

Settings instance.

Settings cached 🔗

Bases: BaseSettings

Source code in gole/config.py
@cache
class Settings(BaseSettings):
    core: CoreConfig = Field(default_factory=CoreConfig)
    editor: EditorConfig = Field(default_factory=EditorConfig)
    theme: ThemeConfig = Field(default_factory=ThemeConfig)
    language: LanguageConfig = Field(default_factory=LanguageConfig)

    version: str = Field(default=app_version, exclude=True)
    config_file: Path = Field(default=CONFIG_FILE, exclude=True)
    cache_dir: Path = Field(
        default=user_cache_path(app_name, app_author, ensure_exists=True),
        exclude=True,
    )

    model_config = SettingsConfigDict(extra='allow', toml_file=CONFIG_FILE)

    @classmethod
    def settings_customise_sources(
        cls,
        settings_cls: type[BaseSettings],
        init_settings: PydanticBaseSettingsSource,
        env_settings: PydanticBaseSettingsSource,
        dotenv_settings: PydanticBaseSettingsSource,
        file_secret_settings: PydanticBaseSettingsSource,
    ) -> tuple[PydanticBaseSettingsSource, ...]:
        return (TomlConfigSettingsSource(settings_cls),)

    @cached_property
    def options(self) -> tuple[str, ...]:
        return tuple(
            option
            for key, value in self.model_dump().items()
            for option in get_options(value, key)
        )

    def __getitem__(self, name):
        value = self
        for attr in name.lower().split('.'):
            value = getattr(value, attr)
        return value

    async def write_config_file(self, config: dict):
        @singledispatch
        def add(value, doc: tomlkit.TOMLDocument, key: str, comments: str):
            doc.add(key, value)
            for comment in comments.splitlines():
                doc.add(tomlkit.comment(comment))
            if comments:
                doc.add(tomlkit.nl())

        @add.register
        def _(
            value: BaseModel, doc: tomlkit.TOMLDocument, key: str, comment: str
        ):
            table = tomlkit.table()

            if comment:
                table.add(tomlkit.comment(comment))

            for opt, field in value.model_fields.items():
                if value := getattr(value, opt, None):
                    add(value, table, opt, field.description or '')
            doc.add(key, table)

        config = lower_keys(config)
        doc = tomlkit.document()
        for key, field in self.model_fields.items():
            if not (value := config.get(key)):
                continue
            add(value, doc, key, field.description or '')

        await AsyncPath(self.config_file).write_text(tomlkit.dumps(doc))

    async def save(self, **options):
        """Save config file."""
        for opt, val in options.items():
            opts = opt.lower().split('.')
            key = opts.pop()
            obj = self
            for attr in opts:
                obj = getattr(obj, attr)
            setattr(obj, key, val)

        config_file = AsyncPath(self.config_file)

        configs = {}
        if await config_file.exists():
            configs = tomlkit.parse(await config_file.read_text())

        configs |= lower_keys(self.model_dump())

        await self.write_config_file(configs)

save(**options) async 🔗

Save config file.

Source code in gole/config.py
async def save(self, **options):
    """Save config file."""
    for opt, val in options.items():
        opts = opt.lower().split('.')
        key = opts.pop()
        obj = self
        for attr in opts:
            obj = getattr(obj, attr)
        setattr(obj, key, val)

    config_file = AsyncPath(self.config_file)

    configs = {}
    if await config_file.exists():
        configs = tomlkit.parse(await config_file.read_text())

    configs |= lower_keys(self.model_dump())

    await self.write_config_file(configs)