Raiff1982 commited on
Commit
d6288dd
·
verified ·
1 Parent(s): 4847b46

Update config.py

Browse files
Files changed (1) hide show
  1. config.py +273 -273
config.py CHANGED
@@ -1,273 +1,273 @@
1
- #!/usr/bin/env python3
2
- """
3
- Configuration management for Codette AI
4
- Centralizes all settings and configuration
5
- """
6
- import os
7
- import json
8
- from typing import Dict, Any, Optional
9
- from pathlib import Path
10
- import logging
11
-
12
- logger = logging.getLogger(__name__)
13
-
14
-
15
- class CodetteConfig:
16
- """Centralized configuration manager"""
17
-
18
- # Default configuration values
19
- DEFAULTS = {
20
- # API Configuration
21
- "api": {
22
- "host": "127.0.0.1",
23
- "port": 8000,
24
- "debug": False,
25
- "log_level": "INFO"
26
- },
27
- # Codette AI Configuration
28
- "codette": {
29
- "user_name": "User",
30
- "perspectives": ["Newton", "DaVinci", "Ethical", "Quantum", "Memory"],
31
- "spiderweb_dim": 5,
32
- "recursion_depth": 4,
33
- "quantum_fluctuation": 0.07,
34
- "memory_path": "quantum_cocoon.json"
35
- },
36
- # Database Configuration
37
- "database": {
38
- "path": "codette_data.db",
39
- "backup_enabled": True,
40
- "backup_dir": "./backups"
41
- },
42
- # Feature Flags
43
- "features": {
44
- "enable_memory": True,
45
- "enable_learning": True,
46
- "enable_analytics": False,
47
- "max_history": 1000
48
- },
49
- # Performance
50
- "performance": {
51
- "cache_enabled": True,
52
- "max_cache_size": 1000,
53
- "response_timeout": 30
54
- },
55
- # Security
56
- "security": {
57
- "require_auth": False,
58
- "password_min_length": 8,
59
- "session_timeout": 3600
60
- }
61
- }
62
-
63
- def __init__(self, config_path: Optional[str] = None):
64
- """Initialize configuration
65
-
66
- Args:
67
- config_path: Path to config JSON file (optional)
68
- """
69
- self.config = self.DEFAULTS.copy()
70
- self.config_path = config_path
71
-
72
- if config_path and os.path.exists(config_path):
73
- self._load_config_file(config_path)
74
-
75
- # Override with environment variables
76
- self._load_env_variables()
77
-
78
- def _load_config_file(self, path: str):
79
- """Load configuration from JSON file
80
-
81
- Args:
82
- path: Path to config file
83
- """
84
- try:
85
- with open(path, 'r') as f:
86
- user_config = json.load(f)
87
- self._merge_config(user_config)
88
- logger.info(f"Loaded configuration from {path}")
89
- except (FileNotFoundError, json.JSONDecodeError) as e:
90
- logger.warning(f"Could not load config file {path}: {e}")
91
-
92
- def _merge_config(self, user_config: Dict[str, Any]):
93
- """Merge user config into defaults
94
-
95
- Args:
96
- user_config: User configuration dict
97
- """
98
- for section, values in user_config.items():
99
- if section in self.config:
100
- if isinstance(values, dict):
101
- self.config[section].update(values)
102
- else:
103
- self.config[section] = values
104
- else:
105
- self.config[section] = values
106
-
107
- def _load_env_variables(self):
108
- """Load configuration from environment variables"""
109
- # API settings
110
- if host := os.getenv("CODETTE_API_HOST"):
111
- self.config["api"]["host"] = host
112
- if port := os.getenv("CODETTE_API_PORT"):
113
- self.config["api"]["port"] = int(port)
114
- if debug := os.getenv("CODETTE_DEBUG"):
115
- self.config["api"]["debug"] = debug.lower() in ("true", "1", "yes")
116
-
117
- # Database settings
118
- if db_path := os.getenv("CODETTE_DB_PATH"):
119
- self.config["database"]["path"] = db_path
120
-
121
- # Codette settings
122
- if user_name := os.getenv("CODETTE_USER_NAME"):
123
- self.config["codette"]["user_name"] = user_name
124
-
125
- def get(self, section: str, key: Optional[str] = None, default: Any = None) -> Any:
126
- """Get configuration value
127
-
128
- Args:
129
- section: Configuration section
130
- key: Optional key within section
131
- default: Default value if not found
132
-
133
- Returns:
134
- Configuration value
135
- """
136
- if section not in self.config:
137
- return default
138
-
139
- if key is None:
140
- return self.config.get(section, default)
141
-
142
- if isinstance(self.config[section], dict):
143
- return self.config[section].get(key, default)
144
-
145
- return default
146
-
147
- def set(self, section: str, key: str, value: Any):
148
- """Set configuration value
149
-
150
- Args:
151
- section: Configuration section
152
- key: Key within section
153
- value: New value
154
- """
155
- if section not in self.config:
156
- self.config[section] = {}
157
-
158
- if isinstance(self.config[section], dict):
159
- self.config[section][key] = value
160
- else:
161
- logger.warning(f"Cannot set {section}.{key}: section is not a dict")
162
-
163
- def save(self, path: str):
164
- """Save configuration to file
165
-
166
- Args:
167
- path: Path to save config
168
- """
169
- try:
170
- Path(path).parent.mkdir(parents=True, exist_ok=True)
171
- with open(path, 'w') as f:
172
- json.dump(self.config, f, indent=2)
173
- logger.info(f"Configuration saved to {path}")
174
- except IOError as e:
175
- logger.error(f"Could not save configuration: {e}")
176
-
177
- def to_dict(self) -> Dict[str, Any]:
178
- """Get config as dictionary
179
-
180
- Returns:
181
- Configuration dictionary
182
- """
183
- return self.config.copy()
184
-
185
- def validate(self) -> bool:
186
- """Validate configuration
187
-
188
- Returns:
189
- True if valid, False otherwise
190
- """
191
- required_sections = ["api", "codette", "database"]
192
-
193
- for section in required_sections:
194
- if section not in self.config:
195
- logger.error(f"Missing required section: {section}")
196
- return False
197
-
198
- # Validate API port
199
- api_port = self.config["api"]["port"]
200
- if not (0 < api_port < 65536):
201
- logger.error(f"Invalid API port: {api_port}")
202
- return False
203
-
204
- return True
205
-
206
-
207
- # Global configuration instance
208
- _config: Optional[CodetteConfig] = None
209
-
210
-
211
- def get_config(config_path: Optional[str] = None) -> CodetteConfig:
212
- """Get or create global config instance
213
-
214
- Args:
215
- config_path: Optional path to config file
216
-
217
- Returns:
218
- CodetteConfig instance
219
- """
220
- global _config
221
- if _config is None:
222
- _config = CodetteConfig(config_path)
223
- return _config
224
-
225
-
226
- # Convenience getters
227
- def get_api_host() -> str:
228
- """Get API host"""
229
- return get_config().get("api", "host", "127.0.0.1")
230
-
231
-
232
- def get_api_port() -> int:
233
- """Get API port"""
234
- return get_config().get("api", "port", 8000)
235
-
236
-
237
- def get_db_path() -> str:
238
- """Get database path"""
239
- return get_config().get("database", "path", "codette_data.db")
240
-
241
-
242
- def get_codette_user_name() -> str:
243
- """Get Codette user name"""
244
- return get_config().get("codette", "user_name", "User")
245
-
246
-
247
- # Backwards compatibility - Bot Configuration
248
- class DefaultConfig:
249
- """Legacy Bot Configuration - kept for compatibility"""
250
-
251
- PORT = 3978
252
- APP_ID = os.environ.get("MicrosoftAppId", "")
253
- APP_PASSWORD = os.environ.get("MicrosoftAppPassword", "")
254
-
255
-
256
- if __name__ == "__main__":
257
- # Test configuration
258
- logging.basicConfig(level=logging.INFO)
259
-
260
- config = get_config()
261
-
262
- print("\n=== Codette Configuration ===\n")
263
- print(f"API: {config.get('api', 'host')}:{config.get('api', 'port')}")
264
- print(f"Database: {config.get('database', 'path')}")
265
- print(f"Codette User: {config.get('codette', 'user_name')}")
266
- print(f"Perspectives: {config.get('codette', 'perspectives')}")
267
-
268
- # Validate
269
- if config.validate():
270
- print("\n✓ Configuration is valid\n")
271
- else:
272
- print("\n✗ Configuration is invalid\n")
273
-
 
