feat: Added config node

This commit is contained in:
Çağan Kiraz
2025-08-28 22:27:45 +03:00
parent f1792cf25f
commit bcf8af770d
7 changed files with 420 additions and 281 deletions
+1
View File
@@ -4,6 +4,7 @@ import importlib
node_list = [
"api_node",
"finetune",
"config_node",
]
NODE_CLASS_MAPPINGS = {}
+48 -36
View File
@@ -14,11 +14,12 @@ class FluxPro11(BaseFlux):
"output_format": (["jpeg", "png"], {"default": "jpeg"})
},
"optional": {
"seed": ("INT", {"default": -1})
"seed": ("INT", {"default": -1}),
"config": ("BFL_CONFIG",)
}
}
def generate_image(self, prompt, width, height, prompt_upsampling, safety_tolerance, output_format, seed):
def generate_image(self, prompt, width, height, prompt_upsampling, safety_tolerance, output_format, seed=-1, config=None):
arguments = {
"prompt": prompt,
"width": width,
@@ -29,7 +30,7 @@ class FluxPro11(BaseFlux):
}
if seed != -1:
arguments["seed"] = seed
return super().generate_image("flux-pro-1.1", arguments)
return super().generate_image("flux-pro-1.1", arguments, config)
class FluxDev(BaseFlux):
@@ -47,11 +48,12 @@ class FluxDev(BaseFlux):
"output_format": (["jpeg", "png"], {"default": "jpeg"})
},
"optional": {
"seed": ("INT", {"default": -1})
"seed": ("INT", {"default": -1}),
"config": ("BFL_CONFIG",)
}
}
def generate_image(self, prompt, width, height, steps, prompt_upsampling, safety_tolerance, guidance, output_format, seed):
def generate_image(self, prompt, width, height, steps, prompt_upsampling, safety_tolerance, guidance, output_format, seed=-1, config=None):
arguments = {
"prompt": prompt,
"width": width,
@@ -64,7 +66,7 @@ class FluxDev(BaseFlux):
}
if seed != -1:
arguments["seed"] = seed
return super().generate_image("flux-dev", arguments)
return super().generate_image("flux-dev", arguments, config)
class FluxDevRedux(BaseFlux):
@classmethod
@@ -82,11 +84,12 @@ class FluxDevRedux(BaseFlux):
"output_format": (["jpeg", "png"], {"default": "jpeg"})
},
"optional": {
"seed": ("INT", {"default": -1})
"seed": ("INT", {"default": -1}),
"config": ("BFL_CONFIG",)
}
}
def generate_image(self, prompt, image_prompt, width, height, steps, prompt_upsampling, safety_tolerance, guidance, output_format, seed):
def generate_image(self, prompt, image_prompt, width, height, steps, prompt_upsampling, safety_tolerance, guidance, output_format, seed=-1, config=None):
arguments = {
"prompt": prompt,
"image_prompt": image_prompt,
@@ -100,7 +103,7 @@ class FluxDevRedux(BaseFlux):
}
if seed != -1:
arguments["seed"] = seed
return super().generate_image("flux-dev", arguments)
return super().generate_image("flux-dev", arguments, config)
class FluxPro(BaseFlux):
@classmethod
@@ -118,11 +121,12 @@ class FluxPro(BaseFlux):
"output_format": (["jpeg", "png"], {"default": "jpeg"})
},
"optional": {
"seed": ("INT", {"default": -1})
"seed": ("INT", {"default": -1}),
"config": ("BFL_CONFIG",)
}
}
def generate_image(self, prompt, width, height, steps, prompt_upsampling, safety_tolerance, guidance, interval, output_format, seed):
def generate_image(self, prompt, width, height, steps, prompt_upsampling, safety_tolerance, guidance, interval, output_format, seed=-1, config=None):
arguments = {
"prompt": prompt,
"width": width,
@@ -136,7 +140,7 @@ class FluxPro(BaseFlux):
}
if seed != -1:
arguments["seed"] = seed
return super().generate_image("flux-pro", arguments)
return super().generate_image("flux-pro", arguments, config)
class FluxPro11Ultra(BaseFlux):
@@ -151,11 +155,12 @@ class FluxPro11Ultra(BaseFlux):
"raw": ("BOOLEAN", {"default": False})
},
"optional": {
"seed": ("INT", {"default": -1})
"seed": ("INT", {"default": -1}),
"config": ("BFL_CONFIG",)
}
}
def generate_image(self, prompt, aspect_ratio, safety_tolerance, output_format, raw, seed):
def generate_image(self, prompt, aspect_ratio, safety_tolerance, output_format, raw, seed=-1, config=None):
arguments = {
"prompt": prompt,
"aspect_ratio": aspect_ratio,
@@ -165,7 +170,7 @@ class FluxPro11Ultra(BaseFlux):
}
if seed != -1:
arguments["seed"] = seed
return super().generate_image("flux-pro-1.1-ultra", arguments)
return super().generate_image("flux-pro-1.1-ultra", arguments, config)
class FluxProFill(BaseFlux):
@classmethod
@@ -182,12 +187,13 @@ class FluxProFill(BaseFlux):
"output_format": (["jpeg", "png"], {"default": "jpeg"})
},
"optional": {
"seed": ("INT", {"default": -1})
"seed": ("INT", {"default": -1}),
"config": ("BFL_CONFIG",)
}
}
def generate_image(self, image, mask=None, prompt=None, steps=50, prompt_upsampling=False, guidance=60.0,
safety_tolerance=2, output_format="jpeg", seed=-1):
safety_tolerance=2, output_format="jpeg", seed=-1, config=None):
arguments = {
"image": image,
"steps": steps,
@@ -209,7 +215,7 @@ class FluxProFill(BaseFlux):
if prompt is not None:
arguments["prompt"] = prompt
return super().generate_image("flux-pro-1.0-fill", arguments)
return super().generate_image("flux-pro-1.0-fill", arguments, config)
class FluxProCanny(BaseFlux):
@classmethod
@@ -225,11 +231,12 @@ class FluxProCanny(BaseFlux):
"output_format": (["jpeg", "png"], {"default": "jpeg"})
},
"optional": {
"seed": ("INT", {"default": -1})
"seed": ("INT", {"default": -1}),
"config": ("BFL_CONFIG",)
}
}
def generate_image(self, prompt, control_image, prompt_upsampling, steps, guidance, safety_tolerance, output_format, seed):
def generate_image(self, prompt, control_image, prompt_upsampling, steps, guidance, safety_tolerance, output_format, seed=-1, config=None):
arguments = {
"prompt": prompt,
"control_image": control_image,
@@ -241,7 +248,7 @@ class FluxProCanny(BaseFlux):
}
if seed != -1:
arguments["seed"] = seed
return super().generate_image("flux-pro-1.0-canny", arguments)
return super().generate_image("flux-pro-1.0-canny", arguments, config)
class FluxProDepth(BaseFlux):
@@ -258,11 +265,12 @@ class FluxProDepth(BaseFlux):
"output_format": (["jpeg", "png"], {"default": "jpeg"})
},
"optional": {
"seed": ("INT", {"default": -1})
"seed": ("INT", {"default": -1}),
"config": ("BFL_CONFIG",)
}
}
def generate_image(self, prompt, control_image, prompt_upsampling, steps, guidance, safety_tolerance, output_format, seed):
def generate_image(self, prompt, control_image, prompt_upsampling, steps, guidance, safety_tolerance, output_format, seed=-1, config=None):
arguments = {
"prompt": prompt,
"control_image": control_image,
@@ -274,7 +282,7 @@ class FluxProDepth(BaseFlux):
}
if seed != -1:
arguments["seed"] = seed
return super().generate_image("flux-pro-1.0-depth", arguments)
return super().generate_image("flux-pro-1.0-depth", arguments, config)
class FluxPro11Redux(BaseFlux):
@classmethod
@@ -290,11 +298,12 @@ class FluxPro11Redux(BaseFlux):
"output_format": (["jpeg", "png"], {"default": "jpeg"})
},
"optional": {
"seed": ("INT", {"default": -1})
"seed": ("INT", {"default": -1}),
"config": ("BFL_CONFIG",)
}
}
def generate_image(self, prompt, image_prompt, width, height, prompt_upsampling, safety_tolerance, output_format, seed):
def generate_image(self, prompt, image_prompt, width, height, prompt_upsampling, safety_tolerance, output_format, seed=-1, config=None):
arguments = {
"prompt": prompt,
"image_prompt": image_prompt,
@@ -306,7 +315,7 @@ class FluxPro11Redux(BaseFlux):
}
if seed != -1:
arguments["seed"] = seed
return super().generate_image("flux-pro-1.1", arguments)
return super().generate_image("flux-pro-1.1", arguments, config)
class FluxPro11UltraRedux(BaseFlux):
@classmethod
@@ -322,11 +331,12 @@ class FluxPro11UltraRedux(BaseFlux):
"raw": ("BOOLEAN", {"default": False})
},
"optional": {
"seed": ("INT", {"default": -1})
"seed": ("INT", {"default": -1}),
"config": ("BFL_CONFIG",)
}
}
def generate_image(self, prompt, image_prompt, image_prompt_strength, aspect_ratio, safety_tolerance, output_format, raw, seed):
def generate_image(self, prompt, image_prompt, image_prompt_strength, aspect_ratio, safety_tolerance, output_format, raw, seed=-1, config=None):
arguments = {
"prompt": prompt,
"image_prompt": image_prompt,
@@ -338,7 +348,7 @@ class FluxPro11UltraRedux(BaseFlux):
}
if seed != -1:
arguments["seed"] = seed
return super().generate_image("flux-pro-1.1-ultra", arguments)
return super().generate_image("flux-pro-1.1-ultra", arguments, config)
class FluxKontextPro(BaseFlux):
@classmethod
@@ -353,11 +363,12 @@ class FluxKontextPro(BaseFlux):
"output_format": (["jpeg", "png"], {"default": "jpeg"})
},
"optional": {
"seed": ("INT", {"default": -1})
"seed": ("INT", {"default": -1}),
"config": ("BFL_CONFIG",)
}
}
def generate_image(self, prompt, input_image, aspect_ratio, prompt_upsampling, safety_tolerance, output_format, seed):
def generate_image(self, prompt, input_image, aspect_ratio, prompt_upsampling, safety_tolerance, output_format, seed=-1, config=None):
arguments = {
"prompt": prompt,
"input_image": input_image,
@@ -368,7 +379,7 @@ class FluxKontextPro(BaseFlux):
}
if seed != -1:
arguments["seed"] = seed
return super().generate_image("flux-kontext-pro", arguments)
return super().generate_image("flux-kontext-pro", arguments, config)
class FluxKontextMax(BaseFlux):
@classmethod
@@ -383,11 +394,12 @@ class FluxKontextMax(BaseFlux):
"output_format": (["jpeg", "png"], {"default": "jpeg"})
},
"optional": {
"seed": ("INT", {"default": -1})
"seed": ("INT", {"default": -1}),
"config": ("BFL_CONFIG",)
}
}
def generate_image(self, prompt, input_image, aspect_ratio, prompt_upsampling, safety_tolerance, output_format, seed):
def generate_image(self, prompt, input_image, aspect_ratio, prompt_upsampling, safety_tolerance, output_format, seed=-1, config=None):
arguments = {
"prompt": prompt,
"input_image": input_image,
@@ -398,7 +410,7 @@ class FluxKontextMax(BaseFlux):
}
if seed != -1:
arguments["seed"] = seed
return super().generate_image("flux-kontext-max", arguments)
return super().generate_image("flux-kontext-max", arguments, config)
NODE_CLASS_MAPPINGS = {
"FluxPro_BFL": FluxPro,
+17 -9
View File
@@ -7,6 +7,7 @@ import os
import time
from .status import Status
from .config import config_loader
from .config_node import get_config_loader
class BaseFlux:
RETURN_TYPES = ("IMAGE",)
@@ -44,9 +45,13 @@ class BaseFlux:
if width % 32 != 0 or height % 32 != 0:
raise ValueError(f"Width {width} and height {height} must be multiples of 32.")
def post_request(self, url_path, arguments):
post_url = config_loader.create_url(url_path)
headers = {"x-key": os.environ["X_KEY"]}
def post_request(self, url_path, arguments, config_override=None):
# Use ConfigLoader with optional config override
config_loader_instance = get_config_loader(config_override)
config_loader_instance.set_x_key() # Ensure X_KEY is set in environment
post_url = config_loader_instance.create_url(url_path)
headers = {"x-key": config_loader_instance.get_x_key()}
response = requests.post(post_url, json=arguments, headers=headers)
if response.status_code == 200:
@@ -55,9 +60,12 @@ class BaseFlux:
print(f"Error initiating request: {response.status_code}, {response.text}")
return None
def get_result(self, task_id, output_format="jpeg", max_attempts=20):
headers = {"x-key": os.environ["X_KEY"]}
get_url = config_loader.create_url(f"get_result?id={task_id}")
def get_result(self, task_id, output_format="jpeg", max_attempts=20, config_override=None):
# Use ConfigLoader with optional config override
config_loader_instance = get_config_loader(config_override)
headers = {"x-key": config_loader_instance.get_x_key()}
get_url = config_loader_instance.create_url(f"get_result?id={task_id}")
attempt = 1
while attempt <= max_attempts:
@@ -104,15 +112,15 @@ class BaseFlux:
print(f"All attempts exhausted for task_id {task_id}. Returning blank image.")
return self.create_blank_image()
def generate_image(self, url_path, arguments):
def generate_image(self, url_path, arguments, config_override=None):
if "width" in arguments and "height" in arguments:
self.check_multiple_of_32(arguments["width"], arguments["height"])
try:
task_id = self.post_request(url_path, arguments)
task_id = self.post_request(url_path, arguments, config_override)
if task_id:
print(f"Task ID '{task_id}'")
return self.get_result(task_id, output_format=arguments.get("output_format", "jpeg"))
return self.get_result(task_id, output_format=arguments.get("output_format", "jpeg"), config_override=config_override)
return self.create_blank_image()
except Exception as e:
print(f"Error generating image: {str(e)}")
+28 -1
View File
@@ -3,7 +3,16 @@ import configparser
from urllib.parse import urljoin
class ConfigLoader:
def __init__(self):
def __init__(self, config_override=None):
"""
Initialize ConfigLoader with optional config override.
Args:
config_override: Optional dict with config values to override file-based config
"""
self.config_override = config_override
# Load file-based config
current_dir = os.path.dirname(os.path.abspath(__file__))
parent_dir = os.path.dirname(current_dir)
config_path = os.path.join(parent_dir, "config.ini")
@@ -18,6 +27,15 @@ class ConfigLoader:
}
def get_key(self, section, key):
"""Get a config value, preferring override over file config."""
# Check for override values first
if self.config_override:
if section == 'API' and key == 'X_KEY' and self.config_override.get('x_key'):
return self.config_override['x_key']
elif section == 'API' and key == 'BASE_URL' and self.config_override.get('base_url'):
return self.config_override['base_url']
# Fall back to file config
try:
return self.config[section][key]
except KeyError:
@@ -33,6 +51,10 @@ class ConfigLoader:
If provided, uses regional endpoint instead of global
"""
try:
# Use region from config override if available and region not explicitly provided
if not region and self.config_override and self.config_override.get("default_region"):
region = self.config_override["default_region"]
if region and region in self.regional_endpoints:
base_url = self.regional_endpoints[region]
return urljoin(base_url, f"/v1/{path}")
@@ -49,11 +71,16 @@ class ConfigLoader:
return self.regional_endpoints[region]
def set_x_key(self):
"""Set the X_KEY environment variable from config or override."""
try:
x_key = self.get_key('API', 'X_KEY')
os.environ["X_KEY"] = x_key
except KeyError as e:
print(f"Error: {str(e)}")
def get_x_key(self):
"""Get the API key directly without setting environment variable."""
return self.get_key('API', 'X_KEY')
# Create a singleton instance to be shared across modules
config_loader = ConfigLoader()
+77
View File
@@ -0,0 +1,77 @@
from .config import ConfigLoader
class FluxConfig_BFL:
"""
Configuration node for BFL API settings.
Provides optional configuration that can be connected to other nodes.
If not connected, nodes will use the default file-based configuration.
"""
@classmethod
def INPUT_TYPES(cls):
return {
"required": {
"x_key": ("STRING", {
"default": "",
"multiline": False,
"placeholder": "Enter your BFL API key"
}),
"base_url": ("STRING", {
"default": "https://api.bfl.ml/v1/",
"multiline": False,
"placeholder": "Base API URL"
}),
},
"optional": {
"region": (["none", "us", "eu"], {
"default": "none",
"tooltip": "Regional endpoint for finetuning operations"
})
}
}
RETURN_TYPES = ("BFL_CONFIG",)
RETURN_NAMES = ("config",)
FUNCTION = "create_config"
CATEGORY = "BFL/Config"
def create_config(self, x_key, base_url, region="none"):
"""Create a configuration object with the provided settings."""
# Regional endpoints for finetuning (required by BFL API)
regional_endpoints = {
"us": "https://api.us1.bfl.ai",
"eu": "https://api.eu1.bfl.ai"
}
config = {
"x_key": x_key.strip() if x_key.strip() else None,
"base_url": base_url.strip() if base_url.strip() else "https://api.bfl.ml/v1/",
"regional_endpoints": regional_endpoints,
"default_region": region if region != "none" else None
}
return (config,)
def get_config_loader(config_override=None):
"""
Get a ConfigLoader instance with optional config override.
Args:
config_override: Optional config dict from FluxConfig_BFL node
Returns:
ConfigLoader instance
"""
return ConfigLoader(config_override)
# Node mappings for ComfyUI
NODE_CLASS_MAPPINGS = {
"FluxConfig_BFL": FluxConfig_BFL,
}
NODE_DISPLAY_NAME_MAPPINGS = {
"FluxConfig_BFL": "Flux Config (BFL)",
}
+37 -24
View File
@@ -4,6 +4,7 @@ import json
import base64
from .base import BaseFinetuneFlux
from .config import config_loader
from .config_node import get_config_loader
class FluxFinetune:
RETURN_TYPES = ("STRING",)
@@ -310,13 +311,14 @@ class FluxProFinetune(BaseFinetuneFlux):
"image_prompt": ("STRING", {"default": ""}),
"seed": ("INT", {"default": -1}),
"webhook_url": ("STRING", {"default": ""}),
"webhook_secret": ("STRING", {"default": ""})
"webhook_secret": ("STRING", {"default": ""}),
"config": ("BFL_CONFIG",)
}
}
def generate_image(self, finetune_id, region, prompt, finetune_strength, steps, guidance, width, height,
prompt_upsampling, safety_tolerance, output_format, image_prompt="", seed=-1,
webhook_url="", webhook_secret=""):
webhook_url="", webhook_secret="", config=None):
arguments = {
"finetune_id": finetune_id,
"prompt": prompt,
@@ -339,23 +341,27 @@ class FluxProFinetune(BaseFinetuneFlux):
if webhook_secret:
arguments["webhook_secret"] = webhook_secret
return self.generate_regional_image("flux-pro-finetuned", arguments, region)
return self.generate_regional_image("flux-pro-finetuned", arguments, region, config)
def generate_regional_image(self, endpoint, arguments, region):
def generate_regional_image(self, endpoint, arguments, region, config_override=None):
if "width" in arguments and "height" in arguments:
self.check_multiple_of_32(arguments["width"], arguments["height"])
try:
post_url = config_loader.create_url(endpoint, region=region)
headers = {"x-key": os.environ["X_KEY"]}
# Use ConfigLoader with optional config override
config_loader_instance = get_config_loader(config_override)
config_loader_instance.set_x_key() # Ensure X_KEY is set in environment
post_url = config_loader_instance.create_url(endpoint, region=region)
headers = {"x-key": config_loader_instance.get_x_key()}
response = requests.post(post_url, json=arguments, headers=headers)
if response.status_code == 200:
task_id = response.json().get("id")
if task_id:
regional_endpoint = config_loader.get_regional_endpoint(region)
regional_endpoint = config_loader_instance.get_regional_endpoint(region)
print(f"Finetune Task ID '{task_id}' (Region: {region.upper()} - {regional_endpoint})")
return self.get_result(task_id, output_format=arguments.get("output_format", "jpeg"))
return self.get_result(task_id, output_format=arguments.get("output_format", "jpeg"), config_override=config_override)
else:
print(f"Error initiating regional finetune request: {response.status_code}, {response.text}")
return self.create_blank_image()
@@ -381,12 +387,13 @@ class FluxProDepthFinetune(BaseFinetuneFlux):
"optional": {
"seed": ("INT", {"default": -1}),
"webhook_url": ("STRING", {"default": ""}),
"webhook_secret": ("STRING", {"default": ""})
"webhook_secret": ("STRING", {"default": ""}),
"config": ("BFL_CONFIG",)
}
}
def generate_image(self, finetune_id, prompt, control_image, finetune_strength, prompt_upsampling,
steps, output_format, guidance, safety_tolerance, seed=-1, webhook_url="", webhook_secret=""):
steps, output_format, guidance, safety_tolerance, seed=-1, webhook_url="", webhook_secret="", config=None):
arguments = {
"finetune_id": finetune_id,
"prompt": prompt,
@@ -406,7 +413,7 @@ class FluxProDepthFinetune(BaseFinetuneFlux):
if webhook_secret:
arguments["webhook_secret"] = webhook_secret
return super().generate_image("flux-pro-1.0-depth-finetuned", arguments)
return super().generate_image("flux-pro-1.0-depth-finetuned", arguments, config)
class FluxProCannyFinetune(BaseFinetuneFlux):
@classmethod
@@ -428,13 +435,14 @@ class FluxProCannyFinetune(BaseFinetuneFlux):
"optional": {
"seed": ("INT", {"default": -1}),
"webhook_url": ("STRING", {"default": ""}),
"webhook_secret": ("STRING", {"default": ""})
"webhook_secret": ("STRING", {"default": ""}),
"config": ("BFL_CONFIG",)
}
}
def generate_image(self, finetune_id, prompt, control_image, finetune_strength, canny_low_threshold,
canny_high_threshold, prompt_upsampling, steps, output_format, guidance, safety_tolerance,
seed=-1, webhook_url="", webhook_secret=""):
seed=-1, webhook_url="", webhook_secret="", config=None):
arguments = {
"finetune_id": finetune_id,
"prompt": prompt,
@@ -456,7 +464,7 @@ class FluxProCannyFinetune(BaseFinetuneFlux):
if webhook_secret:
arguments["webhook_secret"] = webhook_secret
return super().generate_image("flux-pro-1.0-canny-finetuned", arguments)
return super().generate_image("flux-pro-1.0-canny-finetuned", arguments, config)
class FluxProFillFinetune(BaseFinetuneFlux):
@classmethod
@@ -482,7 +490,7 @@ class FluxProFillFinetune(BaseFinetuneFlux):
}
def generate_image(self, finetune_id, image, finetune_strength, steps, prompt_upsampling, guidance,
safety_tolerance, output_format, mask="", prompt="", seed=-1, webhook_url="", webhook_secret=""):
safety_tolerance, output_format, mask="", prompt="", seed=-1, webhook_url="", webhook_secret="", config=None):
arguments = {
"finetune_id": finetune_id,
"image": image,
@@ -505,7 +513,7 @@ class FluxProFillFinetune(BaseFinetuneFlux):
if webhook_secret:
arguments["webhook_secret"] = webhook_secret
return super().generate_image("flux-pro-1.0-fill-finetuned", arguments)
return super().generate_image("flux-pro-1.0-fill-finetuned", arguments, config)
class FluxPro11UltraFinetune(BaseFinetuneFlux):
@classmethod
@@ -524,12 +532,13 @@ class FluxPro11UltraFinetune(BaseFinetuneFlux):
"optional": {
"seed": ("INT", {"default": -1}),
"webhook_url": ("STRING", {"default": ""}),
"webhook_secret": ("STRING", {"default": ""})
"webhook_secret": ("STRING", {"default": ""}),
"config": ("BFL_CONFIG",)
}
}
def generate_image(self, finetune_id, region, prompt, finetune_strength, aspect_ratio, safety_tolerance,
output_format, raw, seed=-1, webhook_url="", webhook_secret=""):
output_format, raw, seed=-1, webhook_url="", webhook_secret="", config=None):
arguments = {
"finetune_id": finetune_id,
"prompt": prompt,
@@ -547,20 +556,24 @@ class FluxPro11UltraFinetune(BaseFinetuneFlux):
if webhook_secret:
arguments["webhook_secret"] = webhook_secret
return self.generate_regional_image("flux-pro-1.1-ultra-finetuned", arguments, region)
return self.generate_regional_image("flux-pro-1.1-ultra-finetuned", arguments, region, config)
def generate_regional_image(self, endpoint, arguments, region):
def generate_regional_image(self, endpoint, arguments, region, config_override=None):
try:
post_url = config_loader.create_url(endpoint, region=region)
headers = {"x-key": os.environ["X_KEY"]}
# Use ConfigLoader with optional config override
config_loader_instance = get_config_loader(config_override)
config_loader_instance.set_x_key() # Ensure X_KEY is set in environment
post_url = config_loader_instance.create_url(endpoint, region=region)
headers = {"x-key": config_loader_instance.get_x_key()}
response = requests.post(post_url, json=arguments, headers=headers)
if response.status_code == 200:
task_id = response.json().get("id")
if task_id:
regional_endpoint = config_loader.get_regional_endpoint(region)
regional_endpoint = config_loader_instance.get_regional_endpoint(region)
print(f"Finetune Task ID '{task_id}' (Region: {region.upper()} - {regional_endpoint})")
return self.get_result(task_id, output_format=arguments.get("output_format", "jpeg"))
return self.get_result(task_id, output_format=arguments.get("output_format", "jpeg"), config_override=config_override)
else:
print(f"Error initiating regional finetune request: {response.status_code}, {response.text}")
return self.create_blank_image()
+212 -211
View File
@@ -1,21 +1,23 @@
{
"last_node_id": 19,
"last_link_id": 10,
"id": "da553514-59db-4d0f-ab66-b010a0ba3a55",
"revision": 0,
"last_node_id": 20,
"last_link_id": 13,
"nodes": [
{
"id": 8,
"type": "PreviewImage",
"pos": {
"0": 1331.552978515625,
"1": 215.39434814453125
},
"size": {
"0": 210,
"1": 246
},
"pos": [
1331.552978515625,
215.39434814453125
],
"size": [
210,
246
],
"flags": {},
"order": 5,
"mode": 2,
"order": 4,
"mode": 4,
"inputs": [
{
"name": "images",
@@ -25,6 +27,8 @@
],
"outputs": [],
"properties": {
"cnr_id": "comfy-core",
"ver": "0.3.49",
"Node name for S&R": "PreviewImage"
},
"widgets_values": []
@@ -32,27 +36,33 @@
{
"id": 7,
"type": "FluxPro11_BFL",
"pos": {
"0": 711.2532958984375,
"1": 215.6094970703125
},
"size": {
"0": 400,
"1": 244
},
"pos": [
711.2532958984375,
215.6094970703125
],
"size": [
400,
256
],
"flags": {},
"order": 1,
"mode": 2,
"inputs": [],
"order": 0,
"mode": 4,
"inputs": [
{
"name": "config",
"shape": 7,
"type": "BFL_CONFIG",
"link": null
}
],
"outputs": [
{
"name": "IMAGE",
"type": "IMAGE",
"slot_index": 0,
"links": [
5
],
"slot_index": 0,
"shape": 3
]
}
],
"properties": {
@@ -65,72 +75,40 @@
false,
2,
"png",
1259,
"randomize"
]
},
{
"id": 19,
"type": "FluxPro11Ultra_BFL",
"pos": {
"0": 719.71240234375,
"1": -135.97286987304688
},
"size": {
"0": 400,
"1": 220
},
"flags": {},
"order": 3,
"mode": 0,
"inputs": [],
"outputs": [
{
"name": "IMAGE",
"type": "IMAGE",
"links": [
10
],
"slot_index": 0
}
],
"properties": {
"Node name for S&R": "FluxPro11Ultra_BFL"
},
"widgets_values": [
"istanbul hagia sophia",
"16:9",
2,
"jpeg",
true,
675,
955,
"randomize"
]
},
{
"id": 11,
"type": "FluxPro_BFL",
"pos": {
"0": 710.218994140625,
"1": 561.643798828125
},
"size": {
"0": 400,
"1": 316
},
"pos": [
710.218994140625,
561.643798828125
],
"size": [
400,
328
],
"flags": {},
"order": 2,
"mode": 2,
"inputs": [],
"order": 1,
"mode": 4,
"inputs": [
{
"name": "config",
"shape": 7,
"type": "BFL_CONFIG",
"link": null
}
],
"outputs": [
{
"name": "IMAGE",
"type": "IMAGE",
"slot_index": 0,
"links": [
7
],
"slot_index": 0,
"shape": 3
]
}
],
"properties": {
@@ -153,27 +131,33 @@
{
"id": 9,
"type": "FluxDev_BFL",
"pos": {
"0": 710.954833984375,
"1": 976.184814453125
},
"size": {
"0": 400,
"1": 292
},
"pos": [
710.954833984375,
976.184814453125
],
"size": [
400,
304
],
"flags": {},
"order": 0,
"mode": 2,
"inputs": [],
"order": 2,
"mode": 4,
"inputs": [
{
"name": "config",
"shape": 7,
"type": "BFL_CONFIG",
"link": null
}
],
"outputs": [
{
"name": "IMAGE",
"type": "IMAGE",
"slot_index": 0,
"links": [
6
],
"slot_index": 0,
"shape": 3
]
}
],
"properties": {
@@ -188,24 +172,24 @@
"2",
3,
884,
42,
737,
"randomize"
]
},
{
"id": 10,
"type": "PreviewImage",
"pos": {
"0": 1335,
"1": 977
},
"size": {
"0": 210,
"1": 246
},
"pos": [
1335,
977
],
"size": [
210,
246
],
"flags": {},
"order": 4,
"mode": 2,
"order": 6,
"mode": 4,
"inputs": [
{
"name": "images",
@@ -215,6 +199,8 @@
],
"outputs": [],
"properties": {
"cnr_id": "comfy-core",
"ver": "0.3.49",
"Node name for S&R": "PreviewImage"
},
"widgets_values": []
@@ -222,17 +208,17 @@
{
"id": 12,
"type": "PreviewImage",
"pos": {
"0": 1333,
"1": 562
},
"size": {
"0": 210,
"1": 246
},
"pos": [
1333,
562
],
"size": [
210,
246
],
"flags": {},
"order": 6,
"mode": 2,
"order": 5,
"mode": 4,
"inputs": [
{
"name": "images",
@@ -242,24 +228,104 @@
],
"outputs": [],
"properties": {
"cnr_id": "comfy-core",
"ver": "0.3.49",
"Node name for S&R": "PreviewImage"
},
"widgets_values": []
},
{
"id": 14,
"type": "PreviewImage",
"pos": {
"0": 1333,
"1": -137.97286987304688
},
"size": {
"0": 210,
"1": 246
"id": 20,
"type": "FluxConfig_BFL",
"pos": [
717.29052734375,
-134.6406707763672
],
"size": [
270,
106
],
"flags": {},
"order": 3,
"mode": 0,
"inputs": [],
"outputs": [
{
"name": "config",
"type": "BFL_CONFIG",
"links": [
13
]
}
],
"properties": {
"Node name for S&R": "FluxConfig_BFL"
},
"widgets_values": [
"x-key",
"https://api.bfl.ml/v1/",
"none"
]
},
{
"id": 19,
"type": "FluxPro11Ultra_BFL",
"pos": [
1012.481689453125,
-136.26632690429688
],
"size": [
400,
232
],
"flags": {},
"order": 7,
"mode": 0,
"inputs": [
{
"name": "config",
"shape": 7,
"type": "BFL_CONFIG",
"link": 13
}
],
"outputs": [
{
"name": "IMAGE",
"type": "IMAGE",
"slot_index": 0,
"links": [
10
]
}
],
"properties": {
"Node name for S&R": "FluxPro11Ultra_BFL"
},
"widgets_values": [
"istanbul hagia sophia",
"16:9",
2,
"jpeg",
true,
980,
"randomize"
]
},
{
"id": 14,
"type": "PreviewImage",
"pos": [
1434.077392578125,
-139.47886657714844
],
"size": [
210,
246
],
"flags": {},
"order": 8,
"mode": 0,
"inputs": [
{
"name": "images",
@@ -269,6 +335,8 @@
],
"outputs": [],
"properties": {
"cnr_id": "comfy-core",
"ver": "0.3.49",
"Node name for S&R": "PreviewImage"
},
"widgets_values": []
@@ -306,22 +374,32 @@
14,
0,
"IMAGE"
],
[
13,
20,
0,
19,
0,
"BFL_CONFIG"
]
],
"groups": [
{
"id": 1,
"title": "Flux Pro 1.1 Ultra",
"bounding": [
702,
-227,
857,
354
707.29052734375,
-213.07887268066406,
946.786865234375,
329.6000061035156
],
"color": "#3f789e",
"font_size": 24,
"flags": {}
},
{
"id": 2,
"title": "Flux Pro",
"bounding": [
700,
@@ -334,6 +412,7 @@
"flags": {}
},
{
"id": 3,
"title": "Flux Dev",
"bounding": [
702,
@@ -346,6 +425,7 @@
"flags": {}
},
{
"id": 4,
"title": "Flux Pro 1.1",
"bounding": [
701,
@@ -361,93 +441,14 @@
"config": {},
"extra": {
"ds": {
"scale": 0.6727499949325623,
"scale": 0.6727499949325617,
"offset": [
95.41390143669695,
214.70408909184692
401.3714466821817,
784.6786514326493
]
},
"groupNodes": {
"Flux Pro 1.1 Ultra": {
"nodes": [
{
"id": -1,
"type": "FluxPro11Ultra_BFL",
"pos": {
"0": 715,
"1": -85
},
"size": {
"0": 400,
"1": 220
},
"flags": {},
"order": 3,
"mode": 0,
"inputs": [],
"outputs": [
{
"name": "IMAGE",
"type": "IMAGE",
"links": [],
"slot_index": 0
}
],
"properties": {
"Node name for S&R": "FluxPro11Ultra_BFL"
},
"widgets_values": [
"",
"16:9",
2,
"jpeg",
false,
42,
"randomize"
],
"index": 0
},
{
"id": -1,
"type": "PreviewImage",
"pos": {
"0": 1360,
"1": -80
},
"size": {
"0": 210,
"1": 26
},
"flags": {},
"order": 7,
"mode": 0,
"inputs": [
{
"name": "images",
"type": "IMAGE",
"link": null
}
],
"outputs": [],
"properties": {
"Node name for S&R": "PreviewImage"
},
"index": 1
}
],
"links": [
[
0,
0,
1,
0,
13,
"IMAGE"
]
],
"external": []
}
}
"groupNodes": {},
"frontendVersion": "1.24.4"
},
"version": 0.4
}