Skip to content

Instantly share code, notes, and snippets.

@javiergarciad
Last active June 28, 2023 15:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save javiergarciad/af922336f0ff8b6edea65944e0e98e78 to your computer and use it in GitHub Desktop.
Save javiergarciad/af922336f0ff8b6edea65944e0e98e78 to your computer and use it in GitHub Desktop.
Config class for storing and accessing configurations.
from dotenv import dotenv_values
class Config:
"""
v0.2
Config class for storing and accessing configurations.
This class loads configurations from different sources, such as '.env' files and environment variables,
and provides a convenient way to access the configuration values.
Attributes:
_config (dict): Dictionary to store the configuration values.
Methods:
__init__(): Initializes the Config object and loads the configuration values.
__getattr__(name): Allows accessing the configuration values using dot notation.
get(name, default=None): Retrieves the configuration value with optional default value.
validate(): Validates the configuration values.
load_from_dotenv(file_paths): Loads configuration values from .env files.
load_from_environment_variables(): Loads configuration values from environment variables.
"""
def __init__(self, envs_list: list[str]):
"""
Initializes the Config object and loads the configuration values.
The configuration values are loaded from multiple sources, including '.env' files and environment variables.
The values from different sources are merged, with higher priority given to environment variables.
Environment variables override the values loaded from '.env' files.
"""
self._config = {}
self._envroot = Path(__file__).parent.parent.parent / "envs"
self._envs_list = [self._envroot / env for env in envs_list]
# load the .env files
self.load_from_dotenv()
self.load_from_environment_variables()
def __getattr__(self, name: str) -> str | AttributeError:
"""
Allows accessing the configuration values using dot notation.
Args:
name (str): The name of the configuration variable.
Returns:
The value of the configuration variable.
Raises:
AttributeError: If the configuration variable does not exist.
"""
if name in self._config:
return self._config[name]
else:
raise AttributeError(f"Configuration variable '{name}' does not exist.")
def get(self, name: str, default: str | None = None) -> str | None:
"""
Retrieves the configuration value with optional default value.
Args:
name (str): The name of the configuration variable.
default (any, optional): The default value to return if the configuration variable is not found.
Defaults to None.
Returns:
The value of the configuration variable, or the default value if not found.
"""
return self._config.get(name, default)
def validate(self) -> ValueError | None:
"""
Validates the configuration values.
Raises:
ValueError: If a required configuration variable is missing or has an invalid value.
"""
required_variables = ["SECRET_KEY", "DATABASE_URL"]
for variable in required_variables:
if variable not in self._config:
raise ValueError(
f"Required configuration variable '{variable}' is missing."
)
# Additional validation logic for specific variables
# if self._config.get("SOME_VARIABLE") is None:
# raise ValueError("Some variable is required.")
# Perform more validations as needed
def load_from_dotenv(self) -> None:
"""
Loads configuration values from .env files.
Args:
file_paths (list): List of file paths for the .env files.
"""
envs_file_paths = self._envs_list
for file_path in envs_file_paths:
dot_values = dotenv_values(file_path)
self._config.update(dot_values)
def load_from_environment_variables(self) -> None:
"""
Loads configuration values from environment variables.
"""
environment_variables = os.environ
self._config.update(environment_variables)
@property
def config(self) -> dict:
"""
Returns the configuration values as an immutable dictionary.
Returns:
dict: The configuration values.
"""
return dict(self._config)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment