diff --git a/sijapi/classes.py b/sijapi/classes.py index 7ce1b5b..55257ee 100644 --- a/sijapi/classes.py +++ b/sijapi/classes.py @@ -211,30 +211,30 @@ class Configuration(BaseModel): class DirConfig(BaseModel): HOME: Path = Path.home() - + @classmethod def load(cls, yaml_path: Union[str, Path]) -> 'DirConfig': yaml_path = cls._resolve_path(yaml_path, 'config') - + try: with yaml_path.open('r') as file: config_data = yaml.safe_load(file) - + print(f"Loaded configuration data from {yaml_path}") - + # Ensure HOME is set if 'HOME' not in config_data: config_data['HOME'] = str(Path.home()) print(f"HOME was not in config, set to default: {config_data['HOME']}") - + instance = cls.create_dynamic_model(**config_data) - resolved_data = instance.resolve_placeholders(config_data) + resolved_data = instance.resolve_placeholders(config_data, {}) return cls.create_dynamic_model(**resolved_data) - + except Exception as e: print(f"Error loading configuration: {str(e)}") raise - + @classmethod def _resolve_path(cls, path: Union[str, Path], default_dir: str) -> Path: base_path = Path(__file__).parent.parent @@ -244,10 +244,10 @@ class DirConfig(BaseModel): elif not path.is_absolute(): path = base_path / path return path - - def resolve_placeholders(self, data: Any) -> Any: + + def resolve_placeholders(self, data: Any, secrets_data: Dict[str, Any]) -> Any: if isinstance(data, dict): - resolved_data = {k: self.resolve_placeholders(v) for k, v in data.items()} + resolved_data = {k: self.resolve_placeholders(v, secrets_data) for k, v in data.items()} home_dir = Path(resolved_data.get('HOME', self.HOME)).expanduser() base_dir = Path(__file__).parent.parent data_dir = base_dir / "data" @@ -256,16 +256,16 @@ class DirConfig(BaseModel): resolved_data['DATA'] = str(data_dir) return resolved_data elif isinstance(data, list): - return [self.resolve_placeholders(v) for v in data] + return [self.resolve_placeholders(v, secrets_data) for v in data] elif isinstance(data, str): - return self.resolve_string_placeholders(data) + return self.resolve_string_placeholders(data, secrets_data, self.HOME) else: return data - + def resolve_string_placeholders(self, value: str, secrets_data: Dict[str, Any], home_dir: Path) -> Any: pattern = r'\{\{\s*([^}]+)\s*\}\}' matches = re.findall(pattern, value) - + for match in matches: parts = match.split('.') if len(parts) == 1: # Internal reference @@ -274,23 +274,13 @@ class DirConfig(BaseModel): replacement = str(home_dir / parts[1].lower()) elif len(parts) == 2 and parts[0] == 'ENV': replacement = os.getenv(parts[1], '') - elif len(parts) == 2 and parts[0] == 'SECRET': - secret_key = parts[1].strip() # Remove any leading/trailing whitespace - replacement = secrets_data.get(secret_key) - if replacement is None: - warn(f"Secret '{secret_key}' not found in secrets file") - replacement = '' else: replacement = value - - value = value.replace('{{' + match + '}}', str(replacement)) - - # Convert to Path if it looks like a file path - if isinstance(value, str) and (value.startswith(('/', '~')) or (':' in value and value[1] == ':')): - return Path(value).expanduser() - return value - - + + value = value.replace('{{' + match + '}}', replacement) + + return Path(value).expanduser() if value.startswith(('/', '~')) else value + @classmethod def create_dynamic_model(cls, **data): DynamicModel = create_model( @@ -299,11 +289,12 @@ class DirConfig(BaseModel): **{k: (Path, v) for k, v in data.items()} ) return DynamicModel(**data) - + class Config: arbitrary_types_allowed = True + # Configuration class for API & Database methods. class APIConfig(BaseModel): HOST: str