Last active
December 15, 2022 07:56
-
-
Save huaxlin/5494f1510eceafdd8dfe669a37ba9aa5 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from pathlib import Path | |
from typing import Any, Dict, Optional, Union | |
from hydra import compose, initialize_config_dir | |
from omegaconf import DictConfig | |
from pydantic import BaseModel, BaseSettings | |
from pydantic.env_settings import SettingsSourceCallable | |
# {python project}/app/config.py | |
project_dir = Path(__file__).parent.parent | |
def dictconfig_to_pydict(cfg) -> dict: | |
"""convert omegaconf.DictConfig to python build-in dict | |
If initialized Settings with hydra and | |
BaseSetting#changing-priority(env_settings > init_settings ...), | |
there is bug when partial override config by environ variable. | |
Convert dictconfig to python build-in dict to fix it. | |
""" | |
if not isinstance(cfg, DictConfig): | |
return cfg | |
return {k: dictconfig_to_pydict(v) for k, v in cfg.items()} | |
def hydra_config_settings_source(settings: BaseSettings) -> Dict[str, Any]: | |
# https://docs.pydantic.dev/usage/settings/#adding-sources | |
config_dir, config_name = str(project_dir), 'config.yaml' | |
try: | |
initialize_config_dir(version_base=None, config_dir=config_dir) | |
_cfg = compose(config_name) | |
return dictconfig_to_pydict(_cfg) | |
except Exception as exc: | |
raise ValueError(f"initialize config fail. {config_dir = }; {config_name = }") from exc | |
class Mongo(BaseModel): | |
HOST: str | |
PORT: int | |
DBNAME: str | |
USER: Optional[str] = None | |
PASSWORD: Optional[str] = None | |
class Stuff(BaseModel): | |
URL: str | |
TIMEOUT: int | |
class Settings(BaseSettings): | |
MONGO: Mongo | |
STUFF: Stuff | |
class Config: | |
case_sensitive = True | |
frozen = True | |
env_nested_delimiter = "__" | |
env_file = ".env" | |
env_file_encoding = "utf-8" | |
# https://pydantic-docs.helpmanual.io/usage/settings/#changing-priority | |
@classmethod | |
def customise_sources( | |
cls, | |
init_settings: SettingsSourceCallable, | |
env_settings: SettingsSourceCallable, | |
file_secret_settings: SettingsSourceCallable, | |
) -> tuple[SettingsSourceCallable, ...]: | |
return env_settings, init_settings, hydra_config_settings_source, file_secret_settings | |
settings = Settings() | |
if __name__ == '__main__': | |
print(settings) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment