o
    iJ                  	   @   s  d Z ddlmZ ddlmZ ddl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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%m&Z& dZ'dZ(d	Z)d
Z*dZ+dZ,G dd de-Z.G dd de/eZ0G dd de/eZ1dede/dB fddZ2dede3dB fddZ4dede/dB fddZ5	d0de6ej7 de/de8dB defdd Z9	d0de6ej7 d!ede8dB de	j:fd"d#Z;G d$d% d%ej7Z<G d&d' d'ej7Z=G d(d) d)ej7Z>G d*d+ d+ej7Z?G d,d- d-eZ@de@fd.d/ZAdS )1a  Runway API Nodes

API Docs:
  - https://docs.dev.runwayml.com/api/#tag/Task-management/paths/~1v1~1tasks~1%7Bid%7D/delete

User Guides:
  - https://help.runwayml.com/hc/en-us/sections/30265301423635-Gen-3-Alpha
  - https://help.runwayml.com/hc/en-us/articles/37327109429011-Creating-with-Gen-4-Video
  - https://help.runwayml.com/hc/en-us/articles/33927968552339-Creating-with-Act-One-on-Gen-3-Alpha-and-Turbo
  - https://help.runwayml.com/hc/en-us/articles/34170748696595-Creating-with-Keyframes-on-Gen-3

    )Enum)override)IOComfyExtensionInput	InputImpl)RunwayImageToVideoRequestRunwayImageToVideoResponseRunwayTaskStatusResponseRunwayModelEnumRunwayDurationEnumRunwayAspectRatioEnumRunwayPromptImageObjectRunwayPromptImageDetailedObjectRunwayTextToImageRequestRunwayTextToImageResponseModel4ReferenceImage RunwayTextToImageAspectRatioEnum)
image_tensor_pair_to_batchvalidate_stringvalidate_image_dimensionsvalidate_image_aspect_ratioupload_images_to_comfyapidownload_url_to_video_outputdownload_url_to_image_tensorApiEndpointsync_oppoll_opz/proxy/runway/image_to_videoz/proxy/runway/text_to_imagez/proxy/runway/tasks@      )   c                   @   s   e Zd ZdZdS )RunwayApiErrorz%Base exception for Runway API errors.N)__name__
__module____qualname____doc__ r'   r'   :/mnt/c/Users/fbmor/ComfyUI/comfy_api_nodes/nodes_runway.pyr"   8   s    r"   c                   @   s(   e Zd ZdZdZdZdZdZdZdZ	dS )	RunwayGen4TurboAspectRatiozKAspect ratios supported for Image to Video API when using gen4_turbo model.z1280:720z720:1280z1104:832z832:1104z960:960z1584:672N)
r#   r$   r%   r&   field_1280_720field_720_1280field_1104_832field_832_1104field_960_960field_1584_672r'   r'   r'   r(   r)   >   s    r)   c                   @   s   e Zd ZdZdZdZdS )RunwayGen3aAspectRatiozLAspect ratios supported for Image to Video API when using gen3a_turbo model.z768:1280z1280:768N)r#   r$   r%   r&   field_768_1280field_1280_768r'   r'   r'   r(   r0   I   s    r0   responsereturnNc                 C   &   t | drt| jdkr| jd S dS )zAReturns the video URL from the task status response if it exists.outputr   Nhasattrlenr6   r3   r'   r'   r(   get_video_url_from_task_statusP      
r;   c                 C   s"   t | dr| jd ur| jd S d S )Nprogressd   )r8   r=   r:   r'   r'   r(   !extract_progress_from_task_statusW   s   
r?   c                 C   r5   )zAReturns the image URL from the task status response if it exists.r6   r   Nr7   r:   r'   r'   r(   get_image_url_from_task_status_   r<   r@   clstask_idestimated_durationc                    s0   t | tt d| dtdd |tdI dH S )z@Poll the task status until it is finished then get the response./)pathc                 S   s   | j jS N)statusvalue)rr'   r'   r(   <lambda>n   s    zget_response.<locals>.<lambda>)response_modelstatus_extractorrC   progress_extractorN)r   r   PATH_GET_TASK_STATUSTaskStatusResponser?   )rA   rB   rC   r'   r'   r(   get_responsef   s   rP   requestc                    sX   t | ttddt|dI d H }t| |j|I d H }|js!tdt|}t	|I d H S )NPOSTrE   methodendpointrK   dataz:Runway task succeeded but no video data found in response.)
r   r   PATH_IMAGE_TO_VIDEOr	   rP   idr6   r"   r;   r   )rA   rQ   rC   initial_responsefinal_response	video_urlr'   r'   r(   generate_videot   s   
r]   c                   @   B   e Zd Zedd Zededejdededede	j
fd	d
ZdS )RunwayImageToVideoNodeGen3ac                 C      t jddddt jjddddd	t jjd
ddt jjdtdt jjdtdt jjddddddt j	j
ddgt j gt jjt jjt jjgdt jt jdgdddd	S )Nr_   z#Runway Image to Video (Gen3a Turbo)api node/video/Runwaya-  Generate a video from a single starting frame using Gen3a Turbo model. Before diving in, review these best practices to ensure that your input selections will set your generation up for success: https://help.runwayml.com/hc/en-us/articles/33927968552339-Creating-with-Act-One-on-Gen-3-Alpha-and-Turbo.promptT Text prompt for the generation	multilinedefaulttooltipstart_frame$Start frame to be used for the videorh   durationoptionsratioseedr          Random seed for generationrg   minmaxstepcontrol_after_generatedisplay_moderh   widgets/{"type":"usd","usd": 0.0715 * widgets.duration}
depends_onexpr	node_iddisplay_namecategorydescriptioninputsoutputshiddenis_api_nodeprice_badger   SchemaStringr   ImageComboDurationr0   IntNumberDisplaynumberVideoOutputHiddenauth_token_comfy_orgapi_key_comfy_org	unique_id
PriceBadgePriceBadgeDependsrA   r'   r'   r(   define_schema   \   z)RunwayImageToVideoNodeGen3a.define_schemarb   ri   rl   ro   rp   r4   c                    s   t |dd t|ddd t|dd t| |dddI d H }tt| t||td	t	|t
|ttt|d
 ddgddI d H S )Nrr   
