Refactoring Code

This commit is contained in:
Jimmy Wong
2024-11-04 16:38:55 +08:00
parent 094b28ac89
commit cf11a9477d
5 changed files with 113 additions and 47 deletions
+2 -2
View File
@@ -19,7 +19,7 @@ from .nodes_omost import (
from .nodes_json import FlowyPreviewJSON, FlowyExtractJSON, ComflowyLoadJSON
from .nodes_http import FlowyHttpRequest
from .nodes_llm import FlowyLLM
from .nodes_upscale import FlowyUpscale
from .nodes_clarityupscale import FlowyClarityUpscale
from .nodes_flux import FlowyFlux
from .nodes_ideogram import FlowyIdeogram
@@ -70,7 +70,7 @@ NODE_CLASS_MAPPINGS = {
"Comflowy_Omost_Load_Canvas_Python_Code": ComflowyOmostLoadCanvasPythonCodeNode,
"Comflowy_Omost_Load_Canvas_Conditioning": ComflowyOmostLoadCanvasConditioningNode,
"Comflowy_Set_API_Key": ComflowySetAPIKey,
"Comflowy_Upscale": FlowyUpscale,
"Comflowy_Upscale": FlowyClarityUpscale,
"Comflowy_Ideogram": FlowyIdeogram,
"Comflowy_Flux": FlowyFlux,
}
@@ -13,14 +13,37 @@ from .api_key_manager import load_api_key
logger = logging.getLogger(__name__)
class FlowyUpscale:
class FlowyClarityUpscale:
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"image": ("IMAGE",),
"scale_factor": ("INT", {"default": 2, "min": 1, "max": 4, "step": 1}),
"model": (["clarity-upscaler"],),
"scale_factor": ([2, 4, 6, 8], {"default": 2}),
"dynamic": ("FLOAT", {"default": 6.0, "min": 1.0, "max": 50.0, "step": 0.1}),
"creativity": ("FLOAT", {"default": 0.35, "min": 0.0, "max": 1.0, "step": 0.01}),
"resemblance": ("FLOAT", {"default": 0.6, "min": 0.0, "max": 3.0, "step": 0.01}),
"tiling_width": ([16, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 240, 256], {"default": 112}),
"tiling_height": ([16, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 240, 256], {"default": 144}),
"num_inference_steps": ("INT", {"default": 18, "min": 1, "max": 100}),
"seed": ("INT", {"default": 1337, "min": 0, "max": 2147483647}),
"handfix": (["disabled", "hands_only", "image_and_hands"], {"default": "disabled"}),
"pattern": ("BOOLEAN", {"default": False}),
"sharpen": ("FLOAT", {"default": 0.0, "min": 0.0, "max": 10.0, "step": 0.1}),
"downscaling": ("BOOLEAN", {"default": False}),
"downscaling_resolution": ("INT", {"default": 768, "min": 256, "max": 2048}),
"sd_model": (["epicrealism_naturalSinRC1VAE.safetensors [84d76a0328]",
"juggernaut_reborn.safetensors [338b85bc4f]",
"flat2DAnimerge_v45Sharp.safetensors"], {"default": "juggernaut_reborn.safetensors [338b85bc4f]"}),
"scheduler": (["DPM++ 2M Karras", "DPM++ SDE Karras", "DPM++ 2M SDE Exponential",
"DPM++ 2M SDE Karras", "Euler a", "Euler", "LMS", "Heun", "DPM2",
"DPM2 a", "DPM++ 2S a", "DPM++ 2M", "DPM++ SDE", "DPM++ 2M SDE",
"DPM++ 2M SDE Heun", "DPM++ 2M SDE Heun Karras",
"DPM++ 2M SDE Heun Exponential", "DPM++ 3M SDE",
"DPM++ 3M SDE Karras", "DPM++ 3M SDE Exponential",
"DPM fast", "DPM adaptive", "LMS Karras", "DPM2 Karras",
"DPM2 a Karras", "DPM++ 2S a Karras", "Restart", "DDIM",
"PLMS", "UniPC"], {"default": "DPM++ 3M SDE Karras"}),
}
}
@@ -37,7 +60,7 @@ Nodes from https://comflowy.com:
- Output: Returns the upscaled image.
"""
def upscale(self, image, scale_factor, model):
def upscale(self, image, scale_factor, dynamic, creativity, resemblance, tiling_width, tiling_height, num_inference_steps, seed,handfix=None, pattern=False, sharpen=0, downscaling=False,downscaling_resolution=768, sd_model=None, scheduler=None):
api_key = load_api_key()
if not api_key:
@@ -45,7 +68,7 @@ Nodes from https://comflowy.com:
logger.error(error_msg)
raise ValueError(error_msg)
logger.info(f"Starting image upscale request. scale_factor: {scale_factor}, model: {model}")
logger.info(f"Starting image upscale request. scale_factor: {scale_factor}")
# Process input image
if isinstance(image, torch.Tensor):
@@ -74,14 +97,28 @@ Nodes from https://comflowy.com:
img_str = base64.b64encode(buffered.getvalue()).decode()
try:
# Build the URL for the API request
# Build URL for API request using API_HOST
response = requests.post(
f"{API_HOST}/api/open/v0/upscale",
f"{API_HOST}/api/open/v0/flowy",
headers={"Authorization": f"Bearer {api_key}", "Content-Type": "application/json"},
json={
"image": f"data:image/jpeg;base64,{img_str}",
"scale_factor": scale_factor,
"model": model
"dynamic": dynamic,
"creativity": creativity,
"resemblance": resemblance,
"tiling_width": tiling_width,
"tiling_height": tiling_height,
"num_inference_steps": num_inference_steps,
"seed": seed,
"handfix": handfix,
"pattern": pattern,
"sharpen": sharpen,
"downscaling": downscaling,
"downscaling_resolution": downscaling_resolution,
"sd_model": sd_model,
"scheduler": scheduler,
"model_type": "clarityupscaler",
}
)
response.raise_for_status()
@@ -94,22 +131,22 @@ Nodes from https://comflowy.com:
logger.error(f"API request failed. Response content: {json.dumps(result, indent=2)}")
raise Exception(f"API request failed. Response content: {json.dumps(result, indent=2)}")
output_url = result.get('data', {}).get('output', [None])[0]
if not output_url:
output_url = result.get('data', {}).get('output')
if not output_url or not isinstance(output_url, str):
logger.error(f"Complete API response: {json.dumps(result, indent=2)}")
raise Exception(f"Unable to get valid output image URL. API response does not have expected data structure. Complete response: {json.dumps(result, indent=2)}")
raise Exception(f"Unable to get valid output image URL. API response doesn't have expected data structure. Complete response: {json.dumps(result, indent=2)}")
logger.info(f"Obtained output URL: {output_url}")
logger.info(f"Received output URL: {output_url}")
# Verify URL is accessible
# Verify if URL is accessible
try:
url_check = requests.head(output_url)
url_check.raise_for_status()
except requests.RequestException as e:
logger.error(f"Unable to access output URL: {str(e)}")
raise Exception(f"Unable to access output URL: {str(e)}")
logger.error(f"Cannot access output URL: {str(e)}")
raise Exception(f"Cannot access output URL: {str(e)}")
# Add delay, wait for Replicate to process
# Add delay to wait for Replicate processing
time.sleep(10)
img_response = requests.get(output_url, stream=True)
@@ -118,10 +155,10 @@ Nodes from https://comflowy.com:
# Convert image data to PIL Image
img = Image.open(img_response.raw)
# Convert image data to numpy array
# Convert to numpy array
img_np = np.array(img)
# Ensure image is 3 channel RGB
# Ensure image has 3 RGB channels
if len(img_np.shape) == 2: # Grayscale image
img_np = np.stack([img_np] * 3, axis=-1)
elif img_np.shape[-1] == 4: # RGBA image
@@ -130,7 +167,7 @@ Nodes from https://comflowy.com:
# Convert to float32 and normalize to 0-1 range
img_np = img_np.astype(np.float32) / 255.0
# Convert to torch tensor, ensuring shape is [B,H,W,C]
# Convert to torch tensor, ensure shape is [B,H,W,C]
img_tensor = torch.from_numpy(img_np).unsqueeze(0) # Add batch dimension
logger.info(f"Image processing completed. Output tensor shape: {img_tensor.shape}")
@@ -140,9 +177,9 @@ Nodes from https://comflowy.com:
return (img_tensor,)
except Exception as e:
error_msg = f"Error during image upscale: {str(e)}"
error_msg = f"Error during upscaling: {str(e)}"
logger.error(error_msg)
logger.exception("Detailed error information:")
# Return an error marked image, ensuring shape is [B,H,W,C]
# Return an error marker image, ensure shape is [B,H,W,C]
error_image = torch.zeros((1, 100, 400, 3), dtype=torch.float32)
return (error_image,)
+10 -10
View File
@@ -7,8 +7,7 @@ import torch
import numpy as np
import logging
import json
from .types import STRING, INT, API_HOST, SAFETY_TOLERANCE, BOOLEAN
from .utils import logger, get_nested_value
from .types import STRING, INT, SAFETY_TOLERANCE, BOOLEAN, get_api_host
from .api_key_manager import load_api_key
logger = logging.getLogger(__name__)
@@ -60,7 +59,7 @@ Nodes from https://comflowy.com:
def generate(self, prompt, version, aspect_ratio, height, width, seed, prompt_upsampling, safety_tolerance, output_quality):
api_key = load_api_key()
API_HOST = get_api_host()
if not api_key:
error_msg = "API Key is not set. Please use the 'Comflowy Set API Key' node to set a global API Key before using this node."
logger.error(error_msg)
@@ -70,7 +69,7 @@ Nodes from https://comflowy.com:
try:
response = requests.post(
f"{API_HOST}/api/open/v0/flux",
f"{API_HOST}/api/open/v0/flowy",
headers={"Authorization": f"Bearer {api_key}", "Content-Type": "application/json"},
json={
"prompt": prompt,
@@ -82,6 +81,7 @@ Nodes from https://comflowy.com:
"prompt_upsampling": prompt_upsampling,
"safety_tolerance": safety_tolerance,
"output_quality": output_quality,
"model_type": "flux",
}
)
response.raise_for_status()
@@ -97,11 +97,11 @@ Nodes from https://comflowy.com:
output_url = result.get('data', {}).get('output')
if not output_url or not isinstance(output_url, str):
logger.error(f"Complete API response: {json.dumps(result, indent=2)}")
raise Exception(f"Unable to get valid output image URL. API response does not have expected data structure. Complete response: {json.dumps(result, indent=2)}")
raise Exception(f"Unable to get valid output image URL. API response doesn't have expected data structure. Complete response: {json.dumps(result, indent=2)}")
logger.info(f"Obtained output URL: {output_url}")
# Verify URL is accessible
# Verify if URL is accessible
try:
url_check = requests.head(output_url)
url_check.raise_for_status()
@@ -109,7 +109,7 @@ Nodes from https://comflowy.com:
logger.error(f"Unable to access output URL: {str(e)}")
raise Exception(f"Unable to access output URL: {str(e)}")
# Add delay, wait for Replicate to process
# Add delay to wait for Replicate processing
time.sleep(10)
img_response = requests.get(output_url, stream=True)
@@ -121,7 +121,7 @@ Nodes from https://comflowy.com:
# Convert to numpy array
img_np = np.array(img)
# Ensure image is 3 channel RGB
# Ensure image has 3 RGB channels
if len(img_np.shape) == 2: # Grayscale image
img_np = np.stack([img_np] * 3, axis=-1)
elif img_np.shape[-1] == 4: # RGBA image
@@ -130,7 +130,7 @@ Nodes from https://comflowy.com:
# Convert to float32 and normalize to 0-1 range
img_np = img_np.astype(np.float32) / 255.0
# Convert to torch tensor, ensuring shape is [B,H,W,C]
# Convert to torch tensor, ensure shape is [B,H,W,C]
img_tensor = torch.from_numpy(img_np).unsqueeze(0) # Add batch dimension
logger.info(f"Image processing completed. Output tensor shape: {img_tensor.shape}")
@@ -141,6 +141,6 @@ Nodes from https://comflowy.com:
error_msg = f"Error during image generation: {str(e)}"
logger.error(error_msg)
logger.exception("Detailed error information:")
# Return an error marked image, ensuring shape is [B,H,W,C]
# Return an error marker image, ensure shape is [B,H,W,C]
error_image = torch.zeros((1, 100, 400, 3), dtype=torch.float32)
return (error_image,)
+11 -13
View File
@@ -56,7 +56,7 @@ Nodes from https://comflowy.com:
try:
response = requests.post(
f"{API_HOST}/api/open/v0/ideogram",
f"{API_HOST}/api/open/v0/flowy",
headers={"Authorization": f"Bearer {api_key}", "Content-Type": "application/json"},
json={
"prompt": prompt,
@@ -67,6 +67,7 @@ Nodes from https://comflowy.com:
"aspect_ratio": aspect_ratio,
"magic_prompt_option": magic_prompt_option,
"seed": seed,
"model_type": "ideogram",
}
)
response.raise_for_status()
@@ -82,31 +83,28 @@ Nodes from https://comflowy.com:
output_url = result.get('data', {}).get('output')
if not output_url or not isinstance(output_url, str):
logger.error(f"Complete API response: {json.dumps(result, indent=2)}")
raise Exception(f"Unable to get valid output image URL. API response does not have expected data structure. Complete response: {json.dumps(result, indent=2)}")
raise Exception(f"Unable to get valid output image URL. API response doesn't have expected data structure. Complete response: {json.dumps(result, indent=2)}")
logger.info(f"Obtained output URL: {output_url}")
logger.info(f"Received output URL: {output_url}")
# Verify URL is accessible
# Verify if URL is accessible
try:
url_check = requests.head(output_url)
url_check.raise_for_status()
except requests.RequestException as e:
logger.error(f"Unable to access output URL: {str(e)}")
raise Exception(f"Unable to access output URL: {str(e)}")
logger.error(f"Cannot access output URL: {str(e)}")
raise Exception(f"Cannot access output URL: {str(e)}")
# Add delay, wait for Replicate to process
# Add delay to wait for Replicate processing
time.sleep(10)
img_response = requests.get(output_url, stream=True)
img_response.raise_for_status()
# Convert image data to PIL Image
img = Image.open(img_response.raw)
# Convert to numpy array
img_np = np.array(img)
# Ensure image is 3 channel RGB
# Ensure image has 3 RGB channels
if len(img_np.shape) == 2: # Grayscale image
img_np = np.stack([img_np] * 3, axis=-1)
elif img_np.shape[-1] == 4: # RGBA image
@@ -115,7 +113,7 @@ Nodes from https://comflowy.com:
# Convert to float32 and normalize to 0-1 range
img_np = img_np.astype(np.float32) / 255.0
# Convert to torch tensor, ensuring shape is [B,H,W,C]
# Convert to torch tensor, ensure shape is [B,H,W,C]
img_tensor = torch.from_numpy(img_np).unsqueeze(0) # Add batch dimension
logger.info(f"Image processing completed. Output tensor shape: {img_tensor.shape}")
@@ -126,6 +124,6 @@ Nodes from https://comflowy.com:
error_msg = f"Error during image generation: {str(e)}"
logger.error(error_msg)
logger.exception("Detailed error information:")
# Return an error marked image, ensuring shape is [B,H,W,C]
# Return an error marker image, ensure shape is [B,H,W,C]
error_image = torch.zeros((1, 100, 400, 3), dtype=torch.float32)
return (error_image,)
+32 -1
View File
@@ -1,7 +1,37 @@
import json
import sys
import os
API_HOST = "https://app.comflowy.com"
API_HOST = "https://app.comflowy.com"
# API_HOST = "http://127.0.0.1:3000"
custom_node_api_config_inited = False
def init_custom_node_api_config_from_file():
global API_HOST, PPT_TOKEN, RUN_ID, custom_node_api_config_inited
config_path = "/comfyui/custom_node_api_config.json"
if os.path.exists(config_path):
try:
with open(config_path, "r") as f:
config = json.load(f)
API_HOST = config.get("domain", API_HOST)
PPT_TOKEN = config.get("ppt_token", PPT_TOKEN)
RUN_ID = config.get("run_id", RUN_ID)
custom_node_api_config_inited = True
print(f"Custom node API config initialized: API_HOST={API_HOST}, PPT_TOKEN={PPT_TOKEN}, RUN_ID={RUN_ID}")
except Exception as e:
print(f"Error reading custom node api config: {e}")
else:
print("Custom node API config file not found. Using default values.")
init_custom_node_api_config_from_file()
def get_api_host():
if not custom_node_api_config_inited:
init_custom_node_api_config_from_file()
return API_HOST
FLOAT = (
"FLOAT",
{"default": 1, "min": -sys.float_info.max, "max": sys.float_info.max, "step": 0.01},
@@ -50,3 +80,4 @@ class AnyType(str):
return False
any = AnyType("*")