mrradix commited on
Commit
ce9686e
·
verified ·
1 Parent(s): 13eeac4

Update utils/config.py

Browse files
Files changed (1) hide show
  1. utils/config.py +140 -221
utils/config.py CHANGED
@@ -1,233 +1,152 @@
1
- """
2
- Configuration module for the MONA application.
3
-
4
- This module centralizes all configuration settings and constants used throughout
5
- the application, making it easier to maintain and modify settings in one place.
6
- """
7
-
8
  import os
9
- from pathlib import Path
 
 
10
 
11
- # Base paths
12
- BASE_DIR = Path(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
13
- DATA_DIR = BASE_DIR / "data"
14
- EXPORT_DIR = DATA_DIR / "exports"
15
- BACKUP_DIR = DATA_DIR / "backups"
16
 
17
- # Ensure directories exist
18
- os.makedirs(DATA_DIR, exist_ok=True)
19
- os.makedirs(EXPORT_DIR, exist_ok=True)
20
- os.makedirs(BACKUP_DIR, exist_ok=True)
21
 
22
- # File paths
23
- FILE_PATHS = {
24
- "tasks": DATA_DIR / "tasks.json",
25
- "notes": DATA_DIR / "notes.json",
26
- "goals": DATA_DIR / "goals.json",
27
- "settings": DATA_DIR / "settings.json",
28
- "usage": DATA_DIR / "usage.json",
29
- "activity": DATA_DIR / "activity.json",
30
- "focus": DATA_DIR / "focus.json",
31
- "mood": DATA_DIR / "mood.json",
32
- "wellness": DATA_DIR / "wellness.json",
33
- "integrations": DATA_DIR / "integrations.json",
34
- }
 
 
 
 
 
 
 
 
 
 
 
35
 
36
- # AI Models configuration
37
- AI_MODELS = {
38
- "text_generation": {
39
- "name": "microsoft/DialoGPT-medium",
40
- "max_length": 100,
41
- "temperature": 0.7,
42
- },
43
- "question_answering": {
44
- "name": "distilbert-base-uncased-distilled-squad",
45
- },
46
- "image_captioning": {
47
- "name": "Salesforce/blip-image-captioning-base",
48
- "max_length": 50,
49
- },
50
- "speech_to_text": {
51
- "name": "openai/whisper-small",
52
- },
53
- "translation": {
54
- "name": "Helsinki-NLP/opus-mt-en-de",
55
- },
56
- "sentiment": {
57
- "name": "cardiffnlp/twitter-roberta-base-sentiment-latest",
58
- },
59
- "summarization": {
60
- "name": "facebook/bart-large-cnn",
61
- "max_length": 150,
62
- "min_length": 30,
63
- },
64
- "code_generation": {
65
- "name": "microsoft/CodeBERT-base",
66
- },
67
- }
68
 
69
- # Default application settings
70
- DEFAULT_SETTINGS = {
71
- "appearance": {
72
- "theme": "light",
73
- "primary_color": "#7B68EE",
74
- "secondary_color": "#FF6B6B",
75
- "font_size": "medium",
76
- "sidebar_position": "left",
77
- "default_page": "dashboard",
78
- "compact_mode": False,
79
- "show_welcome": True,
80
- },
81
- "notifications": {
82
- "enable_notifications": True,
83
- "notification_sound": True,
84
- "task_reminders": True,
85
- "goal_reminders": True,
86
- "focus_reminders": True,
87
- "reminder_time": "09:00",
88
- },
89
- "ai_preferences": {
90
- "enable_suggestions": True,
91
- "preferred_model": "balanced",
92
- "usage_limit": 100,
93
- "current_usage": 0,
94
- },
95
- "data_management": {
96
- "auto_backup": True,
97
- "backup_frequency": "weekly",
98
- "data_retention": "1 year",
99
- "auto_archive": True,
100
- },
101
- "user_profile": {
102
- "name": "User",
103
- "email": "",
104
- "timezone": "UTC",
105
- "language": "English",
106
- "date_format": "MM/DD/YYYY",
107
- "time_format": "12h",
108
- },
109
- "api_keys": {
110
- "OpenWeatherMap": "",
111
- "GitHub": "",
112
- "Google Calendar": "",
113
- "Telegram": "",
114
- "News API": "",
115
- "Crypto API": "",
116
- },
117
- }
118
 
119
- # UI Constants
120
- UI_CONSTANTS = {
121
- "sidebar_width": 300,
122
- "header_height": 60,
123
- "card_border_radius": "10px",
124
- "animation_duration": "0.3s",
125
- "max_items_per_page": 20,
126
- "chart_colors": ["#7B68EE", "#FF6B6B", "#64DFDF", "#FFAB4C", "#9D65C9"],
127
- }
 
 
128
 
129
- # UI Colors for components
130
- UI_COLORS = {
131
- "blue": "#3498db",
132
- "green": "#2ecc71",
133
- "red": "#e74c3c",
134
- "yellow": "#f1c40f",
135
- "purple": "#9b59b6",
136
- "orange": "#e67e22",
137
- "teal": "#1abc9c",
138
- "gray": "#95a5a6",
139
- "dark": "#34495e",
140
- "primary": "#7B68EE",
141
- "secondary": "#FF6B6B",
142
- "success": "#2ecc71",
143
- "warning": "#f1c40f",
144
- "danger": "#e74c3c",
145
- "info": "#3498db",
146
- }
147
 
148
- # UI Sizes for components
149
- UI_SIZES = {
150
- "xs": "0.75rem",
151
- "sm": "0.875rem",
152
- "md": "1rem",
153
- "lg": "1.25rem",
154
- "xl": "1.5rem",
155
- "2xl": "2rem",
156
- "3xl": "3rem",
157
- "icon_sm": "16px",
158
- "icon_md": "24px",
159
- "icon_lg": "32px",
160
- "spacing_xs": "0.25rem",
161
- "spacing_sm": "0.5rem",
162
- "spacing_md": "1rem",
163
- "spacing_lg": "1.5rem",
164
- "spacing_xl": "2rem",
165
- }
166
 
167
- # Feature flags for enabling/disabling features
168
- FEATURE_FLAGS = {
169
- "enable_voice_input": True,
170
- "enable_image_analysis": True,
171
- "enable_code_generation": True,
172
- "enable_integrations": True,
173
- "enable_export": True,
174
- "enable_analytics": True,
175
- }
176
 
177
- # Integration settings
178
- INTEGRATION_SETTINGS = {
179
- "google_calendar": {
180
- "enabled": False,
181
- "auth_url": "https://accounts.google.com/o/oauth2/auth",
182
- "token_url": "https://oauth2.googleapis.com/token",
183
- "scope": "https://www.googleapis.com/auth/calendar.readonly",
184
- },
185
- "microsoft_todo": {
186
- "enabled": False,
187
- "auth_url": "https://login.microsoftonline.com/common/oauth2/v2.0/authorize",
188
- "token_url": "https://login.microsoftonline.com/common/oauth2/v2.0/token",
189
- "scope": "Tasks.ReadWrite",
190
- },
191
- "notion": {
192
- "enabled": False,
193
- "auth_url": "https://api.notion.com/v1/oauth/authorize",
194
- "token_url": "https://api.notion.com/v1/oauth/token",
195
- },
196
- "weather_api": {
197
- "enabled": False,
198
- "base_url": "https://api.openweathermap.org/data/2.5/weather",
199
- "units": "metric",
200
- },
201
- }
202
 
203
- # Logging configuration
204
- LOGGING_CONFIG = {
205
- "version": 1,
206
- "disable_existing_loggers": False,
207
- "formatters": {
208
- "standard": {
209
- "format": "%(asctime)s [%(levelname)s] %(name)s: %(message)s"
210
- },
211
- },
212
- "handlers": {
213
- "console": {
214
- "class": "logging.StreamHandler",
215
- "level": "INFO",
216
- "formatter": "standard",
217
- },
218
- "file": {
219
- "class": "logging.FileHandler",
220
- "level": "DEBUG",
221
- "formatter": "standard",
222
- "filename": DATA_DIR / "mona.log",
223
- "mode": "a",
224
- },
225
- },
226
- "loggers": {
227
- "": { # root logger
228
- "handlers": ["console", "file"],
229
- "level": "DEBUG",
230
- "propagate": True,
231
- },
232
- },
233
- }
 
 
 
 
 
 
 
 
 
1
  import os
2
+ from typing import Dict, Any, Optional
3
+ from dataclasses import dataclass, asdict
4
+ import streamlit as st
5
 
6
+ from utils.logging import get_logger
7
+ from utils.error_handling import ConfigError
 
 
 
8
 
9
+ logger = get_logger(__name__)
 
 
 
10
 
11
+ @dataclass
12
+ class AppConfig:
13
+ """Application configuration data class"""
14
+ app_name: str = "MONA Dashboard"
15
+ version: str = "1.0.0"
16
+ debug_mode: bool = False
17
+ max_data_points: int = 1000
18
+ refresh_interval: int = 30
19
+ default_chart_type: str = "line"
20
+ theme: str = "light"
21
+
22
+ # UI Configuration
23
+ sidebar_width: int = 300
24
+ chart_height: int = 400
25
+ table_page_size: int = 50
26
+
27
+ # Data Configuration
28
+ data_cache_timeout: int = 300
29
+ max_file_size_mb: int = 10
30
+ supported_file_types: list = None
31
+
32
+ def __post_init__(self):
33
+ if self.supported_file_types is None:
34
+ self.supported_file_types = ['.csv', '.xlsx', '.json', '.parquet']
35
 
36
+ # Global configuration instance
37
+ _config = None
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
38
 
39
+ def load_config() -> AppConfig:
40
+ """Load application configuration"""
41
+ global _config
42
+
43
+ if _config is None:
44
+ try:
45
+ # Create default config
46
+ _config = AppConfig()
47
+
48
+ # Override with environment variables if available
49
+ _config.debug_mode = os.getenv('DEBUG', 'False').lower() == 'true'
50
+ _config.max_data_points = int(os.getenv('MAX_DATA_POINTS', '1000'))
51
+ _config.refresh_interval = int(os.getenv('REFRESH_INTERVAL', '30'))
52
+ _config.theme = os.getenv('THEME', 'light')
53
+
54
+ # Override with Streamlit session state if available
55
+ if 'app_config' in st.session_state:
56
+ session_config = st.session_state.app_config
57
+ for key, value in session_config.items():
58
+ if hasattr(_config, key):
59
+ setattr(_config, key, value)
60
+
61
+ logger.info("Configuration loaded successfully")
62
+
63
+ except Exception as e:
64
+ logger.error(f"Failed to load configuration: {str(e)}")
65
+ raise ConfigError(f"Configuration loading failed: {str(e)}")
66
+
67
+ return _config
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
68
 
69
+ def save_config(config: AppConfig) -> bool:
70
+ """Save configuration to session state"""
71
+ try:
72
+ st.session_state.app_config = asdict(config)
73
+ global _config
74
+ _config = config
75
+ logger.info("Configuration saved successfully")
76
+ return True
77
+ except Exception as e:
78
+ logger.error(f"Failed to save configuration: {str(e)}")
79
+ return False
80
 
81
+ def get_config_value(key: str, default_value: Any = None) -> Any:
82
+ """Get a specific configuration value"""
83
+ try:
84
+ config = load_config()
85
+ return getattr(config, key, default_value)
86
+ except Exception as e:
87
+ logger.error(f"Failed to get config value for key {key}: {str(e)}")
88
+ return default_value
 
 
 
 
 
 
 
 
 
 
89
 
90
+ def update_config_value(key: str, value: Any) -> bool:
91
+ """Update a specific configuration value"""
92
+ try:
93
+ config = load_config()
94
+ if hasattr(config, key):
95
+ setattr(config, key, value)
96
+ return save_config(config)
97
+ else:
98
+ logger.warning(f"Configuration key '{key}' does not exist")
99
+ return False
100
+ except Exception as e:
101
+ logger.error(f"Failed to update config value for key {key}: {str(e)}")
102
+ return False
 
 
 
 
 
103
 
104
+ def reset_config() -> AppConfig:
105
+ """Reset configuration to defaults"""
106
+ global _config
107
+ _config = AppConfig()
108
+ save_config(_config)
109
+ logger.info("Configuration reset to defaults")
110
+ return _config
 
 
111
 
112
+ def get_config_dict() -> Dict[str, Any]:
113
+ """Get configuration as dictionary"""
114
+ try:
115
+ config = load_config()
116
+ return asdict(config)
117
+ except Exception as e:
118
+ logger.error(f"Failed to get configuration dictionary: {str(e)}")
119
+ return {}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
120
 
121
+ def validate_config(config: AppConfig) -> bool:
122
+ """Validate configuration values"""
123
+ try:
124
+ # Validate numeric values
125
+ if config.max_data_points <= 0:
126
+ raise ConfigError("max_data_points must be positive")
127
+
128
+ if config.refresh_interval <= 0:
129
+ raise ConfigError("refresh_interval must be positive")
130
+
131
+ if config.sidebar_width <= 0:
132
+ raise ConfigError("sidebar_width must be positive")
133
+
134
+ if config.chart_height <= 0:
135
+ raise ConfigError("chart_height must be positive")
136
+
137
+ # Validate string values
138
+ if config.theme not in ['light', 'dark']:
139
+ raise ConfigError("theme must be 'light' or 'dark'")
140
+
141
+ if config.default_chart_type not in ['line', 'bar', 'scatter', 'area']:
142
+ raise ConfigError("invalid default_chart_type")
143
+
144
+ logger.info("Configuration validation successful")
145
+ return True
146
+
147
+ except ConfigError as e:
148
+ logger.error(f"Configuration validation failed: {str(e)}")
149
+ raise e
150
+ except Exception as e:
151
+ logger.error(f"Unexpected error during configuration validation: {str(e)}")
152
+ raise ConfigError(f"Configuration validation error: {str(e)}")