Open onefish51 opened 9 months ago
I see! because "extra_data" not in prompt_text = """ so https://github.com/comfyanonymous/ComfyUI/blob/777f6b15225197898a5f49742682a2be859072d7/server.py#L474 not work
How can I auto convert prompt_text to workflow ?
prompt_text = """
{
"3": {
"class_type": "KSampler",
"inputs": {
"cfg": 8,
"denoise": 1,
"latent_image": [
"5",
0
],
"model": [
"4",
0
],
"negative": [
"7",
0
],
"positive": [
"6",
0
],
"sampler_name": "euler",
"scheduler": "normal",
"seed": 8566257,
"steps": 20
}
},
"4": {
"class_type": "CheckpointLoaderSimple",
"inputs": {
"ckpt_name": "v1-5-pruned-emaonly.ckpt"
}
},
"5": {
"class_type": "EmptyLatentImage",
"inputs": {
"batch_size": 1,
"height": 512,
"width": 512
}
},
"6": {
"class_type": "CLIPTextEncode",
"inputs": {
"clip": [
"4",
1
],
"text": "masterpiece best quality girl"
}
},
"7": {
"class_type": "CLIPTextEncode",
"inputs": {
"clip": [
"4",
1
],
"text": "bad hands"
}
},
"8": {
"class_type": "VAEDecode",
"inputs": {
"samples": [
"3",
0
],
"vae": [
"4",
2
]
}
},
"9": {
"class_type": "SaveImage",
"inputs": {
"filename_prefix": "ComfyUI",
"images": [
"8",
0
]
}
}
}
"""
I'd like to know as well.
Hello, I (with the help of Perplexity) create a method to do that for my workflows, I don't use a lot of node so, there is maybe some type node to add, but it's a good start :
SAVE_IMAGE = "SaveImage"
CTRL_NET_APPLY_ADVANCED = "ControlNetApplyAdvanced"
CLIP_SET_LAST_LAYER = "CLIPSetLastLayer"
PREVIEW_IMAGE = "PreviewImage"
LOAD_IMAGE = "LoadImage"
VAE_DECODE = "VAEDecode"
LORA_LOADER = "LoraLoader"
CLIP_TEXT_ENCODE = "CLIPTextEncode"
K_SAMPLER = "KSampler"
CONTROL_NET_LOADER = "ControlNetLoader"
EMPTY_LATENT_IMAGE = "EmptyLatentImage"
OPENPOSE_PREPROCESSOR = "OpenposePreprocessor"
CHECKPOINT_LOADER_SIMPLE = "CheckpointLoaderSimple"
SAVE_IMAGE_WEBSOCKET = "SaveImageWebsocket"
def convert_workflow_to_prompt_format(self, workflow_json):
prompt_format = {}
link_to_node = {}
node_output_types = {}
for node in workflow_json.get("nodes", []):
node_id = str(node["id"])
outputs = node.get("outputs", [])
for i, output in enumerate(outputs):
links = output.get("links", [])
if links is None:
continue
for link in links:
if link is not None:
link_to_node[link] = (node_id, i)
node_output_types[f"{node_id}_{i}"] = output.get("type")
for node in workflow_json.get("nodes", []):
node_id = str(node["id"])
node_type = node["type"]
node_inputs = {}
widgets_values = node.get("widgets_values", [])
if node_type == CHECKPOINT_LOADER_SIMPLE and widgets_values:
node_inputs["ckpt_name"] = widgets_values[0]
elif node_type == LORA_LOADER and len(widgets_values) >= 3:
node_inputs["lora_name"] = widgets_values[0]
node_inputs["strength_model"] = widgets_values[1]
node_inputs["strength_clip"] = widgets_values[2]
elif node_type == CONTROL_NET_LOADER and widgets_values:
node_inputs["control_net_name"] = widgets_values[0]
elif node_type == LOAD_IMAGE and widgets_values:
node_inputs["image"] = widgets_values[0]
node_inputs["upload"] = "image"
elif node_type == CTRL_NET_APPLY_ADVANCED and len(widgets_values) >= 3:
node_inputs["strength"] = widgets_values[0]
node_inputs["start_percent"] = widgets_values[1]
node_inputs["end_percent"] = widgets_values[2]
elif node_type == CLIP_SET_LAST_LAYER and widgets_values:
node_inputs["stop_at_clip_layer"] = widgets_values[0]
elif node_type == EMPTY_LATENT_IMAGE and len(widgets_values) >= 3:
node_inputs["width"] = widgets_values[0]
node_inputs["height"] = widgets_values[1]
node_inputs["batch_size"] = widgets_values[2]
elif node_type == K_SAMPLER and len(widgets_values) >= 6:
node_inputs["seed"] = widgets_values[0]
node_inputs["steps"] = widgets_values[2]
node_inputs["cfg"] = widgets_values[3]
node_inputs["sampler_name"] = widgets_values[4]
node_inputs["scheduler"] = widgets_values[5]
node_inputs["denoise"] = 1
elif node_type == CLIP_TEXT_ENCODE and widgets_values:
node_inputs["text"] = widgets_values[0]
elif node_type == OPENPOSE_PREPROCESSOR and len(widgets_values) >= 4:
node_inputs["detect_body"] = widgets_values[0]
node_inputs["detect_hand"] = widgets_values[1]
node_inputs["detect_face"] = widgets_values[2]
node_inputs["resolution"] = widgets_values[3]
inputs = node.get("inputs", [])
for input_data in inputs:
input_name = input_data["name"]
link = input_data.get("link")
if link is not None:
source_node_id, slot_index = link_to_node.get(link, (link, 0))
node_inputs[input_name] = [source_node_id, slot_index]
prompt_format[node_id] = {
"inputs": node_inputs,
"class_type": node_type,
"_meta": {
"title": self.get_node_title(node_type)
}
}
return prompt_format
def get_node_title(self, node_type):
titles = {
CHECKPOINT_LOADER_SIMPLE: "Load Checkpoint",
LORA_LOADER: "Load LoRA",
CONTROL_NET_LOADER: "Load ControlNet Model",
CTRL_NET_APPLY_ADVANCED: "Apply ControlNet (Advanced)",
LOAD_IMAGE: "Load Image",
OPENPOSE_PREPROCESSOR: "OpenPose Pose",
CLIP_SET_LAST_LAYER: "CLIP Set Last Layer",
CLIP_TEXT_ENCODE: "CLIP Text Encode (Prompt)",
EMPTY_LATENT_IMAGE: "Empty Latent Image",
K_SAMPLER: "KSampler",
VAE_DECODE: "VAE Decode",
SAVE_IMAGE_WEBSOCKET: "SaveImageWebsocket"
}
return titles.get(node_type, node_type)
I test it on a workflow that I converted to a prompt workflow using ComfyUi Dev mode option, and it return the same prompt using this method.
great work ! when I run the demo
script_examples/websockets_api_example.py
, I found the output image without the workflow.How I get the workflow when I call comfyUI by websockets API ?