Merge pull request #12 from pydn/dev

Dev
This commit is contained in:
Peyton DeNiro
2023-08-25 16:15:49 -05:00
committed by GitHub
2 changed files with 79 additions and 34 deletions
+35 -14
View File
@@ -2,24 +2,21 @@ import copy
import glob
import inspect
import json
import logging
import os
import random
import sys
import re
from typing import Dict, List, Any, Callable, Tuple
import black
from utils import import_custom_nodes, add_comfyui_directory_to_sys_path, get_value_at_index
from utils import import_custom_nodes, find_path, add_comfyui_directory_to_sys_path, add_extra_model_paths, get_value_at_index
sys.path.append('../')
from nodes import NODE_CLASS_MAPPINGS
logging.basicConfig(level=logging.INFO)
class FileHandler:
"""Handles reading and writing files.
@@ -217,7 +214,7 @@ class CodeGenerator:
continue
class_type, import_statement, class_code = self.get_class_info(class_type)
initialized_objects[class_type] = class_type.lower().strip()
initialized_objects[class_type] = self.clean_variable_name(class_type)
if class_type in self.base_node_class_mappings.keys():
import_statements.add(import_statement)
if class_type not in self.base_node_class_mappings.keys():
@@ -234,9 +231,9 @@ class CodeGenerator:
inputs['unique_id'] = random.randint(1, 2**64)
# Create executed variable and generate code
executed_variables[idx] = f'{class_type.lower().strip()}_{idx}'
executed_variables[idx] = f'{self.clean_variable_name(class_type)}_{idx}'
inputs = self.update_inputs(inputs, executed_variables)
if is_special_function:
special_functions_code.append(self.create_function_call_code(initialized_objects[class_type], class_def.FUNCTION, executed_variables[idx], is_special_function, **inputs))
else:
@@ -306,11 +303,11 @@ class CodeGenerator:
"""
# Get the source code of the utils functions as a string
func_strings = []
for func in [add_comfyui_directory_to_sys_path, get_value_at_index]:
for func in [get_value_at_index, find_path, add_comfyui_directory_to_sys_path, add_extra_model_paths]:
func_strings.append(f'\n{inspect.getsource(func)}')
# Define static import statements required for the script
static_imports = ['import os', 'import random', 'import sys', 'from typing import Sequence, Mapping, Any, Union',
'import torch'] + func_strings + ['\n\nadd_comfyui_directory_to_sys_path()']
'import torch'] + func_strings + ['\n\nadd_comfyui_directory_to_sys_path()\nadd_extra_model_paths()\n']
# Check if custom nodes should be included
if custom_nodes:
static_imports.append(f'\n{inspect.getsource(import_custom_nodes)}\n')
@@ -328,7 +325,7 @@ class CodeGenerator:
final_code = black.format_str(final_code, mode=black.Mode())
return final_code
def get_class_info(self, class_type: str) -> Tuple[str, str, str]:
"""Generates and returns necessary information about class type.
@@ -339,12 +336,36 @@ class CodeGenerator:
Tuple[str, str, str]: Updated class type, import statement string, class initialization code.
"""
import_statement = class_type
variable_name = self.clean_variable_name(class_type)
if class_type in self.base_node_class_mappings.keys():
class_code = f'{class_type.lower().strip()} = {class_type.strip()}()'
class_code = f'{variable_name} = {class_type.strip()}()'
else:
class_code = f'{class_type.lower().strip()} = NODE_CLASS_MAPPINGS["{class_type}"]()'
class_code = f'{variable_name} = NODE_CLASS_MAPPINGS["{class_type}"]()'
return class_type, import_statement, class_code
@staticmethod
def clean_variable_name(class_type: str) -> str:
"""
Remove any characters from variable name that could cause errors running the Python script.
Args:
class_type (str): Class type.
Returns:
str: Cleaned variable name with no special characters or spaces
"""
# Convert to lowercase and replace spaces with underscores
clean_name = class_type.lower().strip().replace("-", "_").replace(" ", "_")
# Remove characters that are not letters, numbers, or underscores
clean_name = re.sub(r'[^a-z0-9_]', '', clean_name)
# Ensure that it doesn't start with a number
if clean_name[0].isdigit():
clean_name = "_" + clean_name
return clean_name
def get_function_parameters(self, func: Callable) -> List:
"""Get the names of a function's parameters.
+44 -20
View File
@@ -27,32 +27,56 @@ def import_custom_nodes() -> None:
# Initializing custom nodes
init_custom_nodes()
def find_path(name: str, path: str = None) -> str:
"""
Recursively looks at parent folders starting from the given path until it finds the given name.
Returns the path as a Path object if found, or None otherwise.
"""
# If no path is given, use the current working directory
if path is None:
path = os.getcwd()
# Check if the current directory contains the name
if name in os.listdir(path):
path_name = os.path.join(path, name)
print(f"{name} found: {path_name}")
return path_name
# Get the parent directory
parent_directory = os.path.dirname(path)
# If the parent directory is the same as the current directory, we've reached the root and stop the search
if parent_directory == path:
return None
# Recursively call the function with the parent directory
return find_path(name, parent_directory)
def add_comfyui_directory_to_sys_path() -> None:
"""
Recursively looks at parent folders starting from the current working directory until it finds 'ComfyUI'.
Once found, the directory is added to sys.path.
Add 'ComfyUI' to the sys.path
"""
start_path = os.getcwd() # Get the current working directory
comfyui_path = find_path('ComfyUI')
if comfyui_path is not None and os.path.isdir(comfyui_path):
sys.path.append(comfyui_path)
print(f"'{comfyui_path}' added to sys.path")
def search_directory(path: str) -> None:
# Check if the current directory contains 'ComfyUI'
if 'ComfyUI' in os.listdir(path):
directory_path = os.path.join(path, 'ComfyUI')
sys.path.append(directory_path)
print(f"ComfyUI found and added to sys.path: {directory_path}")
# Get the parent directory
parent_directory = os.path.dirname(path)
def add_extra_model_paths() -> None:
"""
Parse the optional extra_model_paths.yaml file and add the parsed paths to the sys.path.
"""
from main import load_extra_path_config
# If the parent directory is the same as the current directory, we've reached the root and stop the search
if parent_directory == path:
return
# Recursively call the function with the parent directory
search_directory(parent_directory)
# Start the search from the current working directory
search_directory(start_path)
extra_model_paths = find_path("extra_model_paths.yaml")
if extra_model_paths is not None:
load_extra_path_config(extra_model_paths)
else:
print("Could not find the extra_model_paths config file.")
def get_value_at_index(obj: Union[Sequence, Mapping], index: int) -> Any: