import os from typing import Optional import tomllib from pydantic import ValidationError import logging from comfy_config.types import ( ProjectConfig, PyProjectConfig, ) """ Extract configuration from a custom node directory's pyproject.toml file. This function reads and parses the pyproject.toml file in the specified directory to extract project and ComfyUI-specific configuration information. If no pyproject.toml file is found, it creates a minimal configuration using the folder name as the project name. Args: path (str): Path to the directory containing the pyproject.toml file. If pyproject.toml doesn't exist, the folder name will be used as the default project name. Returns: Optional[PyProjectConfig]: A PyProjectConfig object containing: - project: Basic project information (name, version, dependencies, etc.) - tool_comfy: ComfyUI-specific configuration (publisher_id, models, etc.) Returns None if configuration extraction fails. Notes: - If pyproject.toml is missing, creates a default config with folder name Example: >>> from comfy_config import config_parser >>> custom_node_dir = os.path.dirname(os.path.realpath(__file__)) >>> project_config = config_parser.extract_node_configuration(custom_node_dir) >>> print(project_config.project.name) # "my_custom_node" or name from pyproject.toml >>> nodes.EXTENSION_WEB_DIRS[project_config.project.name] = js_dir """ def extract_node_configuration(path) -> Optional[PyProjectConfig]: folder_name = os.path.basename(path) toml_path = os.path.join(path, "pyproject.toml") if not os.path.isfile(toml_path): logging.warning( "No pyproject.toml file found in the current directory, will use custom node folder name as project name as default.") try: project = ProjectConfig(name=folder_name) return PyProjectConfig(project=project) except ValidationError as e: logging.error(f"Failed to create default configuration: {e}") return None try: with open(toml_path, "rb") as f: data = tomllib.load(f) except Exception as e: logging.error(f"Failed to read pyproject.toml: {e}") return None try: config_data = { "project": data.get("project", {}), "tool_comfy": data.get("tool", {}).get("comfy", {}) } return PyProjectConfig(**config_data) except ValidationError as e: logging.error(f"Validation error while parsing configuration: {e}") logging.error(f"Validation details: {e.errors()}") return None except Exception as e: logging.error(f"Unexpected error while parsing configuration: {e}") return None