o
    ipb                     @   s4  d dl Z d dlmZ d dlmZ d dlmZmZmZ d dl	m
Z
mZmZmZmZmZmZmZ d dlmZmZmZmZmZmZmZmZmZ dejfdd	ZG d
d dejZG dd dejZ G dd de Z!G dd dejZ"G dd dejZ#G dd dejZ$G dd de$Z%G dd deZ&de&fddZ'dS )    N)	BaseModel)override)IOComfyExtensionInput)BFLFluxExpandImageRequestBFLFluxFillImageRequest BFLFluxKontextProGenerateRequestBFLFluxProGenerateResponseBFLFluxProUltraGenerateRequestBFLFluxStatusResponse	BFLStatusFlux2ProGenerateRequest)	ApiEndpointdownload_url_to_image_tensorget_number_of_imagespoll_opresize_mask_to_imagesync_optensor_to_base64_stringvalidate_aspect_ratio_stringvalidate_stringmaskc                 C   s"   |  d} tj| gd dd} | S )zg
    Make mask have the expected amount of dims (4) and channels (3) to be recognized as an image.
       )dim)	unsqueezetorchcat)r    r   7/mnt/c/Users/fbmor/ComfyUI/comfy_api_nodes/nodes_bfl.pyconvert_mask_to_image   s   
r!   c                   @   st   e Zd ZedejfddZedefddZe						
ddedede	de	de
dejd	B dedejfddZd	S )FluxProUltraImageNodereturnc                 C   s   t jddddt jjddddd	t jjd
ddddt jjdddddddt jjddddt jjddddt jjdddt jjdddddd dd!gt j gt j	j
t j	jt j	jgdt jd"d#d$	S )%Nr"   zFlux 1.1 [pro] Ultra Imageapi node/image/BFLzQGenerates images using Flux Pro 1.1 Ultra via api based on prompt and resolution.promptT Prompt for the image generation	multilinedefaulttooltipprompt_upsamplingFWhether 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).r*   r+   advancedseedr       ,The random seed used for creating the noise.r*   minmaxcontrol_after_generater+   aspect_ratio16:93Aspect ratio of image; must be between 1:4 and 4:1.r*   r+   rawz@When True, generate less processed, more natural-looking images.image_promptoptionalimage_prompt_strength皙?g        g      ?g{Gz?z.Blend between the prompt and the image prompt.)r*   r4   r5   stepr+   r>   z{"type":"usd","usd":0.06}expr	node_iddisplay_namecategorydescriptioninputsoutputshiddenis_api_nodeprice_badge)r   SchemaStringr   BooleanIntImageFloatOutputHiddenauth_token_comfy_orgapi_key_comfy_org	unique_id
PriceBadgeclsr   r   r    define_schema(   sv   
/z#FluxProUltraImageNode.define_schemar7   c                 C   s   t |dd dS )N      r_   r^   T)r   )r[   r7   r   r   r    validate_inputsj   s   z%FluxProUltraImageNode.validate_inputsFr   Nr@   r%   r,   r;   r0   r<   r?   c           
         s   |d u rt |dd t| tdddtt||||||d u r|nt||d u r(d nt|dddI d H }t| t|jt	d	d
 dd
 t
jgt
jt
jt
jt
jgg dI d H }	tt|	jd I d H S )NFstrip_whitespacez&/proxy/bfl/flux-pro-1.1-ultra/generatePOSTpathmethod   )r%   r,   r0   r7   r;   r<   r?   response_modeldatac                 S      | j S Nstatusrr   r   r    <lambda>       z/FluxProUltraImageNode.execute.<locals>.<lambda>c                 S   rl   rm   progressrp   r   r   r    rr      rs   rj   status_extractorprogress_extractorcompleted_statusesfailed_statusesqueued_statusessample)r   r   r   r
   r   r   roundr   polling_urlr   r   readyrequest_moderatedcontent_moderatederrortask_not_foundr   
NodeOutputr   result)
r[   r%   r7   r,   r;   r0   r<   r?   initial_responseresponser   r   r    executeo   s@   
zFluxProUltraImageNode.execute)FFr   Nr@   )__name__
__module____qualname__classmethodr   rN   r\   strra   boolintr   rR   floatr   r   r   r   r   r    r"   &   s8    A	r"   c                   @   sb   e Zd ZedejfddZdZd ZdZ	e			dd	e
d
e
dededejdB dejfddZdS )FluxKontextProImageNoder#   c                 C   s   t j| j| jddt jjdddddt jjdd	d
dt jjdddddddt jjddddddt jjdddddddt jjddd dd!t j	jd"dd#gt j	
 gt jjt jjt jjgdd$S )%Nr$   zQEdits images using Flux.1 Kontext [pro] via api based on prompt and aspect ratio.r%   Tr&   z?Prompt for the image generation - specify what and how to edit.r(   r7   r8   r9   r:   guidanceg      @r@   g     X@2Guidance strength for the image generation process)r*   r4   r5   rA   r+   steps2   r^      0Number of steps for the image generation processr*   r4   r5   r+   r0   i  r   r1   r2   r3   r,   Fr-   r.   input_imager=   )rE   rF   rG   rH   rI   rJ   rK   rL   )r   rN   NODE_IDDISPLAY_NAMErO   r   rS   rQ   rP   rR   rT   rU   rV   rW   rX   rZ   r   r   r    r\      sr   
