diff --git a/components/API/responses/OpenAI_Image.py b/components/API/responses/OpenAI_Image.py new file mode 100644 index 0000000..3155d2a --- /dev/null +++ b/components/API/responses/OpenAI_Image.py @@ -0,0 +1,55 @@ +from __future__ import annotations + +from typing import Any +import json +import requests +import comfy.utils +import numpy as np +import torch +from PIL import Image +import fal_client +from io import BytesIO +import base64 + +def handle_response(api_result, schema=None, loaded_client=None, response_url=None): + result_image = None + image_list = [] + final_batch_img = [] + + if type(api_result.data).__name__ == "list" and len(api_result.data) > 1: + batch_images = [] + for single_result in result.data: + image_base64 = single_result.b64_json + image_bytes = base64.b64decode(image_base64) + result_image = Image.open(BytesIO(image_bytes)) + if result_image is not None: + result_image = result_image.convert("RGB") + result_image = np.array(result_image).astype(np.float32) / 255.0 + result_image = torch.from_numpy(result_image)[None,] + batch_images.append(result_image) + + if type(batch_images).__name__ == "list" and len(batch_images) > 1: + image_list = batch_images + single_image_start = batch_images[0] + batch_count = 0 + s = None + for single_image in batch_images: + if (batch_count + 1) < len(batch_images): + current_single_image = batch_images[batch_count + 1] + if single_image_start.shape[1:] != current_single_image.shape[1:]: + current_single_image = comfy.utils.common_upscale(current_single_image.movedim(-1, 1), single_image_start.shape[2], single_image_start.shape[1], "bilinear", "center").movedim(1, -1) + batch_count = batch_count + 1 + if s is not None: + single_image = s + s = torch.cat((current_single_image, single_image), dim=0) + result_image = s + else: + image_base64 = api_result.data[0].b64_json + image_bytes = base64.b64decode(image_base64) + result_image = Image.open(BytesIO(image_bytes)) + if result_image is not None: + result_image = result_image.convert("RGB") + result_image = np.array(result_image).astype(np.float32) / 255.0 + result_image = torch.from_numpy(result_image)[None,] + + return result_image \ No newline at end of file diff --git a/front_end/api_schemas.json b/front_end/api_schemas.json index 28fcfdf..b5bd3a6 100644 --- a/front_end/api_schemas.json +++ b/front_end/api_schemas.json @@ -385,71 +385,48 @@ } }, "BlackForest": { - "FluxExpandPro": { + "flux-2-klein-4b": { "provider": "BlackForest", - "service": "FluxExpandPro", + "service": "flux-2-klein-4b", + "response_handler": "Blackforest_Image.py", + "import_modules": [ + ], "possible_parameters": { - "blackforest_guidance": "FLOAT", - "blackforest_steps": "INT", - "top": "INT", - "bottom": "INT", - "left": "INT", - "right": "INT", - "safety_tolerance": [1, 2, 3, 4, 5, 6] + "safety_tolerance": [0, 1, 2, 3, 4, 5], + "prompt_upsampling": [false, true], + "guidance": "FLOAT", + "steps": "INT" }, "request": { "method": "SDK", "endpoint": "requests.post", "sdk_call": { "args": [ - "{{arg0}}" + "https://api.bfl.ai/v1/flux-2-klein-4b" ], "kwargs": { - "payload": { - "image": "{{reference_images}}", - "top": "{{top}}", - "bottom": "{{bottom}}", - "left": "{{left}}", - "right": "{{right}}", - "prompt": "{{prompt}}", - "steps": "{{blackforest_steps}}", - "prompt_upsampling": false, - "seed": "{{seed}}", - "guidance": "{{blackforest_guidance}}", + "headers": { + "accept": "application/json", + "x-key": { + "$call": "os.environ.get", + "$args": [ + "{{BFL_API_KEY}}" + ], + "$kwargs": {} + }, + "Content-Type": "application/json" + }, + "json": { "output_format": "png", - "safety_tolerance": "{{safety_tolerance}}" - } - } - } - } - }, - "FluxFillPro": { - "provider": "BlackForest", - "service": "FluxFillPro", - "possible_parameters": { - "blackforest_guidance": "FLOAT", - "blackforest_steps": "INT", - "safety_tolerance": [1, 2, 3, 4, 5, 6] - }, - "request": { - "method": "SDK", - "endpoint": "requests.post", - "sdk_call": { - "args": [ - "{{arg0}}" - ], - "kwargs": { - "payload": { - "output_format": "png", - "image": "{{reference_images}}", - "mask": "{{mask_images}}", + "image_prompt": "{{reference_images}}", "safety_tolerance": "{{safety_tolerance}}", "prompt": "{{prompt}}", "seed": "{{seed}}", - "aspect_ratio": "{{aspect_ratio}}", - "prompt_upsampling": false, + "width": "{{width}}", + "height": "{{height}}", + "prompt_upsampling": "{{prompt_upsampling}}", "guidance": "{{guidance}}", - "steps": "{{blackforest_steps}}" + "steps": "{{steps}}" } } } @@ -457,16 +434,21 @@ } }, "OpenAI": { - "GPT_T2I": { + "OpenAI_GPT_T2I": { "provider": "OpenAI", - "service": "GPT_T2I", + "service": "OpenAI_GPT_T2I", + "response_handler": "OpenAI_Image.py", + "import_modules": [ + "from openai import OpenAI" + ], "possible_parameters": { - "model": ["gpt-image-1", "gpt-image-1-mini", "gpt-image-1.5", "chatgpt-image-latest", "dall-e-2"], - "size": ["256x256", "512x512", "1024x1024", "1536x1024", "1024x1536", "auto"], - "quality": ["standard", "low", "medium", "high", "auto"], - "input_fidelity": ["high", "low"], + "model": ["gpt-image-1.5", "gpt-image-1", "gpt-image-1-mini"], "background": ["auto", "transparent", "opaque"], - "moderation": ["low", "high"] + "moderation": ["low", "auto"], + "output_format": ["jpeg", "png", "webp"], + "output_compression": "INT", + "quality": ["high", "low", "medium", "auto"], + "size": ["1024x1024", "1536x1024", "1024x1536", "auto"] }, "request": { "method": "SDK", @@ -477,42 +459,43 @@ "model": "{{model}}", "prompt": "{{prompt}}", "n": "{{batch}}", - "size": "{{size}}", - "quality": "{{quality}}", - "input_fidelity": "{{input_fidelity}}", - "background": "{{background}}", "moderation": "{{moderation}}", - "output_format": "png" + "background": "{{background}}", + "output_format": "{{output_format}}", + "output_compression": "{{output_compression}}", + "size": "{{size}}", + "quality": "{{quality}}" } } } }, - "GPT_I2I": { + "OpenAI_DALL-E_T2I": { "provider": "OpenAI", - "service": "GPT_I2I", + "service": "OpenAI_DALL-E_T2I", + "response_handler": "OpenAI_Image.py", + "import_modules": [ + "from openai import OpenAI" + ], "possible_parameters": { - "model": ["gpt-image-1", "gpt-image-1-mini", "gpt-image-1.5", "chatgpt-image-latest", "dall-e-2"], - "size": ["256x256", "512x512", "1024x1024", "1536x1024", "1024x1536", "auto"], - "quality": ["standard", "low", "medium", "high", "auto"], - "input_fidelity": ["high", "low"], - "background": ["auto", "transparent", "opaque"] + "model": ["dall-e-2", "dall-e-3"], + "quality": ["standard", "hd"], + "response_format": ["b64_json", "url"], + "size": ["1024x1024", "1792x1024", "1024x1792"], + "style": ["vivid", "natural"] }, "request": { "method": "SDK", - "endpoint": "client.images.edit", + "endpoint": "client.images.generate", "sdk_call": { "args": [], "kwargs": { "model": "{{model}}", - "image": "{{reference_images}}", - "mask": "{{mask}}", "prompt": "{{prompt}}", - "n": "{{batch}}", + "n": 1, "size": "{{size}}", "quality": "{{quality}}", - "input_fidelity": "{{input_fidelity}}", - "background": "{{background}}", - "output_format": "png" + "response_format": "{{response_format}}", + "style": "{{style}}" } } } diff --git a/terminal_helpers/result-OAI.json b/terminal_helpers/result-OAI.json new file mode 100644 index 0000000..6284fd3 --- /dev/null +++ b/terminal_helpers/result-OAI.json @@ -0,0 +1,70 @@ +{ + "OpenAI": { + "OpenAI_T2I": { + "provider": "OpenAI", + "service": "OpenAI_T2I", + "response_handler": "OpenAI_OpenAI_T2I.py", + "import_modules": [ + "import your_provider_sdk", + "from your_provider_sdk import types" + ], + "possible_parameters": { + "background": [ + "fake_background_value_1", + "fake_background_value_2" + ], + "batch": [ + "fake_batch_value_1", + "fake_batch_value_2" + ], + "model": [ + "example-model-1", + "example-model-2" + ], + "moderation": [ + "fake_moderation_value_1", + "fake_moderation_value_2" + ], + "output_compression": [ + "fake_output_compression_value_1", + "fake_output_compression_value_2" + ], + "output_format": [ + "fake_output_format_value_1", + "fake_output_format_value_2" + ], + "quality": [ + "fake_quality_value_1", + "fake_quality_value_2" + ], + "response_format": [ + "fake_response_format_value_1", + "fake_response_format_value_2" + ], + "size": [ + "fake_size_value_1", + "fake_size_value_2" + ] + }, + "request": { + "method": "SDK", + "endpoint": "client.images.generate", + "sdk_call": { + "args": [], + "kwargs": { + "model": "{{model}}", + "prompt": "{{prompt}}", + "n": "{{batch}}", + "moderation": "{{moderation}}", + "background": "{{background}}", + "output_format": "{{output_format}}", + "output_compression": "{{output_compression}}", + "size": "{{size}}", + "quality": "{{quality}}", + "response_format": "{{response_format}}" + } + } + } + } + } +} diff --git a/terminal_helpers/result-bfl.json b/terminal_helpers/result-bfl.json new file mode 100644 index 0000000..bf2edaf --- /dev/null +++ b/terminal_helpers/result-bfl.json @@ -0,0 +1,48 @@ +{ + "BFL": { + "BFL_SERVICE": { + "provider": "BFL", + "service": "BFL_SERVICE", + "response_handler": "BFL_BFL_SERVICE.py", + "import_modules": [ + ], + "possible_parameters": { + "safety_tolerance": [0, 1, 2, 3, 4, 5] + }, + "request": { + "method": "SDK", + "endpoint": "requests.post", + "sdk_call": { + "args": [ + "https://api.bfl.ai/v1/flux-2-klein-4b" + ], + "kwargs": { + "headers": { + "accept": "application/json", + "x-key": { + "$call": "os.environ.get", + "$args": [ + "{{BFL_API_KEY}}" + ], + "$kwargs": {} + }, + "Content-Type": "application/json" + }, + "json": { + "output_format": "png", + "image_prompt": "{{reference_images}}", + "safety_tolerance": "{{safety_tolerance}}", + "prompt": "{{prompt}}", + "seed": "{{seed}}", + "width": "{{width}}", + "height": "{{height}}", + "prompt_upsampling": "BOOLEAN", + "guidance": "FLOAT", + "steps": "INT" + } + } + } + } + } + } +} diff --git a/terminal_helpers/result.json b/terminal_helpers/result.json index 43f4102..6284fd3 100644 --- a/terminal_helpers/result.json +++ b/terminal_helpers/result.json @@ -1,39 +1,67 @@ { - "Gemini": { - "Nanox": { - "provider": "Gemini", - "service": "Nanox", - "response_handler": "Gemini_Nanox.py", + "OpenAI": { + "OpenAI_T2I": { + "provider": "OpenAI", + "service": "OpenAI_T2I", + "response_handler": "OpenAI_OpenAI_T2I.py", "import_modules": [ "import your_provider_sdk", "from your_provider_sdk import types" ], "possible_parameters": { - "reference_image": [ - "fake_reference_image_value_1", - "fake_reference_image_value_2" + "background": [ + "fake_background_value_1", + "fake_background_value_2" ], - "with_logs": [ - "fake_with_logs_value_1", - "fake_with_logs_value_2" + "batch": [ + "fake_batch_value_1", + "fake_batch_value_2" + ], + "model": [ + "example-model-1", + "example-model-2" + ], + "moderation": [ + "fake_moderation_value_1", + "fake_moderation_value_2" + ], + "output_compression": [ + "fake_output_compression_value_1", + "fake_output_compression_value_2" + ], + "output_format": [ + "fake_output_format_value_1", + "fake_output_format_value_2" + ], + "quality": [ + "fake_quality_value_1", + "fake_quality_value_2" + ], + "response_format": [ + "fake_response_format_value_1", + "fake_response_format_value_2" + ], + "size": [ + "fake_size_value_1", + "fake_size_value_2" ] }, "request": { "method": "SDK", - "endpoint": "fal_client.subscribe", + "endpoint": "client.images.generate", "sdk_call": { - "args": [ - "fal-ai/kling-video/o3/pro/reference-to-video" - ], + "args": [], "kwargs": { - "arguments": { - "prompt": "{{prompt}}", - "multi_prompt": null, - "start_image_url": "{{reference_image}}", - "duration": "8", - "aspect_ratio": "16:9", - "with_logs": "{{with_logs}}" - } + "model": "{{model}}", + "prompt": "{{prompt}}", + "n": "{{batch}}", + "moderation": "{{moderation}}", + "background": "{{background}}", + "output_format": "{{output_format}}", + "output_compression": "{{output_compression}}", + "size": "{{size}}", + "quality": "{{quality}}", + "response_format": "{{response_format}}" } } } diff --git a/terminal_helpers/snippet-OAI.py b/terminal_helpers/snippet-OAI.py new file mode 100644 index 0000000..d272f13 --- /dev/null +++ b/terminal_helpers/snippet-OAI.py @@ -0,0 +1,12 @@ +response = client.images.generate( + model=model, + prompt=prompt, + n=batch, + moderation = moderation, + background = background, + output_format = output_format, + output_compression = "INT", + size=size, + quality = quality, + response_format = response_format +) diff --git a/terminal_helpers/snippet-bfl.py b/terminal_helpers/snippet-bfl.py new file mode 100644 index 0000000..ee83106 --- /dev/null +++ b/terminal_helpers/snippet-bfl.py @@ -0,0 +1,19 @@ +response = requests.post("https://api.bfl.ai/v1/flux-2-klein-4b", + headers={ + "accept": "application/json", + "x-key": os.environ.get("BFL_API_KEY"), + "Content-Type": "application/json", + }, + json={ + "output_format": "png", + "image_prompt": reference_images, + "safety_tolerance": safety_tolerance, + "prompt": prompt, + "seed": seed, + "width": width, + "height": height, + "prompt_upsampling": "BOOLEAN", + "guidance": "FLOAT", + "steps": "INT", + }, + ) diff --git a/terminal_helpers/snippet.py b/terminal_helpers/snippet.py index 53ceb5d..d272f13 100644 --- a/terminal_helpers/snippet.py +++ b/terminal_helpers/snippet.py @@ -1,10 +1,12 @@ -result = fal_client.subscribe("fal-ai/kling-video/o3/pro/reference-to-video", - arguments={ - "prompt": prompt, - "multi_prompt": null, - "start_image_url": reference_image, - "duration": "8", - "aspect_ratio": "16:9", - "with_logs": with_logs - } -) \ No newline at end of file +response = client.images.generate( + model=model, + prompt=prompt, + n=batch, + moderation = moderation, + background = background, + output_format = output_format, + output_compression = "INT", + size=size, + quality = quality, + response_format = response_format +)