diff --git a/comfy_api_nodes/apis/recraft_api.py b/comfy_api_nodes/apis/recraft_api.py index 514c081d9..c36d95f24 100644 --- a/comfy_api_nodes/apis/recraft_api.py +++ b/comfy_api_nodes/apis/recraft_api.py @@ -8,68 +8,6 @@ from typing import Optional from pydantic import BaseModel, Field, conint, confloat -class RecraftColor: - def __init__(self, r: int, g: int, b: int): - self.color = [r, g, b] - - def create_api_model(self): - return RecraftColorObject(rgb=self.color) - - -class RecraftColorChain: - def __init__(self): - self.colors: list[RecraftColor] = [] - - def get_first(self): - if len(self.colors) > 0: - return self.colors[0] - return None - - def add(self, color: RecraftColor): - self.colors.append(color) - - def create_api_model(self): - if not self.colors: - return None - colors_api = [x.create_api_model() for x in self.colors] - return colors_api - - def clone(self): - c = RecraftColorChain() - for color in self.colors: - c.add(color) - return c - - def clone_and_merge(self, other: RecraftColorChain): - c = self.clone() - for color in other.colors: - c.add(color) - return c - - -class RecraftControls: - def __init__(self, colors: RecraftColorChain=None, background_color: RecraftColorChain=None, - artistic_level: int=None, no_text: bool=None): - self.colors = colors - self.background_color = background_color - self.artistic_level = artistic_level - self.no_text = no_text - - def create_api_model(self): - if self.colors is None and self.background_color is None and self.artistic_level is None and self.no_text is None: - return None - colors_api = None - background_color_api = None - if self.colors: - colors_api = self.colors.create_api_model() - if self.background_color: - first_background = self.background_color.get_first() - background_color_api = first_background.create_api_model() if first_background else None - - return RecraftControlsObject(colors=colors_api, background_color=background_color_api, - artistic_level=self.artistic_level, no_text=self.no_text) - - class RecraftColor: def __init__(self, r: int, g: int, b: int): self.color = [r, g, b] diff --git a/comfy_api_nodes/nodes_bfl.py b/comfy_api_nodes/nodes_bfl.py index 5f43ecf6a..509170b34 100644 --- a/comfy_api_nodes/nodes_bfl.py +++ b/comfy_api_nodes/nodes_bfl.py @@ -34,99 +34,6 @@ import time from server import PromptServer -def convert_mask_to_image(mask: torch.Tensor): - """ - Make mask have the expected amount of dims (4) and channels (3) to be recognized as an image. - """ - mask = mask.unsqueeze(-1) - mask = torch.cat([mask]*3, dim=-1) - return mask - - -def handle_bfl_synchronous_operation( - operation: SynchronousOperation, - timeout_bfl_calls=360, - node_id: Union[str, None] = None, -): - response_api: BFLFluxProGenerateResponse = operation.execute() - return _poll_until_generated( - response_api.polling_url, timeout=timeout_bfl_calls, node_id=node_id - ) - - -def _poll_until_generated( - polling_url: str, timeout=360, node_id: Union[str, None] = None -): - # used bfl-comfy-nodes to verify code implementation: - # https://github.com/black-forest-labs/bfl-comfy-nodes/tree/main - start_time = time.time() - retries_404 = 0 - max_retries_404 = 5 - retry_404_seconds = 2 - retry_202_seconds = 2 - retry_pending_seconds = 1 - request = requests.Request(method=HttpMethod.GET, url=polling_url) - # NOTE: should True loop be replaced with checking if workflow has been interrupted? - while True: - if node_id: - time_elapsed = time.time() - start_time - PromptServer.instance.send_progress_text( - f"Generating ({time_elapsed:.0f}s)", node_id - ) - - response = requests.Session().send(request.prepare()) - if response.status_code == 200: - result = response.json() - if result["status"] == BFLStatus.ready: - img_url = result["result"]["sample"] - if node_id: - PromptServer.instance.send_progress_text( - f"Result URL: {img_url}", node_id - ) - img_response = requests.get(img_url) - return process_image_response(img_response) - elif result["status"] in [ - BFLStatus.request_moderated, - BFLStatus.content_moderated, - ]: - status = result["status"] - raise Exception( - f"BFL API did not return an image due to: {status}." - ) - elif result["status"] == BFLStatus.error: - raise Exception(f"BFL API encountered an error: {result}.") - elif result["status"] == BFLStatus.pending: - time.sleep(retry_pending_seconds) - continue - elif response.status_code == 404: - if retries_404 < max_retries_404: - retries_404 += 1 - time.sleep(retry_404_seconds) - continue - raise Exception( - f"BFL API could not find task after {max_retries_404} tries." - ) - elif response.status_code == 202: - time.sleep(retry_202_seconds) - elif time.time() - start_time > timeout: - raise Exception( - f"BFL API experienced a timeout; could not return request under {timeout} seconds." - ) - else: - raise Exception(f"BFL API encountered an error: {response.json()}") - -def convert_image_to_base64(image: torch.Tensor): - scaled_image = downscale_image_tensor(image, total_pixels=2048 * 2048) - # remove batch dimension if present - if len(scaled_image.shape) > 3: - scaled_image = scaled_image[0] - image_np = (scaled_image.numpy() * 255).astype(np.uint8) - img = Image.fromarray(image_np) - img_byte_arr = io.BytesIO() - img.save(img_byte_arr, format="PNG") - return base64.b64encode(img_byte_arr.getvalue()).decode() - - def convert_mask_to_image(mask: torch.Tensor): """ Make mask have the expected amount of dims (4) and channels (3) to be recognized as an image. diff --git a/comfy_api_nodes/nodes_ideogram.py b/comfy_api_nodes/nodes_ideogram.py index dc6db81b9..b1cbf511d 100644 --- a/comfy_api_nodes/nodes_ideogram.py +++ b/comfy_api_nodes/nodes_ideogram.py @@ -787,6 +787,7 @@ class IdeogramV3(ComfyNodeABC): display_image_urls_on_node(image_urls, unique_id) return (download_and_process_images(image_urls),) + NODE_CLASS_MAPPINGS = { "IdeogramV1": IdeogramV1, "IdeogramV2": IdeogramV2, diff --git a/comfy_api_nodes/nodes_kling.py b/comfy_api_nodes/nodes_kling.py index 00f5d6f98..641cd6353 100644 --- a/comfy_api_nodes/nodes_kling.py +++ b/comfy_api_nodes/nodes_kling.py @@ -102,23 +102,6 @@ AVERAGE_DURATION_VIDEO_EXTEND = 320 R = TypeVar("R") -MAX_PROMPT_LENGTH_T2V = 2500 -MAX_PROMPT_LENGTH_I2V = 500 -MAX_PROMPT_LENGTH_IMAGE_GEN = 500 -MAX_NEGATIVE_PROMPT_LENGTH_IMAGE_GEN = 200 -MAX_PROMPT_LENGTH_LIP_SYNC = 120 - -# TODO: adjust based on tests -AVERAGE_DURATION_T2V = 319 # 319, -AVERAGE_DURATION_I2V = 164 # 164, -AVERAGE_DURATION_LIP_SYNC = 120 -AVERAGE_DURATION_VIRTUAL_TRY_ON = 19 # 19, -AVERAGE_DURATION_IMAGE_GEN = 32 -AVERAGE_DURATION_VIDEO_EFFECTS = 320 -AVERAGE_DURATION_VIDEO_EXTEND = 320 - -R = TypeVar("R") - class KlingApiError(Exception): """Base exception for Kling API errors.""" @@ -557,9 +540,6 @@ class KlingCameraControlT2VNode(KlingTextToVideoNode): def INPUT_TYPES(s): return { "required": { - "start_frame": model_field_to_node_input( - IO.IMAGE, KlingImage2VideoRequest, "image" - ), "prompt": model_field_to_node_input( IO.STRING, KlingText2VideoRequest, "prompt", multiline=True ), @@ -786,13 +766,6 @@ class KlingCameraControlI2VNode(KlingImage2VideoNode): "negative_prompt", multiline=True, ), - "model_name": model_field_to_node_input( - IO.COMBO, - KlingImage2VideoRequest, - "model_name", - enum_type=ModelName, - default="kling-v2-master", - ), "cfg_scale": model_field_to_node_input( IO.FLOAT, KlingImage2VideoRequest, @@ -828,7 +801,6 @@ class KlingCameraControlI2VNode(KlingImage2VideoNode): start_frame: torch.Tensor, prompt: str, negative_prompt: str, - model_name: str, cfg_scale: float, aspect_ratio: str, camera_control: KlingCameraControl,