Compare commits

..
Author SHA1 Message Date
Ubuntu b5d4d41bb8 update version 2025-11-12 12:03:13 +00:00
Ubuntu 0f2b1115c5 fix invalid token error message 2025-11-12 09:44:45 +00:00
Yazan Numoor b408c8781a Update pyproject.toml 2025-11-11 15:50:02 +02:00
Yazan Numoor f6e134cfd3 Merge pull request #30 from Bria-AI/WAI-4030
WAI-4030
2025-11-11 15:39:44 +02:00
Ubuntu 7855c4dba2 WAI-4030 2025-11-09 06:51:29 +00:00
galbria c1f67dd4fb remove FIBO Workflow.json file 2025-10-30 15:41:37 +02:00
ליזה ירושבסקי c1a77106b4 adding fibo workflow 2025-10-30 15:39:49 +02:00
Yazan Numoor 0f170bfc6b Merge pull request #29 from Bria-AI/fix_comfy_refine_to_support_generate
fix_comfy_refine_to_support_generate
2025-10-29 18:27:06 +02:00
Ubuntu 6b4b9e2dee update version 2025-10-29 16:26:29 +00:00
Ubuntu 4385a8c429 fix_comfy_refine_to_support_generate 2025-10-29 16:18:44 +00:00
Yazan Numoor dd8d70000f Merge pull request #27 from Bria-AI/WAI-4116
WAI-4116
2025-10-29 17:08:48 +02:00
Ubuntu 582e16600e Merge branch 'WAI-4116' of https://github.com/Bria-AI/ComfyUI-BRIA-API into WAI-4116 2025-10-29 12:12:53 +00:00
Ubuntu 33f657ccbd update version 2025-10-29 12:12:29 +00:00
mabualrob1997 f8a6650b4b Update Readme.md 2025-10-29 14:10:43 +02:00
Ubuntu 493d23bdcb remove pro nodes 2025-10-29 11:24:22 +00:00
Ubuntu ecf52dd764 fix images paramter 2025-10-28 15:08:16 +00:00
Ubuntu a9f894102d remmove duplicate import 2025-10-28 07:06:24 +00:00
Ubuntu e50dd5dd63 remmove duplicate import 2025-10-28 07:04:34 +00:00
Ubuntu 00ce39dae5 Merge branch 'main' of https://github.com/Bria-AI/ComfyUI-BRIA-API into WAI-4116 2025-10-28 07:01:47 +00:00
Ubuntu 270128d32a add fibo pro nodes 2025-10-27 20:19:53 +00:00
Yazan Numoor 513fec79b5 Merge pull request #26 from Bria-AI/WAI-4049
WAI-4049
2025-10-23 09:48:24 +03:00
Ubuntu 43893286cc update Gaia model name to Fibo 2025-10-16 09:27:30 +00:00
Ubuntu 96d2924dfc WAI-4116 2025-10-14 12:30:13 +00:00
Ubuntu 327ace887b WAI-4116 2025-10-14 08:57:45 +00:00
22 changed files with 937 additions and 25 deletions
+15 -1
View File
@@ -30,7 +30,21 @@ To load a workflow, import the compatible workflow.json files from this [folder]
# Available Nodes
## Image Generation Nodes
These nodes create high-quality images from text or image prompts, generating photorealistic or artistic results with support for various aspect ratios.
These nodes allow you to leverage Bria's image generation capabilities within ComfyUI. We offer our latest **V2 nodes** designed for precise control via structured prompts (currently powered by the **FIBO** model), alongside our **V1 nodes** for various established pipelines.
### V2 Generation Nodes
These nodes generate images based on detailed **structured prompts** for enhanced control and consistency. They are currently powered by the state-of-the-art **FIBO** text-to-image model.
| **Node** | **Description** |
| --- | --- |
| **Generate Image** | Creates new images from text or image inputs. Internally translates the input into a structured prompt using a selected VLM bridge before generating with the image model. |
| **Refine and Regenerate Image** | Refines a generated image using a provided `structured_prompt` (from a previous generation) and a refinement text prompt. |
### V1 Generation Nodes
These nodes create high-quality images using Bria's V1 pipelines, supporting various aspect ratios and styles.
| Node | Description |
|------------------------|--------------------------------------------------------------------|
+8 -2
View File
@@ -14,6 +14,8 @@ from .nodes import (
Text2ImageHDNode,
TailoredPortraitNode,
ReimagineNode,
GenerateImageNodeV2,
RefineImageNodeV2,
ShotByTextAutomaticNode,
ShotByImageManualPaddingNode,
ShotByImageAutomaticAspectRatioNode,
@@ -54,7 +56,9 @@ NODE_CLASS_MAPPINGS = {
"Text2ImageFastNode": Text2ImageFastNode,
"Text2ImageHDNode": Text2ImageHDNode,
"ReimagineNode": ReimagineNode,
"AttributionByImageNode":AttributionByImageNode
"AttributionByImageNode": AttributionByImageNode,
"GenerateImageNodeV2": GenerateImageNodeV2,
"RefineImageNodeV2": RefineImageNodeV2,
}
# Map the node display name to the one shown in the ComfyUI node interface
NODE_DISPLAY_NAME_MAPPINGS = {
@@ -83,5 +87,7 @@ NODE_DISPLAY_NAME_MAPPINGS = {
"Text2ImageFastNode": "Bria Text2Image Fast",
"Text2ImageHDNode": "Bria Text2Image HD",
"ReimagineNode": "Bria Reimagine",
"AttributionByImageNode":"Attribution By Image Node"
"AttributionByImageNode": "Attribution By Image Node",
"GenerateImageNodeV2": "Generate Image",
"RefineImageNodeV2": "Refine and Regenerate Image",
}
+2
View File
@@ -11,6 +11,8 @@ from .text_2_image_base_node import Text2ImageBaseNode
from .text_2_image_fast_node import Text2ImageFastNode
from .text_2_image_hd_node import Text2ImageHDNode
from .reimagine_node import ReimagineNode
from .generate_image_node_v2 import GenerateImageNodeV2
from .refine_image_node_v2 import RefineImageNodeV2
from .shot_by_text_node import ShotByTextOriginalNode
from .shot_by_text_automatic_aspect_ratio_node import ShotByTextAutomaticAspectRatioNode
from .shot_by_text_automatic_node import ShotByTextAutomaticNode
+2 -1
View File
@@ -1,7 +1,7 @@
import requests
import torch
from .common import preprocess_image, image_to_base64, poll_status_until_completed
from .common import deserialize_and_get_comfy_key, preprocess_image, image_to_base64, poll_status_until_completed
class AttributionByImageNode():
@classmethod
@@ -26,6 +26,7 @@ class AttributionByImageNode():
def execute(self, image, model_version, api_key):
if api_key.strip() == "" or api_key.strip() == "BRIA_API_TOKEN":
raise Exception("Please insert a valid API key.")
api_key = deserialize_and_get_comfy_key(api_key)
# Check if image is tensor, if so, convert to NumPy array
if isinstance(image, torch.Tensor):
+28
View File
@@ -6,6 +6,15 @@ import base64
from torchvision.transforms import ToPILImage
import requests
import time
import json
COMFY_KEY_ERROR = (
"Invalid Token Type\n\n"
"The API token you’ve entered is not a ComfyUI token.\n"
"Please use the valid token from your BRIA Account API Keys page:\n"
"https://platform.bria.ai/console/account/api-keys"
)
def postprocess_image(image):
result_image = Image.open(io.BytesIO(image))
@@ -48,6 +57,7 @@ def preprocess_mask(mask):
def process_request(api_url, image, mask, api_key, visual_input_content_moderation, visual_output_content_moderation):
if api_key.strip() == "" or api_key.strip() == "BRIA_API_TOKEN":
raise Exception("Please insert a valid API key.")
api_key = deserialize_and_get_comfy_key(api_key)
# Check if image and mask are tensors, if so, convert to NumPy arrays
if isinstance(image, torch.Tensor):
@@ -145,3 +155,21 @@ def poll_status_until_completed(status_url, api_key, timeout=360, check_interval
raise Exception(f"Error checking status: {e}")
raise Exception(f"Timeout reached after {timeout} seconds")
def deserialize_and_get_comfy_key(encoded: str) -> str:
"""
Decodes a base64-encoded JSON token and returns the ComfyUI API key.
"""
try:
decoded = base64.b64decode(encoded).decode("utf-8")
payload = json.loads(decoded)
if payload.get("type") != "comfy":
raise Exception(COMFY_KEY_ERROR)
return payload.get("apiKey")
except Exception as e:
raise Exception(COMFY_KEY_ERROR)
+143
View File
@@ -0,0 +1,143 @@
import requests
import torch
from .common import (
deserialize_and_get_comfy_key,
postprocess_image,
preprocess_image,
image_to_base64,
poll_status_until_completed,
)
class _BaseGenerateImageNodeV2:
"""Base class for image generation nodes (standard & pro)."""
api_url = None # Each subclass must define its API endpoint
@classmethod
def INPUT_TYPES(cls):
return {
"required": {
"api_token": ("STRING", {"default": "BRIA_API_TOKEN"}),
"prompt": ("STRING",),
},
"optional": {
"model_version": (["FIBO"], {"default": "FIBO"}),
"negative_prompt": ("STRING", {"default": ""}),
"images": ("IMAGE",),
"aspect_ratio": (
["1:1", "2:3", "3:2", "3:4", "4:3", "4:5", "5:4", "9:16", "16:9"],
{"default": "1:1"},
),
"steps_num": ("INT", {"default": 50, "min": 20, "max": 50}),
"guidance_scale": ("INT", {"default": 5, "min": 3, "max": 5}),
"seed": ("INT", {"default": 123456}),
},
}
RETURN_TYPES = ("IMAGE", "STRING", "INT")
RETURN_NAMES = ("image", "structured_prompt", "seed")
CATEGORY = "API Nodes"
FUNCTION = "execute"
def _validate_token(self, api_token: str):
if api_token.strip() == "" or api_token.strip() == "BRIA_API_TOKEN":
raise Exception("Please insert a valid API token.")
def _build_payload(
self,
prompt,
model_version,
negative_prompt,
aspect_ratio,
steps_num,
guidance_scale,
seed,
images=None,
):
payload = {
"prompt": prompt,
"model_version": model_version,
"negative_prompt": negative_prompt,
"aspect_ratio": aspect_ratio,
"steps_num": steps_num,
"guidance_scale": guidance_scale,
"seed": seed,
}
if images is not None:
if isinstance(images, torch.Tensor):
preprocess_images = preprocess_image(images)
payload["images"] = [image_to_base64(preprocess_images)]
return payload
def execute(
self,
api_token,
prompt,
model_version,
negative_prompt,
aspect_ratio,
steps_num,
guidance_scale,
seed,
images=None,
):
self._validate_token(api_token)
payload = self._build_payload(
prompt,
model_version,
negative_prompt,
aspect_ratio,
steps_num,
guidance_scale,
seed,
images,
)
api_token = deserialize_and_get_comfy_key(api_token)
headers = {"Content-Type": "application/json", "api_token": api_token}
try:
response = requests.post(self.api_url, json=payload, headers=headers)
if response.status_code in (200, 202):
print(
f"Initial request successful to {self.api_url}, polling for completion..."
)
response_dict = response.json()
status_url = response_dict.get("status_url")
request_id = response_dict.get("request_id")
if not status_url:
raise Exception("No status_url returned from API")
print(f"Request ID: {request_id}, Status URL: {status_url}")
final_response = poll_status_until_completed(status_url, api_token)
result = final_response.get("result", {})
result_image_url = result.get("image_url")
structured_prompt = result.get("structured_prompt", "")
used_seed = result.get("seed")
image_response = requests.get(result_image_url)
result_image = postprocess_image(image_response.content)
return (result_image, structured_prompt, used_seed)
raise Exception(
f"Error: API request failed with status code {response.status_code} {response.text}"
)
except Exception as e:
raise Exception(f"{e}")
class GenerateImageNodeV2(_BaseGenerateImageNodeV2):
"""Standard Image Generation Node"""
def __init__(self):
self.api_url = "https://engine.prod.bria-api.com/v2/image/generate"
+2 -1
View File
@@ -4,7 +4,7 @@ from PIL import Image
import io
import torch
from .common import preprocess_image, preprocess_mask, image_to_base64, poll_status_until_completed
from .common import deserialize_and_get_comfy_key, preprocess_image, preprocess_mask, image_to_base64, poll_status_until_completed
class GenFillNode():
@@ -39,6 +39,7 @@ class GenFillNode():
def execute(self, image, mask, prompt, api_key, seed, prompt_content_moderation, visual_input_content_moderation, visual_output_content_moderation):
if api_key.strip() == "" or api_key.strip() == "BRIA_API_TOKEN":
raise Exception("Please insert a valid API key.")
api_key = deserialize_and_get_comfy_key(api_key)
# Check if image and mask are tensors, if so, convert to NumPy arrays
if isinstance(image, torch.Tensor):
+2 -1
View File
@@ -4,7 +4,7 @@ from PIL import Image
import io
import torch
from .common import image_to_base64, preprocess_image, poll_status_until_completed
from .common import deserialize_and_get_comfy_key, image_to_base64, preprocess_image, poll_status_until_completed
class ImageExpansionNode():
@@ -55,6 +55,7 @@ class ImageExpansionNode():
api_key):
if api_key.strip() == "" or api_key.strip() == "BRIA_API_TOKEN":
raise Exception("Please insert a valid API key.")
api_key = deserialize_and_get_comfy_key(api_key)
original_image_size = [int(x.strip()) for x in original_image_size.split(",")] if original_image_size else ()
original_image_location = [int(x.strip()) for x in original_image_location.split(",")] if original_image_location else ()
canvas_size = [int(x.strip()) for x in canvas_size.split(",")] if canvas_size else ()
+161
View File
@@ -0,0 +1,161 @@
import requests
from .common import deserialize_and_get_comfy_key, poll_status_until_completed, postprocess_image
class _BaseRefineImageNodeV2:
"""Base class for refine image nodes (standard & pro)."""
api_url = None # Must be overridden by subclasses
generate_api_url = None
@classmethod
def INPUT_TYPES(cls):
return {
"required": {
"api_token": ("STRING", {"default": "BRIA_API_TOKEN"}),
"prompt": ("STRING",),
"structured_prompt": ("STRING",),
},
"optional": {
"model_version": (["FIBO"], {"default": "FIBO"}),
"negative_prompt": ("STRING", {"default": ""}),
"aspect_ratio": (
["1:1", "2:3", "3:2", "3:4", "4:3", "4:5", "5:4", "9:16", "16:9"],
{"default": "1:1"},
),
"steps_num": ("INT", {"default": 50, "min": 20, "max": 50}),
"guidance_scale": ("INT", {"default": 5, "min": 3, "max": 5}),
"seed": ("INT", {"default": 123456}),
},
}
RETURN_TYPES = ("IMAGE", "STRING", "INT")
RETURN_NAMES = ("image", "structured_prompt", "seed")
CATEGORY = "API Nodes"
FUNCTION = "execute"
def _validate_token(self, api_token: str):
if api_token.strip() == "" or api_token.strip() == "BRIA_API_TOKEN":
raise Exception("Please insert a valid API token.")
def _build_payload(
self,
prompt,
structured_prompt,
model_version,
negative_prompt,
aspect_ratio,
steps_num,
guidance_scale,
seed,
):
return {
"prompt": prompt,
"model_version": model_version,
"negative_prompt": negative_prompt,
"aspect_ratio": aspect_ratio,
"steps_num": steps_num,
"guidance_scale": guidance_scale,
"seed": seed,
"structured_prompt": structured_prompt,
}
def execute(
self,
api_token,
prompt,
structured_prompt,
model_version,
negative_prompt,
aspect_ratio,
steps_num,
guidance_scale,
seed,
):
self._validate_token(api_token)
payload = self._build_payload(
prompt,
structured_prompt,
model_version,
negative_prompt,
aspect_ratio,
steps_num,
guidance_scale,
seed,
)
api_token = deserialize_and_get_comfy_key(api_token)
headers = {"Content-Type": "application/json", "api_token": api_token}
try:
response = requests.post(self.api_url, json=payload, headers=headers)
if response.status_code in (200, 202):
print(f"Initial refine request successful to {self.api_url}, polling for completion...")
response_dict = response.json()
status_url = response_dict.get("status_url")
request_id = response_dict.get("request_id")
if not status_url:
raise Exception("No status_url returned from API")
print(f"Request ID: {request_id}, Status URL: {status_url}")
final_response = poll_status_until_completed(status_url, api_token)
result = final_response.get("result", {})
structured_prompt = result.get("structured_prompt", "")
used_seed = result.get("seed", seed)
# Step 2 to call genearte image
payloadForImageGenetrate = {
"prompt": prompt,
"structured_prompt":structured_prompt,
"model_version": model_version,
"negative_prompt": negative_prompt,
"aspect_ratio": aspect_ratio,
"steps_num": steps_num,
"guidance_scale": guidance_scale,
"seed": used_seed,
}
headers = {"Content-Type": "application/json", "api_token": api_token}
response = requests.post(self.generate_api_url, json=payloadForImageGenetrate, headers=headers)
if response.status_code in (200, 202):
print(
f"Initial request successful to {self.generate_api_url}, polling for completion..."
)
response_dict = response.json()
status_url = response_dict.get("status_url")
request_id = response_dict.get("request_id")
if not status_url:
raise Exception("No status_url returned from API")
print(f"Request ID: {request_id}, Status URL: {status_url}")
final_response = poll_status_until_completed(status_url, api_token)
result = final_response.get("result", {})
result_image_url = result.get("image_url")
structured_prompt = result.get("structured_prompt", "")
used_seed = result.get("seed")
image_response = requests.get(result_image_url)
result_image = postprocess_image(image_response.content)
return (result_image, structured_prompt, used_seed)
raise Exception(
f"Error: API request failed with status code {response.status_code} {response.text}"
)
except Exception as e:
raise Exception(f"{e}")
class RefineImageNodeV2(_BaseRefineImageNodeV2):
"""Standard Refine Image Node"""
def __init__(self):
self.api_url = "https://engine.prod.bria-api.com/v2/structured_prompt/generate"
self.generate_api_url = "https://engine.prod.bria-api.com/v2/image/generate"
+3 -2
View File
@@ -1,6 +1,6 @@
import requests
from .common import postprocess_image, preprocess_image, image_to_base64
from .common import deserialize_and_get_comfy_key, postprocess_image, preprocess_image, image_to_base64
class ReimagineNode():
@@ -37,7 +37,8 @@ class ReimagineNode():
steps_num, fast, structure_ref_influence, structure_image=None,
tailored_model_id=None, tailored_model_influence=None, tailored_generation_prefix=None,
content_moderation=0,
):
):
api_key = deserialize_and_get_comfy_key(api_key)
payload = {
"prompt": tailored_generation_prefix + prompt,
"num_results": 1,
+2 -1
View File
@@ -4,7 +4,7 @@ from PIL import Image
import io
import torch
from .common import preprocess_image, image_to_base64, poll_status_until_completed
from .common import deserialize_and_get_comfy_key, preprocess_image, image_to_base64, poll_status_until_completed
class RemoveForegroundNode():
@@ -34,6 +34,7 @@ class RemoveForegroundNode():
def execute(self, image, visual_input_content_moderation, visual_output_content_moderation, preserve_alpha, api_key):
if api_key.strip() == "" or api_key.strip() == "BRIA_API_TOKEN":
raise Exception("Please insert a valid API key.")
api_key = deserialize_and_get_comfy_key(api_key)
# Check if image is tensor, if so, convert to NumPy array
if isinstance(image, torch.Tensor):
+2 -1
View File
@@ -4,7 +4,7 @@ from PIL import Image
import io
import torch
from .common import image_to_base64, preprocess_image, preprocess_mask, poll_status_until_completed
from .common import deserialize_and_get_comfy_key, image_to_base64, preprocess_image, preprocess_mask, poll_status_until_completed
class ReplaceBgNode():
@@ -53,6 +53,7 @@ class ReplaceBgNode():
ref_images=None,):
if api_key.strip() == "" or api_key.strip() == "BRIA_API_TOKEN":
raise Exception("Please insert a valid API key.")
api_key = deserialize_and_get_comfy_key(api_key)
# Check if image and mask are tensors, if so, convert to NumPy arrays
if isinstance(image, torch.Tensor):
+2 -2
View File
@@ -4,7 +4,7 @@ from PIL import Image
import io
import torch
from .common import preprocess_image, image_to_base64, poll_status_until_completed
from .common import deserialize_and_get_comfy_key, preprocess_image, image_to_base64, poll_status_until_completed
class RmbgNode():
@classmethod
@@ -34,7 +34,7 @@ class RmbgNode():
def execute(self, image, visual_input_content_moderation, visual_output_content_moderation, preserve_alpha, api_key):
if api_key.strip() == "" or api_key.strip() == "BRIA_API_TOKEN":
raise Exception("Please insert a valid API key.")
api_key = deserialize_and_get_comfy_key(api_key)
# Check if image is tensor, if so, convert to NumPy array
if isinstance(image, torch.Tensor):
image = preprocess_image(image)
+2 -1
View File
@@ -1,6 +1,6 @@
import requests
from .common import postprocess_image, preprocess_image, image_to_base64
from .common import deserialize_and_get_comfy_key, postprocess_image, preprocess_image, image_to_base64
class TailoredGenNode():
@@ -45,6 +45,7 @@ class TailoredGenNode():
guidance_method_2=None, guidance_method_2_scale=None, guidance_method_2_image=None,
content_moderation=0,
):
api_key = deserialize_and_get_comfy_key(api_key)
payload = {
"prompt": generation_prefix + prompt,
"num_results": 1,
+2 -1
View File
@@ -1,5 +1,5 @@
import requests
from .common import deserialize_and_get_comfy_key
class TailoredModelInfoNode():
@classmethod
@@ -21,6 +21,7 @@ class TailoredModelInfoNode():
# Define the execute method as expected by ComfyUI
def execute(self, model_id, api_key):
api_key = deserialize_and_get_comfy_key(api_key)
response = requests.get(
self.api_url + model_id,
headers={"api_token": api_key}
+5 -4
View File
@@ -4,7 +4,7 @@ from PIL import Image
import io
import torch
from .common import image_to_base64, preprocess_image
from .common import deserialize_and_get_comfy_key, image_to_base64, preprocess_image
class TailoredPortraitNode():
@classmethod
@@ -12,7 +12,7 @@ class TailoredPortraitNode():
return {
"required": {
"image": ("IMAGE",), # Input image from another node
"tailored_model_id": ("INT",),
"tailored_model_id": ("STRING",), # API Key input with a default value
"api_key": ("STRING", {"default": "BRIA_API_TOKEN"}), # API Key input with a default value
},
"optional": {
@@ -34,6 +34,7 @@ class TailoredPortraitNode():
def execute(self, image, tailored_model_id, api_key, seed, tailored_model_influence, id_strength):
if api_key.strip() == "" or api_key.strip() == "BRIA_API_TOKEN":
raise Exception("Please insert a valid API key.")
api_key = deserialize_and_get_comfy_key(api_key)
# Convert the image and mask directly to if isinstance(image, torch.Tensor):
if isinstance(image, torch.Tensor):
@@ -44,7 +45,7 @@ class TailoredPortraitNode():
# Prepare the API request payload
payload = {
"id_image_file": f"{image_base64}",
"tailored_model_id": tailored_model_id,
"tailored_model_id": int(tailored_model_id),
"tailored_model_influence": tailored_model_influence,
"id_strength": id_strength,
"seed": seed
@@ -69,7 +70,7 @@ class TailoredPortraitNode():
result_image = torch.from_numpy(result_image)[None,]
return (result_image,)
else:
raise Exception(f"Error: API request failed with status code {response.status_code}")
raise Exception(f"Error: API request failed with status code {response.status_code} {response.text}")
except Exception as e:
raise Exception(f"{e}")
+2 -1
View File
@@ -1,6 +1,6 @@
import requests
from .common import postprocess_image, preprocess_image, image_to_base64
from .common import deserialize_and_get_comfy_key, postprocess_image, preprocess_image, image_to_base64
class Text2ImageBaseNode():
@@ -48,6 +48,7 @@ class Text2ImageBaseNode():
image_prompt_mode=None, image_prompt_image=None, image_prompt_scale=None,
content_moderation=0,
):
api_key = deserialize_and_get_comfy_key(api_key)
payload = {
"prompt": prompt,
"num_results": 1,
+2 -1
View File
@@ -1,6 +1,6 @@
import requests
from .common import postprocess_image, preprocess_image, image_to_base64
from .common import deserialize_and_get_comfy_key, postprocess_image, preprocess_image, image_to_base64
class Text2ImageFastNode():
@@ -45,6 +45,7 @@ class Text2ImageFastNode():
image_prompt_mode=None, image_prompt_image=None, image_prompt_scale=None,
content_moderation=0,
):
api_key = deserialize_and_get_comfy_key(api_key)
payload = {
"prompt": prompt,
"num_results": 1,
+3 -2
View File
@@ -1,6 +1,6 @@
import requests
from .common import postprocess_image
from .common import deserialize_and_get_comfy_key, postprocess_image
class Text2ImageHDNode():
@@ -29,12 +29,13 @@ class Text2ImageHDNode():
FUNCTION = "execute"
def __init__(self):
self.api_url = "https://engine.prod.bria-api.com/v1/text-to-image/hd/2.3" #"http://0.0.0.0:5000/v1/text-to-image/hd/2.3"
self.api_url = "https://engine.prod.bria-api.com/v1/text-to-image/hd/2.2" #"http://0.0.0.0:5000/v1/text-to-image/hd/2.3"
def execute(
self, api_key, prompt, aspect_ratio, seed, negative_prompt,
steps_num, prompt_enhancement, text_guidance_scale, medium, content_moderation=0,
):
api_key = deserialize_and_get_comfy_key(api_key)
payload = {
"prompt": prompt,
"num_results": 1,
+5 -2
View File
@@ -1,6 +1,6 @@
import requests
import torch
from ..common import postprocess_image, preprocess_image, image_to_base64
from ..common import deserialize_and_get_comfy_key, postprocess_image, preprocess_image, image_to_base64
shot_by_text_api_url = (
"https://engine.prod.bria-api.com/v1/product/lifestyle_shot_by_text"
@@ -68,6 +68,7 @@ def create_text_payload(
validate_api_key(api_key)
# Process image
if isinstance(image, torch.Tensor):
image = preprocess_image(image)
@@ -126,9 +127,11 @@ def create_image_payload(image, ref_image, api_key, placement_type, **kwargs):
def make_api_request(api_url, payload, api_key, Placement_type = None):
"""Make API request and return processed image"""
headers = {"Content-Type": "application/json", "api_token": f"{api_key}"}
try:
api_key = deserialize_and_get_comfy_key(api_key)
headers = {"Content-Type": "application/json", "api_token": f"{api_key}"}
response = requests.post(api_url, json=payload, headers=headers)
if response.status_code == 200:
+1 -1
View File
@@ -1,7 +1,7 @@
[project]
name = "comfyui-bria-api"
description = "Custom nodes for ComfyUI using BRIA's API."
version = "2.1.3"
version = "2.1.7"
license = {file = "LICENSE"}
[project.urls]
+543
View File
@@ -0,0 +1,543 @@
{
"id": "3875cd62-7a0e-4c8c-8951-22ec8a63dd8d",
"revision": 0,
"last_node_id": 14,
"last_link_id": 8,
"nodes": [
{
"id": 3,
"type": "PreviewImage",
"pos": [
632.3427124023438,
32.13115310668945
],
"size": [
140,
26
],
"flags": {},
"order": 4,
"mode": 0,
"inputs": [
{
"name": "images",
"type": "IMAGE",
"link": 1
}
],
"outputs": [],
"properties": {
"cnr_id": "comfy-core",
"ver": "0.3.62",
"Node name for S&R": "PreviewImage"
}
},
{
"id": 2,
"type": "RefineImageNodeV2",
"pos": [
704.8090209960938,
218.65850830078125
],
"size": [
287.4712829589844,
314
],
"flags": {},
"order": 5,
"mode": 0,
"inputs": [
{
"name": "structured_prompt",
"type": "STRING",
"widget": {
"name": "structured_prompt"
},
"link": 3
},
{
"name": "seed",
"shape": 7,
"type": "INT",
"widget": {
"name": "seed"
},
"link": 2
}
],
"outputs": [
{
"name": "image",
"type": "IMAGE",
"links": [
4
]
},
{
"name": "structured_prompt",
"type": "STRING",
"links": null
},
{
"name": "seed",
"type": "INT",
"links": null
}
],
"properties": {
"cnr_id": "comfyui-bria-api",
"ver": "2.1.4",
"Node name for S&R": "RefineImageNodeV2",
"ue_properties": {
"widget_ue_connectable": {
"api_token": true,
"prompt": true,
"structured_prompt": true,
"model_version": true,
"negative_prompt": true,
"aspect_ratio": true,
"steps_num": true,
"guidance_scale": true,
"seed": true
},
"version": "7.1",
"input_ue_unconnectable": {}
}
},
"widgets_values": [
"BRIA_API_TOKEN",
"",
"",
"FIBO",
"",
"1:1",
50,
5,
123456,
"randomize"
]
},
{
"id": 4,
"type": "PreviewImage",
"pos": [
1153.29345703125,
270.2264404296875
],
"size": [
140,
26
],
"flags": {},
"order": 8,
"mode": 0,
"inputs": [
{
"name": "images",
"type": "IMAGE",
"link": 4
}
],
"outputs": [],
"properties": {
"cnr_id": "comfy-core",
"ver": "0.3.62",
"Node name for S&R": "PreviewImage"
}
},
{
"id": 1,
"type": "GenerateImageNodeV2",
"pos": [
272.6366882324219,
227.9468231201172
],
"size": [
270,
290
],
"flags": {},
"order": 0,
"mode": 0,
"inputs": [
{
"name": "images",
"shape": 7,
"type": "IMAGE",
"link": null
}
],
"outputs": [
{
"name": "image",
"type": "IMAGE",
"links": [
1
]
},
{
"name": "structured_prompt",
"type": "STRING",
"links": [
3
]
},
{
"name": "seed",
"type": "INT",
"links": [
2
]
}
],
"properties": {
"cnr_id": "comfyui-bria-api",
"ver": "2.1.4",
"Node name for S&R": "GenerateImageNodeV2",
"ue_properties": {
"widget_ue_connectable": {
"api_token": true,
"prompt": true,
"model_version": true,
"negative_prompt": true,
"aspect_ratio": true,
"steps_num": true,
"guidance_scale": true,
"seed": true
},
"version": "7.1",
"input_ue_unconnectable": {}
}
},
"widgets_values": [
"BRIA_API_TOKEN",
"",
"FIBO",
"",
"1:1",
50,
5,
123456,
"randomize"
]
},
{
"id": 5,
"type": "Note",
"pos": [
-43.613197326660156,
324.2381896972656
],
"size": [
210,
88
],
"flags": {},
"order": 1,
"mode": 0,
"inputs": [],
"outputs": [],
"properties": {},
"widgets_values": [
"If you would like to start with prompt"
],
"color": "#c09430",
"bgcolor": "rgba(24,24,27,.9)"
},
{
"id": 10,
"type": "PreviewImage",
"pos": [
1182.5216064453125,
1006.7373657226562
],
"size": [
140,
26
],
"flags": {},
"order": 9,
"mode": 0,
"inputs": [
{
"name": "images",
"type": "IMAGE",
"link": 7
}
],
"outputs": [],
"properties": {
"cnr_id": "comfy-core",
"ver": "0.3.62",
"Node name for S&R": "PreviewImage"
}
},
{
"id": 9,
"type": "RefineImageNodeV2",
"pos": [
703.2684326171875,
1034.9910888671875
],
"size": [
287.4712829589844,
314
],
"flags": {},
"order": 7,
"mode": 0,
"inputs": [
{
"name": "structured_prompt",
"type": "STRING",
"widget": {
"name": "structured_prompt"
},
"link": 5
},
{
"name": "seed",
"shape": 7,
"type": "INT",
"widget": {
"name": "seed"
},
"link": 6
}
],
"outputs": [
{
"name": "image",
"type": "IMAGE",
"links": [
7
]
},
{
"name": "structured_prompt",
"type": "STRING",
"links": null
},
{
"name": "seed",
"type": "INT",
"links": null
}
],
"properties": {
"cnr_id": "comfyui-bria-api",
"ver": "2.1.5",
"Node name for S&R": "RefineImageNodeV2"
},
"widgets_values": [
"BRIA_API_TOKEN",
"",
"",
"FIBO",
"",
"1:1",
50,
5,
123456,
"randomize"
]
},
{
"id": 6,
"type": "Note",
"pos": [
-47.50065612792969,
1042.9178466796875
],
"size": [
210,
95.76702880859375
],
"flags": {},
"order": 2,
"mode": 0,
"inputs": [],
"outputs": [],
"properties": {},
"widgets_values": [
"If you would like to start with reference image + prompt"
],
"color": "#c09430",
"bgcolor": "rgba(24,24,27,.9)"
},
{
"id": 14,
"type": "PreviewImage",
"pos": [
593.5224609375,
844.5531616210938
],
"size": [
140,
26
],
"flags": {},
"order": 6,
"mode": 0,
"inputs": [
{
"name": "images",
"type": "IMAGE",
"link": 8
}
],
"outputs": [],
"properties": {
"cnr_id": "comfy-core",
"ver": "0.3.62",
"Node name for S&R": "PreviewImage"
}
},
{
"id": 7,
"type": "GenerateImageNodeV2",
"pos": [
262.3690490722656,
1041.67431640625
],
"size": [
270,
290
],
"flags": {},
"order": 3,
"mode": 0,
"inputs": [
{
"name": "images",
"shape": 7,
"type": "IMAGE",
"link": null
}
],
"outputs": [
{
"name": "image",
"type": "IMAGE",
"links": [
8
]
},
{
"name": "structured_prompt",
"type": "STRING",
"links": [
5
]
},
{
"name": "seed",
"type": "INT",
"links": [
6
]
}
],
"properties": {
"cnr_id": "comfyui-bria-api",
"ver": "2.1.5",
"Node name for S&R": "GenerateImageNodeV2"
},
"widgets_values": [
"BRIA_API_TOKEN",
"",
"FIBO",
"",
"1:1",
50,
5,
123456,
"randomize"
]
}
],
"links": [
[
1,
1,
0,
3,
0,
"IMAGE"
],
[
2,
1,
2,
2,
1,
"INT"
],
[
3,
1,
1,
2,
0,
"STRING"
],
[
4,
2,
0,
4,
0,
"IMAGE"
],
[
5,
7,
1,
9,
0,
"STRING"
],
[
6,
7,
2,
9,
1,
"INT"
],
[
7,
9,
0,
10,
0,
"IMAGE"
],
[
8,
7,
0,
14,
0,
"IMAGE"
]
],
"groups": [],
"config": {},
"extra": {
"ue_links": [],
"ds": {
"scale": 0.3897342147473183,
"offset": [
658.5745748406673,
99.37411299539059
]
},
"frontendVersion": "1.28.4",
"VHS_latentpreview": false,
"VHS_latentpreviewrate": 0,
"VHS_MetadataImage": true,
"VHS_KeepIntermediate": true
},
"version": 0.4
}