Compare commits
8
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
98c1aca606 | ||
|
|
09eab3202f | ||
|
|
f66adfa04f | ||
|
|
0ff751b60f | ||
|
|
a4e3bc2571 | ||
|
|
bf8e2a17b9 | ||
|
|
60c93b65f4 | ||
|
|
5d2ade4fd4 |
@@ -4,6 +4,7 @@ import numpy as np
|
|||||||
from PIL import Image
|
from PIL import Image
|
||||||
from PIL.PngImagePlugin import PngInfo
|
from PIL.PngImagePlugin import PngInfo
|
||||||
import folder_paths
|
import folder_paths
|
||||||
|
from comfy.cli_args import args
|
||||||
|
|
||||||
|
|
||||||
class ComfyDeployOutputImage:
|
class ComfyDeployOutputImage:
|
||||||
@@ -33,7 +34,6 @@ class ComfyDeployOutputImage:
|
|||||||
"STRING",
|
"STRING",
|
||||||
{"multiline": False, "default": "output_images"},
|
{"multiline": False, "default": "output_images"},
|
||||||
),
|
),
|
||||||
"remove_metadata": ("BOOLEAN", {"default": True}),
|
|
||||||
},
|
},
|
||||||
"hidden": {"prompt": "PROMPT", "extra_pnginfo": "EXTRA_PNGINFO"},
|
"hidden": {"prompt": "PROMPT", "extra_pnginfo": "EXTRA_PNGINFO"},
|
||||||
}
|
}
|
||||||
@@ -54,7 +54,6 @@ class ComfyDeployOutputImage:
|
|||||||
output_id="output_images",
|
output_id="output_images",
|
||||||
prompt=None,
|
prompt=None,
|
||||||
extra_pnginfo=None,
|
extra_pnginfo=None,
|
||||||
remove_metadata=True,
|
|
||||||
):
|
):
|
||||||
filename_prefix += self.prefix_append
|
filename_prefix += self.prefix_append
|
||||||
full_output_folder, filename, counter, subfolder, filename_prefix = (
|
full_output_folder, filename, counter, subfolder, filename_prefix = (
|
||||||
@@ -66,8 +65,9 @@ class ComfyDeployOutputImage:
|
|||||||
for batch_number, image in enumerate(images):
|
for batch_number, image in enumerate(images):
|
||||||
i = 255.0 * image.cpu().numpy()
|
i = 255.0 * image.cpu().numpy()
|
||||||
img = Image.fromarray(np.clip(i, 0, 255).astype(np.uint8))
|
img = Image.fromarray(np.clip(i, 0, 255).astype(np.uint8))
|
||||||
metadata = PngInfo()
|
metadata = None
|
||||||
if not remove_metadata:
|
if not args.disable_metadata:
|
||||||
|
metadata = PngInfo()
|
||||||
if prompt is not None:
|
if prompt is not None:
|
||||||
metadata.add_text("prompt", json.dumps(prompt))
|
metadata.add_text("prompt", json.dumps(prompt))
|
||||||
if extra_pnginfo is not None:
|
if extra_pnginfo is not None:
|
||||||
|
|||||||
+55
-33
@@ -1,8 +1,5 @@
|
|||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
from pprint import pprint
|
|
||||||
from aiohttp import web
|
|
||||||
import os
|
import os
|
||||||
import requests
|
|
||||||
import folder_paths
|
import folder_paths
|
||||||
import json
|
import json
|
||||||
import server
|
import server
|
||||||
@@ -13,34 +10,24 @@ import random
|
|||||||
import traceback
|
import traceback
|
||||||
import uuid
|
import uuid
|
||||||
import asyncio
|
import asyncio
|
||||||
import logging
|
import inspect
|
||||||
from urllib.parse import quote
|
from urllib.parse import quote, urlencode
|
||||||
import threading
|
import threading
|
||||||
import hashlib
|
import hashlib
|
||||||
import aiohttp
|
import aiohttp
|
||||||
from aiohttp import ClientSession, web
|
from aiohttp import web, ClientSession, ClientError, ClientTimeout
|
||||||
import aiofiles
|
import aiofiles
|
||||||
from typing import Dict, List, Union, Any, Optional
|
from typing import Dict, Any
|
||||||
from PIL import Image
|
|
||||||
import copy
|
import copy
|
||||||
import struct
|
import struct
|
||||||
from aiohttp import web, ClientSession, ClientError, ClientTimeout, ClientResponseError
|
|
||||||
import atexit
|
import atexit
|
||||||
from model_management import get_torch_device
|
from model_management import get_torch_device
|
||||||
import torch
|
import torch
|
||||||
import psutil
|
import psutil
|
||||||
from collections import OrderedDict
|
|
||||||
import io
|
|
||||||
from urllib.parse import urlencode
|
|
||||||
|
|
||||||
# Global session
|
# Global session
|
||||||
client_session = None
|
client_session = None
|
||||||
|
|
||||||
# def create_client_session():
|
|
||||||
# global client_session
|
|
||||||
# if client_session is None:
|
|
||||||
# client_session = aiohttp.ClientSession()
|
|
||||||
|
|
||||||
|
|
||||||
async def ensure_client_session():
|
async def ensure_client_session():
|
||||||
global client_session
|
global client_session
|
||||||
@@ -82,8 +69,6 @@ retry_delay_multiplier = float(os.environ.get("RETRY_DELAY_MULTIPLIER", "2"))
|
|||||||
|
|
||||||
print(f"max_retries: {max_retries}, retry_delay_multiplier: {retry_delay_multiplier}")
|
print(f"max_retries: {max_retries}, retry_delay_multiplier: {retry_delay_multiplier}")
|
||||||
|
|
||||||
import time
|
|
||||||
|
|
||||||
|
|
||||||
async def async_request_with_retry(
|
async def async_request_with_retry(
|
||||||
method, url, disable_timeout=False, token=None, **kwargs
|
method, url, disable_timeout=False, token=None, **kwargs
|
||||||
@@ -334,9 +319,28 @@ async def post_prompt(json_data):
|
|||||||
extra_data["client_id"] = json_data["client_id"]
|
extra_data["client_id"] = json_data["client_id"]
|
||||||
if valid[0]:
|
if valid[0]:
|
||||||
outputs_to_execute = valid[2]
|
outputs_to_execute = valid[2]
|
||||||
prompt_server.prompt_queue.put(
|
# Backward compatibility: sensitive data handling added in newer ComfyUI
|
||||||
(number, prompt_id, prompt, extra_data, outputs_to_execute)
|
sensitive_keys = getattr(execution, "SENSITIVE_EXTRA_DATA_KEYS", None)
|
||||||
)
|
if sensitive_keys:
|
||||||
|
sensitive = {}
|
||||||
|
for sensitive_val in sensitive_keys:
|
||||||
|
if sensitive_val in extra_data:
|
||||||
|
sensitive[sensitive_val] = extra_data.pop(sensitive_val)
|
||||||
|
prompt_server.prompt_queue.put(
|
||||||
|
(
|
||||||
|
number,
|
||||||
|
prompt_id,
|
||||||
|
prompt,
|
||||||
|
extra_data,
|
||||||
|
outputs_to_execute,
|
||||||
|
sensitive,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
# Old ComfyUI version without sensitive data support
|
||||||
|
prompt_server.prompt_queue.put(
|
||||||
|
(number, prompt_id, prompt, extra_data, outputs_to_execute)
|
||||||
|
)
|
||||||
response = {
|
response = {
|
||||||
"prompt_id": prompt_id,
|
"prompt_id": prompt_id,
|
||||||
"number": number,
|
"number": number,
|
||||||
@@ -1323,6 +1327,9 @@ try:
|
|||||||
is_async = asyncio.iscoroutinefunction(origin_execute)
|
is_async = asyncio.iscoroutinefunction(origin_execute)
|
||||||
|
|
||||||
if is_async:
|
if is_async:
|
||||||
|
# Check signature for backward compatibility (v0.3.67 has 10 params, v0.3.68+ has 11)
|
||||||
|
sig = inspect.signature(origin_execute)
|
||||||
|
has_ui_outputs = len(sig.parameters) >= 11
|
||||||
|
|
||||||
async def swizzle_execute(
|
async def swizzle_execute(
|
||||||
server,
|
server,
|
||||||
@@ -1335,12 +1342,14 @@ try:
|
|||||||
execution_list,
|
execution_list,
|
||||||
pending_subgraph_results,
|
pending_subgraph_results,
|
||||||
pending_async_nodes,
|
pending_async_nodes,
|
||||||
|
ui_outputs=None,
|
||||||
):
|
):
|
||||||
unique_id = current_item
|
unique_id = current_item
|
||||||
class_type = dynprompt.get_node(unique_id)["class_type"]
|
class_type = dynprompt.get_node(unique_id)["class_type"]
|
||||||
last_node_id = server.last_node_id
|
last_node_id = server.last_node_id
|
||||||
|
|
||||||
result = await origin_execute(
|
# Build args list - add ui_outputs only for v0.3.68+
|
||||||
|
args = [
|
||||||
server,
|
server,
|
||||||
dynprompt,
|
dynprompt,
|
||||||
caches,
|
caches,
|
||||||
@@ -1351,12 +1360,16 @@ try:
|
|||||||
execution_list,
|
execution_list,
|
||||||
pending_subgraph_results,
|
pending_subgraph_results,
|
||||||
pending_async_nodes,
|
pending_async_nodes,
|
||||||
)
|
]
|
||||||
|
if has_ui_outputs:
|
||||||
|
args.append(ui_outputs)
|
||||||
|
|
||||||
|
result = await origin_execute(*args)
|
||||||
|
|
||||||
handle_execute(class_type, last_node_id, prompt_id, server, unique_id)
|
handle_execute(class_type, last_node_id, prompt_id, server, unique_id)
|
||||||
return result
|
return result
|
||||||
else:
|
else:
|
||||||
|
# Sync version for very old ComfyUI versions
|
||||||
def swizzle_execute(
|
def swizzle_execute(
|
||||||
server,
|
server,
|
||||||
dynprompt,
|
dynprompt,
|
||||||
@@ -1554,18 +1567,26 @@ async def send_json_override(self, event, data, sid=None):
|
|||||||
)
|
)
|
||||||
|
|
||||||
if event == "executing" and data.get("node") is not None:
|
if event == "executing" and data.get("node") is not None:
|
||||||
node = data.get("node")
|
raw_node = data.get("node")
|
||||||
|
node = str(raw_node)
|
||||||
|
|
||||||
if prompt_id in prompt_metadata:
|
if prompt_id in prompt_metadata:
|
||||||
# if 'progress' not in prompt_metadata[prompt_id]:
|
wf_api = prompt_metadata[prompt_id].workflow_api
|
||||||
# prompt_metadata[prompt_id]["progress"] = set()
|
|
||||||
|
# Normalize dotted display ids like "23.0.0.1" to base "23"
|
||||||
|
if node not in wf_api and "." in node:
|
||||||
|
base = node.split(".")[0]
|
||||||
|
if base in wf_api:
|
||||||
|
node = base
|
||||||
|
|
||||||
|
# If still unknown, skip safely
|
||||||
|
if node not in wf_api:
|
||||||
|
logger.info(f"Skipping unknown node id in 'executing': {raw_node}")
|
||||||
|
return
|
||||||
|
|
||||||
prompt_metadata[prompt_id].progress.add(node)
|
prompt_metadata[prompt_id].progress.add(node)
|
||||||
calculated_progress = len(prompt_metadata[prompt_id].progress) / len(
|
calculated_progress = len(prompt_metadata[prompt_id].progress) / len(wf_api)
|
||||||
prompt_metadata[prompt_id].workflow_api
|
|
||||||
)
|
|
||||||
calculated_progress = round(calculated_progress, 2)
|
calculated_progress = round(calculated_progress, 2)
|
||||||
# logger.info("calculated_progress", calculated_progress)
|
|
||||||
|
|
||||||
if (
|
if (
|
||||||
prompt_metadata[prompt_id].last_updated_node is not None
|
prompt_metadata[prompt_id].last_updated_node is not None
|
||||||
@@ -1573,7 +1594,8 @@ async def send_json_override(self, event, data, sid=None):
|
|||||||
):
|
):
|
||||||
return
|
return
|
||||||
prompt_metadata[prompt_id].last_updated_node = node
|
prompt_metadata[prompt_id].last_updated_node = node
|
||||||
class_type = prompt_metadata[prompt_id].workflow_api[node]["class_type"]
|
|
||||||
|
class_type = wf_api[node]["class_type"]
|
||||||
logger.info(f"At: {round(calculated_progress * 100)}% - {class_type}")
|
logger.info(f"At: {round(calculated_progress * 100)}% - {class_type}")
|
||||||
asyncio.create_task(
|
asyncio.create_task(
|
||||||
send(
|
send(
|
||||||
|
|||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
[project]
|
[project]
|
||||||
name = "comfyui-deploy"
|
name = "comfyui-deploy"
|
||||||
description = "Open source comfyui deployment platform, a vercel for generative workflow infra."
|
description = "Open source comfyui deployment platform, a vercel for generative workflow infra."
|
||||||
version = "2.3.7"
|
version = "2.3.10"
|
||||||
license = { file = "LICENSE" }
|
license = { file = "LICENSE" }
|
||||||
dependencies = ["aiofiles", "pydantic", "opencv-python", "imageio-ffmpeg", "tabulate", "brotli"]
|
dependencies = ["aiofiles", "pydantic", "opencv-python", "imageio-ffmpeg", "tabulate", "brotli"]
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user