From 0639b398d07f00a0913f93cffbd9133a4265bddc Mon Sep 17 00:00:00 2001 From: Sirshendu Ganguly Date: Mon, 16 Mar 2026 21:21:10 -0400 Subject: [PATCH 1/5] Added support for type and strength --- runware/base.py | 6 ++++++ runware/types.py | 7 +++++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/runware/base.py b/runware/base.py index 481b273..ea96676 100644 --- a/runware/base.py +++ b/runware/base.py @@ -17,6 +17,7 @@ from .reconnection import ConnectionState, ReconnectionManager from .types import ( Environment, + IInputReference, IImageInference, IPhotoMaker, IImageCaption, @@ -704,6 +705,11 @@ async def _imageInference( if requestImage.referenceImages: requestImage.referenceImages = await process_image(requestImage.referenceImages) + if requestImage.inputs and requestImage.inputs.referenceImages: + for ref in requestImage.inputs.referenceImages: + if isinstance(ref, IInputReference): + ref.image = await process_image(ref.image) + if requestImage.controlNet: for control_data in requestImage.controlNet: image_uploaded = await self.uploadImage(control_data.guideImage) diff --git a/runware/types.py b/runware/types.py index 0d59706..963b8cc 100644 --- a/runware/types.py +++ b/runware/types.py @@ -870,6 +870,8 @@ class IInputFrame(SerializableMixin): class IInputReference(SerializableMixin): image: Union[str, File] tag: Optional[str] = None + type: Optional[str] = None + strength: Optional[float] = None @dataclass @@ -879,11 +881,11 @@ class IInputs(SerializableMixin): image: Optional[Union[str, File]] = None mask: Optional[Union[str, File]] = None superResolutionReferences: Optional[List[Union[str, File]]] = None - + @property def request_key(self) -> str: return "inputs" - + def __post_init__(self): if self.references: warnings.warn( @@ -978,6 +980,7 @@ def request_key(self) -> str: class IImageInference: model: Union[int, str] positivePrompt: Optional[str] = None + style: Optional[str] = None taskUUID: Optional[str] = None deliveryMethod: str = "sync" outputType: Optional[IOutputType] = None From c1e09251768191125dcd96bd1c0886d1f2561a49 Mon Sep 17 00:00:00 2001 From: Sirshendu Ganguly Date: Tue, 17 Mar 2026 08:11:55 -0400 Subject: [PATCH 2/5] Removed IImageInference.style --- runware/types.py | 1 - 1 file changed, 1 deletion(-) diff --git a/runware/types.py b/runware/types.py index 963b8cc..11a5425 100644 --- a/runware/types.py +++ b/runware/types.py @@ -980,7 +980,6 @@ def request_key(self) -> str: class IImageInference: model: Union[int, str] positivePrompt: Optional[str] = None - style: Optional[str] = None taskUUID: Optional[str] = None deliveryMethod: str = "sync" outputType: Optional[IOutputType] = None From f2ced6b10343fe22b53c4bf3b8bb62cc5708fca7 Mon Sep 17 00:00:00 2001 From: Sirshendu Ganguly Date: Tue, 17 Mar 2026 10:16:11 -0400 Subject: [PATCH 3/5] Fixed process_image conditional statement --- runware/base.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/runware/base.py b/runware/base.py index ea96676..255776d 100644 --- a/runware/base.py +++ b/runware/base.py @@ -706,9 +706,14 @@ async def _imageInference( requestImage.referenceImages = await process_image(requestImage.referenceImages) if requestImage.inputs and requestImage.inputs.referenceImages: + processed_refs = [] for ref in requestImage.inputs.referenceImages: if isinstance(ref, IInputReference): ref.image = await process_image(ref.image) + processed_refs.append(ref) + else: + processed_refs.append(await process_image(ref)) + requestImage.inputs.referenceImages = processed_refs if requestImage.controlNet: for control_data in requestImage.controlNet: From 8212cd77678c099340cff5d44c15cb926bcd46a5 Mon Sep 17 00:00:00 2001 From: Sirshendu Ganguly Date: Tue, 17 Mar 2026 12:18:09 -0400 Subject: [PATCH 4/5] Used refType instead of type to avoid lint errors, consolidated process_images into _process_media_list() --- runware/base.py | 107 ++++++++++++++++++++++++++++------------------- runware/types.py | 11 ++++- 2 files changed, 72 insertions(+), 46 deletions(-) diff --git a/runware/base.py b/runware/base.py index 255776d..ddd3b8a 100644 --- a/runware/base.py +++ b/runware/base.py @@ -18,6 +18,7 @@ from .types import ( Environment, IInputReference, + IInputs, IImageInference, IPhotoMaker, IImageCaption, @@ -50,6 +51,7 @@ IAudio, IAudioInference, IFrameImage, + IVideoInputs, IAsyncTaskResponse, IVectorize, OperationState, @@ -111,6 +113,21 @@ class RunwareBase: + async def _process_media_list( + self, + items: List[Any], + object_attr: Optional[str] = None, + ) -> List[Any]: + + processed: List[Any] = [] + for item in items: + if object_attr and hasattr(item, object_attr): + setattr(item, object_attr, await process_image(getattr(item, object_attr))) + processed.append(item) + else: + processed.append(await process_image(item)) + return processed + def __init__( self, api_key: str, @@ -705,15 +722,15 @@ async def _imageInference( if requestImage.referenceImages: requestImage.referenceImages = await process_image(requestImage.referenceImages) - if requestImage.inputs and requestImage.inputs.referenceImages: - processed_refs = [] - for ref in requestImage.inputs.referenceImages: - if isinstance(ref, IInputReference): - ref.image = await process_image(ref.image) - processed_refs.append(ref) - else: - processed_refs.append(await process_image(ref)) - requestImage.inputs.referenceImages = processed_refs + if requestImage.inputs: + if isinstance(requestImage.inputs, dict): + requestImage.inputs = IInputs(**requestImage.inputs) + + if requestImage.inputs.referenceImages: + requestImage.inputs.referenceImages = await self._process_media_list( + requestImage.inputs.referenceImages, + object_attr="image", + ) if requestImage.controlNet: for control_data in requestImage.controlNet: @@ -784,6 +801,8 @@ async def _imageInference( task_uuid = requestImage.taskUUID number_results = requestImage.numberResults or 1 + import pprint + pprint.pprint(request_object) if delivery_method_enum is EDeliveryMethod.ASYNC: if requestImage.webhookURL: @@ -2061,7 +2080,41 @@ async def _getResponse( ) async def _requestVideo(self, requestVideo: "IVideoInference") -> "Union[List[IVideo], IAsyncTaskResponse]": - await self._processVideoImages(requestVideo) + if requestVideo.frameImages: + requestVideo.frameImages = await self._process_media_list( + requestVideo.frameImages, + object_attr="inputImage", + ) + + if requestVideo.referenceImages: + requestVideo.referenceImages = await self._process_media_list( + requestVideo.referenceImages, + ) + + if requestVideo.inputs: + inputs = requestVideo.inputs + if isinstance(inputs, dict): + inputs = IVideoInputs(**inputs) + requestVideo.inputs = inputs + + if inputs.image: + inputs.image = await process_image(inputs.image) + + if inputs.images: + inputs.images = await self._process_media_list(inputs.images) + + if inputs.mask: + inputs.mask = await process_image(inputs.mask) + + if inputs.referenceImages: + inputs.referenceImages = await self._process_media_list(inputs.referenceImages) + + if inputs.frameImages: + inputs.frameImages = await self._process_media_list( + inputs.frameImages, + object_attr="image", + ) + requestVideo.taskUUID = requestVideo.taskUUID or getUUID() request_object = self._buildVideoRequest(requestVideo) @@ -2077,39 +2130,6 @@ async def _requestVideo(self, requestVideo: "IVideoInference") -> "Union[List[IV debug_key="video-inference-initial" ) - async def _processVideoImages(self, requestVideo: IVideoInference) -> None: - frame_tasks = [] - reference_tasks = [] - - if requestVideo.frameImages: - frame_tasks = [ - process_image(frame_item.inputImage) - for frame_item in requestVideo.frameImages - if isinstance(frame_item, IFrameImage) - ] - - if requestVideo.referenceImages: - reference_tasks = [ - process_image(reference_item) - for reference_item in requestVideo.referenceImages - ] - - frame_results = await gather(*frame_tasks) if frame_tasks else [] - reference_results = await gather(*reference_tasks) if reference_tasks else [] - - if requestVideo.frameImages and frame_results: - processed_frame_images = [] - result_index = 0 - for frame_item in requestVideo.frameImages: - if isinstance(frame_item, IFrameImage): - frame_item.inputImages = frame_results[result_index] - result_index += 1 - processed_frame_images.append(frame_item) - requestVideo.frameImages = processed_frame_images - - if requestVideo.referenceImages and reference_results: - requestVideo.referenceImages = reference_results - def _buildVideoRequest(self, requestVideo: IVideoInference) -> Dict[str, Any]: request_object = { "deliveryMethod": requestVideo.deliveryMethod, @@ -2356,7 +2376,6 @@ def _buildImageRequest(self, requestImage: IImageInference, prompt: Optional[str self._addOptionalField(request_object, requestImage.safety) self._addOptionalField(request_object, requestImage.settings) - return request_object def _addImageSpecialFields(self, request_object: Dict[str, Any], requestImage: IImageInference, control_net_data_dicts: List[Dict], instant_id_data: Optional[Dict], ip_adapters_data: Optional[List[Dict]], ace_plus_plus_data: Optional[Dict], pulid_data: Optional[Dict]) -> None: diff --git a/runware/types.py b/runware/types.py index 11a5425..7a4c6cd 100644 --- a/runware/types.py +++ b/runware/types.py @@ -870,8 +870,15 @@ class IInputFrame(SerializableMixin): class IInputReference(SerializableMixin): image: Union[str, File] tag: Optional[str] = None - type: Optional[str] = None - strength: Optional[float] = None + refType: Optional[str] = None + strength: Optional[float] = None + + def serialize(self) -> Dict[str, Any]: + data = super().serialize() + if self.refType is not None: + data["type"] = self.refType + data.pop("refType", None) + return data @dataclass From d1fed25b31ff1249f2343ea9827c88a30d74bee6 Mon Sep 17 00:00:00 2001 From: Sirshendu Ganguly Date: Tue, 17 Mar 2026 12:18:38 -0400 Subject: [PATCH 5/5] Removed print lines --- runware/base.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/runware/base.py b/runware/base.py index ddd3b8a..bd5d0ad 100644 --- a/runware/base.py +++ b/runware/base.py @@ -801,8 +801,6 @@ async def _imageInference( task_uuid = requestImage.taskUUID number_results = requestImage.numberResults or 1 - import pprint - pprint.pprint(request_object) if delivery_method_enum is EDeliveryMethod.ASYNC: if requestImage.webhookURL: