From a73410aafa573940ebaba9a9a908476a538a8981 Mon Sep 17 00:00:00 2001 From: bymyself Date: Sun, 9 Mar 2025 03:46:08 -0700 Subject: [PATCH 1/7] remove overrides --- nodes.py | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/nodes.py b/nodes.py index bbf49915c..e43c29295 100644 --- a/nodes.py +++ b/nodes.py @@ -1785,14 +1785,7 @@ class LoadImageOutput(LoadImage): DESCRIPTION = "Load an image from the output folder. When the refresh button is clicked, the node will update the image list and automatically select the first image, allowing for easy iteration." EXPERIMENTAL = True - FUNCTION = "load_image_output" - - def load_image_output(self, image): - return self.load_image(f"{image} [output]") - - @classmethod - def VALIDATE_INPUTS(s, image): - return True + FUNCTION = "load_image" class ImageScale: From 1f138dd382bd4fe40c46a1fd1954dfbf0ddae924 Mon Sep 17 00:00:00 2001 From: Chenlei Hu Date: Mon, 10 Mar 2025 15:07:44 -0400 Subject: [PATCH 2/7] Only check frontend package if using default frontend --- app/frontend_management.py | 51 +++++++++++++++++++++++++++----------- main.py | 15 ----------- 2 files changed, 36 insertions(+), 30 deletions(-) diff --git a/app/frontend_management.py b/app/frontend_management.py index 308f71da6..f5a0358e6 100644 --- a/app/frontend_management.py +++ b/app/frontend_management.py @@ -17,27 +17,38 @@ from typing_extensions import NotRequired from comfy.cli_args import DEFAULT_VERSION_STRING +# The path to the requirements.txt file +req_path = Path(__file__).parents[1] / "requirements.txt" def frontend_install_warning_message(): - req_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'requirements.txt')) + """The warning message to display when the frontend version is not up to date.""" + extra = "" if sys.flags.no_user_site: extra = "-s " return f"Please install the updated requirements.txt file by running:\n{sys.executable} {extra}-m pip install -r {req_path}\n\nThis error is happening because the ComfyUI frontend is no longer shipped as part of the main repo but as a pip package instead.\n\nIf you are on the portable package you can run: update\\update_comfyui.bat to solve this problem" -try: - import comfyui_frontend_package -except ImportError: - # TODO: Remove the check after roll out of 0.3.16 - logging.error(f"\n\n********** ERROR ***********\n\ncomfyui-frontend-package is not installed. {frontend_install_warning_message()}\n********** ERROR **********\n") - exit(-1) +def check_frontend_version(): + """Check if the frontend version is up to date.""" + + def parse_version(version: str) -> tuple[int, int, int]: + return tuple(map(int, version.split("."))) + + try: + import comfyui_frontend_package + + frontend_version = parse_version(comfyui_frontend_package.__version__) + required_frontend = parse_version((0,)) + with open(req_path, 'r', encoding='utf-8') as f: + required_frontend = parse_version(f.readline().split('=')[-1]) + if frontend_version < required_frontend: + logging.warning("________________________________________________________________________\nWARNING WARNING WARNING WARNING WARNING\n\nInstalled frontend version {} is lower than the recommended version {}.\n\n{}\n________________________________________________________________________".format('.'.join(map(str, frontend_version)), '.'.join(map(str, required_frontend)), frontend_install_warning_message())) + else: + logging.info("ComfyUI frontend version: {}".format(comfyui_frontend_package.__version__)) + except Exception as e: + logging.error(f"Failed to check frontend version: {e}") -try: - frontend_version = tuple(map(int, comfyui_frontend_package.__version__.split("."))) -except: - frontend_version = (0,) - pass REQUEST_TIMEOUT = 10 # seconds @@ -133,9 +144,17 @@ def download_release_asset_zip(release: Release, destination_path: str) -> None: class FrontendManager: - DEFAULT_FRONTEND_PATH = str(importlib.resources.files(comfyui_frontend_package) / "static") CUSTOM_FRONTENDS_ROOT = str(Path(__file__).parents[1] / "web_custom_versions") + @classmethod + def default_frontend_path(cls) -> str: + try: + import comfyui_frontend_package + return str(importlib.resources.files(comfyui_frontend_package) / "static") + except ImportError: + logging.error(f"\n\n********** ERROR ***********\n\ncomfyui-frontend-package is not installed. {frontend_install_warning_message()}\n********** ERROR **********\n") + sys.exit(-1) + @classmethod def parse_version_string(cls, value: str) -> tuple[str, str, str]: """ @@ -172,7 +191,8 @@ class FrontendManager: main error source might be request timeout or invalid URL. """ if version_string == DEFAULT_VERSION_STRING: - return cls.DEFAULT_FRONTEND_PATH + check_frontend_version() + return cls.default_frontend_path() repo_owner, repo_name, version = cls.parse_version_string(version_string) @@ -225,4 +245,5 @@ class FrontendManager: except Exception as e: logging.error("Failed to initialize frontend: %s", e) logging.info("Falling back to the default frontend.") - return cls.DEFAULT_FRONTEND_PATH + check_frontend_version() + return cls.default_frontend_path() diff --git a/main.py b/main.py index 6fa1cfb0f..dbc15b8ba 100644 --- a/main.py +++ b/main.py @@ -293,28 +293,13 @@ def start_comfyui(asyncio_loop=None): return asyncio_loop, prompt_server, start_all -def warn_frontend_version(frontend_version): - try: - required_frontend = (0,) - req_path = os.path.join(os.path.dirname(__file__), 'requirements.txt') - with open(req_path, 'r') as f: - required_frontend = tuple(map(int, f.readline().split('=')[-1].split('.'))) - if frontend_version < required_frontend: - logging.warning("________________________________________________________________________\nWARNING WARNING WARNING WARNING WARNING\n\nInstalled frontend version {} is lower than the recommended version {}.\n\n{}\n________________________________________________________________________".format('.'.join(map(str, frontend_version)), '.'.join(map(str, required_frontend)), app.frontend_management.frontend_install_warning_message())) - except: - pass - - if __name__ == "__main__": # Running directly, just start ComfyUI. logging.info("ComfyUI version: {}".format(comfyui_version.__version__)) - frontend_version = app.frontend_management.frontend_version - logging.info("ComfyUI frontend version: {}".format('.'.join(map(str, frontend_version)))) event_loop, _, start_all_func = start_comfyui() try: x = start_all_func() - warn_frontend_version(frontend_version) event_loop.run_until_complete(x) except KeyboardInterrupt: logging.info("\nStopped server") From 6f6349b6a76fde39ab65d4952aa0aee7d2eade15 Mon Sep 17 00:00:00 2001 From: Chenlei Hu Date: Mon, 10 Mar 2025 15:10:40 -0400 Subject: [PATCH 3/7] nit --- main.py | 1 - 1 file changed, 1 deletion(-) diff --git a/main.py b/main.py index dbc15b8ba..c6f5c3c1e 100644 --- a/main.py +++ b/main.py @@ -139,7 +139,6 @@ from server import BinaryEventTypes import nodes import comfy.model_management import comfyui_version -import app.frontend_management def cuda_malloc_warning(): From 79460497941d090bc197898dc6e9c5e4feaf0c1d Mon Sep 17 00:00:00 2001 From: Chenlei Hu Date: Mon, 10 Mar 2025 15:14:40 -0400 Subject: [PATCH 4/7] nit --- app/frontend_management.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/app/frontend_management.py b/app/frontend_management.py index f5a0358e6..95df5dee4 100644 --- a/app/frontend_management.py +++ b/app/frontend_management.py @@ -39,9 +39,8 @@ def check_frontend_version(): import comfyui_frontend_package frontend_version = parse_version(comfyui_frontend_package.__version__) - required_frontend = parse_version((0,)) - with open(req_path, 'r', encoding='utf-8') as f: - required_frontend = parse_version(f.readline().split('=')[-1]) + with open(req_path, "r", encoding="utf-8") as f: + required_frontend = parse_version(f.readline().split("=")[-1]) if frontend_version < required_frontend: logging.warning("________________________________________________________________________\nWARNING WARNING WARNING WARNING WARNING\n\nInstalled frontend version {} is lower than the recommended version {}.\n\n{}\n________________________________________________________________________".format('.'.join(map(str, frontend_version)), '.'.join(map(str, required_frontend)), frontend_install_warning_message())) else: From db9f2a34fc87d49abea4e5aa29a8573f5073e0ce Mon Sep 17 00:00:00 2001 From: Chenlei Hu Date: Mon, 10 Mar 2025 15:19:52 -0400 Subject: [PATCH 5/7] Fix unit test --- tests-unit/app_test/frontend_manager_test.py | 57 +++++++++++++++++--- 1 file changed, 51 insertions(+), 6 deletions(-) diff --git a/tests-unit/app_test/frontend_manager_test.py b/tests-unit/app_test/frontend_manager_test.py index a8df52484..7a91ad410 100644 --- a/tests-unit/app_test/frontend_manager_test.py +++ b/tests-unit/app_test/frontend_manager_test.py @@ -70,7 +70,7 @@ def test_get_release_invalid_version(mock_provider): def test_init_frontend_default(): version_string = DEFAULT_VERSION_STRING frontend_path = FrontendManager.init_frontend(version_string) - assert frontend_path == FrontendManager.DEFAULT_FRONTEND_PATH + assert frontend_path == FrontendManager.default_frontend_path() def test_init_frontend_invalid_version(): @@ -84,24 +84,29 @@ def test_init_frontend_invalid_provider(): with pytest.raises(HTTPError): FrontendManager.init_frontend_unsafe(version_string) + @pytest.fixture def mock_os_functions(): - with patch('app.frontend_management.os.makedirs') as mock_makedirs, \ - patch('app.frontend_management.os.listdir') as mock_listdir, \ - patch('app.frontend_management.os.rmdir') as mock_rmdir: + with ( + patch("app.frontend_management.os.makedirs") as mock_makedirs, + patch("app.frontend_management.os.listdir") as mock_listdir, + patch("app.frontend_management.os.rmdir") as mock_rmdir, + ): mock_listdir.return_value = [] # Simulate empty directory yield mock_makedirs, mock_listdir, mock_rmdir + @pytest.fixture def mock_download(): - with patch('app.frontend_management.download_release_asset_zip') as mock: + with patch("app.frontend_management.download_release_asset_zip") as mock: mock.side_effect = Exception("Download failed") # Simulate download failure yield mock + def test_finally_block(mock_os_functions, mock_download, mock_provider): # Arrange mock_makedirs, mock_listdir, mock_rmdir = mock_os_functions - version_string = 'test-owner/test-repo@1.0.0' + version_string = "test-owner/test-repo@1.0.0" # Act & Assert with pytest.raises(Exception): @@ -128,3 +133,43 @@ def test_parse_version_string_invalid(): version_string = "invalid" with pytest.raises(argparse.ArgumentTypeError): FrontendManager.parse_version_string(version_string) + + +def test_init_frontend_default_with_mocks(): + # Arrange + version_string = DEFAULT_VERSION_STRING + + # Act + with ( + patch("app.frontend_management.check_frontend_version") as mock_check, + patch.object( + FrontendManager, "default_frontend_path", return_value="/mocked/path" + ), + ): + frontend_path = FrontendManager.init_frontend(version_string) + + # Assert + assert frontend_path == "/mocked/path" + mock_check.assert_called_once() + + +def test_init_frontend_fallback_on_error(): + # Arrange + version_string = "test-owner/test-repo@1.0.0" + + # Act + with ( + patch.object( + FrontendManager, "init_frontend_unsafe", side_effect=Exception("Test error") + ), + patch("app.frontend_management.check_frontend_version") as mock_check, + patch.object( + FrontendManager, "default_frontend_path", return_value="/default/path" + ), + ): + frontend_path = FrontendManager.init_frontend(version_string) + + # Assert + assert frontend_path == "/default/path" + mock_check.assert_called_once() + From 65ea778a5e5f69ec83e59a1f08678272fb2725d3 Mon Sep 17 00:00:00 2001 From: Chenlei Hu Date: Mon, 10 Mar 2025 15:19:59 -0400 Subject: [PATCH 6/7] nit --- tests-unit/app_test/frontend_manager_test.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests-unit/app_test/frontend_manager_test.py b/tests-unit/app_test/frontend_manager_test.py index 7a91ad410..ce67df6c6 100644 --- a/tests-unit/app_test/frontend_manager_test.py +++ b/tests-unit/app_test/frontend_manager_test.py @@ -172,4 +172,3 @@ def test_init_frontend_fallback_on_error(): # Assert assert frontend_path == "/default/path" mock_check.assert_called_once() - From cfbe4b49ca63eae79fe4f3206d03a41b43ef275e Mon Sep 17 00:00:00 2001 From: huchenlei Date: Mon, 10 Mar 2025 20:43:59 -0400 Subject: [PATCH 7/7] Access package version --- app/frontend_management.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/frontend_management.py b/app/frontend_management.py index 95df5dee4..4b7dfbb98 100644 --- a/app/frontend_management.py +++ b/app/frontend_management.py @@ -11,6 +11,7 @@ from dataclasses import dataclass from functools import cached_property from pathlib import Path from typing import TypedDict, Optional +from importlib.metadata import version import requests from typing_extensions import NotRequired @@ -36,15 +37,14 @@ def check_frontend_version(): return tuple(map(int, version.split("."))) try: - import comfyui_frontend_package - - frontend_version = parse_version(comfyui_frontend_package.__version__) + frontend_version_str = version("comfyui-frontend-package") + frontend_version = parse_version(frontend_version_str) with open(req_path, "r", encoding="utf-8") as f: required_frontend = parse_version(f.readline().split("=")[-1]) if frontend_version < required_frontend: logging.warning("________________________________________________________________________\nWARNING WARNING WARNING WARNING WARNING\n\nInstalled frontend version {} is lower than the recommended version {}.\n\n{}\n________________________________________________________________________".format('.'.join(map(str, frontend_version)), '.'.join(map(str, required_frontend)), frontend_install_warning_message())) else: - logging.info("ComfyUI frontend version: {}".format(comfyui_frontend_package.__version__)) + logging.info("ComfyUI frontend version: {}".format(frontend_version_str)) except Exception as e: logging.error(f"Failed to check frontend version: {e}")