allow flux workflow

This commit is contained in:
Karl Hudgell 2025-04-19 16:11:41 +01:00
parent 6fdfb51a49
commit 2bbb2fe15b
3 changed files with 503 additions and 7 deletions

436
FLUX.json Normal file
View File

@ -0,0 +1,436 @@
{
"8": {
"inputs": {
"samples": [
"62",
1
],
"vae": [
"27",
0
]
},
"class_type": "VAEDecode",
"_meta": {
"title": "VAE Decode"
}
},
"22": {
"inputs": {
"clip_name1": "t5/t5xxl_fp8_e4m3fn.safetensors",
"clip_name2": "clip_l.safetensors",
"type": "flux",
"device": "default"
},
"class_type": "DualCLIPLoader",
"_meta": {
"title": "DualCLIPLoader"
}
},
"27": {
"inputs": {
"vae_name": "FLUX1/ae.safetensors"
},
"class_type": "VAELoader",
"_meta": {
"title": "Load VAE"
}
},
"32": {
"inputs": {
"upscale_model": [
"33",
0
],
"image": [
"8",
0
]
},
"class_type": "ImageUpscaleWithModel",
"_meta": {
"title": "Upscale Image (using Model)"
}
},
"33": {
"inputs": {
"model_name": "4x-UltraSharp.pth"
},
"class_type": "UpscaleModelLoader",
"_meta": {
"title": "Load Upscale Model"
}
},
"34": {
"inputs": {
"upscale_method": "lanczos",
"scale_by": 0.5,
"image": [
"32",
0
]
},
"class_type": "ImageScaleBy",
"_meta": {
"title": "Half size"
}
},
"35": {
"inputs": {
"unet_name": "flux1-dev-Q4_0.gguf"
},
"class_type": "UnetLoaderGGUF",
"_meta": {
"title": "Unet Loader (GGUF)"
}
},
"40": {
"inputs": {
"int": 20
},
"class_type": "Int Literal (Image Saver)",
"_meta": {
"title": "Generation Steps"
}
},
"41": {
"inputs": {
"width": 720,
"height": 1080,
"aspect_ratio": "custom",
"swap_dimensions": "Off",
"upscale_factor": 2,
"prescale_factor": 1,
"batch_size": 1
},
"class_type": "CR Aspect Ratio",
"_meta": {
"title": "🔳 CR Aspect Ratio"
}
},
"42": {
"inputs": {
"filename": "THISFILE",
"path": "",
"extension": "png",
"steps": [
"40",
0
],
"cfg": [
"52",
0
],
"modelname": "flux1-dev-Q4_0.gguf",
"sampler_name": [
"50",
1
],
"scheduler": [
"49",
1
],
"positive": [
"44",
0
],
"negative": [
"45",
0
],
"seed_value": [
"48",
0
],
"width": [
"41",
0
],
"height": [
"41",
1
],
"lossless_webp": true,
"quality_jpeg_or_webp": 100,
"optimize_png": false,
"counter": 0,
"denoise": [
"53",
0
],
"clip_skip": 0,
"time_format": "%Y-%m-%d-%H%M%S",
"save_workflow_as_json": true,
"embed_workflow": true,
"additional_hashes": "",
"download_civitai_data": true,
"easy_remix": true,
"speak_and_recognation": {
"__value__": [
false,
true
]
},
"images": [
"34",
0
]
},
"class_type": "Image Saver",
"_meta": {
"title": "CivitAI Image Saver"
}
},
"44": {
"inputs": {
"text": "A council of wise owls wearing tiny glasses and wizard hats, gathered around an ancient floating book in the middle of an enchanted forest at twilight, glowing mushrooms providing light, whimsical and magical, highly detailed, children's book illustration style, soft colors, hand-drawn look",
"speak_and_recognation": {
"__value__": [
false,
true
]
}
},
"class_type": "ttN text",
"_meta": {
"title": "Positive Prompt T5"
}
},
"45": {
"inputs": {
"text": "",
"speak_and_recognation": {
"__value__": [
false,
true
]
}
},
"class_type": "ttN text",
"_meta": {
"title": "Negative Prompt"
}
},
"47": {
"inputs": {
"text": [
"44",
0
],
"speak_and_recognation": {
"__value__": [
false,
true
]
},
"clip": [
"68",
1
]
},
"class_type": "CLIPTextEncode",
"_meta": {
"title": "CLIP Text Encode (Prompt)"
}
},
"48": {
"inputs": {
"seed": 903006749445372
},
"class_type": "Seed Generator (Image Saver)",
"_meta": {
"title": "Seed"
}
},
"49": {
"inputs": {
"scheduler": "beta"
},
"class_type": "Scheduler Selector (Comfy) (Image Saver)",
"_meta": {
"title": "Scheduler Selector"
}
},
"50": {
"inputs": {
"sampler_name": "euler"
},
"class_type": "Sampler Selector (Image Saver)",
"_meta": {
"title": "Sampler Selector (Image Saver)"
}
},
"51": {
"inputs": {
"images": [
"8",
0
]
},
"class_type": "PreviewImage",
"_meta": {
"title": "Preview Image"
}
},
"52": {
"inputs": {
"float": 3.5
},
"class_type": "Float Literal (Image Saver)",
"_meta": {
"title": "CFG"
}
},
"53": {
"inputs": {
"float": 1
},
"class_type": "Float Literal (Image Saver)",
"_meta": {
"title": "Denoise"
}
},
"60": {
"inputs": {
"clip_l": "",
"t5xxl": [
"44",
0
],
"guidance": [
"52",
0
],
"speak_and_recognation": {
"__value__": [
false,
true
]
},
"clip": [
"68",
1
]
},
"class_type": "CLIPTextEncodeFlux",
"_meta": {
"title": "CLIPTextEncodeFlux"
}
},
"62": {
"inputs": {
"noise": [
"65",
0
],
"guider": [
"67",
0
],
"sampler": [
"63",
0
],
"sigmas": [
"64",
0
],
"latent_image": [
"41",
5
]
},
"class_type": "SamplerCustomAdvanced",
"_meta": {
"title": "SamplerCustomAdvanced"
}
},
"63": {
"inputs": {
"sampler_name": [
"50",
0
]
},
"class_type": "KSamplerSelect",
"_meta": {
"title": "KSamplerSelect"
}
},
"64": {
"inputs": {
"scheduler": [
"49",
0
],
"steps": [
"40",
0
],
"denoise": [
"53",
0
],
"model": [
"68",
0
]
},
"class_type": "BasicScheduler",
"_meta": {
"title": "BasicScheduler"
}
},
"65": {
"inputs": {
"noise_seed": [
"48",
0
]
},
"class_type": "RandomNoise",
"_meta": {
"title": "RandomNoise"
}
},
"67": {
"inputs": {
"model": [
"68",
0
],
"conditioning": [
"47",
0
]
},
"class_type": "BasicGuider",
"_meta": {
"title": "BasicGuider"
}
},
"68": {
"inputs": {
"lora_01": "None",
"strength_01": 1,
"lora_02": "None",
"strength_02": 1,
"lora_03": "None",
"strength_03": 1,
"lora_04": "None",
"strength_04": 1,
"model": [
"35",
0
],
"clip": [
"22",
0
]
},
"class_type": "Lora Loader Stack (rgthree)",
"_meta": {
"title": "Lora Loader Stack (rgthree)"
}
}
}

