From 60746c625390bcf55eece25b17e49a0505eea783 Mon Sep 17 00:00:00 2001 From: Jin Yi Date: Wed, 30 Jul 2025 07:57:19 +0900 Subject: [PATCH] [feat] Add bulk import failure info API endpoint (#2035) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [feat] Add bulk import failure info API endpoint - Add import_fail_info_bulk endpoint to both glob and legacy manager servers - Supports bulk processing of cnr_ids and urls arrays in single request - Maintains same error handling pattern as original import_fail_info API - Reduces API calls from N to 1 for conflict detection optimization - Validates input parameters and provides proper error responses 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude * modified: remove manager button completely. Now, even when using the legacy UI, it must always be accessed through the menu. * chore(api): Add temporary cache reload for import_fail_info_bulk --------- Co-authored-by: Claude Co-authored-by: Dr.Lt.Data --- comfyui_manager/glob/manager_server.py | 59 ++++++++++++++++++++++++ comfyui_manager/js/comfyui-manager.js | 2 - comfyui_manager/legacy/manager_server.py | 59 ++++++++++++++++++++++++ pyproject.toml | 2 +- 4 files changed, 119 insertions(+), 3 deletions(-) diff --git a/comfyui_manager/glob/manager_server.py b/comfyui_manager/glob/manager_server.py index ff7db2bd..e2699389 100644 --- a/comfyui_manager/glob/manager_server.py +++ b/comfyui_manager/glob/manager_server.py @@ -1656,6 +1656,65 @@ async def import_fail_info(request): return web.Response(status=500, text="Internal server error") +@routes.post("/v2/customnode/import_fail_info_bulk") +async def import_fail_info_bulk(request): + try: + json_data = await request.json() + + # Basic validation - ensure we have either cnr_ids or urls + if not isinstance(json_data, dict): + return web.Response(status=400, text="Request body must be a JSON object") + + if "cnr_ids" not in json_data and "urls" not in json_data: + return web.Response( + status=400, text="Either 'cnr_ids' or 'urls' field is required" + ) + + await core.unified_manager.reload('cache') + await core.unified_manager.get_custom_nodes('default', 'cache') + + results = {} + + if "cnr_ids" in json_data: + if not isinstance(json_data["cnr_ids"], list): + return web.Response(status=400, text="'cnr_ids' must be an array") + for cnr_id in json_data["cnr_ids"]: + if not isinstance(cnr_id, str): + results[cnr_id] = {"error": "cnr_id must be a string"} + continue + module_name = core.unified_manager.get_module_name(cnr_id) + if module_name is not None: + info = cm_global.error_dict.get(module_name) + if info is not None: + results[cnr_id] = info + else: + results[cnr_id] = None + else: + results[cnr_id] = None + + if "urls" in json_data: + if not isinstance(json_data["urls"], list): + return web.Response(status=400, text="'urls' must be an array") + for url in json_data["urls"]: + if not isinstance(url, str): + results[url] = {"error": "url must be a string"} + continue + module_name = core.unified_manager.get_module_name(url) + if module_name is not None: + info = cm_global.error_dict.get(module_name) + if info is not None: + results[url] = info + else: + results[url] = None + else: + results[url] = None + + return web.json_response(results) + except Exception as e: + logging.error(f"[ComfyUI-Manager] Error processing bulk import fail info: {e}") + return web.Response(status=500, text="Internal server error") + + @routes.get("/v2/manager/queue/reset") async def reset_queue(request): logging.debug("[ComfyUI-Manager] Queue reset requested") diff --git a/comfyui_manager/js/comfyui-manager.js b/comfyui_manager/js/comfyui-manager.js index 6ebbbe0e..7baada7f 100644 --- a/comfyui_manager/js/comfyui-manager.js +++ b/comfyui_manager/js/comfyui-manager.js @@ -1514,8 +1514,6 @@ app.registerExtension({ tooltip: "Share" }).element ); - - app.menu?.settingsGroup.element.before(cmGroup.element); } catch(exception) { console.log('ComfyUI is outdated. New style menu based features are disabled.'); diff --git a/comfyui_manager/legacy/manager_server.py b/comfyui_manager/legacy/manager_server.py index c873aca2..8af46ff7 100644 --- a/comfyui_manager/legacy/manager_server.py +++ b/comfyui_manager/legacy/manager_server.py @@ -1308,6 +1308,65 @@ async def import_fail_info(request): return web.Response(status=400) +@routes.post("/v2/customnode/import_fail_info_bulk") +async def import_fail_info_bulk(request): + try: + json_data = await request.json() + + # Basic validation - ensure we have either cnr_ids or urls + if not isinstance(json_data, dict): + return web.Response(status=400, text="Request body must be a JSON object") + + if "cnr_ids" not in json_data and "urls" not in json_data: + return web.Response( + status=400, text="Either 'cnr_ids' or 'urls' field is required" + ) + + await core.unified_manager.reload('cache') + await core.unified_manager.get_custom_nodes('default', 'cache') + + results = {} + + if "cnr_ids" in json_data: + if not isinstance(json_data["cnr_ids"], list): + return web.Response(status=400, text="'cnr_ids' must be an array") + for cnr_id in json_data["cnr_ids"]: + if not isinstance(cnr_id, str): + results[cnr_id] = {"error": "cnr_id must be a string"} + continue + module_name = core.unified_manager.get_module_name(cnr_id) + if module_name is not None: + info = cm_global.error_dict.get(module_name) + if info is not None: + results[cnr_id] = info + else: + results[cnr_id] = None + else: + results[cnr_id] = None + + if "urls" in json_data: + if not isinstance(json_data["urls"], list): + return web.Response(status=400, text="'urls' must be an array") + for url in json_data["urls"]: + if not isinstance(url, str): + results[url] = {"error": "url must be a string"} + continue + module_name = core.unified_manager.get_module_name(url) + if module_name is not None: + info = cm_global.error_dict.get(module_name) + if info is not None: + results[url] = info + else: + results[url] = None + else: + results[url] = None + + return web.json_response(results) + except Exception as e: + logging.error(f"[ComfyUI-Manager] Error processing bulk import fail info: {e}") + return web.Response(status=500, text="Internal server error") + + @routes.post("/v2/manager/queue/reinstall") async def reinstall_custom_node(request): await uninstall_custom_node(request) diff --git a/pyproject.toml b/pyproject.toml index 42b863dd..b5a9b8cd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -5,7 +5,7 @@ build-backend = "setuptools.build_meta" [project] name = "comfyui-manager" license = { text = "GPL-3.0-only" } -version = "4.0.0-beta.10" +version = "4.0.0-beta.11" requires-python = ">= 3.9" description = "ComfyUI-Manager provides features to install and manage custom nodes for ComfyUI, as well as various functionalities to assist with ComfyUI." readme = "README.md"