Files
smthemex-ComfyUI_InteractAv…/utils/config.py
T
2026-02-06 09:34:36 +08:00

102 lines
4.0 KiB
Python

import os
import importlib.util
from pathlib import Path
import json
class Config(dict):
"""A dictionary that allows dot notation access for configuration settings."""
def __init__(self, data=None):
super().__init__()
if data:
for key, value in data.items():
# Set the key-value pair using the key and the converted value
self[key] = self._convert(value)
def _convert(self, value):
"""Recursively convert nested dictionaries to Config."""
if isinstance(value, dict):
return Config(value) # Convert all nested dicts to Config
elif isinstance(value, list):
return [self._convert(item) for item in value] # Convert items in lists
elif isinstance(value, Path):
return str(value) # Convert Path objects to string
return value
def __getattr__(self, item):
"""Allow access to dictionary keys via dot notation."""
if item in self:
return self[item]
raise AttributeError(f"'{self.__class__.__name__}' object has no attribute '{item}'")
def __setattr__(self, key, value):
"""Allow setting dictionary keys via dot notation."""
self[key] = self._convert(value)
@classmethod
def load_config(cls, file_path):
"""Load a Python config file and return it as a Config instance."""
spec = importlib.util.spec_from_file_location("config_module", file_path)
config_module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(config_module)
if hasattr(config_module, "config") and isinstance(config_module.config, dict):
return cls(config_module.config) # Ensure full conversion of nested dicts
else:
raise ValueError("The config file does not define a 'config' dictionary.")
def update_config(self, new_data):
"""Recursively update Config with new dictionary values."""
for key, value in new_data.items():
if isinstance(value, dict) and isinstance(self.get(key), Config):
self[key].update_config(value) # Recursive update for nested dicts
else:
self[key] = self._convert(value) # Convert and assign
def dump_config(self, file_path=None):
"""Dump the Config object into a .py file with a Pythonic and readable format."""
# Ensure the provided path is valid
if file_path is None:
file_path = self.log.output_dir + '/config.py'
else:
dir_name = os.path.dirname(file_path)
if dir_name and not os.path.exists(dir_name):
os.makedirs(dir_name)
# Convert the Config instance into a regular dictionary
def config_to_dict(config):
"""Recursively convert a Config instance into a regular dictionary."""
if isinstance(config, Config):
return {key: config_to_dict(value) if isinstance(value, Config) else value
for key, value in config.items()}
return config
config_dict = config_to_dict(self)
# Write the config dictionary to a .py file in a formatted, readable way
with open(file_path, 'w') as f:
# Use json.dumps to pretty-print the dictionary with indentation and spaces
f.write("config = ")
f.write(json.dumps(config_dict, indent=4)) # Pretty print with indentation
f.write("\n")
print(f"Config has been saved to {file_path}")
def prepare_log(self):
def make_folder(folder):
if not os.path.exists(folder):
os.makedirs(folder)
if self.log.output_dir is not None:
make_folder(self.log.output_dir)
if self.log.model_dir is not None:
make_folder(self.log.model_dir)
if self.log.log_dir is not None:
make_folder(self.log.log_dir)
if self.log.result_dir is not None:
make_folder(self.log.result_dir)