71
lib.py
View File

@ -110,12 +110,12 @@ def create_prompt_on_openwebui(prompt: str) -> str:
# Define the retry logic using Tenacity # Define the retry logic using Tenacity
@retry( # @retry(
stop=stop_after_attempt(3), # stop=stop_after_attempt(3),
wait=wait_fixed(5), # wait=wait_fixed(5),
before=before_log(logging.getLogger(), logging.DEBUG), # before=before_log(logging.getLogger(), logging.DEBUG),
retry=retry_if_exception_type(Exception) # retry=retry_if_exception_type(Exception)
) # )
def generate_image(file_name: str, comfy_prompt: str) -> None: def generate_image(file_name: str, comfy_prompt: str) -> None:
"""Generates an image using the Comfy API with retry logic.""" """Generates an image using the Comfy API with retry logic."""
try: try:
@ -171,6 +171,62 @@ def generate_image(file_name: str, comfy_prompt: str) -> None:
logging.error(f"Failed to generate image for UID: {file_name}. Error: {e}") logging.error(f"Failed to generate image for UID: {file_name}. Error: {e}")
raise # Re-raise the exception for Tenacity to handle retries raise # Re-raise the exception for Tenacity to handle retries
def generate_image_flux(file_name: str, comfy_prompt: str) -> None:
"""Generates an image using the Comfy API with retry logic."""
try:
# Initialize ComfyUI API and workflow
api = ComfyApiWrapper(user_config["comfyui"]["comfyui_url"])
wf = ComfyWorkflowWrapper("./FLUX.json")
# Set workflow parameters
wf.set_node_param(
"Seed", "seed", random.getrandbits(32)
) # Set a random seed for the sampler
wf.set_node_param(
"Positive Prompt T5", "text", comfy_prompt
) # Set the prompt to be used for image generation
wf.set_node_param(
"CivitAI Image Saver", "filename", file_name
) # Set the filename prefix for the generated image
# wf.set_node_param( # Set image dimensions
# "Empty Latent Image", "width", user_config["comfyui"]["width"]
# )
# wf.set_node_param(
# "Empty Latent Image", "height", user_config["comfyui"]["height"]
# )
# # Validate available models and choose a random one
# valid_models = list(
# set(get_available_models()) # Get all available models from ComfyUI
# & set(user_config["comfyui"]["models"].split(","))
# )
# if not valid_models:
# raise Exception("No valid options available.")
# model = random.choice(valid_models)
# wf.set_node_param(
# "Load Checkpoint", "ckpt_name", model
# ) # Set the model to be used for image generation
# Generate the image using the workflow and wait for completion
logging.debug(f"Generating image: {file_name}")
results = api.queue_and_wait_images(
# wf, "Save Image"
wf, "CivitAI Image Saver"
) # Queue the workflow and wait for image generation to complete
rename_image() # Rename the generated image file if it exists
# Save the generated image to disk
for filename, image_data in results.items():
with open(
user_config["comfyui"]["output_dir"] + file_name + ".png", "wb+"
) as f:
f.write(image_data)
logging.debug(f"Image generated successfully for UID: {file_name}")
except Exception as e:
logging.error(f"Failed to generate image for UID: {file_name}. Error: {e}")
raise # Re-raise the exception for Tenacity to handle retries
def create_image(prompt: str | None = None) -> None: def create_image(prompt: str | None = None) -> None:
"""Main function for generating images.""" """Main function for generating images."""
@ -178,6 +234,9 @@ def create_image(prompt: str | None = None) -> None:
prompt = create_prompt_on_openwebui(user_config["comfyui"]["prompt"]) prompt = create_prompt_on_openwebui(user_config["comfyui"]["prompt"])
if prompt: if prompt:
logging.info(f"Generated prompt: {prompt}") # Log generated prompt logging.info(f"Generated prompt: {prompt}") # Log generated prompt
if user_config["comfyui"]["FLUX"]:
generate_image_flux("image", prompt)
else:
generate_image("image", prompt) generate_image("image", prompt)
print(f"Image generation started with prompt: {prompt}") print(f"Image generation started with prompt: {prompt}")
else: else:

View File

@ -11,6 +11,7 @@ output_dir = ./output/
prompt = "Generate a random detailed prompt for stable diffusion." prompt = "Generate a random detailed prompt for stable diffusion."
width = 1568 width = 1568
height = 672 height = 672
FLUX = False
[openwebui] [openwebui]
base_url = https://openwebui base_url = https://openwebui