From e407987b319668e89fb2298588627919e25f7287 Mon Sep 17 00:00:00 2001 From: shivansh-gupta4 Date: Fri, 11 Jul 2025 23:11:07 +0530 Subject: [PATCH 1/7] Added the parameter required_frontend_version in the /system_stats api response --- server.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/server.py b/server.py index e8bad9f4e429..b6dbe25ede41 100644 --- a/server.py +++ b/server.py @@ -553,6 +553,7 @@ async def system_stats(request): ram_free = comfy.model_management.get_free_memory(cpu_device) vram_total, torch_vram_total = comfy.model_management.get_total_memory(device, torch_total_too=True) vram_free, torch_vram_free = comfy.model_management.get_free_memory(device, torch_free_too=True) + required_frontend_version = open(os.path.join(os.path.dirname(__file__), "requirements.txt")).readline().split("==")[1].strip() system_stats = { "system": { @@ -560,6 +561,7 @@ async def system_stats(request): "ram_total": ram_total, "ram_free": ram_free, "comfyui_version": __version__, + "required_frontend_version":required_frontend_version, "python_version": sys.version, "pytorch_version": comfy.model_management.torch_version, "embedded_python": os.path.split(os.path.split(sys.executable)[0])[1] == "python_embeded", From 028432539823f79d103be44e5934c8157a8cb647 Mon Sep 17 00:00:00 2001 From: SHIVANSH GUPTA <121501003+shivansh-gupta4@users.noreply.github.com> Date: Fri, 11 Jul 2025 23:32:01 +0530 Subject: [PATCH 2/7] Update server.py --- server.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server.py b/server.py index b6dbe25ede41..9334aa8e86a6 100644 --- a/server.py +++ b/server.py @@ -561,7 +561,7 @@ async def system_stats(request): "ram_total": ram_total, "ram_free": ram_free, "comfyui_version": __version__, - "required_frontend_version":required_frontend_version, + "required_frontend_version": required_frontend_version, "python_version": sys.version, "pytorch_version": comfy.model_management.torch_version, "embedded_python": os.path.split(os.path.split(sys.executable)[0])[1] == "python_embeded", From e7040c37e325eef1ca17a11ad68d234d2e5a7553 Mon Sep 17 00:00:00 2001 From: shivansh-gupta4 Date: Sat, 12 Jul 2025 14:56:53 +0530 Subject: [PATCH 3/7] Created a function get_required_frontend_version and wrote tests for it --- app/frontend_management.py | 29 ++++++++++++++++++-- server.py | 2 +- tests-unit/app_test/frontend_manager_test.py | 9 ++++++ 3 files changed, 37 insertions(+), 3 deletions(-) diff --git a/app/frontend_management.py b/app/frontend_management.py index 001ebbecb4f2..8495b46c16e7 100644 --- a/app/frontend_management.py +++ b/app/frontend_management.py @@ -29,6 +29,26 @@ def frontend_install_warning_message(): This error is happening because the ComfyUI frontend is no longer shipped as part of the main repo but as a pip package instead. """.strip() +def is_valid_version(version: str) -> bool: + """Validate if a string is a valid semantic version (X.Y.Z format).""" + pattern = r"^(\d+)\.(\d+)\.(\d+)$" + return bool(re.match(pattern, version)) + +def get_required_frontend_version(): + """Get the required frontend version from requirements.txt.""" + try: + with open(requirements_path, "r", encoding="utf-8") as f: + version_str = f.readline().split("=")[-1].strip() + if not is_valid_version(version_str): + logging.error(f"Invalid version format in requirements.txt: {version_str}") + return None + return version_str + except FileNotFoundError: + logging.error("requirements.txt not found. Cannot determine required frontend version.") + return None + except Exception as e: + logging.error(f"Error reading requirements.txt: {e}") + return None def check_frontend_version(): """Check if the frontend version is up to date.""" @@ -39,8 +59,8 @@ def parse_version(version: str) -> tuple[int, int, int]: try: frontend_version_str = version("comfyui-frontend-package") frontend_version = parse_version(frontend_version_str) - with open(requirements_path, "r", encoding="utf-8") as f: - required_frontend = parse_version(f.readline().split("=")[-1]) + required_frontend_str = get_required_frontend_version() + required_frontend = parse_version(required_frontend_str) if frontend_version < required_frontend: app.logger.log_startup_warning( f""" @@ -168,6 +188,11 @@ def download_release_asset_zip(release: Release, destination_path: str) -> None: class FrontendManager: CUSTOM_FRONTENDS_ROOT = str(Path(__file__).parents[1] / "web_custom_versions") + @classmethod + def get_required_frontend_version(cls) -> str: + """Get the required frontend version from requirements.txt.""" + return get_required_frontend_version() + @classmethod def default_frontend_path(cls) -> str: try: diff --git a/server.py b/server.py index 9334aa8e86a6..dfb846b66b95 100644 --- a/server.py +++ b/server.py @@ -553,7 +553,7 @@ async def system_stats(request): ram_free = comfy.model_management.get_free_memory(cpu_device) vram_total, torch_vram_total = comfy.model_management.get_total_memory(device, torch_total_too=True) vram_free, torch_vram_free = comfy.model_management.get_free_memory(device, torch_free_too=True) - required_frontend_version = open(os.path.join(os.path.dirname(__file__), "requirements.txt")).readline().split("==")[1].strip() + required_frontend_version = FrontendManager.get_required_frontend_version() system_stats = { "system": { diff --git a/tests-unit/app_test/frontend_manager_test.py b/tests-unit/app_test/frontend_manager_test.py index ce67df6c6ab3..44db1cd5b175 100644 --- a/tests-unit/app_test/frontend_manager_test.py +++ b/tests-unit/app_test/frontend_manager_test.py @@ -172,3 +172,12 @@ def test_init_frontend_fallback_on_error(): # Assert assert frontend_path == "/default/path" mock_check.assert_called_once() + +def test_get_required_frontend_version(): + #Arrange + expected_version = "1.23.4" + + version = FrontendManager.get_required_frontend_version() + + #Assert + assert version == expected_version From b3eed4fa35073c9485a95a2a7945a1b3d32a0066 Mon Sep 17 00:00:00 2001 From: shivansh-gupta4 Date: Sat, 12 Jul 2025 23:41:25 +0530 Subject: [PATCH 4/7] Refactored the function to return currently installed frontend pacakage version --- app/frontend_management.py | 40 ++++++-------------- server.py | 2 +- tests-unit/app_test/frontend_manager_test.py | 4 +- 3 files changed, 15 insertions(+), 31 deletions(-) diff --git a/app/frontend_management.py b/app/frontend_management.py index 8495b46c16e7..8d5aa20f3a69 100644 --- a/app/frontend_management.py +++ b/app/frontend_management.py @@ -29,38 +29,22 @@ def frontend_install_warning_message(): This error is happening because the ComfyUI frontend is no longer shipped as part of the main repo but as a pip package instead. """.strip() -def is_valid_version(version: str) -> bool: - """Validate if a string is a valid semantic version (X.Y.Z format).""" - pattern = r"^(\d+)\.(\d+)\.(\d+)$" - return bool(re.match(pattern, version)) +def parse_version(version: str) -> tuple[int, int, int]: + return tuple(map(int, version.split("."))) -def get_required_frontend_version(): - """Get the required frontend version from requirements.txt.""" - try: - with open(requirements_path, "r", encoding="utf-8") as f: - version_str = f.readline().split("=")[-1].strip() - if not is_valid_version(version_str): - logging.error(f"Invalid version format in requirements.txt: {version_str}") - return None - return version_str - except FileNotFoundError: - logging.error("requirements.txt not found. Cannot determine required frontend version.") - return None - except Exception as e: - logging.error(f"Error reading requirements.txt: {e}") - return None +def get_installed_frontend_version(): + """Get the currently installed frontend package version.""" + frontend_version_str = version("comfyui-frontend-package") + return frontend_version_str 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: - frontend_version_str = version("comfyui-frontend-package") + frontend_version_str = get_installed_frontend_version() frontend_version = parse_version(frontend_version_str) - required_frontend_str = get_required_frontend_version() - required_frontend = parse_version(required_frontend_str) + with open(requirements_path, "r", encoding="utf-8") as f: + required_frontend = parse_version(f.readline().split("=")[-1]) if frontend_version < required_frontend: app.logger.log_startup_warning( f""" @@ -189,9 +173,9 @@ class FrontendManager: CUSTOM_FRONTENDS_ROOT = str(Path(__file__).parents[1] / "web_custom_versions") @classmethod - def get_required_frontend_version(cls) -> str: - """Get the required frontend version from requirements.txt.""" - return get_required_frontend_version() + def get_frontend_version(cls) -> str: + """Get the currently installed frontend package version.""" + return get_installed_frontend_version() @classmethod def default_frontend_path(cls) -> str: diff --git a/server.py b/server.py index dfb846b66b95..17e6f6ad781f 100644 --- a/server.py +++ b/server.py @@ -553,7 +553,7 @@ async def system_stats(request): ram_free = comfy.model_management.get_free_memory(cpu_device) vram_total, torch_vram_total = comfy.model_management.get_total_memory(device, torch_total_too=True) vram_free, torch_vram_free = comfy.model_management.get_free_memory(device, torch_free_too=True) - required_frontend_version = FrontendManager.get_required_frontend_version() + required_frontend_version = FrontendManager.get_frontend_version() system_stats = { "system": { diff --git a/tests-unit/app_test/frontend_manager_test.py b/tests-unit/app_test/frontend_manager_test.py index 44db1cd5b175..ce0685d5aaea 100644 --- a/tests-unit/app_test/frontend_manager_test.py +++ b/tests-unit/app_test/frontend_manager_test.py @@ -173,11 +173,11 @@ def test_init_frontend_fallback_on_error(): assert frontend_path == "/default/path" mock_check.assert_called_once() -def test_get_required_frontend_version(): +def test_get_frontend_version(): #Arrange expected_version = "1.23.4" - version = FrontendManager.get_required_frontend_version() + version = FrontendManager.get_frontend_version() #Assert assert version == expected_version From 8355adc750f5c53d55913db3d25e3e20572b564d Mon Sep 17 00:00:00 2001 From: shivansh-gupta4 Date: Sun, 13 Jul 2025 23:51:06 +0530 Subject: [PATCH 5/7] Moved required_frontend to a new function and imported that in server.py --- app/frontend_management.py | 36 +++++++++++++++++--- server.py | 2 +- tests-unit/app_test/frontend_manager_test.py | 2 +- 3 files changed, 33 insertions(+), 7 deletions(-) diff --git a/app/frontend_management.py b/app/frontend_management.py index 8d5aa20f3a69..a5eba7b104c3 100644 --- a/app/frontend_management.py +++ b/app/frontend_management.py @@ -31,20 +31,46 @@ def frontend_install_warning_message(): def parse_version(version: str) -> tuple[int, int, int]: return tuple(map(int, version.split("."))) + +def is_valid_version(version: str) -> bool: + """Validate if a string is a valid semantic version (X.Y.Z format).""" + pattern = r"^(\d+)\.(\d+)\.(\d+)$" + return bool(re.match(pattern, version)) def get_installed_frontend_version(): """Get the currently installed frontend package version.""" frontend_version_str = version("comfyui-frontend-package") return frontend_version_str +def get_required_frontend_version(): + """Get the required frontend version from requirements.txt.""" + try: + with open(requirements_path, "r", encoding="utf-8") as f: + for line in f: + line = line.strip() + if line.startswith("comfyui-frontend-package=="): + version_str = line.split("==")[-1] + if not is_valid_version(version_str): + logging.error(f"Invalid version format in requirements.txt: {version_str}") + return None + return version_str + logging.error("comfyui-frontend-package not found in requirements.txt") + return None + except FileNotFoundError: + logging.error("requirements.txt not found. Cannot determine required frontend version.") + return None + except Exception as e: + logging.error(f"Error reading requirements.txt: {e}") + return None + def check_frontend_version(): """Check if the frontend version is up to date.""" try: frontend_version_str = get_installed_frontend_version() frontend_version = parse_version(frontend_version_str) - with open(requirements_path, "r", encoding="utf-8") as f: - required_frontend = parse_version(f.readline().split("=")[-1]) + required_frontend_str = get_required_frontend_version() + required_frontend = parse_version(required_frontend_str) if frontend_version < required_frontend: app.logger.log_startup_warning( f""" @@ -173,9 +199,9 @@ class FrontendManager: CUSTOM_FRONTENDS_ROOT = str(Path(__file__).parents[1] / "web_custom_versions") @classmethod - def get_frontend_version(cls) -> str: - """Get the currently installed frontend package version.""" - return get_installed_frontend_version() + def get_required_frontend_version(cls) -> str: + """Get the required frontend package version.""" + return get_required_frontend_version() @classmethod def default_frontend_path(cls) -> str: diff --git a/server.py b/server.py index 17e6f6ad781f..dfb846b66b95 100644 --- a/server.py +++ b/server.py @@ -553,7 +553,7 @@ async def system_stats(request): ram_free = comfy.model_management.get_free_memory(cpu_device) vram_total, torch_vram_total = comfy.model_management.get_total_memory(device, torch_total_too=True) vram_free, torch_vram_free = comfy.model_management.get_free_memory(device, torch_free_too=True) - required_frontend_version = FrontendManager.get_frontend_version() + required_frontend_version = FrontendManager.get_required_frontend_version() system_stats = { "system": { diff --git a/tests-unit/app_test/frontend_manager_test.py b/tests-unit/app_test/frontend_manager_test.py index ce0685d5aaea..b481a1678d78 100644 --- a/tests-unit/app_test/frontend_manager_test.py +++ b/tests-unit/app_test/frontend_manager_test.py @@ -177,7 +177,7 @@ def test_get_frontend_version(): #Arrange expected_version = "1.23.4" - version = FrontendManager.get_frontend_version() + version = FrontendManager.get_required_frontend_version() #Assert assert version == expected_version From 56981f5da4a691cb47d19a0e560264fb7c84180d Mon Sep 17 00:00:00 2001 From: shivansh-gupta4 Date: Mon, 14 Jul 2025 06:48:19 +0530 Subject: [PATCH 6/7] Corrected test cases using mocking techniques --- tests-unit/app_test/frontend_manager_test.py | 42 +++++++++++++++----- 1 file changed, 33 insertions(+), 9 deletions(-) diff --git a/tests-unit/app_test/frontend_manager_test.py b/tests-unit/app_test/frontend_manager_test.py index b481a1678d78..ce43ac564e8a 100644 --- a/tests-unit/app_test/frontend_manager_test.py +++ b/tests-unit/app_test/frontend_manager_test.py @@ -1,7 +1,7 @@ import argparse import pytest from requests.exceptions import HTTPError -from unittest.mock import patch +from unittest.mock import patch, mock_open from app.frontend_management import ( FrontendManager, @@ -172,12 +172,36 @@ def test_init_frontend_fallback_on_error(): # Assert assert frontend_path == "/default/path" mock_check.assert_called_once() - + + def test_get_frontend_version(): - #Arrange - expected_version = "1.23.4" - - version = FrontendManager.get_required_frontend_version() - - #Assert - assert version == expected_version + # Arrange + expected_version = "1.25.0" + mock_requirements_content = """torch +torchsde +comfyui-frontend-package==1.25.0 +other-package==1.0.0 +numpy""" + + # Act + with patch("builtins.open", mock_open(read_data=mock_requirements_content)): + version = FrontendManager.get_required_frontend_version() + + # Assert + assert version == expected_version + + +def test_get_frontend_version_invalid_semver(): + # Arrange + mock_requirements_content = """torch +torchsde +comfyui-frontend-package==1.29.3.75 +other-package==1.0.0 +numpy""" + + # Act + with patch("builtins.open", mock_open(read_data=mock_requirements_content)): + version = FrontendManager.get_required_frontend_version() + + # Assert + assert version is None From de49e6e1f7a71a52f2b168f51f704ec10df30c84 Mon Sep 17 00:00:00 2001 From: shivansh-gupta4 Date: Wed, 16 Jul 2025 00:13:56 +0530 Subject: [PATCH 7/7] Corrected files to comply with ruff formatting --- app/frontend_management.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/frontend_management.py b/app/frontend_management.py index a5eba7b104c3..0bee73685b93 100644 --- a/app/frontend_management.py +++ b/app/frontend_management.py @@ -31,7 +31,7 @@ def frontend_install_warning_message(): def parse_version(version: str) -> tuple[int, int, int]: return tuple(map(int, version.split("."))) - + def is_valid_version(version: str) -> bool: """Validate if a string is a valid semantic version (X.Y.Z format).""" pattern = r"^(\d+)\.(\d+)\.(\d+)$"