From 9d894979320f1c90657d1b098b05e6339047a936 Mon Sep 17 00:00:00 2001 From: Jin Yi Date: Sun, 27 Jul 2025 18:09:58 +0900 Subject: [PATCH] [feat] Add bulk import failure info API endpoint MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 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 --- comfyui_manager/glob/manager_server.py | 56 ++++++++++++++++++++++++ comfyui_manager/legacy/manager_server.py | 56 ++++++++++++++++++++++++ 2 files changed, 112 insertions(+) diff --git a/comfyui_manager/glob/manager_server.py b/comfyui_manager/glob/manager_server.py index ff7db2bd..3e69ffe3 100644 --- a/comfyui_manager/glob/manager_server.py +++ b/comfyui_manager/glob/manager_server.py @@ -1656,6 +1656,62 @@ 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" + ) + + 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/legacy/manager_server.py b/comfyui_manager/legacy/manager_server.py index c873aca2..0a28b1a7 100644 --- a/comfyui_manager/legacy/manager_server.py +++ b/comfyui_manager/legacy/manager_server.py @@ -1308,6 +1308,62 @@ 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" + ) + + 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)