1. import logging
  2. import os
  3. import json
  4. from typing import Dict, Any
  5. # Configure logging
  6. logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
  7. def log_config_operation(filepath: str, operation: str, data: Dict[str, Any] = None):
  8. """Logs the operation performed on a configuration file."""
  9. try:
  10. logging.info(f"Operation: {operation} on file: {filepath}")
  11. if data:
  12. logging.debug(f"Data: {data}")
  13. except Exception as e:
  14. logging.error(f"Error logging operation: {e}")
  15. def load_config(filepath: str) -> Dict[str, Any]:
  16. """Loads configuration data from a file with error handling."""
  17. try:
  18. if not os.path.exists(filepath):
  19. raise FileNotFoundError(f"File not found: {filepath}")
  20. try:
  21. with open(filepath, 'r') as f:
  22. config = json.load(f)
  23. return config
  24. except json.JSONDecodeError as e:
  25. raise ValueError(f"Invalid JSON format in {filepath}: {e}")
  26. except Exception as e:
  27. logging.error(f"Error loading config from {filepath}: {e}")
  28. raise
  29. def save_config(filepath: str, data: Dict[str, Any]):
  30. """Saves configuration data to a file with defensive checks."""
  31. try:
  32. if not isinstance(data, dict):
  33. raise TypeError("Data must be a dictionary.")
  34. with open(filepath, 'w') as f:
  35. json.dump(data, f, indent=4)
  36. logging.info(f"Successfully saved configuration to {filepath}")
  37. except Exception as e:
  38. logging.error(f"Error saving configuration to {filepath}: {e}")
  39. raise
  40. def validate_config(config: Dict[str, Any]) -> bool:
  41. """Validates the configuration data (example validation)."""
  42. # Add your validation logic here. This is just an example.
  43. if not isinstance(config, dict):
  44. logging.warning("Configuration is not a dictionary.")
  45. return False
  46. if 'required_key' not in config:
  47. logging.warning("Missing required key 'required_key'.")
  48. return False
  49. if not isinstance(config['required_key'], str):
  50. logging.warning("Value of 'required_key' is not a string.")
  51. return False
  52. return True
  53. def apply_config(filepath: str, config: Dict[str, Any]):
  54. """Applies the configuration data."""
  55. try:
  56. # Placeholder for applying the configuration.
  57. # Replace with your actual application logic.
  58. logging.info(f"Applying configuration from {filepath}: {config}")
  59. validate_config(config) # Validate before applying
  60. except Exception as e:
  61. logging.error(f"Error applying configuration from {filepath}: {e}")
  62. raise
  63. if __name__ == '__main__':
  64. # Example Usage
  65. config_file = "config.json"
  66. # Load configuration
  67. try:
  68. config = load_config(config_file)
  69. log_config_operation(config_file, "load", config)
  70. # Apply configuration
  71. apply_config(config_file, config)
  72. log_config_operation(config_file, "apply")
  73. # Save configuration
  74. config['new_key'] = 'new_value'
  75. save_config(config_file, config)
  76. log_config_operation(config_file, "save", config)
  77. except Exception as e:
  78. print(f"An error occurred: {e}")

Add your comment