Skip to content

Commit aeba0b3

Browse files
authored
Reduce code duplication for [pro] and [max], rename Pro and Max to [pro] and [max] to be consistent with other BFL nodes, make default seed for Kontext nodes be 1234. since 0 is interpreted by API as 'choose random seed' (#8337)
1 parent 094306b commit aeba0b3

File tree

2 files changed

+12
-157
lines changed

2 files changed

+12
-157
lines changed

comfy_api_nodes/apis/bfl_api.py

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -125,22 +125,6 @@ class BFLFluxKontextProGenerateRequest(BaseModel):
125125
None, description='Whether to perform upsampling on the prompt. If active, automatically modifies the prompt for more creative generation.'
126126
)
127127

128-
class BFLFluxKontextMaxGenerateRequest(BaseModel):
129-
prompt: str = Field(..., description='The text prompt for what you wannt to edit.')
130-
input_image: Optional[str] = Field(None, description='Image to edit in base64 format')
131-
seed: Optional[int] = Field(None, description='The seed value for reproducibility.')
132-
guidance: confloat(ge=0.1, le=99.0) = Field(..., description='Guidance strength for the image generation process')
133-
steps: conint(ge=1, le=150) = Field(..., description='Number of steps for the image generation process')
134-
safety_tolerance: Optional[conint(ge=0, le=2)] = Field(
135-
2, description='Tolerance level for input and output moderation. Between 0 and 2, 0 being most strict, 6 being least strict. Defaults to 2.'
136-
)
137-
output_format: Optional[BFLOutputFormat] = Field(
138-
BFLOutputFormat.png, description="Output format for the generated image. Can be 'jpeg' or 'png'.", examples=['png']
139-
)
140-
aspect_ratio: Optional[str] = Field(None, description='Aspect ratio of the image between 21:9 and 9:21.')
141-
prompt_upsampling: Optional[bool] = Field(
142-
None, description='Whether to perform upsampling on the prompt. If active, automatically modifies the prompt for more creative generation.'
143-
)
144128

145129
class BFLFluxProUltraGenerateRequest(BaseModel):
146130
prompt: str = Field(..., description='The text prompt for image generation.')

comfy_api_nodes/nodes_bfl.py

