From f9618b7e4b5a5e022b587394e277cdf6e96ec574 Mon Sep 17 00:00:00 2001 From: Sasbom Date: Wed, 5 Nov 2025 07:40:32 +0100 Subject: [PATCH] Add QOL feature for changing the custom nodes folder location through cli args or a COMFYUI_CUSTOM_NODES_DIR environment variable. --- app/custom_node_manager.py | 16 ++++++++++---- comfy/cli_args.py | 2 ++ folder_paths.py | 11 +++++++--- main.py | 45 ++++++++++++++++++++++++-------------- 4 files changed, 50 insertions(+), 24 deletions(-) diff --git a/app/custom_node_manager.py b/app/custom_node_manager.py index 281febca9..f408dcb1c 100644 --- a/app/custom_node_manager.py +++ b/app/custom_node_manager.py @@ -1,15 +1,15 @@ from __future__ import annotations -import os -import folder_paths import glob -from aiohttp import web import json import logging +import os from functools import lru_cache -from utils.json_util import merge_json_recursive +from aiohttp import web +import folder_paths +from utils.json_util import merge_json_recursive # Extra locale files to load into main.json EXTRA_LOCALE_FILES = [ @@ -32,6 +32,14 @@ def safe_load_json_file(file_path: str) -> dict: class CustomNodeManager: + """Manages and resolves folders for custom nodes. + + The custom_nodes folder location can be overridden using either + by passing in a folder through client argument --custom-nodes-directory, + or by setting COMFYUI_CUSTOM_NODES_DIR as an environment variable. + + The cli argument takes prescedence if passed in. + """ @lru_cache(maxsize=1) def build_translations(self): """Load all custom nodes translations during initialization. Translations are diff --git a/comfy/cli_args.py b/comfy/cli_args.py index 3947e62a8..0729d436b 100644 --- a/comfy/cli_args.py +++ b/comfy/cli_args.py @@ -1,6 +1,7 @@ import argparse import enum import os + import comfy.options @@ -47,6 +48,7 @@ parser.add_argument("--extra-model-paths-config", type=str, default=None, metava parser.add_argument("--output-directory", type=str, default=None, help="Set the ComfyUI output directory. Overrides --base-directory.") parser.add_argument("--temp-directory", type=str, default=None, help="Set the ComfyUI temp directory (default is in the ComfyUI directory). Overrides --base-directory.") parser.add_argument("--input-directory", type=str, default=None, help="Set the ComfyUI input directory. Overrides --base-directory.") +parser.add_argument("--custom-nodes-directory", type=str, default=None, help="Set the ComfyUI custom_nodes directory. Overrides --base-directory and environment variable COMFYUI_CUSTOM_NODES_DIR.") parser.add_argument("--auto-launch", action="store_true", help="Automatically launch ComfyUI in the default browser.") parser.add_argument("--disable-auto-launch", action="store_true", help="Disable auto launching the browser.") parser.add_argument("--cuda-device", type=int, default=None, metavar="DEVICE_ID", help="Set the id of the cuda device this instance will use. All other devices will not be visible.") diff --git a/folder_paths.py b/folder_paths.py index f110d832b..8aa2b7be9 100644 --- a/folder_paths.py +++ b/folder_paths.py @@ -1,11 +1,11 @@ from __future__ import annotations +import logging +import mimetypes import os import time -import mimetypes -import logging -from typing import Literal, List from collections.abc import Collection +from typing import List, Literal from comfy.cli_args import args @@ -115,6 +115,11 @@ def set_input_directory(input_dir: str) -> None: global input_directory input_directory = input_dir +def set_custom_nodes_directory(custom_nodes_dir: str) -> None: + #NOTE: this function doesn't need a "get_custom_nodes_directory", we have "get_folder_paths". + global folder_names_and_paths + folder_names_and_paths["custom_nodes"] = ([custom_nodes_dir], set()) + def get_output_directory() -> str: global output_directory return output_directory diff --git a/main.py b/main.py index e1b0f1620..e415879bc 100644 --- a/main.py +++ b/main.py @@ -1,19 +1,21 @@ import comfy.options + comfy.options.enable_args_parsing() -import os import importlib.util -import folder_paths -import time -from comfy.cli_args import args -from app.logger import setup_logger import itertools -import utils.extra_config import logging +import os import sys +import time + +import folder_paths +import utils.extra_config +from app.logger import setup_logger +from comfy.cli_args import args +from comfy_api import feature_flags from comfy_execution.progress import get_progress_state from comfy_execution.utils import get_executing_context -from comfy_api import feature_flags if __name__ == "__main__": #NOTE: These do not do anything on core ComfyUI, they are for custom nodes. @@ -32,7 +34,7 @@ def apply_custom_paths(): for config_path in itertools.chain(*args.extra_model_paths_config): utils.extra_config.load_extra_path_config(config_path) - # --output-directory, --input-directory, --user-directory + # --output-directory, --input-directory, --user-directory, --custom-nodes-directory if args.output_directory: output_dir = os.path.abspath(args.output_directory) logging.info(f"Setting output directory to: {output_dir}") @@ -56,6 +58,16 @@ def apply_custom_paths(): logging.info(f"Setting user directory to: {user_dir}") folder_paths.set_user_directory(user_dir) + #NOTE: hierarchy of resolution should be cli args first, then environment. + if args.custom_nodes_directory: + custom_nodes_dir = os.path.abspath(args.custom_nodes_dir) + logging.info(f"Setting custom nodes directory to: {custom_nodes_dir}") + folder_paths.set_custom_nodes_directory(custom_nodes_dir) + elif os.environ.get("COMFYUI_CUSTOM_NODES_DIR", None): + custom_nodes_dir = os.path.abspath(os.environ.get("COMFYUI_CUSTOM_NODES_DIR")) + logging.info(f"Setting custom nodes directory to: {custom_nodes_dir} from environment variable COMFYUI_CUSTOM_NODES_DIR") + folder_paths.set_custom_nodes_directory(custom_nodes_dir) + def execute_prestartup_script(): if args.disable_all_custom_nodes and len(args.whitelist_custom_nodes) == 0: @@ -106,10 +118,9 @@ execute_prestartup_script() # Main code import asyncio +import gc import shutil import threading -import gc - if os.name == "nt": os.environ['MIMALLOC_PURGE_DELAY'] = '0' @@ -144,16 +155,16 @@ if __name__ == "__main__": if 'torch' in sys.modules: logging.warning("WARNING: Potential Error in code: Torch already imported, torch should never be imported before this point.") +import app.logger +import comfy.model_management import comfy.utils - +import comfyui_version import execution +import hook_breaker_ac10a0 +import nodes import server from protocol import BinaryEventTypes -import nodes -import comfy.model_management -import comfyui_version -import app.logger -import hook_breaker_ac10a0 + def cuda_malloc_warning(): device = comfy.model_management.get_torch_device() @@ -293,7 +304,7 @@ def cleanup_temp(): def setup_database(): try: - from app.database.db import init_db, dependencies_available + from app.database.db import dependencies_available, init_db if dependencies_available(): init_db() except Exception as e: