Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 12 additions & 3 deletions comfy_api_nodes/apis/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -782,9 +782,11 @@ def __init__(
poll_endpoint: ApiEndpoint[EmptyRequest, R],
completed_statuses: list[str],
failed_statuses: list[str],
*,
status_extractor: Callable[[R], Optional[str]],
progress_extractor: Callable[[R], Optional[float]] | None = None,
result_url_extractor: Callable[[R], Optional[str]] | None = None,
price_extractor: Callable[[R], Optional[float]] | None = None,
request: Optional[T] = None,
api_base: str | None = None,
auth_token: Optional[str] = None,
Expand Down Expand Up @@ -815,10 +817,12 @@ def __init__(
self.status_extractor = status_extractor or (lambda x: getattr(x, "status", None))
self.progress_extractor = progress_extractor
self.result_url_extractor = result_url_extractor
self.price_extractor = price_extractor
self.node_id = node_id
self.completed_statuses = completed_statuses
self.failed_statuses = failed_statuses
self.final_response: Optional[R] = None
self.extracted_price: Optional[float] = None

async def execute(self, client: Optional[ApiClient] = None) -> R:
owns_client = client is None
Expand All @@ -840,6 +844,8 @@ async def execute(self, client: Optional[ApiClient] = None) -> R:
def _display_text_on_node(self, text: str):
if not self.node_id:
return
if self.extracted_price is not None:
text = f"Price: {self.extracted_price}$\n{text}"
PromptServer.instance.send_progress_text(text, self.node_id)

def _display_time_progress_on_node(self, time_completed: int | float):
Expand Down Expand Up @@ -877,9 +883,7 @@ async def _poll_until_complete(self, client: ApiClient) -> R:
try:
logging.debug("[DEBUG] Polling attempt #%s", poll_count)

request_dict = (
None if self.request is None else self.request.model_dump(exclude_none=True)
)
request_dict = None if self.request is None else self.request.model_dump(exclude_none=True)

if poll_count == 1:
logging.debug(
Expand Down Expand Up @@ -912,6 +916,11 @@ async def _poll_until_complete(self, client: ApiClient) -> R:
if new_progress is not None:
progress.update_absolute(new_progress, total=PROGRESS_BAR_MAX)

if self.price_extractor:
price = self.price_extractor(response_obj)
if price is not None:
self.extracted_price = price

if status == TaskStatus.COMPLETED:
message = "Task completed successfully"
if self.result_url_extractor:
Expand Down
33 changes: 19 additions & 14 deletions comfy_api_nodes/nodes_kling.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@
validate_video_dimensions,
validate_video_duration,
)
from comfy_api.input_impl import VideoFromFile
from comfy_api.input.basic_types import AudioInput
from comfy_api.input.video_types import VideoInput
from comfy_api.latest import ComfyExtension, io as comfy_io
Expand Down Expand Up @@ -511,7 +512,7 @@ async def execute_video_effect(
image_1: torch.Tensor,
image_2: Optional[torch.Tensor] = None,
model_mode: Optional[KlingVideoGenMode] = None,
) -> comfy_io.NodeOutput:
) -> tuple[VideoFromFile, str, str]:
if dual_character:
request_input_field = KlingDualCharacterEffectInput(
model_name=model_name,
Expand Down Expand Up @@ -562,7 +563,7 @@ async def execute_video_effect(
validate_video_result_response(final_response)

video = get_video_from_response(final_response)
return comfy_io.NodeOutput(await download_url_to_video_output(str(video.url)), str(video.id), str(video.duration))
return await download_url_to_video_output(str(video.url)), str(video.id), str(video.duration)


async def execute_lipsync(
Expand Down Expand Up @@ -1271,7 +1272,7 @@ async def execute(
image_1=image_left,
image_2=image_right,
)
return video, duration
return comfy_io.NodeOutput(video, duration)


class KlingSingleImageVideoEffectNode(comfy_io.ComfyNode):
Expand Down Expand Up @@ -1320,17 +1321,21 @@ async def execute(
model_name: KlingSingleImageEffectModelName,
duration: KlingVideoGenDuration,
) -> comfy_io.NodeOutput:
return await execute_video_effect(
auth_kwargs={
"auth_token": cls.hidden.auth_token_comfy_org,
"comfy_api_key": cls.hidden.api_key_comfy_org,
},
node_id=cls.hidden.unique_id,
dual_character=False,
effect_scene=effect_scene,
model_name=model_name,
duration=duration,
image_1=image,
return comfy_io.NodeOutput(
*(
await execute_video_effect(
auth_kwargs={
"auth_token": cls.hidden.auth_token_comfy_org,
"comfy_api_key": cls.hidden.api_key_comfy_org,
},
node_id=cls.hidden.unique_id,
dual_character=False,
effect_scene=effect_scene,
model_name=model_name,
duration=duration,
image_1=image,
)
)
)


Expand Down
2 changes: 2 additions & 0 deletions comfy_api_nodes/nodes_pika.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
from comfy_api_nodes.apinode_utils import (
download_url_to_video_output,
tensor_to_bytesio,
validate_string,
)
from comfy_api_nodes.apis import pika_defs
from comfy_api_nodes.apis.client import (
Expand Down Expand Up @@ -590,6 +591,7 @@ async def execute(
resolution: str,
duration: int,
) -> comfy_io.NodeOutput:
validate_string(prompt_text, field_name="prompt_text", min_length=1)
pika_files = [
("keyFrames", ("image_start.png", tensor_to_bytesio(image_start), "image/png")),
("keyFrames", ("image_end.png", tensor_to_bytesio(image_end), "image/png")),
Expand Down