mirror of
https://git.datalinker.icu/comfyanonymous/ComfyUI
synced 2026-09-02 04:47:05 +08:00
Merge 8b1226dac2906d0512285350bc21664fcaabe71e into c60dc4177c16d50da025bda4ac7fd513bb86e699
This commit is contained in:
commit
70fa1d8fd5
44
nodes.py
44
nodes.py
@ -2078,6 +2078,7 @@ EXTENSION_WEB_DIRS = {}
|
||||
# Dictionary of successfully loaded module names and associated directories.
|
||||
LOADED_MODULE_DIRS = {}
|
||||
|
||||
LOADED_CUSTOM_NODES = {}
|
||||
|
||||
def get_module_name(module_path: str) -> str:
|
||||
"""
|
||||
@ -2103,6 +2104,8 @@ def get_module_name(module_path: str) -> str:
|
||||
|
||||
def load_custom_node(module_path: str, ignore=set(), module_parent="custom_nodes") -> bool:
|
||||
module_name = get_module_name(module_path)
|
||||
project_name = module_name
|
||||
|
||||
if os.path.isfile(module_path):
|
||||
sp = os.path.splitext(module_path)
|
||||
module_name = sp[0]
|
||||
@ -2110,6 +2113,15 @@ def load_custom_node(module_path: str, ignore=set(), module_parent="custom_nodes
|
||||
elif os.path.isdir(module_path):
|
||||
sys_module_name = module_path.replace(".", "_x_")
|
||||
|
||||
is_custom_node = module_parent == "custom_nodes"
|
||||
|
||||
if is_custom_node:
|
||||
LOADED_CUSTOM_NODES[project_name] = {
|
||||
"project_name": project_name,
|
||||
"status": "loading",
|
||||
"error": None
|
||||
}
|
||||
|
||||
try:
|
||||
logging.debug("Trying to load custom node {}".format(module_path))
|
||||
if os.path.isfile(module_path):
|
||||
@ -2130,14 +2142,20 @@ def load_custom_node(module_path: str, ignore=set(), module_parent="custom_nodes
|
||||
|
||||
project_config = config_parser.extract_node_configuration(module_path)
|
||||
|
||||
project_name_from_config = project_config.project.name
|
||||
|
||||
if is_custom_node and project_name_from_config != project_name:
|
||||
LOADED_CUSTOM_NODES[project_name_from_config] = LOADED_CUSTOM_NODES.pop(project_name)
|
||||
LOADED_CUSTOM_NODES[project_name_from_config]["project_name"] = project_name_from_config
|
||||
|
||||
project_name = project_name_from_config
|
||||
|
||||
web_dir_name = project_config.tool_comfy.web
|
||||
|
||||
if web_dir_name:
|
||||
web_dir_path = os.path.join(module_path, web_dir_name)
|
||||
|
||||
if os.path.isdir(web_dir_path):
|
||||
project_name = project_config.project.name
|
||||
|
||||
EXTENSION_WEB_DIRS[project_name] = web_dir_path
|
||||
|
||||
logging.info("Automatically register web folder {} for {}".format(web_dir_name, project_name))
|
||||
@ -2150,17 +2168,39 @@ def load_custom_node(module_path: str, ignore=set(), module_parent="custom_nodes
|
||||
EXTENSION_WEB_DIRS[module_name] = web_dir
|
||||
|
||||
if hasattr(module, "NODE_CLASS_MAPPINGS") and getattr(module, "NODE_CLASS_MAPPINGS") is not None:
|
||||
node_count = 0
|
||||
for name, node_cls in module.NODE_CLASS_MAPPINGS.items():
|
||||
if name not in ignore:
|
||||
NODE_CLASS_MAPPINGS[name] = node_cls
|
||||
node_cls.RELATIVE_PYTHON_MODULE = "{}.{}".format(module_parent, get_module_name(module_path))
|
||||
node_count += 1
|
||||
|
||||
if hasattr(module, "NODE_DISPLAY_NAME_MAPPINGS") and getattr(module, "NODE_DISPLAY_NAME_MAPPINGS") is not None:
|
||||
NODE_DISPLAY_NAME_MAPPINGS.update(module.NODE_DISPLAY_NAME_MAPPINGS)
|
||||
|
||||
if is_custom_node:
|
||||
LOADED_CUSTOM_NODES[project_name].update({
|
||||
"status": "loaded",
|
||||
"node_count": node_count,
|
||||
"nodes": list(module.NODE_CLASS_MAPPINGS.keys())
|
||||
})
|
||||
logging.info(f"Successfully loaded custom node: {project_name} with {node_count} nodes")
|
||||
|
||||
return True
|
||||
else:
|
||||
if is_custom_node:
|
||||
LOADED_CUSTOM_NODES[project_name].update({
|
||||
"status": "skipped",
|
||||
"error": "No NODE_CLASS_MAPPINGS found"
|
||||
})
|
||||
logging.warning(f"Skip {module_path} module for custom nodes due to the lack of NODE_CLASS_MAPPINGS.")
|
||||
return False
|
||||
except Exception as e:
|
||||
if is_custom_node:
|
||||
LOADED_CUSTOM_NODES[project_name].update({
|
||||
"status": "failed",
|
||||
"error": str(e)
|
||||
})
|
||||
logging.warning(traceback.format_exc())
|
||||
logging.warning(f"Cannot import {module_path} module for custom nodes: {e}")
|
||||
return False
|
||||
|
||||
121
server.py
121
server.py
@ -748,6 +748,127 @@ class PromptServer():
|
||||
|
||||
return web.Response(status=200)
|
||||
|
||||
@routes.get("/custom_nodes")
|
||||
async def get_custom_nodes(request):
|
||||
"""
|
||||
{
|
||||
"custom_nodes": [
|
||||
{
|
||||
"project_name": "node_1",
|
||||
"status": "loaded|failed|skipped|loading",
|
||||
"node_count": 5,
|
||||
"nodes": ["NodeClass1", "NodeClass2"],
|
||||
"error": "error message if failed"
|
||||
}
|
||||
],
|
||||
"total_count": 10,
|
||||
"loaded_count": 8,
|
||||
"failed_count": 1,
|
||||
"skipped_count": 1
|
||||
}
|
||||
"""
|
||||
try:
|
||||
custom_nodes_list = []
|
||||
loaded_count = 0
|
||||
failed_count = 0
|
||||
skipped_count = 0
|
||||
|
||||
for project_name, node_info in nodes.LOADED_CUSTOM_NODES.items():
|
||||
node_data = {
|
||||
"project_name": node_info.get("project_name", project_name),
|
||||
"status": node_info.get("status", "unknown")
|
||||
}
|
||||
|
||||
if node_info.get("status") == "loaded":
|
||||
node_data.update({
|
||||
"node_count": node_info.get("node_count", 0),
|
||||
"nodes": node_info.get("nodes", [])
|
||||
})
|
||||
loaded_count += 1
|
||||
elif node_info.get("status") == "failed":
|
||||
node_data["error"] = node_info.get("error", "Unknown error")
|
||||
failed_count += 1
|
||||
elif node_info.get("status") == "skipped":
|
||||
node_data["error"] = node_info.get("error", "No NODE_CLASS_MAPPINGS found")
|
||||
skipped_count += 1
|
||||
|
||||
custom_nodes_list.append(node_data)
|
||||
|
||||
response_data = {
|
||||
"custom_nodes": custom_nodes_list,
|
||||
"total_count": len(custom_nodes_list),
|
||||
"loaded_count": loaded_count,
|
||||
"failed_count": failed_count,
|
||||
"skipped_count": skipped_count
|
||||
}
|
||||
|
||||
return web.json_response(response_data)
|
||||
|
||||
except Exception as e:
|
||||
logging.error(f"Error in get_custom_nodes: {e}")
|
||||
logging.error(traceback.format_exc())
|
||||
return web.json_response({
|
||||
"error": f"Failed to get custom nodes: {str(e)}",
|
||||
"custom_nodes": [],
|
||||
"total_count": 0,
|
||||
"loaded_count": 0,
|
||||
"failed_count": 0,
|
||||
"skipped_count": 0
|
||||
}, status=500)
|
||||
|
||||
@routes.get("/custom_node/{project_name}")
|
||||
async def get_custom_node_by_name(request):
|
||||
try:
|
||||
project_name = request.match_info["project_name"]
|
||||
|
||||
if not project_name:
|
||||
return web.json_response({
|
||||
"error": "Project name is required",
|
||||
"message": "Please provide a valid project name in the URL path"
|
||||
}, status=400)
|
||||
|
||||
import urllib.parse
|
||||
project_name = urllib.parse.unquote(project_name)
|
||||
|
||||
if project_name not in nodes.LOADED_CUSTOM_NODES:
|
||||
return web.json_response({
|
||||
"error": f"Custom node '{project_name}' not found",
|
||||
"message": f"The custom node '{project_name}' is not loaded or does not exist"
|
||||
}, status=404)
|
||||
|
||||
node_info = nodes.LOADED_CUSTOM_NODES[project_name]
|
||||
|
||||
response_data = {
|
||||
"project_name": node_info.get("project_name", project_name),
|
||||
"status": node_info.get("status", "unknown")
|
||||
}
|
||||
|
||||
if node_info.get("status") == "loaded":
|
||||
response_data.update({
|
||||
"node_count": node_info.get("node_count", 0),
|
||||
"nodes": node_info.get("nodes", [])
|
||||
})
|
||||
elif node_info.get("status") in ["failed", "skipped"]:
|
||||
response_data["error"] = node_info.get("error", "Unknown error")
|
||||
|
||||
return web.json_response(response_data)
|
||||
|
||||
except KeyError as e:
|
||||
logging.error(f"Missing parameter in get_custom_node_by_name: {e}")
|
||||
return web.json_response({
|
||||
"error": "Invalid request",
|
||||
"message": "Required parameter is missing from the request"
|
||||
}, status=400)
|
||||
|
||||
except Exception as e:
|
||||
logging.error(f"Error in get_custom_node_by_name: {e}")
|
||||
logging.error(traceback.format_exc())
|
||||
return web.json_response({
|
||||
"error": f"Failed to get custom node information: {str(e)}",
|
||||
"message": "An internal error occurred while retrieving the custom node information"
|
||||
}, status=500)
|
||||
|
||||
|
||||
async def setup(self):
|
||||
timeout = aiohttp.ClientTimeout(total=None) # no timeout
|
||||
self.client_session = aiohttp.ClientSession(timeout=timeout)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user