Files
drb-core-client/app/config.py
2025-05-11 20:36:31 -04:00

139 lines
4.9 KiB
Python

import os
import json
class Config:
"""
Manages application configuration stored in a JSON file.
Provides attribute-style access to configuration values.
"""
def __init__(self, file_path='/data/config.json'):
"""
Initializes the Config manager.
Loads configuration from the JSON file. Creates the file with an
empty JSON object if it doesn't exist.
Args:
file_path (str): The path to the JSON configuration file.
"""
self.file_path = file_path
self._config_data = {} # Internal dictionary to hold config data
self._load_config()
def _load_config(self):
"""Loads configuration key-value pairs from the JSON file."""
# Check if the file exists. If not, create it with an empty JSON object.
if not os.path.exists(self.file_path):
self._save_config() # Create the file with empty data
try:
with open(self.file_path, 'r') as f:
# Load data from the file. Handle empty file case.
content = f.read()
if content:
self._config_data = json.loads(content)
else:
self._config_data = {} # Initialize as empty if file is empty
except (FileNotFoundError, json.JSONDecodeError) as e:
print(f"Error loading config file {self.file_path}: {e}")
# If there's an error loading, initialize with empty data
self._config_data = {}
# Optionally, you might want to back up the problematic file
# or log the error more severely in a real application.
def _save_config(self):
"""Saves the current configuration data to the JSON file."""
try:
with open(self.file_path, 'w') as f:
json.dump(self._config_data, f, indent=4) # Use indent for readability
except IOError as e:
print(f"Error saving config file {self.file_path}: {e}")
except TypeError as e:
print(f"Error serializing config data to JSON: {e}. Ensure all values are JSON serializable.")
def get(self, key, default=None):
"""
Retrieves a configuration value by key.
Args:
key (str): The configuration key.
default: The value to return if the key is not found.
Returns:
The configuration value or the default value if not found.
"""
return self._config_data.get(key, default)
def set(self, key, value):
"""
Sets or updates a configuration value in memory and saves to the file.
Args:
key (str): The configuration key.
value: The configuration value. Must be JSON serializable.
"""
self._config_data[key] = value
self._save_config()
def delete(self, key):
"""
Deletes a configuration key-value pair from memory and saves to the file.
Args:
key (str): The configuration key to delete.
"""
if key in self._config_data:
del self._config_data[key]
self._save_config()
else:
print(f"Warning: Key '{key}' not found in config.")
def __getattr__(self, name):
"""
Allows accessing configuration values using attribute notation (e.g., config.my_key).
Args:
name (str): The attribute name (configuration key).
Returns:
The configuration value associated with the key.
Raises:
AttributeError: If the key is not found in the configuration.
"""
if name in self._config_data:
return self._config_data[name]
# Fallback for standard attributes if not found in config data
try:
return self.__getattribute__(name)
except AttributeError:
raise AttributeError(f"'Config' object has no attribute '{name}' and key '{name}' not found in config.")
def __setattr__(self, name, value):
"""
Allows setting configuration values using attribute notation (e.g., config.my_key = value).
Args:
name (str): The attribute name (configuration key).
value: The value to set. Must be JSON serializable.
"""
# Handle setting internal attributes like file_path or _config_data
if name in ('file_path', '_config_data'):
super().__setattr__(name, value)
else:
# Treat other attribute assignments as setting config values
self.set(name, value)
def __delattr__(self, name):
"""
Allows deleting configuration values using attribute notation (e.g., del config.my_key).
Args:
name (str): The attribute name (configuration key) to delete.
"""
if name in self._config_data:
self.delete(name)
else:
# Fallback for standard attributes
super().__delattr__(name)