Lines changed: 12 additions & 141 deletions
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,7 @@ def api_call(
272272

273273
class FluxKontextProImageNode(ComfyNodeABC):
274274
"""
275-
Edits images using Flux.1 Kontext Pro via api based on prompt and resolution.
275+
Edits images using Flux.1 Kontext [pro] via api based on prompt and aspect ratio.
276276
"""
277277

278278
MINIMUM_RATIO = 1 / 4
@@ -321,7 +321,7 @@ def INPUT_TYPES(s):
321321
"seed": (
322322
IO.INT,
323323
{
324-
"default": 0,
324+
"default": 1234,
325325
"min": 0,
326326
"max": 0xFFFFFFFFFFFFFFFF,
327327
"control_after_generate": True,
@@ -366,6 +366,8 @@ def VALIDATE_INPUTS(cls, aspect_ratio: str):
366366
API_NODE = True
367367
CATEGORY = "api node/image/BFL"
368368

369+
BFL_PATH = "/proxy/bfl/flux-kontext-pro/generate"
370+
369371
def api_call(
370372
self,
371373
prompt: str,
@@ -382,7 +384,7 @@ def api_call(
382384
validate_string(prompt, strip_whitespace=False)
383385
operation = SynchronousOperation(
384386
endpoint=ApiEndpoint(
385-
path="/proxy/bfl/flux-kontext-pro/generate",
387+
path=self.BFL_PATH,
386388
method=HttpMethod.POST,
387389
request_model=BFLFluxKontextProGenerateRequest,
388390
response_model=BFLFluxProGenerateResponse,
@@ -411,146 +413,15 @@ def api_call(
411413
output_image = handle_bfl_synchronous_operation(operation, node_id=unique_id)
412414
return (output_image,)
413415

414-
class FluxKontextMaxImageNode(ComfyNodeABC):
416+
417+
class FluxKontextMaxImageNode(FluxKontextProImageNode):
415418
"""
416-
Edits images using Flux.1 Kontext Max via api based on prompt and resolution.
419+
Edits images using Flux.1 Kontext [max] via api based on prompt and aspect ratio.
417420
"""
418421

419-
MINIMUM_RATIO = 1 / 4
420-
MAXIMUM_RATIO = 4 / 1
421-
MINIMUM_RATIO_STR = "1:4"
422-
MAXIMUM_RATIO_STR = "4:1"
423-
424-
@classmethod
425-
def INPUT_TYPES(s):
426-
return {
427-
"required": {
428-
"prompt": (
429-
IO.STRING,
430-
{
431-
"multiline": True,
432-
"default": "",
433-
"tooltip": "Prompt for the image generation - specify what and how to edit.",
434-
},
435-
),
436-
"aspect_ratio": (
437-
IO.STRING,
438-
{
439-
"default": "16:9",
440-
"tooltip": "Aspect ratio of image; must be between 1:4 and 4:1.",
441-
},
442-
),
443-
"guidance": (
444-
IO.FLOAT,
445-
{
446-
"default": 3.0,
447-
"min": 0.1,
448-
"max": 99.0,
449-
"step": 0.1,
450-
"tooltip": "Guidance strength for the image generation process"
451-
},
452-
),
453-
"steps": (
454-
IO.INT,
455-
{
456-
"default": 50,
457-
"min": 1,
458-
"max": 150,
459-
"tooltip": "Number of steps for the image generation process"
460-
},
461-
),
462-
"seed": (
463-
IO.INT,
464-
{
465-
"default": 0,
466-
"min": 0,
467-
"max": 0xFFFFFFFFFFFFFFFF,
468-
"control_after_generate": True,
469-
"tooltip": "The random seed used for creating the noise.",
470-
},
471-
),
472-
"prompt_upsampling": (
473-
IO.BOOLEAN,
474-
{
475-
"default": False,
476-
"tooltip": "Whether to perform upsampling on the prompt. If active, automatically modifies the prompt for more creative generation, but results are nondeterministic (same seed will not produce exactly the same result).",
477-
},
478-
),
479-
},
480-
"optional": {
481-
"input_image": (IO.IMAGE,),
482-
},
483-
"hidden": {
484-
"auth_token": "AUTH_TOKEN_COMFY_ORG",
485-
"comfy_api_key": "API_KEY_COMFY_ORG",
486-
"unique_id": "UNIQUE_ID",
487-
},
488-
}
489-
490-
@classmethod
491-
def VALIDATE_INPUTS(cls, aspect_ratio: str):
492-
try:
493-
validate_aspect_ratio(
494-
aspect_ratio,
495-
minimum_ratio=cls.MINIMUM_RATIO,
496-
maximum_ratio=cls.MAXIMUM_RATIO,
497-
minimum_ratio_str=cls.MINIMUM_RATIO_STR,
498-
maximum_ratio_str=cls.MAXIMUM_RATIO_STR,
499-
)
500-
except Exception as e:
501-
return str(e)
502-
return True
503-
504-
RETURN_TYPES = (IO.IMAGE,)
505-
DESCRIPTION = cleandoc(__doc__ or "") # Handle potential None value
506-
FUNCTION = "api_call"
507-
API_NODE = True
508-
CATEGORY = "api node/image/BFL"
422+
DESCRIPTION = cleandoc(__doc__ or "")
423+
BFL_PATH = "/proxy/bfl/flux-kontext-max/generate"
509424

510-
def api_call(
511-
self,
512-
prompt: str,
513-
aspect_ratio: str,
514-
guidance: float,
515-
steps: int,
516-
input_image: Optional[torch.Tensor]=None,
517-
seed=0,
518-
prompt_upsampling=False,
519-
unique_id: Union[str, None] = None,
520-
**kwargs,
521-
):
522-
if input_image is None:
523-
validate_string(prompt, strip_whitespace=False)
524-
operation = SynchronousOperation(
525-
endpoint=ApiEndpoint(
526-
path="/proxy/bfl/flux-kontext-max/generate",
527-
method=HttpMethod.POST,
528-
request_model=BFLFluxKontextProGenerateRequest,
529-
response_model=BFLFluxProGenerateResponse,
530-
),
531-
request=BFLFluxKontextProGenerateRequest(
532-
prompt=prompt,
533-
prompt_upsampling=prompt_upsampling,
534-
guidance=round(guidance, 1),
535-
steps=steps,
536-
seed=seed,
537-
aspect_ratio=validate_aspect_ratio(
538-
aspect_ratio,
539-
minimum_ratio=self.MINIMUM_RATIO,
540-
maximum_ratio=self.MAXIMUM_RATIO,
541-
minimum_ratio_str=self.MINIMUM_RATIO_STR,
542-
maximum_ratio_str=self.MAXIMUM_RATIO_STR,
543-
),
544-
input_image=(
545-
input_image
546-
if input_image is None
547-
else convert_image_to_base64(input_image)
548-
)
549-
),
550-
auth_kwargs=kwargs,
551-
)
552-
output_image = handle_bfl_synchronous_operation(operation, node_id=unique_id)
553-
return (output_image,)
554425

555426
class FluxProImageNode(ComfyNodeABC):
556427
"""
@@ -1208,8 +1079,8 @@ def api_call(
12081079
NODE_DISPLAY_NAME_MAPPINGS = {
12091080
"FluxProUltraImageNode": "Flux 1.1 [pro] Ultra Image",
12101081
# "FluxProImageNode": "Flux 1.1 [pro] Image",
1211-
"FluxKontextProImageNode": "Flux.1 Kontext Pro Image",
1212-
"FluxKontextMaxImageNode": "Flux.1 Kontext Max Image",
1082+
"FluxKontextProImageNode": "Flux.1 Kontext [pro] Image",
1083+
"FluxKontextMaxImageNode": "Flux.1 Kontext [max] Image",
12131084
"FluxProExpandNode": "Flux.1 Expand Image",
12141085
"FluxProFillNode": "Flux.1 Fill Image",
12151086
"FluxProCannyNode": "Flux.1 Canny Control Image",

0 commit comments

Comments
 (0)