1
+ #!/usr/bin/env python3
2
+ """
3
+ Configuration management for Codette AI
4
+ Centralizes all settings and configuration
5
+ """
6
+ import os
7
+ import json
8
+ from typing import Dict, Any, Optional
9
+ from pathlib import Path
10
+ import logging
11
+
12
+ logger = logging.getLogger(__name__)
13
+
14
+
15
+ class CodetteConfig:
16
+ """Centralized configuration manager"""
17
+
18
+ # Default configuration values
19
+ DEFAULTS = {
20
+ # API Configuration
21
+ "api": {
22
+ "host": "127.0.0.1",
23
+ "port": 8000,
24
+ "debug": False,
25
+ "log_level": "INFO"
26
+ },
27
+ # Codette AI Configuration
28
+ "codette": {
29
+ "user_name": "Jonathan",
30
+ "perspectives": ["Newton", "DaVinci", "Ethical", "Quantum", "Memory"],
31
+ "spiderweb_dim": 5,
32
+ "recursion_depth": 4,
33
+ "quantum_fluctuation": 0.07,
34
+ "memory_path": "quantum_cocoon.json"
35
+ },
36
+ # Database Configuration
37
+ "database": {
38
+ "path": "codette_data.db",
39
+ "backup_enabled": True,
40
+ "backup_dir": "./backups"
41
+ },
42
+ # Feature Flags
43
+ "features": {
44
+ "enable_memory": True,
45
+ "enable_learning": True,
46
+ "enable_analytics": False,
47
+ "max_history": 1000
48
+ },
49
+ # Performance
50
+ "performance": {
51
+ "cache_enabled": True,
52
+ "max_cache_size": 1000,
53
+ "response_timeout": 30
54
+ },
55
+ # Security
56
+ "security": {
57
+ "require_auth": False,
58
+ "password_min_length": 8,
59
+ "session_timeout": 3600
60
+ }
61
+ }
62
+
63
+ def __init__(self, config_path: Optional[str] = None):
64
+ """Initialize configuration
65
+
66
+ Args:
67
+ config_path: Path to config JSON file (optional)
68
+ """
69
+ self.config = self.DEFAULTS.copy()
70
+ self.config_path = config_path
71
+
72
+ if config_path and os.path.exists(config_path):
73
+ self._load_config_file(config_path)
74
+
75
+ # Override with environment variables
76
+ self._load_env_variables()
77
+
78
+ def _load_config_file(self, path: str):
79
+ """Load configuration from JSON file
80
+
81
+ Args:
82
+ path: Path to config file
83
+ """
84
+ try:
85
+ with open(path, 'r') as f:
86
+ user_config = json.load(f)
87
+ self._merge_config(user_config)
88
+ logger.info(f"Loaded configuration from {path}")
89
+ except (FileNotFoundError, json.JSONDecodeError) as e:
90
+ logger.warning(f"Could not load config file {path}: {e}")
91
+
92
+ def _merge_config(self, user_config: Dict[str, Any]):
93
+ """Merge user config into defaults
94
+
95
+ Args:
96
+ user_config: User configuration dict
97
+ """
98
+ for section, values in user_config.items():
99
+ if section in self.config:
100
+ if isinstance(values, dict):
101
+ self.config[section].update(values)
102
+ else:
103
+ self.config[section] = values
104
+ else:
105
+ self.config[section] = values
106
+
107
+ def _load_env_variables(self):
108
+ """Load configuration from environment variables"""
109
+ # API settings
110
+ if host := os.getenv("CODETTE_API_HOST"):
111
+ self.config["api"]["host"] = host
112
+ if port := os.getenv("CODETTE_API_PORT"):
113
+ self.config["api"]["port"] = int(port)
114
+ if debug := os.getenv("CODETTE_DEBUG"):
115
+ self.config["api"]["debug"] = debug.lower() in ("true", "1", "yes")
116
+
117
+ # Database settings
118
+ if db_path := os.getenv("CODETTE_DB_PATH"):
119
+ self.config["database"]["path"] = db_path
120
+
121
+ # Codette settings
122
+ if user_name := os.getenv("CODETTE_USER_NAME"):
123
+ self.config["codette"]["user_name"] = user_name
124
+
125
+ def get(self, section: str, key: Optional[str] = None, default: Any = None) -> Any:
126
+ """Get configuration value
127
+
128
+ Args:
129
+ section: Configuration section
130
+ key: Optional key within section
131
+ default: Default value if not found
132
+
133
+ Returns:
134
+ Configuration value
135
+ """
136
+ if section not in self.config:
137
+ return default
138
+
139
+ if key is None:
140
+ return self.config.get(section, default)
141
+
142
+ if isinstance(self.config[section], dict):
143
+ return self.config[section].get(key, default)
144
+
145
+ return default
146
+
147
+ def set(self, section: str, key: str, value: Any):
148
+ """Set configuration value
149
+
150
+ Args:
151
+ section: Configuration section
152
+ key: Key within section
153
+ value: New value
154
+ """
155
+ if section not in self.config:
156
+ self.config[section] = {}
157
+
158
+ if isinstance(self.config[section], dict):
159
+ self.config[section][key] = value
160
+ else:
161
+ logger.warning(f"Cannot set {section}.{key}: section is not a dict")
162
+
163
+ def save(self, path: str):
164
+ """Save configuration to file
165
+
166
+ Args:
167
+ path: Path to save config
168
+ """
169
+ try:
170
+ Path(path).parent.mkdir(parents=True, exist_ok=True)
171
+ with open(path, 'w') as f:
172
+ json.dump(self.config, f, indent=2)
173
+ logger.info(f"Configuration saved to {path}")
174
+ except IOError as e:
175
+ logger.error(f"Could not save configuration: {e}")
176
+
177
+ def to_dict(self) -> Dict[str, Any]:
178
+ """Get config as dictionary
179
+
180
+ Returns:
181
+ Configuration dictionary
182
+ """
183
+ return self.config.copy()
184
+
185
+ def validate(self) -> bool:
186
+ """Validate configuration
187
+
188
+ Returns:
189
+ True if valid, False otherwise
190
+ """
191
+ required_sections = ["api", "codette", "database"]
192
+
193
+ for section in required_sections:
194
+ if section not in self.config:
195
+ logger.error(f"Missing required section: {section}")
196
+ return False
197
+
198
+ # Validate API port
199
+ api_port = self.config["api"]["port"]
200
+ if not (0 < api_port < 65536):
201
+ logger.error(f"Invalid API port: {api_port}")
202
+ return False
203
+
204
+ return True
205
+
206
+
207
+ # Global configuration instance
208
+ _config: Optional[CodetteConfig] = None
209
+
210
+
211
+ def get_config(config_path: Optional[str] = None) -> CodetteConfig:
212
+ """Get or create global config instance
213
+
214
+ Args:
215
+ config_path: Optional path to config file
216
+
217
+ Returns:
218
+ CodetteConfig instance
219
+ """
220
+ global _config
221
+ if _config is None:
222
+ _config = CodetteConfig(config_path)
223
+ return _config
224
+
225
+
226
+ # Convenience getters
227
+ def get_api_host() -> str:
228
+ """Get API host"""
229
+ return get_config().get("api", "host", "127.0.0.1")
230
+
231
+
232
+ def get_api_port() -> int:
233
+ """Get API port"""
234
+ return get_config().get("api", "port", 8000)
235
+
236
+
237
+ def get_db_path() -> str:
238
+ """Get database path"""
239
+ return get_config().get("database", "path", "codette_data.db")
240
+
241
+
242
+ def get_codette_user_name() -> str:
243
+ """Get Codette user name"""
244
+ return get_config().get("codette", "user_name", "User")
245
+
246
+
247
+ # Backwards compatibility - Bot Configuration
248
+ class DefaultConfig:
249
+ """Legacy Bot Configuration - kept for compatibility"""
250
+
251
+ PORT = 3978
252
+ APP_ID = os.environ.get("MicrosoftAppId", "")
253
+ APP_PASSWORD = os.environ.get("MicrosoftAppPassword", "")
254
+
255
+
256
+ if __name__ == "__main__":
257
+ # Test configuration
258
+ logging.basicConfig(level=logging.INFO)
259
+
260
+ config = get_config()
261
+
262
+ print("\n=== Codette Configuration ===\n")
263
+ print(f"API: {config.get('api', 'host')}:{config.get('api', 'port')}")
264
+ print(f"Database: {config.get('database', 'path')}")
265
+ print(f"Codette User: {config.get('codette', 'user_name')}")
266
+ print(f"Perspectives: {config.get('codette', 'perspectives')}")
267
+
268
+ # Validate
269
+ if config.validate():
270
+ print("\n✓ Configuration is valid\n")
271
+ else:
272
+ print("\n✗ Configuration is invalid\n")
273
+