Files
Superside-comfyui-superside…/modules/bria_replace_background_node.py
T
Superside ComfyUI Nodes df2c9c0beb Rename all 28 node classes with a Superside prefix
Root cause of nodes not appearing in ComfyUI: this package's node
classes originally reused the exact same class names as the internal
fal-flux-nodes package it was migrated from (e.g. NanoBananaProEditNode,
SeedreamV45EditNode). ComfyUI's NODE_CLASS_MAPPINGS is a flat global
dict - when both packages are installed, whichever loads first wins
and the other's registration for that key is silently dropped, which
is why none of the "Superside "-prefixed nodes were showing up.

Every class is now uniquely prefixed (e.g. SupersideNanoBananaProEditNode),
so this package can never collide with fal-flux-nodes, ComfyUI-fal-API,
or any other node pack regardless of install order. Updated __init__.py,
web/js/show_text.js's TEXT_DISPLAY_NODES list, and README.md to match.
2026-07-09 18:29:46 -04:00

121 lines
4.1 KiB
Python

import logging
from .base_node import (
SupersideFalNode,
ImageProcessingMixin,
APIClientMixin,
API_KEY_INPUT_SPEC,
)
logger = logging.getLogger(__name__)
class SupersideBriaReplaceBackgroundNode(
SupersideFalNode, ImageProcessingMixin, APIClientMixin
):
"""
Bria Replace Background Node: Replace an image's background using
bria/replace-background.
Generates a new background with realistic lighting and perspective
from a text prompt, trained on licensed data for commercial use.
"""
@classmethod
def INPUT_TYPES(cls):
return {
"required": {
"image": ("IMAGE",),
"prompt": (
"STRING",
{
"multiline": True,
"placeholder": "Describe the new background scene",
},
),
"api_key": API_KEY_INPUT_SPEC,
},
"optional": {
"negative_prompt": (
"STRING",
{
"multiline": True,
"default": "",
"placeholder": "Describe what to avoid in the background",
},
),
"steps_num": ("INT", {"default": 30, "min": 1, "max": 100}),
"seed": ("INT", {"default": -1, "min": -1, "max": 2147483647, "tooltip": "-1 = random"}),
"sync_mode": ("BOOLEAN", {"default": False}),
},
"hidden": {
"unique_id": "UNIQUE_ID",
"extra_pnginfo": "EXTRA_PNGINFO",
},
}
RETURN_TYPES = ("IMAGE", "STRING")
RETURN_NAMES = ("image", "info")
FUNCTION = "generate"
OUTPUT_NODE = True
DESCRIPTION = (
"Replace an image's background using Bria Replace Background on fal.ai. "
"Generates realistic lighting and perspective from a text prompt."
)
def prepare_arguments(self, client, image, prompt, **kwargs):
image_url = self.upload_image(client, image)
arguments = {
"image_url": image_url,
"prompt": prompt,
}
if kwargs.get("negative_prompt"):
arguments["negative_prompt"] = kwargs["negative_prompt"]
if kwargs.get("steps_num") is not None:
arguments["steps_num"] = kwargs["steps_num"]
seed = kwargs.get("seed", -1)
if seed is not None and seed != -1:
arguments["seed"] = seed
if kwargs.get("sync_mode") is not None:
arguments["sync_mode"] = kwargs["sync_mode"]
return arguments
def generate(self, image, prompt, api_key, unique_id=None, extra_pnginfo=None, **kwargs):
try:
client = self.get_client(api_key)
arguments = self.prepare_arguments(client, image, prompt, **kwargs)
result = self.call_api(client, "bria/replace-background", arguments)
# This endpoint returns a single "image" object, not an "images" list.
image_data = result.get("image")
if not isinstance(image_data, dict) or "url" not in image_data:
raise RuntimeError("No image was generated by the API.")
images = self.process_images({"images": [image_data]})
info = image_data.get("url", "")
if unique_id is not None and extra_pnginfo is not None:
if (
isinstance(extra_pnginfo, list)
and isinstance(extra_pnginfo[0], dict)
and "workflow" in extra_pnginfo[0]
):
workflow = extra_pnginfo[0]["workflow"]
node = next(
(x for x in workflow["nodes"] if str(x["id"]) == str(unique_id)),
None,
)
if node:
node["widgets_values"] = [info]
return {"ui": {"text": [info]}, "result": (images[0], info)}
except Exception as e:
logger.error(f"Bria replace background failed: {str(e)}")
raise RuntimeError(f"Bria replace background failed: {str(e)}") from e