geronimo.config.user_config
User configuration management for Geronimo.
Provides persistent global settings stored in ~/.geronimo/config.yaml. Settings apply as defaults for all projects.
1"""User configuration management for Geronimo. 2 3Provides persistent global settings stored in ~/.geronimo/config.yaml. 4Settings apply as defaults for all projects. 5""" 6 7import os 8from dataclasses import dataclass, field 9from pathlib import Path 10from typing import Literal, Optional 11 12import yaml 13 14 15# Default config location 16USER_CONFIG_DIR = Path.home() / ".geronimo" 17USER_CONFIG_FILE = USER_CONFIG_DIR / "config.yaml" 18 19 20@dataclass 21class ArtifactConfig: 22 """Configuration for ArtifactStore defaults.""" 23 24 backend: Literal["local", "s3", "gdc"] = "local" 25 """Default storage backend.""" 26 27 s3_bucket: Optional[str] = None 28 """Default S3 bucket (if backend is s3).""" 29 30 base_path: str = "~/.geronimo/artifacts" 31 """Default local base path (if backend is local).""" 32 33 34@dataclass 35class DefaultsConfig: 36 """Default project initialization settings.""" 37 38 framework: str = "sklearn" 39 """Default ML framework.""" 40 41 template: str = "realtime" 42 """Default project template.""" 43 44 45@dataclass 46class UserConfig: 47 """Global user configuration. 48 49 Stored in ~/.geronimo/config.yaml. 50 """ 51 52 artifacts: ArtifactConfig = field(default_factory=ArtifactConfig) 53 """Artifact storage configuration.""" 54 55 defaults: DefaultsConfig = field(default_factory=DefaultsConfig) 56 """Default project settings.""" 57 58 59def load_user_config() -> UserConfig: 60 """Load global config from ~/.geronimo/config.yaml. 61 62 Returns default config if file doesn't exist. 63 64 Returns: 65 UserConfig with loaded or default settings. 66 """ 67 if not USER_CONFIG_FILE.exists(): 68 return UserConfig() 69 70 try: 71 with open(USER_CONFIG_FILE) as f: 72 data = yaml.safe_load(f) or {} 73 74 # Parse artifacts section 75 artifacts_data = data.get("artifacts", {}) 76 artifacts = ArtifactConfig( 77 backend=artifacts_data.get("backend", "local"), 78 s3_bucket=artifacts_data.get("s3_bucket"), 79 base_path=artifacts_data.get("base_path", "~/.geronimo/artifacts"), 80 ) 81 82 # Parse defaults section 83 defaults_data = data.get("defaults", {}) 84 defaults = DefaultsConfig( 85 framework=defaults_data.get("framework", "sklearn"), 86 template=defaults_data.get("template", "realtime"), 87 ) 88 89 return UserConfig(artifacts=artifacts, defaults=defaults) 90 except Exception: 91 # Return defaults on any parsing error 92 return UserConfig() 93 94 95def save_user_config(config: UserConfig) -> None: 96 """Save global config to ~/.geronimo/config.yaml. 97 98 Creates ~/.geronimo directory if it doesn't exist. 99 100 Args: 101 config: UserConfig to save. 102 """ 103 USER_CONFIG_DIR.mkdir(parents=True, exist_ok=True) 104 105 data = { 106 "artifacts": { 107 "backend": config.artifacts.backend, 108 "s3_bucket": config.artifacts.s3_bucket, 109 "base_path": config.artifacts.base_path, 110 }, 111 "defaults": { 112 "framework": config.defaults.framework, 113 "template": config.defaults.template, 114 }, 115 } 116 117 # Remove None values for cleaner YAML 118 data["artifacts"] = {k: v for k, v in data["artifacts"].items() if v is not None} 119 120 with open(USER_CONFIG_FILE, "w") as f: 121 yaml.dump(data, f, default_flow_style=False, sort_keys=False) 122 123 124def get_config_value(key: str) -> Optional[str]: 125 """Get a specific config value by dot-notation key. 126 127 Args: 128 key: Dot-notation key like "artifacts.backend" 129 130 Returns: 131 Value as string, or None if not found. 132 """ 133 config = load_user_config() 134 135 parts = key.split(".") 136 if len(parts) != 2: 137 return None 138 139 section, field = parts 140 141 if section == "artifacts": 142 return getattr(config.artifacts, field, None) 143 elif section == "defaults": 144 return getattr(config.defaults, field, None) 145 146 return None 147 148 149def set_config_value(key: str, value: str) -> bool: 150 """Set a specific config value by dot-notation key. 151 152 Args: 153 key: Dot-notation key like "artifacts.backend" 154 value: Value to set 155 156 Returns: 157 True if successful, False if invalid key. 158 """ 159 config = load_user_config() 160 161 parts = key.split(".") 162 if len(parts) != 2: 163 return False 164 165 section, field_name = parts 166 167 if section == "artifacts": 168 if field_name == "backend": 169 if value not in ("local", "s3", "gdc"): 170 return False 171 config.artifacts.backend = value 172 elif field_name == "s3_bucket": 173 config.artifacts.s3_bucket = value 174 elif field_name == "base_path": 175 config.artifacts.base_path = value 176 else: 177 return False 178 elif section == "defaults": 179 if field_name == "framework": 180 config.defaults.framework = value 181 elif field_name == "template": 182 config.defaults.template = value 183 else: 184 return False 185 else: 186 return False 187 188 save_user_config(config) 189 return True 190 191 192def reset_user_config() -> None: 193 """Reset config to defaults by deleting the config file.""" 194 if USER_CONFIG_FILE.exists(): 195 USER_CONFIG_FILE.unlink()
21@dataclass 22class ArtifactConfig: 23 """Configuration for ArtifactStore defaults.""" 24 25 backend: Literal["local", "s3", "gdc"] = "local" 26 """Default storage backend.""" 27 28 s3_bucket: Optional[str] = None 29 """Default S3 bucket (if backend is s3).""" 30 31 base_path: str = "~/.geronimo/artifacts" 32 """Default local base path (if backend is local)."""
Configuration for ArtifactStore defaults.
35@dataclass 36class DefaultsConfig: 37 """Default project initialization settings.""" 38 39 framework: str = "sklearn" 40 """Default ML framework.""" 41 42 template: str = "realtime" 43 """Default project template."""
Default project initialization settings.
46@dataclass 47class UserConfig: 48 """Global user configuration. 49 50 Stored in ~/.geronimo/config.yaml. 51 """ 52 53 artifacts: ArtifactConfig = field(default_factory=ArtifactConfig) 54 """Artifact storage configuration.""" 55 56 defaults: DefaultsConfig = field(default_factory=DefaultsConfig) 57 """Default project settings."""
Global user configuration.
Stored in ~/.geronimo/config.yaml.
60def load_user_config() -> UserConfig: 61 """Load global config from ~/.geronimo/config.yaml. 62 63 Returns default config if file doesn't exist. 64 65 Returns: 66 UserConfig with loaded or default settings. 67 """ 68 if not USER_CONFIG_FILE.exists(): 69 return UserConfig() 70 71 try: 72 with open(USER_CONFIG_FILE) as f: 73 data = yaml.safe_load(f) or {} 74 75 # Parse artifacts section 76 artifacts_data = data.get("artifacts", {}) 77 artifacts = ArtifactConfig( 78 backend=artifacts_data.get("backend", "local"), 79 s3_bucket=artifacts_data.get("s3_bucket"), 80 base_path=artifacts_data.get("base_path", "~/.geronimo/artifacts"), 81 ) 82 83 # Parse defaults section 84 defaults_data = data.get("defaults", {}) 85 defaults = DefaultsConfig( 86 framework=defaults_data.get("framework", "sklearn"), 87 template=defaults_data.get("template", "realtime"), 88 ) 89 90 return UserConfig(artifacts=artifacts, defaults=defaults) 91 except Exception: 92 # Return defaults on any parsing error 93 return UserConfig()
Load global config from ~/.geronimo/config.yaml.
Returns default config if file doesn't exist.
Returns: UserConfig with loaded or default settings.
96def save_user_config(config: UserConfig) -> None: 97 """Save global config to ~/.geronimo/config.yaml. 98 99 Creates ~/.geronimo directory if it doesn't exist. 100 101 Args: 102 config: UserConfig to save. 103 """ 104 USER_CONFIG_DIR.mkdir(parents=True, exist_ok=True) 105 106 data = { 107 "artifacts": { 108 "backend": config.artifacts.backend, 109 "s3_bucket": config.artifacts.s3_bucket, 110 "base_path": config.artifacts.base_path, 111 }, 112 "defaults": { 113 "framework": config.defaults.framework, 114 "template": config.defaults.template, 115 }, 116 } 117 118 # Remove None values for cleaner YAML 119 data["artifacts"] = {k: v for k, v in data["artifacts"].items() if v is not None} 120 121 with open(USER_CONFIG_FILE, "w") as f: 122 yaml.dump(data, f, default_flow_style=False, sort_keys=False)
Save global config to ~/.geronimo/config.yaml.
Creates ~/.geronimo directory if it doesn't exist.
Args: config: UserConfig to save.
125def get_config_value(key: str) -> Optional[str]: 126 """Get a specific config value by dot-notation key. 127 128 Args: 129 key: Dot-notation key like "artifacts.backend" 130 131 Returns: 132 Value as string, or None if not found. 133 """ 134 config = load_user_config() 135 136 parts = key.split(".") 137 if len(parts) != 2: 138 return None 139 140 section, field = parts 141 142 if section == "artifacts": 143 return getattr(config.artifacts, field, None) 144 elif section == "defaults": 145 return getattr(config.defaults, field, None) 146 147 return None
Get a specific config value by dot-notation key.
Args: key: Dot-notation key like "artifacts.backend"
Returns: Value as string, or None if not found.
150def set_config_value(key: str, value: str) -> bool: 151 """Set a specific config value by dot-notation key. 152 153 Args: 154 key: Dot-notation key like "artifacts.backend" 155 value: Value to set 156 157 Returns: 158 True if successful, False if invalid key. 159 """ 160 config = load_user_config() 161 162 parts = key.split(".") 163 if len(parts) != 2: 164 return False 165 166 section, field_name = parts 167 168 if section == "artifacts": 169 if field_name == "backend": 170 if value not in ("local", "s3", "gdc"): 171 return False 172 config.artifacts.backend = value 173 elif field_name == "s3_bucket": 174 config.artifacts.s3_bucket = value 175 elif field_name == "base_path": 176 config.artifacts.base_path = value 177 else: 178 return False 179 elif section == "defaults": 180 if field_name == "framework": 181 config.defaults.framework = value 182 elif field_name == "template": 183 config.defaults.template = value 184 else: 185 return False 186 else: 187 return False 188 189 save_user_config(config) 190 return True
Set a specific config value by dot-notation key.
Args: key: Dot-notation key like "artifacts.backend" value: Value to set
Returns: True if successful, False if invalid key.
193def reset_user_config() -> None: 194 """Reset config to defaults by deleting the config file.""" 195 if USER_CONFIG_FILE.exists(): 196 USER_CONFIG_FILE.unlink()
Reset config to defaults by deleting the config file.