.z%FluxKontextProImageNode.define_schemaz$/proxy/bfl/flux-kontext-pro/generatezFlux.1 Kontext [pro] ImageNr   Fr%   r7   r   r   r   c           
         s   t |dd |d u rt|dd t| t| jddtt||t|d||||d u r*|nt|dd	I d H }t	| t|j
td
d dd tjgtjtjtjtjgg dI d H }	tt|	jd I d H S )Nr]   r`   Frb   rd   re   r^   )r%   r,   r   r   r0   r7   r   ri   c                 S   rl   rm   rn   rp   r   r   r    rr      rs   z1FluxKontextProImageNode.execute.<locals>.<lambda>c                 S   rl   rm   rt   rp   r   r   r    rr     rs   rv   r|   )r   r   r   r   BFL_PATHr
   r	   r}   r   r   r~   r   r   r   r   r   r   r   r   r   r   r   )
r[   r%   r7   r   r   r   r0   r,   r   r   r   r   r    r      sB   zFluxKontextProImageNode.execute)Nr   F)r   r   r   r   r   rN   r\   r   r   r   r   r   r   r   rR   r   r   r   r   r   r    r      s.    =	r   c                   @   s   e Zd ZdZdZd ZdZdS )FluxKontextMaxImageNodezQEdits images using Flux.1 Kontext [max] via api based on prompt and aspect ratio.z$/proxy/bfl/flux-kontext-max/generatezFlux.1 Kontext [max] ImageN)r   r   r   DESCRIPTIONr   r   r   r   r   r   r    r     
    r   c                   @   s^   e Zd ZedejfddZe	ddejde	de
ded	ed
ededededejfddZdS )FluxProExpandNoder#   c                 C   s   t jddddt jdt jjdddd	d
t jjdddddt jjddddddt jjddddddt jjddddddt jjddddddt jjddddddt jjdd d!d d"dt jjd#ddd$dd%d&g
t j gt j	j
t j	jt j	jgdt jd'd(d)	S )*Nr   zFlux.1 Expand Imager$   z Outpaints image based on prompt.imager%   Tr&   r'   r(   r,   Fr-   r.   topr      z2Number of pixels to expand at the top of the imager   bottomz5Number of pixels to expand at the bottom of the imageleftz3Number of pixels to expand at the left of the imagerightz4Number of pixels to expand at the right of the imager   <         ?d   r   r   r      r   r0   r1   r2   r3   {"type":"usd","usd":0.05}rB   rD   )r   rN   rR   r   rO   rP   rQ   rS   rT   rU   rV   rW   rX   rY   rZ   r   r   r    r\     s   

CzFluxProExpandNode.define_schemar   r   r%   r,   r   r   r   r   r   r   c                    s   t | tdddtt||||||||	|
t|d
dI d H }t| t|jtdd dd tj	gtj
tjtjtjgg d	I d H }tt|jd
 I d H S )Nz'/proxy/bfl/flux-pro-1.0-expand/generaterd   re   )
r%   r,   r   r   r   r   r   r   r0   r   ri   c                 S   rl   rm   rn   rp   r   r   r    rr     rs   z+FluxProExpandNode.execute.<locals>.<lambda>c                 S   rl   rm   rt   rp   r   r   r    rr     rs   rv   r|   )r   r   r
   r   r   r   r~   r   r   r   r   r   r   r   r   r   r   r   )r[   r   r%   r,   r   r   r   r   r   r   r0   r   r   r   r   r    r   n  sB   
zFluxProExpandNode.executeNr   r   r   r   r   r   rN   r\   r   rR   r   r   r   r   r   r   r   r   r   r    r     s4    U	
r   c                   @   sT   e Zd ZedejfddZe	ddejdejde	de
d	ed
edejfddZdS )FluxProFillNoder#   c                 C   s   t jddddt jdt jdt jjddd	d
dt jjdddddt jjddddddt jjddddddt jjdddddddgt j	 gt j
jt j
jt j
jgdt jdd d!	S )"Nr   zFlux.1 Fill Imager$   z(Inpaints image based on mask and prompt.r   r   r%   Tr&   r'   r(   r,   Fr-   r.   r   r   r   r   r   r   r   r   r   r   r0   r   r1   r2   r3   r   rB   rD   )r   rN   rR   r   MaskrO   rP   rS   rQ   rT   rU   rV   rW   rX   rY   rZ   r   r   r    r\     sh   


(zFluxProFillNode.define_schemar   r   r   r%   r,   r   r   c           
         s   t ||}tt|}t| tdddtt|||||t|d d d d d d d df |ddI d H }t| t|jt	dd d	d t
jgt
jt
jt
jt
jgg d
I d H }	tt|	jd I d H S )Nz%/proxy/bfl/flux-pro-1.0-fill/generaterd   re   r   )r%   r,   r   r   r0   r   r   ri   c                 S   rl   rm   rn   rp   r   r   r    rr     rs   z)FluxProFillNode.execute.<locals>.<lambda>c                 S   rl   rm   rt   rp   r   r   r    rr     rs   rv   r|   )r   r   r!   r   r   r
   r   r   r~   r   r   r   r   r   r   r   r   r   r   r   )
r[   r   r   r%   r,   r   r   r0   r   r   r   r   r    r     s@   

"zFluxProFillNode.executeNr   r   r   r   r   r    r     s(    :		r   c                   @   sf   e Zd Zd ZdZdZdZedej	fddZ
e	dded	ed
edededejdB dejfddZdS )Flux2ProImageNodezFlux.2 [pro] Imagez/proxy/bfl/flux-2-pro/generatea  
    (
      $MP := 1024 * 1024;
      $outMP := $max([1, $floor(((widgets.width * widgets.height) + $MP - 1) / $MP)]);
      $outputCost := 0.03 + 0.015 * ($outMP - 1);
      inputs.images.connected
        ? {
            "type":"range_usd",
            "min_usd": $outputCost + 0.015,
            "max_usd": $outputCost + 0.12,
            "format": { "approximate": true }
          }
        : {"type":"usd","usd": $outputCost}
    )
    r#   c                 C   s   t j| j| jddt jjdddddt jjdd	d
dddt jjddd
dddt jjdddddddt jjdddddt jjddddgt j	 gt j
jt j
jt j
jgdt jt jddgdgd| jdd	S )Nr$   z>Generates images synchronously based on prompt and resolution.r%   Tr&   z'Prompt for the image generation or editr(   widthi      r       )r*   r4   r5   rA   heighti   r0   r   r1   r2   r3   r,   zwWhether to perform upsampling on the prompt. If active, automatically modifies the prompt for more creative generation.r.   imagesz(Up to 9 images to be used as references.)r>   r+   )widgetsrI   )
depends_onrC   rD   )r   rN   r   r   rO   r   rQ   rP   rR   rT   rU   rV   rW   rX   rY   PriceBadgeDependsPRICE_BADGE_EXPRrZ   r   r   r    r\     sh   
&zFlux2ProImageNode.define_schemaNr%   r   r   r0   r,   r   c                    s  i }|d ur0t |dkrtdt|jd D ]}|r#d|d  nd}	t|| dd||	< qt| t| jd	d
tt	d|||||d|dI d H  dt
dtd B f fdd}
t| t jtdd dd |
tjgtjtjtjtjgg d	I d H }tt|jd I d H S )N	   z4The current maximum number of supported images is 9.r   input_image_r^   r   i  @ )total_pixelsrd   re   )r%   r   r   r0   r,   ri   _rr#   c                    s    j d u rd S  j d S )Nr   )cost)r   r   r   r    price_extractorx  s   z2Flux2ProImageNode.execute.<locals>.price_extractorc                 S   rl   rm   rn   rp   r   r   r    rr     rs   z+Flux2ProImageNode.execute.<locals>.<lambda>c                 S   rl   rm   rt   rp   r   r   r    rr     rs   )rj   rw   rx   r   ry   rz   r{   r|   r   )r   
ValueErrorrangeshaper   r   r   API_ENDPOINTr
   r   r   r   r   r~   r   r   r   r   r   r   r   r   r   r   r   )r[   r%   r   r   r0   r,   r   reference_imagesimage_indexkey_namer   r   r   r   r    r   Y  sN   
zFlux2ProImageNode.executerm   )r   r   r   r   r   r   r   r   r   rN   r\   r   r   r   r   rR   r   r   r   r   r   r    r   
  s0    9r   c                   @   s   e Zd Zd ZdZdZdZdS )Flux2MaxImageNodezFlux.2 [max] Imagez/proxy/bfl/flux-2-max/generatea  
    (
      $MP := 1024 * 1024;
      $outMP := $max([1, $floor(((widgets.width * widgets.height) + $MP - 1) / $MP)]);
      $outputCost := 0.07 + 0.03 * ($outMP - 1);

      inputs.images.connected
        ? {
            "type":"range_usd",
            "min_usd": $outputCost + 0.03,
            "max_usd": $outputCost + 0.24,
            "format": { "approximate": true }
          }
        : {"type":"usd","usd": $outputCost}
    )
    N)r   r   r   r   r   r   r   r   r   r   r    r     r   r   c                   @   s(   e Zd Zedeeej  fddZdS )BFLExtensionr#   c                    s   t ttttttgS rm   )r"   r   r   r   r   r   r   )selfr   r   r    get_node_list  s   zBFLExtension.get_node_listN)	r   r   r   r   listtyper   	ComfyNoder   r   r   r   r    r     s    r   r#   c                      s   t  S rm   )r   r   r   r   r    comfy_entrypoint  s   r   )(r   pydanticr   typing_extensionsr   comfy_api.latestr   r   r   comfy_api_nodes.apis.bflr   r   r	   r
   r   r   r   r   comfy_api_nodes.utilr   r   r   r   r   r   r   r   r   rR   r!   r   r"   r   r   r   r   r   r   r   r   r   r   r   r    <module>   s$    (,
	vr 
k 