From 80fc31245c39ec4e039308bdbd4a2ebdf6cd9cd5 Mon Sep 17 00:00:00 2001 From: Upstream Data Date: Thu, 29 Aug 2024 15:55:04 -0600 Subject: [PATCH] Rename settings.yaml to goosebit.yaml, and check multiple places for settings. Use can now pass `GOOSEBIT_SETTINGS` to customize settings location, as well as goosebit auto checking `/etc/goosebit` if it exists, the root of the project directory, and the current working directory when it is run. This should allow for more optionality when loading settings files. Renaming settings to `goosebit.yaml` is mainly to specify what the file is when running from CWD, it should be distinct from other files. Fixes: #103 --- settings.yaml => goosebit.yaml | 0 goosebit/settings/__init__.py | 2 +- goosebit/settings/const.py | 4 +++- goosebit/settings/schema.py | 42 +++++++++++++++++++++++++++------- 4 files changed, 38 insertions(+), 10 deletions(-) rename settings.yaml => goosebit.yaml (100%) diff --git a/settings.yaml b/goosebit.yaml similarity index 100% rename from settings.yaml rename to goosebit.yaml diff --git a/goosebit/settings/__init__.py b/goosebit/settings/__init__.py index d63285d0..997de9f2 100644 --- a/goosebit/settings/__init__.py +++ b/goosebit/settings/__init__.py @@ -1,4 +1,4 @@ -from .const import BASE_DIR, PWD_CXT # noqa: F401 +from .const import PWD_CXT # noqa: F401 from .schema import GooseBitSettings config = GooseBitSettings() diff --git a/goosebit/settings/const.py b/goosebit/settings/const.py index e1c8ea55..321d1147 100644 --- a/goosebit/settings/const.py +++ b/goosebit/settings/const.py @@ -1,8 +1,10 @@ +import os from pathlib import Path from argon2 import PasswordHasher -BASE_DIR = Path(__file__).resolve().parent.parent.parent +GOOSEBIT_ROOT_DIR = Path(__file__).resolve().parent.parent.parent +CURRENT_DIR = Path(os.getcwd()) PWD_CXT = PasswordHasher() diff --git a/goosebit/settings/schema.py b/goosebit/settings/schema.py index 6ea04dde..ba711e13 100644 --- a/goosebit/settings/schema.py +++ b/goosebit/settings/schema.py @@ -1,3 +1,5 @@ +import logging +import os import secrets from pathlib import Path from typing import Annotated @@ -11,7 +13,9 @@ YamlConfigSettingsSource, ) -from .const import BASE_DIR, LOGGING_DEFAULT, PWD_CXT +from .const import CURRENT_DIR, GOOSEBIT_ROOT_DIR, LOGGING_DEFAULT, PWD_CXT + +logger = logging.getLogger(__name__) class User(BaseModel): @@ -36,8 +40,6 @@ class GooseBitSettings(BaseSettings): port: int = 60053 # GOOSE - artifacts_dir: Path = BASE_DIR.joinpath("artifacts") - poll_time_default: str = "00:01:00" poll_time_updating: str = "00:00:05" poll_time_registration: str = "00:00:10" @@ -46,7 +48,8 @@ class GooseBitSettings(BaseSettings): users: list[User] = [] - db_uri: str = f"sqlite:///{BASE_DIR.joinpath('db.sqlite3')}" + db_uri: str = f"sqlite:///{GOOSEBIT_ROOT_DIR.joinpath('db.sqlite3')}" + artifacts_dir: Path = GOOSEBIT_ROOT_DIR.joinpath("artifacts") metrics: MetricsSettings = MetricsSettings() @@ -61,9 +64,32 @@ def settings_customise_sources( dotenv_settings: PydanticBaseSettingsSource, file_secret_settings: PydanticBaseSettingsSource, ) -> tuple[PydanticBaseSettingsSource, ...]: - return ( + settings_sources = [ init_settings, - YamlConfigSettingsSource(settings_cls, BASE_DIR.joinpath("settings.yaml")), - env_settings, - file_secret_settings, + YamlConfigSettingsSource(settings_cls, GOOSEBIT_ROOT_DIR.joinpath("goosebit.yaml")), + YamlConfigSettingsSource(settings_cls, CURRENT_DIR.joinpath("goosebit.yaml")), + ] + + config_files = [] + + if (path := os.getenv("GOOSEBIT_SETTINGS")) is not None: + config_files.append(Path(path)) + + config_files.extend( + [ + CURRENT_DIR.joinpath("goosebit.yaml"), + GOOSEBIT_ROOT_DIR.joinpath("goosebit.yaml"), + Path("/etc/goosebit.yaml"), + ] ) + + for config_file in config_files: + if config_file.exists(): + settings_sources.append( + YamlConfigSettingsSource(settings_cls, config_file), + ) + logger.info(f"Selected config file to load: {config_file}") + break + + settings_sources.append(env_settings) + return tuple(settings_sources)