"""Environment variable loader for .env files and os.environ.""" import os from pathlib import Path from typing import Optional from dotenv import dotenv_values class EnvLoader: """Load environment variables from .env files or os.environ.""" def __init__(self, file_path: Optional[str] = None, use_environment: bool = True): """Initialize the loader. Args: file_path: Path to .env file. If None, only uses os.environ. use_environment: Whether to include os.environ as fallback. """ self.file_path = file_path self.use_environment = use_environment self._env_vars: dict[str, str] = {} def load(self) -> dict[str, str]: """Load environment variables. Returns: Dictionary of environment variable names to values. """ self._env_vars = {} if self.file_path: path = Path(self.file_path) if path.exists(): file_values = dotenv_values(str(path)) for key, value in file_values.items(): if value is not None: self._env_vars[key] = value if self.use_environment: for key, value in os.environ.items(): if key not in self._env_vars: self._env_vars[key] = value return self._env_vars def get(self, key: str, default: Optional[str] = None) -> Optional[str]: """Get an environment variable value. Args: key: Variable name. default: Default value if not found. Returns: Variable value or default. """ if not self._env_vars: self.load() return self._env_vars.get(key, default) def get_raw(self) -> dict[str, str]: """Get all loaded variables as a raw dictionary. Returns: Dictionary of all loaded environment variables. """ if not self._env_vars: self.load() return self._env_vars.copy() def set(self, key: str, value: str) -> None: """Set an environment variable value in memory. Args: key: Variable name. value: Variable value. """ self._env_vars[key] = value def load_env_file(file_path: str) -> dict[str, str]: """Convenience function to load environment from a file. Args: file_path: Path to .env file. Returns: Dictionary of environment variables. """ loader = EnvLoader(file_path=file_path, use_environment=False) return loader.load()