min_length?  	max_width
max_heightrr      r   rr   	image/png
max_images	mime_typegen3a_turbor   firsturipositionroot
promptTextrp   modelrl   ro   promptImage)r   r   r   r   r   
NodeOutputr]   r   Modelr   AspectRatior   r   strrA   rb   ri   rl   ro   rp   download_urlsr'   r'   r(   execute   s2   	z#RunwayImageToVideoNodeGen3a.executeNr#   r$   r%   classmethodr   r   r   r   intr   r   r   r'   r'   r'   r(   r_      "    
6r_   c                   @   r^   )RunwayImageToVideoNodeGen4c                 C   r`   )Nr   z"Runway Image to Video (Gen4 Turbo)ra   a  Generate a video from a single starting frame using Gen4 Turbo model. Before diving in, review these best practices to ensure that your input selections will set your generation up for success: https://help.runwayml.com/hc/en-us/articles/37327109429011-Creating-with-Gen-4-Video.rb   Trc   rd   re   ri   rj   rk   rl   rm   ro   rp   r   rq   rr   rs   rt   rz   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   z(RunwayImageToVideoNodeGen4.define_schemarb   ri   rl   ro   rp   r4   c                    s   t |dd t|ddd t|dd t| |dddI d H }tt| t||td	t	|t
|ttt|d
 ddgddtdI d H S )Nrr   r   r   r   r   r   r   r   
gen4_turbor   r   r   r   r   rC   )r   r   r   r   r   r   r]   r   r   r   r   r   r   r   AVERAGE_DURATION_FLF_SECONDSr   r'   r'   r(   r     s4   	

z"RunwayImageToVideoNodeGen4.executeNr   r'   r'   r'   r(   r      r   r   c                   @   sH   e Zd Zedd Zededejdejdededed	e	j
fd
dZdS )RunwayFirstLastFrameNodec                 C   s   t jddddt jjddddd	t jjd
ddt jjdddt jjdtdt jjdtdt jjddddddt j	j
ddgt j gt jjt jjt jjgdt jt jdgdddd	S )Nr   z Runway First-Last-Frame to Videora   a  Upload first and last keyframes, draft a prompt, and generate a video. More complex transitions, such as cases where the Last frame is completely different from the First frame, may benefit from the longer 10s duration. This would give the generation more time to smoothly transition between the two inputs. Before diving in, review these best practices to ensure that your input selections will set your generation up for success: https://help.runwayml.com/hc/en-us/articles/34170748696595-Creating-with-Keyframes-on-Gen-3.rb   Trc   rd   re   ri   rj   rk   	end_framezCEnd frame to be used for the video. Supported for gen3a_turbo only.rl   rm   ro   rp   r   rq   rr   rs   rt   rz   r|   r}   r   r   r   r'   r'   r(   r   G  sd   #z&RunwayFirstLastFrameNode.define_schemarb   ri   r   rl   ro   rp   r4   c           	         s   t |dd t|ddd t|ddd t|dd t|dd t||}t| |ddd	I d H }t|dkr;td
tt	| t
||tdt|t|ttt|d ddtt|d ddgddtdI d H S )Nrr   r   r   r   r   r   r   r   r   z1Failed to upload one or more images to comfy api.r   r   r   r   lastr   r   r   )r   r   r   r   r   r9   r"   r   r   r]   r   r   r   r   r   r   r   r   )	rA   rb   ri   r   rl   ro   rp   stacked_input_imagesr   r'   r'   r(   r     sB   


z RunwayFirstLastFrameNode.executeNr   r'   r'   r'   r(   r   E  s&    
=r   c                
   @   sB   e Zd Zedd Ze	d
dededejdB dej	fdd	Z
dS )RunwayTextToImageNodec                 C   sx   t jddddt jjddddd	t jjd
dd t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ddd	S )Nr   zRunway Text to Imagezapi node/image/Runwayz~Generate an image from a text prompt using Runway's Gen 4 model. You can also include reference image to guide the generation.rb   Trc   rd   re   ro   c                 S   s   g | ]}|j qS r'   )rH   ).0r   r'   r'   r(   
<listcomp>  s    z7RunwayTextToImageNode.define_schema.<locals>.<listcomp>rm   reference_imagez0Optional reference image to guide the generation)rh   optionalz{"type":"usd","usd":0.11})r   r   )r   r   r   r   r   r   r   r   r   r   r   r   r   r   r'   r'   r(   r     s@   z#RunwayTextToImageNode.define_schemaNrb   ro   r   r4   c              
      s   t |dd d }|d ur/t|ddd t|dd t| |dddI d H }tt|d	 d
g}t| ttddt	t
|tj||ddI d H }t| |jtdI d H }|jsWtdttt|I d H S )Nrr   r   r   r   r   r   r   r   r   )r   rR   rS   )r   r   ro   referenceImagesrU   r   z:Runway task succeeded but no image data found in response.)r   r   r   r   r   r   r   r   PATH_TEXT_TO_IMAGEr   r   r   
gen4_imagerP   rY   AVERAGE_DURATION_T2I_SECONDSr6   r"   r   r   r   r@   )rA   rb   ro   r   reference_imagesr   rZ   r[   r'   r'   r(   r     s@   
zRunwayTextToImageNode.executerF   )r#   r$   r%   r   r   r   r   r   r   r   r   r'   r'   r'   r(   r     s    
&r   c                   @   s(   e Zd Zedeeej  fddZdS )RunwayExtensionr4   c                    s   t tttgS rF   )r   r_   r   r   )selfr'   r'   r(   get_node_list  s   zRunwayExtension.get_node_listN)	r#   r$   r%   r   listtyper   	ComfyNoder   r'   r'   r'   r(   r   
  s    r   c                      s   t  S rF   )r   r'   r'   r'   r(   comfy_entrypoint  s   r   rF   )Br&   enumr   typing_extensionsr   comfy_api.latestr   r   r   r   comfy_api_nodes.apis.runwayr   r	   r
   rO   r   r   r   r   r   r   r   r   r   r   r   r   r   comfy_api_nodes.utilr   r   r   r   r   r   r   r   r   r   rX   r   rN   AVERAGE_DURATION_I2V_SECONDSr   r   	Exceptionr"   r   r)   r0   r;   floatr?   r@   r   r   r   rP   VideoFromFiler]   r_   r   r   r   r   r   r'   r'   r'   r(   <module>   s`    <0


^_oV