72 lines
1.8 KiB
Python
72 lines
1.8 KiB
Python
"""Load global config."""
|
|
import os
|
|
from pathlib import Path
|
|
from typing import Union
|
|
|
|
from dotenv import load_dotenv
|
|
from yaml import load
|
|
|
|
from jarvis_core.util import Singleton
|
|
|
|
try:
|
|
from yaml import CLoader as Loader
|
|
except ImportError:
|
|
from yaml import Loader
|
|
|
|
DEFAULT_YAML_PATH = Path("config.yaml")
|
|
DEFAULT_ENV_PATH = Path(".env")
|
|
|
|
|
|
class Config(Singleton):
|
|
REQUIRED = []
|
|
OPTIONAL = {}
|
|
ENV_REQUIRED = []
|
|
ENV_OPTIONAL = {}
|
|
|
|
@classmethod
|
|
def _process_env(cls, **kwargs) -> dict:
|
|
"""Process environment variables into standard arguments"""
|
|
|
|
@classmethod
|
|
def from_env(cls, filepath: Union[Path, str] = DEFAULT_ENV_PATH) -> "Config":
|
|
"""Loag the environment config."""
|
|
if inst := cls.__dict__.get("inst"):
|
|
return inst
|
|
|
|
load_dotenv(filepath)
|
|
|
|
data = {}
|
|
for item in cls.ENV_REQUIRED:
|
|
data[item] = os.environ.get(item, None)
|
|
for item, default in cls.ENV_OPTIONAL.items():
|
|
data[item] = os.environ.get(item, default)
|
|
|
|
data = cls._process_env(**data)
|
|
|
|
return cls(**data)
|
|
|
|
@classmethod
|
|
def from_yaml(cls, filepath: Union[Path, str] = DEFAULT_YAML_PATH) -> "Config":
|
|
"""Load the yaml config file."""
|
|
if inst := cls.__dict__.get("inst"):
|
|
return inst
|
|
|
|
if isinstance(filepath, str):
|
|
filepath = Path(filepath)
|
|
|
|
with filepath.open() as f:
|
|
raw = f.read()
|
|
|
|
y = load(raw, Loader=Loader)
|
|
return cls(**y)
|
|
|
|
@classmethod
|
|
def load(cls) -> "Config":
|
|
if DEFAULT_ENV_PATH.exists():
|
|
return cls.from_env()
|
|
return cls.from_yaml()
|
|
|
|
@classmethod
|
|
def reload(cls) -> bool:
|
|
"""Reload the config."""
|
|
return cls.__dict__.pop("inst", None) is None
|