Copilot commented on code in PR #277: URL: https://github.com/apache/incubator-hugegraph-ai/pull/277#discussion_r2154314451
########## hugegraph-llm/src/hugegraph_llm/config/models/base_config.py: ########## @@ -18,118 +18,139 @@ import os -from dotenv import dotenv_values, set_key from pydantic_settings import BaseSettings +import yaml from hugegraph_llm.utils.log import log dir_name = os.path.dirname -env_path = os.path.join(os.getcwd(), ".env") # Load .env from the current working directory - +yaml_path = os.path.join(os.getcwd(), "config.yaml") class BaseConfig(BaseSettings): class Config: - env_file = env_path + yaml_file = yaml_path case_sensitive = False - extra = 'ignore' # ignore extra fields to avoid ValidationError + extra = 'ignore' # Ignore extra fields to avoid ValidationError env_ignore_empty = True - def generate_env(self): - if os.path.exists(env_path): - log.info("%s already exists, do you want to override with the default configuration? (y/n)", env_path) - update = input() - if update.lower() != "y": - return - self.update_env() - else: - config_dict = self.model_dump() - config_dict = {k.upper(): v for k, v in config_dict.items()} - with open(env_path, "w", encoding="utf-8") as f: - for k, v in config_dict.items(): - if v is None: - f.write(f"{k}=\n") - else: - f.write(f"{k}={v}\n") - log.info("Generate %s successfully!", env_path) - - def update_env(self): + def generate_yaml(self): + # Generate a YAML file based on the current configuration config_dict = self.model_dump() config_dict = {k.upper(): v for k, v in config_dict.items()} - env_config = dotenv_values(f"{env_path}") - - # dotenv_values make None to '', while pydantic make None to None - # dotenv_values make integer to string, while pydantic make integer to integer + current_class_name = self.__class__.__name__ + yaml_data = {} + yaml_section_data = {} for k, v in config_dict.items(): - if k in env_config: - if not (env_config[k] or v): - continue - if env_config[k] == str(v): - continue - log.info("Update %s: %s=%s", env_path, k, v) - set_key(env_path, k, v if v else "", quote_mode="never") - - def check_env(self): - """Synchronize configs between .env file and object. + yaml_section_data[k] = v + yaml_data[current_class_name] = yaml_section_data + with open(yaml_path, "w", encoding="utf-8") as f: + yaml.dump(yaml_data, f, sort_keys=False) + log.info("Generate %s successfully!", yaml_path) + + def update_configs(self): + """Update the configurations of subclasses to the config.yaml files.""" + config_dict = self.model_dump() + config_dict = {k.upper(): v for k, v in config_dict.items()} + + try: + current_class_name = self.__class__.__name__ + with open(yaml_path, "r", encoding="utf-8") as f: + content = f.read() + yaml_config = yaml.safe_load(content) if content.strip() else {} + for k, v in config_dict.items(): + if k in yaml_config[current_class_name]: + yaml_config[current_class_name][k] = v + with open(yaml_path, "w", encoding="utf-8") as f: + yaml.dump(yaml_config, f) + except yaml.YAMLError as e: + log.error("Error parsing YAML from %s: %s", yaml_path, e) + except Exception as e: + log.error("Error loading %s: %s", yaml_path, e) + - This method performs two steps: - 1. Updates object attributes from .env file values when they differ - 2. Adds missing configuration items to the .env file + def check_yaml_configs(self): + """ + Synchronize configs between config.yaml file and object. + Updates object attributes from config.yaml and adds missing items to config.yaml. """ + object_config_dict = {k.upper(): v for k, v in self.model_dump().items()} try: - # Read the.env file and prepare object config - env_config = dotenv_values(env_path) - config_dict = {k.upper(): v for k, v in self.model_dump().items()} + current_class_name = self.__class__.__name__ + # Read the yaml.config file and prepare object config + with open(yaml_path, "r", encoding="utf-8") as f: + content = f.read() + if not content.strip(): + yaml_file_config = {current_class_name: {}} + else: + yaml_file_config = yaml.safe_load(content) + if not isinstance(yaml_file_config, dict): + log.error("Invalid YAML content in %s. Expected a dictionary.", yaml_path) + yaml_file_config = {current_class_name: {}} # Reset to a safe state + elif current_class_name not in yaml_file_config: + yaml_file_config[current_class_name] = {} + + # Step 1: Update the object from yaml.config + if yaml_file_config.get(current_class_name): + self._sync_yaml_to_object(yaml_file_config, object_config_dict) + + # Step 2: Add missing onfig items from object to yaml.config Review Comment: There is a minor typo in the comment ('onfig' should be 'config') – please correct it for clarity. ```suggestion # Step 2: Add missing config items from object to yaml.config ``` ########## hugegraph-llm/src/hugegraph_llm/config/models/base_config.py: ########## @@ -18,118 +18,139 @@ import os -from dotenv import dotenv_values, set_key from pydantic_settings import BaseSettings +import yaml from hugegraph_llm.utils.log import log dir_name = os.path.dirname -env_path = os.path.join(os.getcwd(), ".env") # Load .env from the current working directory - +yaml_path = os.path.join(os.getcwd(), "config.yaml") class BaseConfig(BaseSettings): class Config: - env_file = env_path + yaml_file = yaml_path case_sensitive = False - extra = 'ignore' # ignore extra fields to avoid ValidationError + extra = 'ignore' # Ignore extra fields to avoid ValidationError env_ignore_empty = True - def generate_env(self): - if os.path.exists(env_path): - log.info("%s already exists, do you want to override with the default configuration? (y/n)", env_path) - update = input() - if update.lower() != "y": - return - self.update_env() - else: - config_dict = self.model_dump() - config_dict = {k.upper(): v for k, v in config_dict.items()} - with open(env_path, "w", encoding="utf-8") as f: - for k, v in config_dict.items(): - if v is None: - f.write(f"{k}=\n") - else: - f.write(f"{k}={v}\n") - log.info("Generate %s successfully!", env_path) - - def update_env(self): + def generate_yaml(self): + # Generate a YAML file based on the current configuration config_dict = self.model_dump() config_dict = {k.upper(): v for k, v in config_dict.items()} - env_config = dotenv_values(f"{env_path}") - - # dotenv_values make None to '', while pydantic make None to None - # dotenv_values make integer to string, while pydantic make integer to integer + current_class_name = self.__class__.__name__ + yaml_data = {} + yaml_section_data = {} for k, v in config_dict.items(): - if k in env_config: - if not (env_config[k] or v): - continue - if env_config[k] == str(v): - continue - log.info("Update %s: %s=%s", env_path, k, v) - set_key(env_path, k, v if v else "", quote_mode="never") - - def check_env(self): - """Synchronize configs between .env file and object. + yaml_section_data[k] = v + yaml_data[current_class_name] = yaml_section_data + with open(yaml_path, "w", encoding="utf-8") as f: + yaml.dump(yaml_data, f, sort_keys=False) + log.info("Generate %s successfully!", yaml_path) + + def update_configs(self): + """Update the configurations of subclasses to the config.yaml files.""" + config_dict = self.model_dump() + config_dict = {k.upper(): v for k, v in config_dict.items()} + + try: + current_class_name = self.__class__.__name__ + with open(yaml_path, "r", encoding="utf-8") as f: + content = f.read() + yaml_config = yaml.safe_load(content) if content.strip() else {} Review Comment: Before iterating over the YAML config section, ensure that current_class_name exists as a key in yaml_config. Consider initializing yaml_config[current_class_name] to an empty dict if it does not exist to prevent potential KeyError. ```suggestion yaml_config = yaml.safe_load(content) if content.strip() else {} current_class_name = self.__class__.__name__ if current_class_name not in yaml_config: yaml_config[current_class_name] = {} ``` -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: issues-unsubscr...@hugegraph.apache.org For queries about this service, please contact Infrastructure at: us...@infra.apache.org --------------------------------------------------------------------- To unsubscribe, e-mail: issues-unsubscr...@hugegraph.apache.org For additional commands, e-mail: issues-h...@hugegraph.apache.org