From 9d4f77c847837f20ef333a10e5a0d1d9e6a25cf5 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Tue, 9 Dec 2025 03:16:24 +0000
Subject: [PATCH 01/11] fix(types): allow pyright to infer TypedDict types
within SequenceNotStr
---
src/runwayml/_types.py | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/src/runwayml/_types.py b/src/runwayml/_types.py
index e845cd6..8facef4 100644
--- a/src/runwayml/_types.py
+++ b/src/runwayml/_types.py
@@ -243,6 +243,9 @@ class HttpxSendArgs(TypedDict, total=False):
if TYPE_CHECKING:
# This works because str.__contains__ does not accept object (either in typeshed or at runtime)
# https://github.com/hauntsaninja/useful_types/blob/5e9710f3875107d068e7679fd7fec9cfab0eff3b/useful_types/__init__.py#L285
+ #
+ # Note: index() and count() methods are intentionally omitted to allow pyright to properly
+ # infer TypedDict types when dict literals are used in lists assigned to SequenceNotStr.
class SequenceNotStr(Protocol[_T_co]):
@overload
def __getitem__(self, index: SupportsIndex, /) -> _T_co: ...
@@ -251,8 +254,6 @@ def __getitem__(self, index: slice, /) -> Sequence[_T_co]: ...
def __contains__(self, value: object, /) -> bool: ...
def __len__(self) -> int: ...
def __iter__(self) -> Iterator[_T_co]: ...
- def index(self, value: Any, start: int = 0, stop: int = ..., /) -> int: ...
- def count(self, value: Any, /) -> int: ...
def __reversed__(self) -> Iterator[_T_co]: ...
else:
# just point this to a normal `Sequence` at runtime to avoid having to special case
From 4c142226410821c794e9e3bf43c7bf9a7d5bf6c1 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Tue, 9 Dec 2025 03:18:36 +0000
Subject: [PATCH 02/11] chore: add missing docstrings
---
.../types/character_performance_create_params.py | 16 ++++++++++++++++
.../types/image_to_video_create_params.py | 4 ++++
.../types/organization_retrieve_response.py | 8 ++++++++
.../types/speech_to_speech_create_params.py | 6 ++++++
src/runwayml/types/task_retrieve_response.py | 12 ++++++++++++
.../types/text_to_image_create_params.py | 4 ++++
.../types/text_to_speech_create_params.py | 2 ++
.../types/video_to_video_create_params.py | 6 ++++++
8 files changed, 58 insertions(+)
diff --git a/src/runwayml/types/character_performance_create_params.py b/src/runwayml/types/character_performance_create_params.py
index 8cc93cf..aa66adc 100644
--- a/src/runwayml/types/character_performance_create_params.py
+++ b/src/runwayml/types/character_performance_create_params.py
@@ -62,6 +62,11 @@ class CharacterPerformanceCreateParams(TypedDict, total=False):
class CharacterImage(TypedDict, total=False):
+ """An image of your character.
+
+ In the output, the character will use the reference video performance in its original static environment.
+ """
+
type: Required[Literal["image"]]
uri: Required[str]
@@ -69,6 +74,11 @@ class CharacterImage(TypedDict, total=False):
class CharacterVideo(TypedDict, total=False):
+ """A video of your character.
+
+ In the output, the character will use the reference video performance in its original animated environment and some of the character's own movements.
+ """
+
type: Required[Literal["video"]]
uri: Required[str]
@@ -79,6 +89,10 @@ class CharacterVideo(TypedDict, total=False):
class Reference(TypedDict, total=False):
+ """
+ A video of a person performing in the manner that you would like your character to perform. The video must be between 3 and 30 seconds in duration.
+ """
+
type: Required[Literal["video"]]
uri: Required[str]
@@ -86,6 +100,8 @@ class Reference(TypedDict, total=False):
class ContentModeration(TypedDict, total=False):
+ """Settings that affect the behavior of the content moderation system."""
+
public_figure_threshold: Annotated[Literal["auto", "low"], PropertyInfo(alias="publicFigureThreshold")]
"""
When set to `low`, the content moderation system will be less strict about
diff --git a/src/runwayml/types/image_to_video_create_params.py b/src/runwayml/types/image_to_video_create_params.py
index ecae04a..16ef9a0 100644
--- a/src/runwayml/types/image_to_video_create_params.py
+++ b/src/runwayml/types/image_to_video_create_params.py
@@ -68,6 +68,8 @@ class Gen4TurboPromptImagePromptImage(TypedDict, total=False):
class Gen4TurboContentModeration(TypedDict, total=False):
+ """Settings that affect the behavior of the content moderation system."""
+
public_figure_threshold: Annotated[Literal["auto", "low"], PropertyInfo(alias="publicFigureThreshold")]
"""
When set to `low`, the content moderation system will be less strict about
@@ -160,6 +162,8 @@ class Gen3aTurboPromptImagePromptImage(TypedDict, total=False):
class Gen3aTurboContentModeration(TypedDict, total=False):
+ """Settings that affect the behavior of the content moderation system."""
+
public_figure_threshold: Annotated[Literal["auto", "low"], PropertyInfo(alias="publicFigureThreshold")]
"""
When set to `low`, the content moderation system will be less strict about
diff --git a/src/runwayml/types/organization_retrieve_response.py b/src/runwayml/types/organization_retrieve_response.py
index f3a56ca..236bb0b 100644
--- a/src/runwayml/types/organization_retrieve_response.py
+++ b/src/runwayml/types/organization_retrieve_response.py
@@ -10,6 +10,8 @@
class TierModels(BaseModel):
+ """Limits associated with the model."""
+
max_concurrent_generations: int = FieldInfo(alias="maxConcurrentGenerations")
"""The maximum number of generations that can be run concurrently for this model."""
@@ -18,6 +20,8 @@ class TierModels(BaseModel):
class Tier(BaseModel):
+ """Limits associated with the organization's tier."""
+
max_monthly_credit_spend: int = FieldInfo(alias="maxMonthlyCreditSpend")
"""The maximum number of credits that can be purchased in a month."""
@@ -26,11 +30,15 @@ class Tier(BaseModel):
class UsageModels(BaseModel):
+ """Usage data for the model."""
+
daily_generations: int = FieldInfo(alias="dailyGenerations")
"""The number of generations that have been run for this model in the past day."""
class Usage(BaseModel):
+ """Usage data for the organization."""
+
models: Dict[str, UsageModels]
diff --git a/src/runwayml/types/speech_to_speech_create_params.py b/src/runwayml/types/speech_to_speech_create_params.py
index 50bda5f..18fc4db 100644
--- a/src/runwayml/types/speech_to_speech_create_params.py
+++ b/src/runwayml/types/speech_to_speech_create_params.py
@@ -24,6 +24,8 @@ class SpeechToSpeechCreateParams(TypedDict, total=False):
class MediaAudio(TypedDict, total=False):
+ """An audio file containing dialogue to be processed."""
+
type: Required[Literal["audio"]]
uri: Required[str]
@@ -31,6 +33,8 @@ class MediaAudio(TypedDict, total=False):
class MediaVideo(TypedDict, total=False):
+ """A video file containing dialogue to be processed."""
+
type: Required[Literal["video"]]
uri: Required[str]
@@ -41,6 +45,8 @@ class MediaVideo(TypedDict, total=False):
class Voice(TypedDict, total=False):
+ """A voice preset from the RunwayML API."""
+
preset_id: Required[
Annotated[
Literal[
diff --git a/src/runwayml/types/task_retrieve_response.py b/src/runwayml/types/task_retrieve_response.py
index 9284246..c6a2d91 100644
--- a/src/runwayml/types/task_retrieve_response.py
+++ b/src/runwayml/types/task_retrieve_response.py
@@ -13,6 +13,8 @@
class Pending(BaseModel):
+ """A pending task"""
+
id: str
"""The ID of the task being returned."""
@@ -23,6 +25,8 @@ class Pending(BaseModel):
class Throttled(BaseModel):
+ """A throttled task"""
+
id: str
"""The ID of the task being returned."""
@@ -33,6 +37,8 @@ class Throttled(BaseModel):
class Cancelled(BaseModel):
+ """A cancelled or deleted task"""
+
id: str
"""The ID of the task being returned."""
@@ -43,6 +49,8 @@ class Cancelled(BaseModel):
class Running(BaseModel):
+ """A running task"""
+
id: str
"""The ID of the task being returned."""
@@ -55,6 +63,8 @@ class Running(BaseModel):
class Failed(BaseModel):
+ """A failed task"""
+
id: str
"""The ID of the task being returned."""
@@ -77,6 +87,8 @@ class Failed(BaseModel):
class Succeeded(BaseModel):
+ """A succeeded task"""
+
id: str
"""The ID of the task being returned."""
diff --git a/src/runwayml/types/text_to_image_create_params.py b/src/runwayml/types/text_to_image_create_params.py
index 8a1e6c6..daaf399 100644
--- a/src/runwayml/types/text_to_image_create_params.py
+++ b/src/runwayml/types/text_to_image_create_params.py
@@ -81,6 +81,8 @@ class Gen4ImageTurboReferenceImage(TypedDict, total=False):
class Gen4ImageTurboContentModeration(TypedDict, total=False):
+ """Settings that affect the behavior of the content moderation system."""
+
public_figure_threshold: Annotated[Literal["auto", "low"], PropertyInfo(alias="publicFigureThreshold")]
"""
When set to `low`, the content moderation system will be less strict about
@@ -138,6 +140,8 @@ class Gen4Image(TypedDict, total=False):
class Gen4ImageContentModeration(TypedDict, total=False):
+ """Settings that affect the behavior of the content moderation system."""
+
public_figure_threshold: Annotated[Literal["auto", "low"], PropertyInfo(alias="publicFigureThreshold")]
"""
When set to `low`, the content moderation system will be less strict about
diff --git a/src/runwayml/types/text_to_speech_create_params.py b/src/runwayml/types/text_to_speech_create_params.py
index 7518af7..3940a85 100644
--- a/src/runwayml/types/text_to_speech_create_params.py
+++ b/src/runwayml/types/text_to_speech_create_params.py
@@ -23,6 +23,8 @@ class TextToSpeechCreateParams(TypedDict, total=False):
class Voice(TypedDict, total=False):
+ """A voice preset from the RunwayML API."""
+
preset_id: Required[
Annotated[
Literal[
diff --git a/src/runwayml/types/video_to_video_create_params.py b/src/runwayml/types/video_to_video_create_params.py
index b2cb513..56c5350 100644
--- a/src/runwayml/types/video_to_video_create_params.py
+++ b/src/runwayml/types/video_to_video_create_params.py
@@ -47,6 +47,8 @@ class VideoToVideoCreateParams(TypedDict, total=False):
class ContentModeration(TypedDict, total=False):
+ """Settings that affect the behavior of the content moderation system."""
+
public_figure_threshold: Annotated[Literal["auto", "low"], PropertyInfo(alias="publicFigureThreshold")]
"""
When set to `low`, the content moderation system will be less strict about
@@ -55,6 +57,10 @@ class ContentModeration(TypedDict, total=False):
class Reference(TypedDict, total=False):
+ """
+ Passing an image reference allows the model to emulate the style or content of the reference in the output.
+ """
+
type: Required[Literal["image"]]
uri: Required[str]
From 1c5f3af332fdd873865234b11c0b1b24aa9df688 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Tue, 16 Dec 2025 03:12:43 +0000
Subject: [PATCH 03/11] chore(internal): add missing files argument to base
client
---
src/runwayml/_base_client.py | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/src/runwayml/_base_client.py b/src/runwayml/_base_client.py
index 8e9efd7..cc0bf65 100644
--- a/src/runwayml/_base_client.py
+++ b/src/runwayml/_base_client.py
@@ -1247,9 +1247,12 @@ def patch(
*,
cast_to: Type[ResponseT],
body: Body | None = None,
+ files: RequestFiles | None = None,
options: RequestOptions = {},
) -> ResponseT:
- opts = FinalRequestOptions.construct(method="patch", url=path, json_data=body, **options)
+ opts = FinalRequestOptions.construct(
+ method="patch", url=path, json_data=body, files=to_httpx_files(files), **options
+ )
return self.request(cast_to, opts)
def put(
@@ -1767,9 +1770,12 @@ async def patch(
*,
cast_to: Type[ResponseT],
body: Body | None = None,
+ files: RequestFiles | None = None,
options: RequestOptions = {},
) -> ResponseT:
- opts = FinalRequestOptions.construct(method="patch", url=path, json_data=body, **options)
+ opts = FinalRequestOptions.construct(
+ method="patch", url=path, json_data=body, files=to_httpx_files(files), **options
+ )
return await self.request(cast_to, opts)
async def put(
From cfcc2e96de68498e8b1cbca4b02567283d8af207 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Sat, 17 Jan 2026 00:14:39 +0000
Subject: [PATCH 04/11] chore: speedup initial import
---
examples/upload_file.py | 6 +-
src/runwayml/_client.py | 713 ++++++++++++++----
src/runwayml/lib/polling.py | 64 +-
src/runwayml/resources/tasks.py | 8 +-
src/runwayml/resources/uploads.py | 20 +-
.../types/upload_create_ephemeral_response.py | 1 -
tests/api_resources/test_uploads.py | 1 -
7 files changed, 636 insertions(+), 177 deletions(-)
diff --git a/examples/upload_file.py b/examples/upload_file.py
index c02573b..ea75574 100644
--- a/examples/upload_file.py
+++ b/examples/upload_file.py
@@ -20,7 +20,7 @@ async def async_upload() -> None:
client = AsyncRunwayML()
upload_response = await client.uploads.create_ephemeral(file=file_path)
print(f"Upload successful! URI: {upload_response.uri}")
-
+
if args.i:
image_task = await client.text_to_image.create(
model="gen4_image",
@@ -35,7 +35,7 @@ def sync_upload() -> None:
client = RunwayML()
upload_response = client.uploads.create_ephemeral(file=file_path)
print(f"Upload successful! URI: {upload_response.uri}")
-
+
if args.i:
image_task = client.text_to_image.create(
model="gen4_image",
@@ -49,4 +49,4 @@ def sync_upload() -> None:
if args.use_async:
asyncio.run(async_upload())
else:
- sync_upload()
\ No newline at end of file
+ sync_upload()
diff --git a/src/runwayml/_client.py b/src/runwayml/_client.py
index 1feac10..0172f3c 100644
--- a/src/runwayml/_client.py
+++ b/src/runwayml/_client.py
@@ -3,7 +3,7 @@
from __future__ import annotations
import os
-from typing import Any, Mapping
+from typing import TYPE_CHECKING, Any, Mapping
from typing_extensions import Self, override
import httpx
@@ -20,23 +20,8 @@
not_given,
)
from ._utils import is_given, get_async_library
+from ._compat import cached_property
from ._version import __version__
-from .resources import (
- tasks,
- uploads,
- organization,
- sound_effect,
- text_to_image,
- text_to_video,
- video_upscale,
- voice_dubbing,
- image_to_video,
- text_to_speech,
- video_to_video,
- voice_isolation,
- speech_to_speech,
- character_performance,
-)
from ._streaming import Stream as Stream, AsyncStream as AsyncStream
from ._exceptions import RunwayMLError, APIStatusError
from ._base_client import (
@@ -45,6 +30,38 @@
AsyncAPIClient,
)
+if TYPE_CHECKING:
+ from .resources import (
+ tasks,
+ uploads,
+ organization,
+ sound_effect,
+ text_to_image,
+ text_to_video,
+ video_upscale,
+ voice_dubbing,
+ image_to_video,
+ text_to_speech,
+ video_to_video,
+ voice_isolation,
+ speech_to_speech,
+ character_performance,
+ )
+ from .resources.tasks import TasksResource, AsyncTasksResource
+ from .resources.uploads import UploadsResource, AsyncUploadsResource
+ from .resources.organization import OrganizationResource, AsyncOrganizationResource
+ from .resources.sound_effect import SoundEffectResource, AsyncSoundEffectResource
+ from .resources.text_to_image import TextToImageResource, AsyncTextToImageResource
+ from .resources.text_to_video import TextToVideoResource, AsyncTextToVideoResource
+ from .resources.video_upscale import VideoUpscaleResource, AsyncVideoUpscaleResource
+ from .resources.voice_dubbing import VoiceDubbingResource, AsyncVoiceDubbingResource
+ from .resources.image_to_video import ImageToVideoResource, AsyncImageToVideoResource
+ from .resources.text_to_speech import TextToSpeechResource, AsyncTextToSpeechResource
+ from .resources.video_to_video import VideoToVideoResource, AsyncVideoToVideoResource
+ from .resources.voice_isolation import VoiceIsolationResource, AsyncVoiceIsolationResource
+ from .resources.speech_to_speech import SpeechToSpeechResource, AsyncSpeechToSpeechResource
+ from .resources.character_performance import CharacterPerformanceResource, AsyncCharacterPerformanceResource
+
__all__ = [
"Timeout",
"Transport",
@@ -58,23 +75,6 @@
class RunwayML(SyncAPIClient):
- tasks: tasks.TasksResource
- image_to_video: image_to_video.ImageToVideoResource
- video_to_video: video_to_video.VideoToVideoResource
- text_to_video: text_to_video.TextToVideoResource
- text_to_image: text_to_image.TextToImageResource
- video_upscale: video_upscale.VideoUpscaleResource
- character_performance: character_performance.CharacterPerformanceResource
- text_to_speech: text_to_speech.TextToSpeechResource
- sound_effect: sound_effect.SoundEffectResource
- voice_isolation: voice_isolation.VoiceIsolationResource
- voice_dubbing: voice_dubbing.VoiceDubbingResource
- speech_to_speech: speech_to_speech.SpeechToSpeechResource
- organization: organization.OrganizationResource
- uploads: uploads.UploadsResource
- with_raw_response: RunwayMLWithRawResponse
- with_streaming_response: RunwayMLWithStreamedResponse
-
# client options
api_key: str
runway_version: str
@@ -135,22 +135,97 @@ def __init__(
_strict_response_validation=_strict_response_validation,
)
- self.tasks = tasks.TasksResource(self)
- self.image_to_video = image_to_video.ImageToVideoResource(self)
- self.video_to_video = video_to_video.VideoToVideoResource(self)
- self.text_to_video = text_to_video.TextToVideoResource(self)
- self.text_to_image = text_to_image.TextToImageResource(self)
- self.video_upscale = video_upscale.VideoUpscaleResource(self)
- self.character_performance = character_performance.CharacterPerformanceResource(self)
- self.text_to_speech = text_to_speech.TextToSpeechResource(self)
- self.sound_effect = sound_effect.SoundEffectResource(self)
- self.voice_isolation = voice_isolation.VoiceIsolationResource(self)
- self.voice_dubbing = voice_dubbing.VoiceDubbingResource(self)
- self.speech_to_speech = speech_to_speech.SpeechToSpeechResource(self)
- self.organization = organization.OrganizationResource(self)
- self.uploads = uploads.UploadsResource(self)
- self.with_raw_response = RunwayMLWithRawResponse(self)
- self.with_streaming_response = RunwayMLWithStreamedResponse(self)
+ @cached_property
+ def tasks(self) -> TasksResource:
+ from .resources.tasks import TasksResource
+
+ return TasksResource(self)
+
+ @cached_property
+ def uploads(self) -> UploadsResource:
+ from .resources.uploads import UploadsResource
+
+ return UploadsResource(self)
+
+ @cached_property
+ def image_to_video(self) -> ImageToVideoResource:
+ from .resources.image_to_video import ImageToVideoResource
+
+ return ImageToVideoResource(self)
+
+ @cached_property
+ def video_to_video(self) -> VideoToVideoResource:
+ from .resources.video_to_video import VideoToVideoResource
+
+ return VideoToVideoResource(self)
+
+ @cached_property
+ def text_to_video(self) -> TextToVideoResource:
+ from .resources.text_to_video import TextToVideoResource
+
+ return TextToVideoResource(self)
+
+ @cached_property
+ def text_to_image(self) -> TextToImageResource:
+ from .resources.text_to_image import TextToImageResource
+
+ return TextToImageResource(self)
+
+ @cached_property
+ def video_upscale(self) -> VideoUpscaleResource:
+ from .resources.video_upscale import VideoUpscaleResource
+
+ return VideoUpscaleResource(self)
+
+ @cached_property
+ def character_performance(self) -> CharacterPerformanceResource:
+ from .resources.character_performance import CharacterPerformanceResource
+
+ return CharacterPerformanceResource(self)
+
+ @cached_property
+ def text_to_speech(self) -> TextToSpeechResource:
+ from .resources.text_to_speech import TextToSpeechResource
+
+ return TextToSpeechResource(self)
+
+ @cached_property
+ def sound_effect(self) -> SoundEffectResource:
+ from .resources.sound_effect import SoundEffectResource
+
+ return SoundEffectResource(self)
+
+ @cached_property
+ def voice_isolation(self) -> VoiceIsolationResource:
+ from .resources.voice_isolation import VoiceIsolationResource
+
+ return VoiceIsolationResource(self)
+
+ @cached_property
+ def voice_dubbing(self) -> VoiceDubbingResource:
+ from .resources.voice_dubbing import VoiceDubbingResource
+
+ return VoiceDubbingResource(self)
+
+ @cached_property
+ def speech_to_speech(self) -> SpeechToSpeechResource:
+ from .resources.speech_to_speech import SpeechToSpeechResource
+
+ return SpeechToSpeechResource(self)
+
+ @cached_property
+ def organization(self) -> OrganizationResource:
+ from .resources.organization import OrganizationResource
+
+ return OrganizationResource(self)
+
+ @cached_property
+ def with_raw_response(self) -> RunwayMLWithRawResponse:
+ return RunwayMLWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> RunwayMLWithStreamedResponse:
+ return RunwayMLWithStreamedResponse(self)
@property
@override
@@ -261,23 +336,6 @@ def _make_status_error(
class AsyncRunwayML(AsyncAPIClient):
- tasks: tasks.AsyncTasksResource
- image_to_video: image_to_video.AsyncImageToVideoResource
- video_to_video: video_to_video.AsyncVideoToVideoResource
- text_to_video: text_to_video.AsyncTextToVideoResource
- text_to_image: text_to_image.AsyncTextToImageResource
- video_upscale: video_upscale.AsyncVideoUpscaleResource
- character_performance: character_performance.AsyncCharacterPerformanceResource
- text_to_speech: text_to_speech.AsyncTextToSpeechResource
- sound_effect: sound_effect.AsyncSoundEffectResource
- voice_isolation: voice_isolation.AsyncVoiceIsolationResource
- voice_dubbing: voice_dubbing.AsyncVoiceDubbingResource
- speech_to_speech: speech_to_speech.AsyncSpeechToSpeechResource
- organization: organization.AsyncOrganizationResource
- uploads: uploads.AsyncUploadsResource
- with_raw_response: AsyncRunwayMLWithRawResponse
- with_streaming_response: AsyncRunwayMLWithStreamedResponse
-
# client options
api_key: str
runway_version: str
@@ -338,22 +396,97 @@ def __init__(
_strict_response_validation=_strict_response_validation,
)
- self.tasks = tasks.AsyncTasksResource(self)
- self.image_to_video = image_to_video.AsyncImageToVideoResource(self)
- self.video_to_video = video_to_video.AsyncVideoToVideoResource(self)
- self.text_to_video = text_to_video.AsyncTextToVideoResource(self)
- self.text_to_image = text_to_image.AsyncTextToImageResource(self)
- self.video_upscale = video_upscale.AsyncVideoUpscaleResource(self)
- self.character_performance = character_performance.AsyncCharacterPerformanceResource(self)
- self.text_to_speech = text_to_speech.AsyncTextToSpeechResource(self)
- self.sound_effect = sound_effect.AsyncSoundEffectResource(self)
- self.voice_isolation = voice_isolation.AsyncVoiceIsolationResource(self)
- self.voice_dubbing = voice_dubbing.AsyncVoiceDubbingResource(self)
- self.speech_to_speech = speech_to_speech.AsyncSpeechToSpeechResource(self)
- self.organization = organization.AsyncOrganizationResource(self)
- self.uploads = uploads.AsyncUploadsResource(self)
- self.with_raw_response = AsyncRunwayMLWithRawResponse(self)
- self.with_streaming_response = AsyncRunwayMLWithStreamedResponse(self)
+ @cached_property
+ def tasks(self) -> AsyncTasksResource:
+ from .resources.tasks import AsyncTasksResource
+
+ return AsyncTasksResource(self)
+
+ @cached_property
+ def uploads(self) -> AsyncUploadsResource:
+ from .resources.uploads import AsyncUploadsResource
+
+ return AsyncUploadsResource(self)
+
+ @cached_property
+ def image_to_video(self) -> AsyncImageToVideoResource:
+ from .resources.image_to_video import AsyncImageToVideoResource
+
+ return AsyncImageToVideoResource(self)
+
+ @cached_property
+ def video_to_video(self) -> AsyncVideoToVideoResource:
+ from .resources.video_to_video import AsyncVideoToVideoResource
+
+ return AsyncVideoToVideoResource(self)
+
+ @cached_property
+ def text_to_video(self) -> AsyncTextToVideoResource:
+ from .resources.text_to_video import AsyncTextToVideoResource
+
+ return AsyncTextToVideoResource(self)
+
+ @cached_property
+ def text_to_image(self) -> AsyncTextToImageResource:
+ from .resources.text_to_image import AsyncTextToImageResource
+
+ return AsyncTextToImageResource(self)
+
+ @cached_property
+ def video_upscale(self) -> AsyncVideoUpscaleResource:
+ from .resources.video_upscale import AsyncVideoUpscaleResource
+
+ return AsyncVideoUpscaleResource(self)
+
+ @cached_property
+ def character_performance(self) -> AsyncCharacterPerformanceResource:
+ from .resources.character_performance import AsyncCharacterPerformanceResource
+
+ return AsyncCharacterPerformanceResource(self)
+
+ @cached_property
+ def text_to_speech(self) -> AsyncTextToSpeechResource:
+ from .resources.text_to_speech import AsyncTextToSpeechResource
+
+ return AsyncTextToSpeechResource(self)
+
+ @cached_property
+ def sound_effect(self) -> AsyncSoundEffectResource:
+ from .resources.sound_effect import AsyncSoundEffectResource
+
+ return AsyncSoundEffectResource(self)
+
+ @cached_property
+ def voice_isolation(self) -> AsyncVoiceIsolationResource:
+ from .resources.voice_isolation import AsyncVoiceIsolationResource
+
+ return AsyncVoiceIsolationResource(self)
+
+ @cached_property
+ def voice_dubbing(self) -> AsyncVoiceDubbingResource:
+ from .resources.voice_dubbing import AsyncVoiceDubbingResource
+
+ return AsyncVoiceDubbingResource(self)
+
+ @cached_property
+ def speech_to_speech(self) -> AsyncSpeechToSpeechResource:
+ from .resources.speech_to_speech import AsyncSpeechToSpeechResource
+
+ return AsyncSpeechToSpeechResource(self)
+
+ @cached_property
+ def organization(self) -> AsyncOrganizationResource:
+ from .resources.organization import AsyncOrganizationResource
+
+ return AsyncOrganizationResource(self)
+
+ @cached_property
+ def with_raw_response(self) -> AsyncRunwayMLWithRawResponse:
+ return AsyncRunwayMLWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncRunwayMLWithStreamedResponse:
+ return AsyncRunwayMLWithStreamedResponse(self)
@property
@override
@@ -464,85 +597,367 @@ def _make_status_error(
class RunwayMLWithRawResponse:
+ _client: RunwayML
+
def __init__(self, client: RunwayML) -> None:
- self.tasks = tasks.TasksResourceWithRawResponse(client.tasks)
- self.image_to_video = image_to_video.ImageToVideoResourceWithRawResponse(client.image_to_video)
- self.video_to_video = video_to_video.VideoToVideoResourceWithRawResponse(client.video_to_video)
- self.text_to_video = text_to_video.TextToVideoResourceWithRawResponse(client.text_to_video)
- self.text_to_image = text_to_image.TextToImageResourceWithRawResponse(client.text_to_image)
- self.video_upscale = video_upscale.VideoUpscaleResourceWithRawResponse(client.video_upscale)
- self.character_performance = character_performance.CharacterPerformanceResourceWithRawResponse(
- client.character_performance
- )
- self.text_to_speech = text_to_speech.TextToSpeechResourceWithRawResponse(client.text_to_speech)
- self.sound_effect = sound_effect.SoundEffectResourceWithRawResponse(client.sound_effect)
- self.voice_isolation = voice_isolation.VoiceIsolationResourceWithRawResponse(client.voice_isolation)
- self.voice_dubbing = voice_dubbing.VoiceDubbingResourceWithRawResponse(client.voice_dubbing)
- self.speech_to_speech = speech_to_speech.SpeechToSpeechResourceWithRawResponse(client.speech_to_speech)
- self.organization = organization.OrganizationResourceWithRawResponse(client.organization)
- self.uploads = uploads.UploadsResourceWithRawResponse(client.uploads)
+ self._client = client
+
+ @cached_property
+ def tasks(self) -> tasks.TasksResourceWithRawResponse:
+ from .resources.tasks import TasksResourceWithRawResponse
+
+ return TasksResourceWithRawResponse(self._client.tasks)
+
+ @cached_property
+ def uploads(self) -> uploads.UploadsResourceWithRawResponse:
+ from .resources.uploads import UploadsResourceWithRawResponse
+
+ return UploadsResourceWithRawResponse(self._client.uploads)
+
+ @cached_property
+ def image_to_video(self) -> image_to_video.ImageToVideoResourceWithRawResponse:
+ from .resources.image_to_video import ImageToVideoResourceWithRawResponse
+
+ return ImageToVideoResourceWithRawResponse(self._client.image_to_video)
+
+ @cached_property
+ def video_to_video(self) -> video_to_video.VideoToVideoResourceWithRawResponse:
+ from .resources.video_to_video import VideoToVideoResourceWithRawResponse
+
+ return VideoToVideoResourceWithRawResponse(self._client.video_to_video)
+
+ @cached_property
+ def text_to_video(self) -> text_to_video.TextToVideoResourceWithRawResponse:
+ from .resources.text_to_video import TextToVideoResourceWithRawResponse
+
+ return TextToVideoResourceWithRawResponse(self._client.text_to_video)
+
+ @cached_property
+ def text_to_image(self) -> text_to_image.TextToImageResourceWithRawResponse:
+ from .resources.text_to_image import TextToImageResourceWithRawResponse
+
+ return TextToImageResourceWithRawResponse(self._client.text_to_image)
+
+ @cached_property
+ def video_upscale(self) -> video_upscale.VideoUpscaleResourceWithRawResponse:
+ from .resources.video_upscale import VideoUpscaleResourceWithRawResponse
+
+ return VideoUpscaleResourceWithRawResponse(self._client.video_upscale)
+
+ @cached_property
+ def character_performance(self) -> character_performance.CharacterPerformanceResourceWithRawResponse:
+ from .resources.character_performance import CharacterPerformanceResourceWithRawResponse
+
+ return CharacterPerformanceResourceWithRawResponse(self._client.character_performance)
+
+ @cached_property
+ def text_to_speech(self) -> text_to_speech.TextToSpeechResourceWithRawResponse:
+ from .resources.text_to_speech import TextToSpeechResourceWithRawResponse
+
+ return TextToSpeechResourceWithRawResponse(self._client.text_to_speech)
+
+ @cached_property
+ def sound_effect(self) -> sound_effect.SoundEffectResourceWithRawResponse:
+ from .resources.sound_effect import SoundEffectResourceWithRawResponse
+
+ return SoundEffectResourceWithRawResponse(self._client.sound_effect)
+
+ @cached_property
+ def voice_isolation(self) -> voice_isolation.VoiceIsolationResourceWithRawResponse:
+ from .resources.voice_isolation import VoiceIsolationResourceWithRawResponse
+
+ return VoiceIsolationResourceWithRawResponse(self._client.voice_isolation)
+
+ @cached_property
+ def voice_dubbing(self) -> voice_dubbing.VoiceDubbingResourceWithRawResponse:
+ from .resources.voice_dubbing import VoiceDubbingResourceWithRawResponse
+
+ return VoiceDubbingResourceWithRawResponse(self._client.voice_dubbing)
+
+ @cached_property
+ def speech_to_speech(self) -> speech_to_speech.SpeechToSpeechResourceWithRawResponse:
+ from .resources.speech_to_speech import SpeechToSpeechResourceWithRawResponse
+
+ return SpeechToSpeechResourceWithRawResponse(self._client.speech_to_speech)
+
+ @cached_property
+ def organization(self) -> organization.OrganizationResourceWithRawResponse:
+ from .resources.organization import OrganizationResourceWithRawResponse
+
+ return OrganizationResourceWithRawResponse(self._client.organization)
class AsyncRunwayMLWithRawResponse:
+ _client: AsyncRunwayML
+
def __init__(self, client: AsyncRunwayML) -> None:
- self.tasks = tasks.AsyncTasksResourceWithRawResponse(client.tasks)
- self.image_to_video = image_to_video.AsyncImageToVideoResourceWithRawResponse(client.image_to_video)
- self.video_to_video = video_to_video.AsyncVideoToVideoResourceWithRawResponse(client.video_to_video)
- self.text_to_video = text_to_video.AsyncTextToVideoResourceWithRawResponse(client.text_to_video)
- self.text_to_image = text_to_image.AsyncTextToImageResourceWithRawResponse(client.text_to_image)
- self.video_upscale = video_upscale.AsyncVideoUpscaleResourceWithRawResponse(client.video_upscale)
- self.character_performance = character_performance.AsyncCharacterPerformanceResourceWithRawResponse(
- client.character_performance
- )
- self.text_to_speech = text_to_speech.AsyncTextToSpeechResourceWithRawResponse(client.text_to_speech)
- self.sound_effect = sound_effect.AsyncSoundEffectResourceWithRawResponse(client.sound_effect)
- self.voice_isolation = voice_isolation.AsyncVoiceIsolationResourceWithRawResponse(client.voice_isolation)
- self.voice_dubbing = voice_dubbing.AsyncVoiceDubbingResourceWithRawResponse(client.voice_dubbing)
- self.speech_to_speech = speech_to_speech.AsyncSpeechToSpeechResourceWithRawResponse(client.speech_to_speech)
- self.organization = organization.AsyncOrganizationResourceWithRawResponse(client.organization)
- self.uploads = uploads.AsyncUploadsResourceWithRawResponse(client.uploads)
+ self._client = client
+
+ @cached_property
+ def tasks(self) -> tasks.AsyncTasksResourceWithRawResponse:
+ from .resources.tasks import AsyncTasksResourceWithRawResponse
+
+ return AsyncTasksResourceWithRawResponse(self._client.tasks)
+
+ @cached_property
+ def uploads(self) -> uploads.AsyncUploadsResourceWithRawResponse:
+ from .resources.uploads import AsyncUploadsResourceWithRawResponse
+
+ return AsyncUploadsResourceWithRawResponse(self._client.uploads)
+
+ @cached_property
+ def image_to_video(self) -> image_to_video.AsyncImageToVideoResourceWithRawResponse:
+ from .resources.image_to_video import AsyncImageToVideoResourceWithRawResponse
+
+ return AsyncImageToVideoResourceWithRawResponse(self._client.image_to_video)
+
+ @cached_property
+ def video_to_video(self) -> video_to_video.AsyncVideoToVideoResourceWithRawResponse:
+ from .resources.video_to_video import AsyncVideoToVideoResourceWithRawResponse
+
+ return AsyncVideoToVideoResourceWithRawResponse(self._client.video_to_video)
+
+ @cached_property
+ def text_to_video(self) -> text_to_video.AsyncTextToVideoResourceWithRawResponse:
+ from .resources.text_to_video import AsyncTextToVideoResourceWithRawResponse
+
+ return AsyncTextToVideoResourceWithRawResponse(self._client.text_to_video)
+
+ @cached_property
+ def text_to_image(self) -> text_to_image.AsyncTextToImageResourceWithRawResponse:
+ from .resources.text_to_image import AsyncTextToImageResourceWithRawResponse
+
+ return AsyncTextToImageResourceWithRawResponse(self._client.text_to_image)
+
+ @cached_property
+ def video_upscale(self) -> video_upscale.AsyncVideoUpscaleResourceWithRawResponse:
+ from .resources.video_upscale import AsyncVideoUpscaleResourceWithRawResponse
+
+ return AsyncVideoUpscaleResourceWithRawResponse(self._client.video_upscale)
+
+ @cached_property
+ def character_performance(self) -> character_performance.AsyncCharacterPerformanceResourceWithRawResponse:
+ from .resources.character_performance import AsyncCharacterPerformanceResourceWithRawResponse
+
+ return AsyncCharacterPerformanceResourceWithRawResponse(self._client.character_performance)
+
+ @cached_property
+ def text_to_speech(self) -> text_to_speech.AsyncTextToSpeechResourceWithRawResponse:
+ from .resources.text_to_speech import AsyncTextToSpeechResourceWithRawResponse
+
+ return AsyncTextToSpeechResourceWithRawResponse(self._client.text_to_speech)
+
+ @cached_property
+ def sound_effect(self) -> sound_effect.AsyncSoundEffectResourceWithRawResponse:
+ from .resources.sound_effect import AsyncSoundEffectResourceWithRawResponse
+
+ return AsyncSoundEffectResourceWithRawResponse(self._client.sound_effect)
+
+ @cached_property
+ def voice_isolation(self) -> voice_isolation.AsyncVoiceIsolationResourceWithRawResponse:
+ from .resources.voice_isolation import AsyncVoiceIsolationResourceWithRawResponse
+
+ return AsyncVoiceIsolationResourceWithRawResponse(self._client.voice_isolation)
+
+ @cached_property
+ def voice_dubbing(self) -> voice_dubbing.AsyncVoiceDubbingResourceWithRawResponse:
+ from .resources.voice_dubbing import AsyncVoiceDubbingResourceWithRawResponse
+
+ return AsyncVoiceDubbingResourceWithRawResponse(self._client.voice_dubbing)
+
+ @cached_property
+ def speech_to_speech(self) -> speech_to_speech.AsyncSpeechToSpeechResourceWithRawResponse:
+ from .resources.speech_to_speech import AsyncSpeechToSpeechResourceWithRawResponse
+
+ return AsyncSpeechToSpeechResourceWithRawResponse(self._client.speech_to_speech)
+
+ @cached_property
+ def organization(self) -> organization.AsyncOrganizationResourceWithRawResponse:
+ from .resources.organization import AsyncOrganizationResourceWithRawResponse
+
+ return AsyncOrganizationResourceWithRawResponse(self._client.organization)
class RunwayMLWithStreamedResponse:
+ _client: RunwayML
+
def __init__(self, client: RunwayML) -> None:
- self.tasks = tasks.TasksResourceWithStreamingResponse(client.tasks)
- self.image_to_video = image_to_video.ImageToVideoResourceWithStreamingResponse(client.image_to_video)
- self.video_to_video = video_to_video.VideoToVideoResourceWithStreamingResponse(client.video_to_video)
- self.text_to_video = text_to_video.TextToVideoResourceWithStreamingResponse(client.text_to_video)
- self.text_to_image = text_to_image.TextToImageResourceWithStreamingResponse(client.text_to_image)
- self.video_upscale = video_upscale.VideoUpscaleResourceWithStreamingResponse(client.video_upscale)
- self.character_performance = character_performance.CharacterPerformanceResourceWithStreamingResponse(
- client.character_performance
- )
- self.text_to_speech = text_to_speech.TextToSpeechResourceWithStreamingResponse(client.text_to_speech)
- self.sound_effect = sound_effect.SoundEffectResourceWithStreamingResponse(client.sound_effect)
- self.voice_isolation = voice_isolation.VoiceIsolationResourceWithStreamingResponse(client.voice_isolation)
- self.voice_dubbing = voice_dubbing.VoiceDubbingResourceWithStreamingResponse(client.voice_dubbing)
- self.speech_to_speech = speech_to_speech.SpeechToSpeechResourceWithStreamingResponse(client.speech_to_speech)
- self.organization = organization.OrganizationResourceWithStreamingResponse(client.organization)
- self.uploads = uploads.UploadsResourceWithStreamingResponse(client.uploads)
+ self._client = client
+
+ @cached_property
+ def tasks(self) -> tasks.TasksResourceWithStreamingResponse:
+ from .resources.tasks import TasksResourceWithStreamingResponse
+
+ return TasksResourceWithStreamingResponse(self._client.tasks)
+
+ @cached_property
+ def uploads(self) -> uploads.UploadsResourceWithStreamingResponse:
+ from .resources.uploads import UploadsResourceWithStreamingResponse
+
+ return UploadsResourceWithStreamingResponse(self._client.uploads)
+
+ @cached_property
+ def image_to_video(self) -> image_to_video.ImageToVideoResourceWithStreamingResponse:
+ from .resources.image_to_video import ImageToVideoResourceWithStreamingResponse
+
+ return ImageToVideoResourceWithStreamingResponse(self._client.image_to_video)
+
+ @cached_property
+ def video_to_video(self) -> video_to_video.VideoToVideoResourceWithStreamingResponse:
+ from .resources.video_to_video import VideoToVideoResourceWithStreamingResponse
+
+ return VideoToVideoResourceWithStreamingResponse(self._client.video_to_video)
+
+ @cached_property
+ def text_to_video(self) -> text_to_video.TextToVideoResourceWithStreamingResponse:
+ from .resources.text_to_video import TextToVideoResourceWithStreamingResponse
+
+ return TextToVideoResourceWithStreamingResponse(self._client.text_to_video)
+
+ @cached_property
+ def text_to_image(self) -> text_to_image.TextToImageResourceWithStreamingResponse:
+ from .resources.text_to_image import TextToImageResourceWithStreamingResponse
+
+ return TextToImageResourceWithStreamingResponse(self._client.text_to_image)
+
+ @cached_property
+ def video_upscale(self) -> video_upscale.VideoUpscaleResourceWithStreamingResponse:
+ from .resources.video_upscale import VideoUpscaleResourceWithStreamingResponse
+
+ return VideoUpscaleResourceWithStreamingResponse(self._client.video_upscale)
+
+ @cached_property
+ def character_performance(self) -> character_performance.CharacterPerformanceResourceWithStreamingResponse:
+ from .resources.character_performance import CharacterPerformanceResourceWithStreamingResponse
+
+ return CharacterPerformanceResourceWithStreamingResponse(self._client.character_performance)
+
+ @cached_property
+ def text_to_speech(self) -> text_to_speech.TextToSpeechResourceWithStreamingResponse:
+ from .resources.text_to_speech import TextToSpeechResourceWithStreamingResponse
+
+ return TextToSpeechResourceWithStreamingResponse(self._client.text_to_speech)
+
+ @cached_property
+ def sound_effect(self) -> sound_effect.SoundEffectResourceWithStreamingResponse:
+ from .resources.sound_effect import SoundEffectResourceWithStreamingResponse
+
+ return SoundEffectResourceWithStreamingResponse(self._client.sound_effect)
+
+ @cached_property
+ def voice_isolation(self) -> voice_isolation.VoiceIsolationResourceWithStreamingResponse:
+ from .resources.voice_isolation import VoiceIsolationResourceWithStreamingResponse
+
+ return VoiceIsolationResourceWithStreamingResponse(self._client.voice_isolation)
+
+ @cached_property
+ def voice_dubbing(self) -> voice_dubbing.VoiceDubbingResourceWithStreamingResponse:
+ from .resources.voice_dubbing import VoiceDubbingResourceWithStreamingResponse
+
+ return VoiceDubbingResourceWithStreamingResponse(self._client.voice_dubbing)
+
+ @cached_property
+ def speech_to_speech(self) -> speech_to_speech.SpeechToSpeechResourceWithStreamingResponse:
+ from .resources.speech_to_speech import SpeechToSpeechResourceWithStreamingResponse
+
+ return SpeechToSpeechResourceWithStreamingResponse(self._client.speech_to_speech)
+
+ @cached_property
+ def organization(self) -> organization.OrganizationResourceWithStreamingResponse:
+ from .resources.organization import OrganizationResourceWithStreamingResponse
+
+ return OrganizationResourceWithStreamingResponse(self._client.organization)
class AsyncRunwayMLWithStreamedResponse:
+ _client: AsyncRunwayML
+
def __init__(self, client: AsyncRunwayML) -> None:
- self.tasks = tasks.AsyncTasksResourceWithStreamingResponse(client.tasks)
- self.image_to_video = image_to_video.AsyncImageToVideoResourceWithStreamingResponse(client.image_to_video)
- self.video_to_video = video_to_video.AsyncVideoToVideoResourceWithStreamingResponse(client.video_to_video)
- self.text_to_video = text_to_video.AsyncTextToVideoResourceWithStreamingResponse(client.text_to_video)
- self.text_to_image = text_to_image.AsyncTextToImageResourceWithStreamingResponse(client.text_to_image)
- self.video_upscale = video_upscale.AsyncVideoUpscaleResourceWithStreamingResponse(client.video_upscale)
- self.character_performance = character_performance.AsyncCharacterPerformanceResourceWithStreamingResponse(
- client.character_performance
- )
- self.text_to_speech = text_to_speech.AsyncTextToSpeechResourceWithStreamingResponse(client.text_to_speech)
- self.sound_effect = sound_effect.AsyncSoundEffectResourceWithStreamingResponse(client.sound_effect)
- self.voice_isolation = voice_isolation.AsyncVoiceIsolationResourceWithStreamingResponse(client.voice_isolation)
- self.voice_dubbing = voice_dubbing.AsyncVoiceDubbingResourceWithStreamingResponse(client.voice_dubbing)
- self.speech_to_speech = speech_to_speech.AsyncSpeechToSpeechResourceWithStreamingResponse(
- client.speech_to_speech
- )
- self.organization = organization.AsyncOrganizationResourceWithStreamingResponse(client.organization)
- self.uploads = uploads.AsyncUploadsResourceWithStreamingResponse(client.uploads)
+ self._client = client
+
+ @cached_property
+ def tasks(self) -> tasks.AsyncTasksResourceWithStreamingResponse:
+ from .resources.tasks import AsyncTasksResourceWithStreamingResponse
+
+ return AsyncTasksResourceWithStreamingResponse(self._client.tasks)
+
+ @cached_property
+ def uploads(self) -> uploads.AsyncUploadsResourceWithStreamingResponse:
+ from .resources.uploads import AsyncUploadsResourceWithStreamingResponse
+
+ return AsyncUploadsResourceWithStreamingResponse(self._client.uploads)
+
+ @cached_property
+ def image_to_video(self) -> image_to_video.AsyncImageToVideoResourceWithStreamingResponse:
+ from .resources.image_to_video import AsyncImageToVideoResourceWithStreamingResponse
+
+ return AsyncImageToVideoResourceWithStreamingResponse(self._client.image_to_video)
+
+ @cached_property
+ def video_to_video(self) -> video_to_video.AsyncVideoToVideoResourceWithStreamingResponse:
+ from .resources.video_to_video import AsyncVideoToVideoResourceWithStreamingResponse
+
+ return AsyncVideoToVideoResourceWithStreamingResponse(self._client.video_to_video)
+
+ @cached_property
+ def text_to_video(self) -> text_to_video.AsyncTextToVideoResourceWithStreamingResponse:
+ from .resources.text_to_video import AsyncTextToVideoResourceWithStreamingResponse
+
+ return AsyncTextToVideoResourceWithStreamingResponse(self._client.text_to_video)
+
+ @cached_property
+ def text_to_image(self) -> text_to_image.AsyncTextToImageResourceWithStreamingResponse:
+ from .resources.text_to_image import AsyncTextToImageResourceWithStreamingResponse
+
+ return AsyncTextToImageResourceWithStreamingResponse(self._client.text_to_image)
+
+ @cached_property
+ def video_upscale(self) -> video_upscale.AsyncVideoUpscaleResourceWithStreamingResponse:
+ from .resources.video_upscale import AsyncVideoUpscaleResourceWithStreamingResponse
+
+ return AsyncVideoUpscaleResourceWithStreamingResponse(self._client.video_upscale)
+
+ @cached_property
+ def character_performance(self) -> character_performance.AsyncCharacterPerformanceResourceWithStreamingResponse:
+ from .resources.character_performance import AsyncCharacterPerformanceResourceWithStreamingResponse
+
+ return AsyncCharacterPerformanceResourceWithStreamingResponse(self._client.character_performance)
+
+ @cached_property
+ def text_to_speech(self) -> text_to_speech.AsyncTextToSpeechResourceWithStreamingResponse:
+ from .resources.text_to_speech import AsyncTextToSpeechResourceWithStreamingResponse
+
+ return AsyncTextToSpeechResourceWithStreamingResponse(self._client.text_to_speech)
+
+ @cached_property
+ def sound_effect(self) -> sound_effect.AsyncSoundEffectResourceWithStreamingResponse:
+ from .resources.sound_effect import AsyncSoundEffectResourceWithStreamingResponse
+
+ return AsyncSoundEffectResourceWithStreamingResponse(self._client.sound_effect)
+
+ @cached_property
+ def voice_isolation(self) -> voice_isolation.AsyncVoiceIsolationResourceWithStreamingResponse:
+ from .resources.voice_isolation import AsyncVoiceIsolationResourceWithStreamingResponse
+
+ return AsyncVoiceIsolationResourceWithStreamingResponse(self._client.voice_isolation)
+
+ @cached_property
+ def voice_dubbing(self) -> voice_dubbing.AsyncVoiceDubbingResourceWithStreamingResponse:
+ from .resources.voice_dubbing import AsyncVoiceDubbingResourceWithStreamingResponse
+
+ return AsyncVoiceDubbingResourceWithStreamingResponse(self._client.voice_dubbing)
+
+ @cached_property
+ def speech_to_speech(self) -> speech_to_speech.AsyncSpeechToSpeechResourceWithStreamingResponse:
+ from .resources.speech_to_speech import AsyncSpeechToSpeechResourceWithStreamingResponse
+
+ return AsyncSpeechToSpeechResourceWithStreamingResponse(self._client.speech_to_speech)
+
+ @cached_property
+ def organization(self) -> organization.AsyncOrganizationResourceWithStreamingResponse:
+ from .resources.organization import AsyncOrganizationResourceWithStreamingResponse
+
+ return AsyncOrganizationResourceWithStreamingResponse(self._client.organization)
Client = RunwayML
diff --git a/src/runwayml/lib/polling.py b/src/runwayml/lib/polling.py
index d91c537..b3b8750 100644
--- a/src/runwayml/lib/polling.py
+++ b/src/runwayml/lib/polling.py
@@ -129,34 +129,71 @@ def __init__(self, task_details: TaskRetrieveResponse):
super().__init__(f"Task timed out")
-
class AwaitablePending(AwaitableTaskResponseMixin, Pending): ...
+
+
class AwaitableThrottled(AwaitableTaskResponseMixin, Throttled): ...
+
+
class AwaitableCancelled(AwaitableTaskResponseMixin, Cancelled): ...
+
+
class AwaitableRunning(AwaitableTaskResponseMixin, Running): ...
+
+
class AwaitableFailed(AwaitableTaskResponseMixin, Failed): ...
+
+
class AwaitableSucceeded(AwaitableTaskResponseMixin, Succeeded): ...
+
AwaitableTaskRetrieveResponse: TypeAlias = Annotated[
- Union[AwaitablePending, AwaitableThrottled, AwaitableCancelled, AwaitableRunning, AwaitableFailed, AwaitableSucceeded],
- PropertyInfo(discriminator="status")
+ Union[
+ AwaitablePending, AwaitableThrottled, AwaitableCancelled, AwaitableRunning, AwaitableFailed, AwaitableSucceeded
+ ],
+ PropertyInfo(discriminator="status"),
]
+
class AsyncAwaitablePending(AsyncAwaitableTaskResponseMixin, Pending): ...
+
+
class AsyncAwaitableThrottled(AsyncAwaitableTaskResponseMixin, Throttled): ...
+
+
class AsyncAwaitableCancelled(AsyncAwaitableTaskResponseMixin, Cancelled): ...
+
+
class AsyncAwaitableRunning(AsyncAwaitableTaskResponseMixin, Running): ...
+
+
class AsyncAwaitableFailed(AsyncAwaitableTaskResponseMixin, Failed): ...
+
+
class AsyncAwaitableSucceeded(AsyncAwaitableTaskResponseMixin, Succeeded): ...
+
AsyncAwaitableTaskRetrieveResponse: TypeAlias = Annotated[
- Union[AsyncAwaitablePending, AsyncAwaitableThrottled, AsyncAwaitableCancelled, AsyncAwaitableRunning, AsyncAwaitableFailed, AsyncAwaitableSucceeded],
- PropertyInfo(discriminator="status")
+ Union[
+ AsyncAwaitablePending,
+ AsyncAwaitableThrottled,
+ AsyncAwaitableCancelled,
+ AsyncAwaitableRunning,
+ AsyncAwaitableFailed,
+ AsyncAwaitableSucceeded,
+ ],
+ PropertyInfo(discriminator="status"),
]
-def _make_sync_wait_for_task_output(client: "RunwayML") -> Callable[["AwaitableTaskResponseMixin", Union[float, None]], TaskRetrieveResponse]:
+
+def _make_sync_wait_for_task_output(
+ client: "RunwayML",
+) -> Callable[["AwaitableTaskResponseMixin", Union[float, None]], TaskRetrieveResponse]:
"""Create a wait_for_task_output method bound to the given client."""
- def wait_for_task_output(self: "AwaitableTaskResponseMixin", timeout: Union[float, None] = 60 * 10) -> TaskRetrieveResponse:
+
+ def wait_for_task_output(
+ self: "AwaitableTaskResponseMixin", timeout: Union[float, None] = 60 * 10
+ ) -> TaskRetrieveResponse:
start_time = time.time()
while True:
time.sleep(POLL_TIME + random.random() * POLL_JITTER - POLL_JITTER / 2)
@@ -167,19 +204,26 @@ def wait_for_task_output(self: "AwaitableTaskResponseMixin", timeout: Union[floa
raise TaskFailedError(task_details)
if timeout is not None and time.time() - start_time > timeout:
raise TaskTimeoutError(task_details)
+
return wait_for_task_output
def inject_sync_wait_method(client: "RunwayML", response: T) -> T:
"""Inject the wait_for_task_output method onto the response instance."""
import types
+
response.wait_for_task_output = types.MethodType(_make_sync_wait_for_task_output(client), response) # type: ignore[attr-defined]
return response
-def _make_async_wait_for_task_output(client: "AsyncRunwayML") -> Callable[["AsyncAwaitableTaskResponseMixin", Union[float, None]], Coroutine[None, None, TaskRetrieveResponse]]:
+def _make_async_wait_for_task_output(
+ client: "AsyncRunwayML",
+) -> Callable[["AsyncAwaitableTaskResponseMixin", Union[float, None]], Coroutine[None, None, TaskRetrieveResponse]]:
"""Create an async wait_for_task_output method bound to the given client."""
- async def wait_for_task_output(self: "AsyncAwaitableTaskResponseMixin", timeout: Union[float, None] = 60 * 10) -> TaskRetrieveResponse:
+
+ async def wait_for_task_output(
+ self: "AsyncAwaitableTaskResponseMixin", timeout: Union[float, None] = 60 * 10
+ ) -> TaskRetrieveResponse:
start_time = anyio.current_time()
while True:
await anyio.sleep(POLL_TIME + random.random() * POLL_JITTER - POLL_JITTER / 2)
@@ -190,11 +234,13 @@ async def wait_for_task_output(self: "AsyncAwaitableTaskResponseMixin", timeout:
raise TaskFailedError(task_details)
if timeout is not None and anyio.current_time() - start_time > timeout:
raise TaskTimeoutError(task_details)
+
return wait_for_task_output
def inject_async_wait_method(client: "AsyncRunwayML", response: T) -> T:
"""Inject the async wait_for_task_output method onto the response instance."""
import types
+
response.wait_for_task_output = types.MethodType(_make_async_wait_for_task_output(client), response) # type: ignore[attr-defined]
return response
diff --git a/src/runwayml/resources/tasks.py b/src/runwayml/resources/tasks.py
index 3803e98..f610695 100644
--- a/src/runwayml/resources/tasks.py
+++ b/src/runwayml/resources/tasks.py
@@ -78,7 +78,9 @@ def retrieve(
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
- cast_to=cast(Any, AwaitableTaskRetrieveResponse), # Union types cannot be passed in as arguments in the type system
+ cast_to=cast(
+ Any, AwaitableTaskRetrieveResponse
+ ), # Union types cannot be passed in as arguments in the type system
)
return cast(AwaitableTaskRetrieveResponse, inject_sync_wait_method(self._client, response))
@@ -174,7 +176,9 @@ async def retrieve(
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
- cast_to=cast(Any, AsyncAwaitableTaskRetrieveResponse), # Union types cannot be passed in as arguments in the type system
+ cast_to=cast(
+ Any, AsyncAwaitableTaskRetrieveResponse
+ ), # Union types cannot be passed in as arguments in the type system
)
return cast(AsyncAwaitableTaskRetrieveResponse, inject_async_wait_method(self._client, response))
diff --git a/src/runwayml/resources/uploads.py b/src/runwayml/resources/uploads.py
index 92b80c4..27c2898 100644
--- a/src/runwayml/resources/uploads.py
+++ b/src/runwayml/resources/uploads.py
@@ -202,13 +202,11 @@ def create_ephemeral(
),
cast_to=_RunwayUploadStartedResponse,
)
-
- file_tuple = _build_file_tuple_with_filename(
- filename, _transform_file(file)
- )
+
+ file_tuple = _build_file_tuple_with_filename(filename, _transform_file(file))
form_data = _prepare_upload_data(upload_placeholder.fields, file_metadata)
upload_timeout = _get_upload_timeout(timeout, self._client.timeout)
-
+
with httpx.Client(timeout=upload_timeout) as client:
response = client.post(
upload_placeholder.uploadUrl,
@@ -216,7 +214,7 @@ def create_ephemeral(
files={"file": file_tuple},
)
_handle_upload_errors(response, upload_placeholder.uploadUrl)
-
+
return UploadCreateEphemeralResponse(uri=upload_placeholder.runwayUri)
@@ -286,13 +284,11 @@ async def create_ephemeral(
),
cast_to=_RunwayUploadStartedResponse,
)
-
- file_tuple = _build_file_tuple_with_filename(
- filename, await _async_transform_file(file)
- )
+
+ file_tuple = _build_file_tuple_with_filename(filename, await _async_transform_file(file))
form_data = _prepare_upload_data(upload_placeholder.fields, file_metadata)
upload_timeout = _get_upload_timeout(timeout, self._client.timeout)
-
+
async with httpx.AsyncClient(timeout=upload_timeout) as client:
response = await client.post(
upload_placeholder.uploadUrl,
@@ -300,7 +296,7 @@ async def create_ephemeral(
files={"file": file_tuple},
)
_handle_upload_errors(response, upload_placeholder.uploadUrl)
-
+
return UploadCreateEphemeralResponse(uri=upload_placeholder.runwayUri)
diff --git a/src/runwayml/types/upload_create_ephemeral_response.py b/src/runwayml/types/upload_create_ephemeral_response.py
index 2ef6067..edccb50 100644
--- a/src/runwayml/types/upload_create_ephemeral_response.py
+++ b/src/runwayml/types/upload_create_ephemeral_response.py
@@ -8,4 +8,3 @@
class UploadCreateEphemeralResponse(BaseModel):
uri: str
"""The Runway upload URI to use in other API generation requests."""
-
diff --git a/tests/api_resources/test_uploads.py b/tests/api_resources/test_uploads.py
index 8916101..7086558 100644
--- a/tests/api_resources/test_uploads.py
+++ b/tests/api_resources/test_uploads.py
@@ -123,4 +123,3 @@ async def test_create_ephemeral_accepts_valid_files(
finally:
if file_type == "file_object":
file.close()
-
From c6b880232812c60dce1b0b23678a70c7e158ae84 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Thu, 18 Dec 2025 03:25:49 +0000
Subject: [PATCH 05/11] fix: use async_to_httpx_files in patch method
---
src/runwayml/_base_client.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/runwayml/_base_client.py b/src/runwayml/_base_client.py
index cc0bf65..3902c8c 100644
--- a/src/runwayml/_base_client.py
+++ b/src/runwayml/_base_client.py
@@ -1774,7 +1774,7 @@ async def patch(
options: RequestOptions = {},
) -> ResponseT:
opts = FinalRequestOptions.construct(
- method="patch", url=path, json_data=body, files=to_httpx_files(files), **options
+ method="patch", url=path, json_data=body, files=await async_to_httpx_files(files), **options
)
return await self.request(cast_to, opts)
From 4e5931e064f4596d31f9c5c71abb24ad5f8a1727 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Fri, 19 Dec 2025 03:24:55 +0000
Subject: [PATCH 06/11] chore(internal): add `--fix` argument to lint script
---
scripts/lint | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/scripts/lint b/scripts/lint
index 87c45f7..369e389 100755
--- a/scripts/lint
+++ b/scripts/lint
@@ -4,8 +4,13 @@ set -e
cd "$(dirname "$0")/.."
-echo "==> Running lints"
-rye run lint
+if [ "$1" = "--fix" ]; then
+ echo "==> Running lints with --fix"
+ rye run fix:ruff
+else
+ echo "==> Running lints"
+ rye run lint
+fi
echo "==> Making sure it imports"
rye run python -c 'import runwayml'
From feac56919d1a635a1b3b577591d5a528c587c14e Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Tue, 6 Jan 2026 03:15:03 +0000
Subject: [PATCH 07/11] chore(internal): codegen related update
---
LICENSE | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/LICENSE b/LICENSE
index 7651810..b6e0cb5 100644
--- a/LICENSE
+++ b/LICENSE
@@ -186,7 +186,7 @@
same "printed page" as the copyright notice for easier
identification within third-party archives.
- Copyright 2025 RunwayML
+ Copyright 2026 RunwayML
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
From 384cd8bc9a23b0d9b7b37c737e8cb19d581f5198 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Wed, 14 Jan 2026 04:11:36 +0000
Subject: [PATCH 08/11] feat(client): add support for binary request streaming
---
src/runwayml/_base_client.py | 145 ++++++++++++++++++++++++---
src/runwayml/_models.py | 17 +++-
src/runwayml/_types.py | 9 ++
tests/test_client.py | 187 ++++++++++++++++++++++++++++++++++-
4 files changed, 344 insertions(+), 14 deletions(-)
diff --git a/src/runwayml/_base_client.py b/src/runwayml/_base_client.py
index 3902c8c..e3a7174 100644
--- a/src/runwayml/_base_client.py
+++ b/src/runwayml/_base_client.py
@@ -9,6 +9,7 @@
import inspect
import logging
import platform
+import warnings
import email.utils
from types import TracebackType
from random import random
@@ -51,9 +52,11 @@
ResponseT,
AnyMapping,
PostParser,
+ BinaryTypes,
RequestFiles,
HttpxSendArgs,
RequestOptions,
+ AsyncBinaryTypes,
HttpxRequestFiles,
ModelBuilderProtocol,
not_given,
@@ -477,8 +480,19 @@ def _build_request(
retries_taken: int = 0,
) -> httpx.Request:
if log.isEnabledFor(logging.DEBUG):
- log.debug("Request options: %s", model_dump(options, exclude_unset=True))
-
+ log.debug(
+ "Request options: %s",
+ model_dump(
+ options,
+ exclude_unset=True,
+ # Pydantic v1 can't dump every type we support in content, so we exclude it for now.
+ exclude={
+ "content",
+ }
+ if PYDANTIC_V1
+ else {},
+ ),
+ )
kwargs: dict[str, Any] = {}
json_data = options.json_data
@@ -532,7 +546,13 @@ def _build_request(
is_body_allowed = options.method.lower() != "get"
if is_body_allowed:
- if isinstance(json_data, bytes):
+ if options.content is not None and json_data is not None:
+ raise TypeError("Passing both `content` and `json_data` is not supported")
+ if options.content is not None and files is not None:
+ raise TypeError("Passing both `content` and `files` is not supported")
+ if options.content is not None:
+ kwargs["content"] = options.content
+ elif isinstance(json_data, bytes):
kwargs["content"] = json_data
else:
kwargs["json"] = json_data if is_given(json_data) else None
@@ -1194,6 +1214,7 @@ def post(
*,
cast_to: Type[ResponseT],
body: Body | None = None,
+ content: BinaryTypes | None = None,
options: RequestOptions = {},
files: RequestFiles | None = None,
stream: Literal[False] = False,
@@ -1206,6 +1227,7 @@ def post(
*,
cast_to: Type[ResponseT],
body: Body | None = None,
+ content: BinaryTypes | None = None,
options: RequestOptions = {},
files: RequestFiles | None = None,
stream: Literal[True],
@@ -1219,6 +1241,7 @@ def post(
*,
cast_to: Type[ResponseT],
body: Body | None = None,
+ content: BinaryTypes | None = None,
options: RequestOptions = {},
files: RequestFiles | None = None,
stream: bool,
@@ -1231,13 +1254,25 @@ def post(
*,
cast_to: Type[ResponseT],
body: Body | None = None,
+ content: BinaryTypes | None = None,
options: RequestOptions = {},
files: RequestFiles | None = None,
stream: bool = False,
stream_cls: type[_StreamT] | None = None,
) -> ResponseT | _StreamT:
+ if body is not None and content is not None:
+ raise TypeError("Passing both `body` and `content` is not supported")
+ if files is not None and content is not None:
+ raise TypeError("Passing both `files` and `content` is not supported")
+ if isinstance(body, bytes):
+ warnings.warn(
+ "Passing raw bytes as `body` is deprecated and will be removed in a future version. "
+ "Please pass raw bytes via the `content` parameter instead.",
+ DeprecationWarning,
+ stacklevel=2,
+ )
opts = FinalRequestOptions.construct(
- method="post", url=path, json_data=body, files=to_httpx_files(files), **options
+ method="post", url=path, json_data=body, content=content, files=to_httpx_files(files), **options
)
return cast(ResponseT, self.request(cast_to, opts, stream=stream, stream_cls=stream_cls))
@@ -1247,11 +1282,23 @@ def patch(
*,
cast_to: Type[ResponseT],
body: Body | None = None,
+ content: BinaryTypes | None = None,
files: RequestFiles | None = None,
options: RequestOptions = {},
) -> ResponseT:
+ if body is not None and content is not None:
+ raise TypeError("Passing both `body` and `content` is not supported")
+ if files is not None and content is not None:
+ raise TypeError("Passing both `files` and `content` is not supported")
+ if isinstance(body, bytes):
+ warnings.warn(
+ "Passing raw bytes as `body` is deprecated and will be removed in a future version. "
+ "Please pass raw bytes via the `content` parameter instead.",
+ DeprecationWarning,
+ stacklevel=2,
+ )
opts = FinalRequestOptions.construct(
- method="patch", url=path, json_data=body, files=to_httpx_files(files), **options
+ method="patch", url=path, json_data=body, content=content, files=to_httpx_files(files), **options
)
return self.request(cast_to, opts)
@@ -1261,11 +1308,23 @@ def put(
*,
cast_to: Type[ResponseT],
body: Body | None = None,
+ content: BinaryTypes | None = None,
files: RequestFiles | None = None,
options: RequestOptions = {},
) -> ResponseT:
+ if body is not None and content is not None:
+ raise TypeError("Passing both `body` and `content` is not supported")
+ if files is not None and content is not None:
+ raise TypeError("Passing both `files` and `content` is not supported")
+ if isinstance(body, bytes):
+ warnings.warn(
+ "Passing raw bytes as `body` is deprecated and will be removed in a future version. "
+ "Please pass raw bytes via the `content` parameter instead.",
+ DeprecationWarning,
+ stacklevel=2,
+ )
opts = FinalRequestOptions.construct(
- method="put", url=path, json_data=body, files=to_httpx_files(files), **options
+ method="put", url=path, json_data=body, content=content, files=to_httpx_files(files), **options
)
return self.request(cast_to, opts)
@@ -1275,9 +1334,19 @@ def delete(
*,
cast_to: Type[ResponseT],
body: Body | None = None,
+ content: BinaryTypes | None = None,
options: RequestOptions = {},
) -> ResponseT:
- opts = FinalRequestOptions.construct(method="delete", url=path, json_data=body, **options)
+ if body is not None and content is not None:
+ raise TypeError("Passing both `body` and `content` is not supported")
+ if isinstance(body, bytes):
+ warnings.warn(
+ "Passing raw bytes as `body` is deprecated and will be removed in a future version. "
+ "Please pass raw bytes via the `content` parameter instead.",
+ DeprecationWarning,
+ stacklevel=2,
+ )
+ opts = FinalRequestOptions.construct(method="delete", url=path, json_data=body, content=content, **options)
return self.request(cast_to, opts)
def get_api_list(
@@ -1717,6 +1786,7 @@ async def post(
*,
cast_to: Type[ResponseT],
body: Body | None = None,
+ content: AsyncBinaryTypes | None = None,
files: RequestFiles | None = None,
options: RequestOptions = {},
stream: Literal[False] = False,
@@ -1729,6 +1799,7 @@ async def post(
*,
cast_to: Type[ResponseT],
body: Body | None = None,
+ content: AsyncBinaryTypes | None = None,
files: RequestFiles | None = None,
options: RequestOptions = {},
stream: Literal[True],
@@ -1742,6 +1813,7 @@ async def post(
*,
cast_to: Type[ResponseT],
body: Body | None = None,
+ content: AsyncBinaryTypes | None = None,
files: RequestFiles | None = None,
options: RequestOptions = {},
stream: bool,
@@ -1754,13 +1826,25 @@ async def post(
*,
cast_to: Type[ResponseT],
body: Body | None = None,
+ content: AsyncBinaryTypes | None = None,
files: RequestFiles | None = None,
options: RequestOptions = {},
stream: bool = False,
stream_cls: type[_AsyncStreamT] | None = None,
) -> ResponseT | _AsyncStreamT:
+ if body is not None and content is not None:
+ raise TypeError("Passing both `body` and `content` is not supported")
+ if files is not None and content is not None:
+ raise TypeError("Passing both `files` and `content` is not supported")
+ if isinstance(body, bytes):
+ warnings.warn(
+ "Passing raw bytes as `body` is deprecated and will be removed in a future version. "
+ "Please pass raw bytes via the `content` parameter instead.",
+ DeprecationWarning,
+ stacklevel=2,
+ )
opts = FinalRequestOptions.construct(
- method="post", url=path, json_data=body, files=await async_to_httpx_files(files), **options
+ method="post", url=path, json_data=body, content=content, files=await async_to_httpx_files(files), **options
)
return await self.request(cast_to, opts, stream=stream, stream_cls=stream_cls)
@@ -1770,11 +1854,28 @@ async def patch(
*,
cast_to: Type[ResponseT],
body: Body | None = None,
+ content: AsyncBinaryTypes | None = None,
files: RequestFiles | None = None,
options: RequestOptions = {},
) -> ResponseT:
+ if body is not None and content is not None:
+ raise TypeError("Passing both `body` and `content` is not supported")
+ if files is not None and content is not None:
+ raise TypeError("Passing both `files` and `content` is not supported")
+ if isinstance(body, bytes):
+ warnings.warn(
+ "Passing raw bytes as `body` is deprecated and will be removed in a future version. "
+ "Please pass raw bytes via the `content` parameter instead.",
+ DeprecationWarning,
+ stacklevel=2,
+ )
opts = FinalRequestOptions.construct(
- method="patch", url=path, json_data=body, files=await async_to_httpx_files(files), **options
+ method="patch",
+ url=path,
+ json_data=body,
+ content=content,
+ files=await async_to_httpx_files(files),
+ **options,
)
return await self.request(cast_to, opts)
@@ -1784,11 +1885,23 @@ async def put(
*,
cast_to: Type[ResponseT],
body: Body | None = None,
+ content: AsyncBinaryTypes | None = None,
files: RequestFiles | None = None,
options: RequestOptions = {},
) -> ResponseT:
+ if body is not None and content is not None:
+ raise TypeError("Passing both `body` and `content` is not supported")
+ if files is not None and content is not None:
+ raise TypeError("Passing both `files` and `content` is not supported")
+ if isinstance(body, bytes):
+ warnings.warn(
+ "Passing raw bytes as `body` is deprecated and will be removed in a future version. "
+ "Please pass raw bytes via the `content` parameter instead.",
+ DeprecationWarning,
+ stacklevel=2,
+ )
opts = FinalRequestOptions.construct(
- method="put", url=path, json_data=body, files=await async_to_httpx_files(files), **options
+ method="put", url=path, json_data=body, content=content, files=await async_to_httpx_files(files), **options
)
return await self.request(cast_to, opts)
@@ -1798,9 +1911,19 @@ async def delete(
*,
cast_to: Type[ResponseT],
body: Body | None = None,
+ content: AsyncBinaryTypes | None = None,
options: RequestOptions = {},
) -> ResponseT:
- opts = FinalRequestOptions.construct(method="delete", url=path, json_data=body, **options)
+ if body is not None and content is not None:
+ raise TypeError("Passing both `body` and `content` is not supported")
+ if isinstance(body, bytes):
+ warnings.warn(
+ "Passing raw bytes as `body` is deprecated and will be removed in a future version. "
+ "Please pass raw bytes via the `content` parameter instead.",
+ DeprecationWarning,
+ stacklevel=2,
+ )
+ opts = FinalRequestOptions.construct(method="delete", url=path, json_data=body, content=content, **options)
return await self.request(cast_to, opts)
def get_api_list(
diff --git a/src/runwayml/_models.py b/src/runwayml/_models.py
index ca9500b..29070e0 100644
--- a/src/runwayml/_models.py
+++ b/src/runwayml/_models.py
@@ -3,7 +3,20 @@
import os
import inspect
import weakref
-from typing import TYPE_CHECKING, Any, Type, Union, Generic, TypeVar, Callable, Optional, cast
+from typing import (
+ IO,
+ TYPE_CHECKING,
+ Any,
+ Type,
+ Union,
+ Generic,
+ TypeVar,
+ Callable,
+ Iterable,
+ Optional,
+ AsyncIterable,
+ cast,
+)
from datetime import date, datetime
from typing_extensions import (
List,
@@ -787,6 +800,7 @@ class FinalRequestOptionsInput(TypedDict, total=False):
timeout: float | Timeout | None
files: HttpxRequestFiles | None
idempotency_key: str
+ content: Union[bytes, bytearray, IO[bytes], Iterable[bytes], AsyncIterable[bytes], None]
json_data: Body
extra_json: AnyMapping
follow_redirects: bool
@@ -805,6 +819,7 @@ class FinalRequestOptions(pydantic.BaseModel):
post_parser: Union[Callable[[Any], Any], NotGiven] = NotGiven()
follow_redirects: Union[bool, None] = None
+ content: Union[bytes, bytearray, IO[bytes], Iterable[bytes], AsyncIterable[bytes], None] = None
# It should be noted that we cannot use `json` here as that would override
# a BaseModel method in an incompatible fashion.
json_data: Union[Body, None] = None
diff --git a/src/runwayml/_types.py b/src/runwayml/_types.py
index 8facef4..bae9789 100644
--- a/src/runwayml/_types.py
+++ b/src/runwayml/_types.py
@@ -13,9 +13,11 @@
Mapping,
TypeVar,
Callable,
+ Iterable,
Iterator,
Optional,
Sequence,
+ AsyncIterable,
)
from typing_extensions import (
Set,
@@ -56,6 +58,13 @@
else:
Base64FileInput = Union[IO[bytes], PathLike]
FileContent = Union[IO[bytes], bytes, PathLike] # PathLike is not subscriptable in Python 3.8.
+
+
+# Used for sending raw binary data / streaming data in request bodies
+# e.g. for file uploads without multipart encoding
+BinaryTypes = Union[bytes, bytearray, IO[bytes], Iterable[bytes]]
+AsyncBinaryTypes = Union[bytes, bytearray, IO[bytes], AsyncIterable[bytes]]
+
FileTypes = Union[
# file (or bytes)
FileContent,
diff --git a/tests/test_client.py b/tests/test_client.py
index 68d28a2..3e4deaa 100644
--- a/tests/test_client.py
+++ b/tests/test_client.py
@@ -8,10 +8,11 @@
import json
import asyncio
import inspect
+import dataclasses
import tracemalloc
-from typing import Any, Union, cast
+from typing import Any, Union, TypeVar, Callable, Iterable, Iterator, Optional, Coroutine, cast
from unittest import mock
-from typing_extensions import Literal
+from typing_extensions import Literal, AsyncIterator, override
import httpx
import pytest
@@ -36,6 +37,7 @@
from .utils import update_env
+T = TypeVar("T")
base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
api_key = "My API Key"
@@ -50,6 +52,57 @@ def _low_retry_timeout(*_args: Any, **_kwargs: Any) -> float:
return 0.1
+def mirror_request_content(request: httpx.Request) -> httpx.Response:
+ return httpx.Response(200, content=request.content)
+
+
+# note: we can't use the httpx.MockTransport class as it consumes the request
+# body itself, which means we can't test that the body is read lazily
+class MockTransport(httpx.BaseTransport, httpx.AsyncBaseTransport):
+ def __init__(
+ self,
+ handler: Callable[[httpx.Request], httpx.Response]
+ | Callable[[httpx.Request], Coroutine[Any, Any, httpx.Response]],
+ ) -> None:
+ self.handler = handler
+
+ @override
+ def handle_request(
+ self,
+ request: httpx.Request,
+ ) -> httpx.Response:
+ assert not inspect.iscoroutinefunction(self.handler), "handler must not be a coroutine function"
+ assert inspect.isfunction(self.handler), "handler must be a function"
+ return self.handler(request)
+
+ @override
+ async def handle_async_request(
+ self,
+ request: httpx.Request,
+ ) -> httpx.Response:
+ assert inspect.iscoroutinefunction(self.handler), "handler must be a coroutine function"
+ return await self.handler(request)
+
+
+@dataclasses.dataclass
+class Counter:
+ value: int = 0
+
+
+def _make_sync_iterator(iterable: Iterable[T], counter: Optional[Counter] = None) -> Iterator[T]:
+ for item in iterable:
+ if counter:
+ counter.value += 1
+ yield item
+
+
+async def _make_async_iterator(iterable: Iterable[T], counter: Optional[Counter] = None) -> AsyncIterator[T]:
+ for item in iterable:
+ if counter:
+ counter.value += 1
+ yield item
+
+
def _get_open_connections(client: RunwayML | AsyncRunwayML) -> int:
transport = client._client._transport
assert isinstance(transport, httpx.HTTPTransport) or isinstance(transport, httpx.AsyncHTTPTransport)
@@ -502,6 +555,70 @@ def test_multipart_repeating_array(self, client: RunwayML) -> None:
b"",
]
+ @pytest.mark.respx(base_url=base_url)
+ def test_binary_content_upload(self, respx_mock: MockRouter, client: RunwayML) -> None:
+ respx_mock.post("/upload").mock(side_effect=mirror_request_content)
+
+ file_content = b"Hello, this is a test file."
+
+ response = client.post(
+ "/upload",
+ content=file_content,
+ cast_to=httpx.Response,
+ options={"headers": {"Content-Type": "application/octet-stream"}},
+ )
+
+ assert response.status_code == 200
+ assert response.request.headers["Content-Type"] == "application/octet-stream"
+ assert response.content == file_content
+
+ def test_binary_content_upload_with_iterator(self) -> None:
+ file_content = b"Hello, this is a test file."
+ counter = Counter()
+ iterator = _make_sync_iterator([file_content], counter=counter)
+
+ def mock_handler(request: httpx.Request) -> httpx.Response:
+ assert counter.value == 0, "the request body should not have been read"
+ return httpx.Response(200, content=request.read())
+
+ with RunwayML(
+ base_url=base_url,
+ api_key=api_key,
+ _strict_response_validation=True,
+ http_client=httpx.Client(transport=MockTransport(handler=mock_handler)),
+ ) as client:
+ response = client.post(
+ "/upload",
+ content=iterator,
+ cast_to=httpx.Response,
+ options={"headers": {"Content-Type": "application/octet-stream"}},
+ )
+
+ assert response.status_code == 200
+ assert response.request.headers["Content-Type"] == "application/octet-stream"
+ assert response.content == file_content
+ assert counter.value == 1
+
+ @pytest.mark.respx(base_url=base_url)
+ def test_binary_content_upload_with_body_is_deprecated(self, respx_mock: MockRouter, client: RunwayML) -> None:
+ respx_mock.post("/upload").mock(side_effect=mirror_request_content)
+
+ file_content = b"Hello, this is a test file."
+
+ with pytest.deprecated_call(
+ match="Passing raw bytes as `body` is deprecated and will be removed in a future version. Please pass raw bytes via the `content` parameter instead."
+ ):
+ response = client.post(
+ "/upload",
+ body=file_content,
+ cast_to=httpx.Response,
+ options={"headers": {"Content-Type": "application/octet-stream"}},
+ )
+
+ assert response.status_code == 200
+ assert response.request.headers["Content-Type"] == "application/octet-stream"
+ assert response.content == file_content
+
@pytest.mark.respx(base_url=base_url)
def test_basic_union_response(self, respx_mock: MockRouter, client: RunwayML) -> None:
class Model1(BaseModel):
@@ -1337,6 +1454,72 @@ def test_multipart_repeating_array(self, async_client: AsyncRunwayML) -> None:
b"",
]
+ @pytest.mark.respx(base_url=base_url)
+ async def test_binary_content_upload(self, respx_mock: MockRouter, async_client: AsyncRunwayML) -> None:
+ respx_mock.post("/upload").mock(side_effect=mirror_request_content)
+
+ file_content = b"Hello, this is a test file."
+
+ response = await async_client.post(
+ "/upload",
+ content=file_content,
+ cast_to=httpx.Response,
+ options={"headers": {"Content-Type": "application/octet-stream"}},
+ )
+
+ assert response.status_code == 200
+ assert response.request.headers["Content-Type"] == "application/octet-stream"
+ assert response.content == file_content
+
+ async def test_binary_content_upload_with_asynciterator(self) -> None:
+ file_content = b"Hello, this is a test file."
+ counter = Counter()
+ iterator = _make_async_iterator([file_content], counter=counter)
+
+ async def mock_handler(request: httpx.Request) -> httpx.Response:
+ assert counter.value == 0, "the request body should not have been read"
+ return httpx.Response(200, content=await request.aread())
+
+ async with AsyncRunwayML(
+ base_url=base_url,
+ api_key=api_key,
+ _strict_response_validation=True,
+ http_client=httpx.AsyncClient(transport=MockTransport(handler=mock_handler)),
+ ) as client:
+ response = await client.post(
+ "/upload",
+ content=iterator,
+ cast_to=httpx.Response,
+ options={"headers": {"Content-Type": "application/octet-stream"}},
+ )
+
+ assert response.status_code == 200
+ assert response.request.headers["Content-Type"] == "application/octet-stream"
+ assert response.content == file_content
+ assert counter.value == 1
+
+ @pytest.mark.respx(base_url=base_url)
+ async def test_binary_content_upload_with_body_is_deprecated(
+ self, respx_mock: MockRouter, async_client: AsyncRunwayML
+ ) -> None:
+ respx_mock.post("/upload").mock(side_effect=mirror_request_content)
+
+ file_content = b"Hello, this is a test file."
+
+ with pytest.deprecated_call(
+ match="Passing raw bytes as `body` is deprecated and will be removed in a future version. Please pass raw bytes via the `content` parameter instead."
+ ):
+ response = await async_client.post(
+ "/upload",
+ body=file_content,
+ cast_to=httpx.Response,
+ options={"headers": {"Content-Type": "application/octet-stream"}},
+ )
+
+ assert response.status_code == 200
+ assert response.request.headers["Content-Type"] == "application/octet-stream"
+ assert response.content == file_content
+
@pytest.mark.respx(base_url=base_url)
async def test_basic_union_response(self, respx_mock: MockRouter, async_client: AsyncRunwayML) -> None:
class Model1(BaseModel):
From a0b9bbe40fcde1c6286a19b77c8ac1c8425b2327 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Sat, 17 Jan 2026 00:17:02 +0000
Subject: [PATCH 09/11] feat(api): Sunset upscale endpoint
---
.stats.yml | 6 +-
api.md | 12 --
src/runwayml/_client.py | 38 ----
src/runwayml/resources/__init__.py | 14 --
src/runwayml/resources/video_upscale.py | 193 ------------------
src/runwayml/types/__init__.py | 2 -
.../organization_retrieve_usage_response.py | 2 -
.../types/video_upscale_create_params.py | 16 --
.../types/video_upscale_create_response.py | 10 -
tests/api_resources/test_video_upscale.py | 92 ---------
10 files changed, 3 insertions(+), 382 deletions(-)
delete mode 100644 src/runwayml/resources/video_upscale.py
delete mode 100644 src/runwayml/types/video_upscale_create_params.py
delete mode 100644 src/runwayml/types/video_upscale_create_response.py
delete mode 100644 tests/api_resources/test_video_upscale.py
diff --git a/.stats.yml b/.stats.yml
index cfa3db4..9ff44e1 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
-configured_endpoints: 15
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/runwayml%2Frunwayml-f1f066255f00c8db87d86efaff73852278f21c2619f83dcf9f4e5cf54ef146b0.yml
-openapi_spec_hash: af56570f2801ec4bfc94a05ca5393f9c
+configured_endpoints: 14
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/runwayml%2Frunwayml-9cf1febc614000f72d4332f8bee51b6873b6bce49c9bdc02daae300e6882f9dd.yml
+openapi_spec_hash: 03bc8d7e2d182e5a9aa9fdb7ca4f4e07
config_hash: b98eed33f1bba05e3c2a3e20d85d582a
diff --git a/api.md b/api.md
index 0f29848..72145fe 100644
--- a/api.md
+++ b/api.md
@@ -59,18 +59,6 @@ Methods:
- client.text_to_image.create(\*\*params) -> TextToImageCreateResponse
-# VideoUpscale
-
-Types:
-
-```python
-from runwayml.types import VideoUpscaleCreateResponse
-```
-
-Methods:
-
-- client.video_upscale.create(\*\*params) -> VideoUpscaleCreateResponse
-
# CharacterPerformance
Types:
diff --git a/src/runwayml/_client.py b/src/runwayml/_client.py
index 0172f3c..827ba30 100644
--- a/src/runwayml/_client.py
+++ b/src/runwayml/_client.py
@@ -38,7 +38,6 @@
sound_effect,
text_to_image,
text_to_video,
- video_upscale,
voice_dubbing,
image_to_video,
text_to_speech,
@@ -53,7 +52,6 @@
from .resources.sound_effect import SoundEffectResource, AsyncSoundEffectResource
from .resources.text_to_image import TextToImageResource, AsyncTextToImageResource
from .resources.text_to_video import TextToVideoResource, AsyncTextToVideoResource
- from .resources.video_upscale import VideoUpscaleResource, AsyncVideoUpscaleResource
from .resources.voice_dubbing import VoiceDubbingResource, AsyncVoiceDubbingResource
from .resources.image_to_video import ImageToVideoResource, AsyncImageToVideoResource
from .resources.text_to_speech import TextToSpeechResource, AsyncTextToSpeechResource
@@ -171,12 +169,6 @@ def text_to_image(self) -> TextToImageResource:
return TextToImageResource(self)
- @cached_property
- def video_upscale(self) -> VideoUpscaleResource:
- from .resources.video_upscale import VideoUpscaleResource
-
- return VideoUpscaleResource(self)
-
@cached_property
def character_performance(self) -> CharacterPerformanceResource:
from .resources.character_performance import CharacterPerformanceResource
@@ -432,12 +424,6 @@ def text_to_image(self) -> AsyncTextToImageResource:
return AsyncTextToImageResource(self)
- @cached_property
- def video_upscale(self) -> AsyncVideoUpscaleResource:
- from .resources.video_upscale import AsyncVideoUpscaleResource
-
- return AsyncVideoUpscaleResource(self)
-
@cached_property
def character_performance(self) -> AsyncCharacterPerformanceResource:
from .resources.character_performance import AsyncCharacterPerformanceResource
@@ -638,12 +624,6 @@ def text_to_image(self) -> text_to_image.TextToImageResourceWithRawResponse:
return TextToImageResourceWithRawResponse(self._client.text_to_image)
- @cached_property
- def video_upscale(self) -> video_upscale.VideoUpscaleResourceWithRawResponse:
- from .resources.video_upscale import VideoUpscaleResourceWithRawResponse
-
- return VideoUpscaleResourceWithRawResponse(self._client.video_upscale)
-
@cached_property
def character_performance(self) -> character_performance.CharacterPerformanceResourceWithRawResponse:
from .resources.character_performance import CharacterPerformanceResourceWithRawResponse
@@ -729,12 +709,6 @@ def text_to_image(self) -> text_to_image.AsyncTextToImageResourceWithRawResponse
return AsyncTextToImageResourceWithRawResponse(self._client.text_to_image)
- @cached_property
- def video_upscale(self) -> video_upscale.AsyncVideoUpscaleResourceWithRawResponse:
- from .resources.video_upscale import AsyncVideoUpscaleResourceWithRawResponse
-
- return AsyncVideoUpscaleResourceWithRawResponse(self._client.video_upscale)
-
@cached_property
def character_performance(self) -> character_performance.AsyncCharacterPerformanceResourceWithRawResponse:
from .resources.character_performance import AsyncCharacterPerformanceResourceWithRawResponse
@@ -820,12 +794,6 @@ def text_to_image(self) -> text_to_image.TextToImageResourceWithStreamingRespons
return TextToImageResourceWithStreamingResponse(self._client.text_to_image)
- @cached_property
- def video_upscale(self) -> video_upscale.VideoUpscaleResourceWithStreamingResponse:
- from .resources.video_upscale import VideoUpscaleResourceWithStreamingResponse
-
- return VideoUpscaleResourceWithStreamingResponse(self._client.video_upscale)
-
@cached_property
def character_performance(self) -> character_performance.CharacterPerformanceResourceWithStreamingResponse:
from .resources.character_performance import CharacterPerformanceResourceWithStreamingResponse
@@ -911,12 +879,6 @@ def text_to_image(self) -> text_to_image.AsyncTextToImageResourceWithStreamingRe
return AsyncTextToImageResourceWithStreamingResponse(self._client.text_to_image)
- @cached_property
- def video_upscale(self) -> video_upscale.AsyncVideoUpscaleResourceWithStreamingResponse:
- from .resources.video_upscale import AsyncVideoUpscaleResourceWithStreamingResponse
-
- return AsyncVideoUpscaleResourceWithStreamingResponse(self._client.video_upscale)
-
@cached_property
def character_performance(self) -> character_performance.AsyncCharacterPerformanceResourceWithStreamingResponse:
from .resources.character_performance import AsyncCharacterPerformanceResourceWithStreamingResponse
diff --git a/src/runwayml/resources/__init__.py b/src/runwayml/resources/__init__.py
index b5aec52..1b6f367 100644
--- a/src/runwayml/resources/__init__.py
+++ b/src/runwayml/resources/__init__.py
@@ -48,14 +48,6 @@
TextToVideoResourceWithStreamingResponse,
AsyncTextToVideoResourceWithStreamingResponse,
)
-from .video_upscale import (
- VideoUpscaleResource,
- AsyncVideoUpscaleResource,
- VideoUpscaleResourceWithRawResponse,
- AsyncVideoUpscaleResourceWithRawResponse,
- VideoUpscaleResourceWithStreamingResponse,
- AsyncVideoUpscaleResourceWithStreamingResponse,
-)
from .voice_dubbing import (
VoiceDubbingResource,
AsyncVoiceDubbingResource,
@@ -144,12 +136,6 @@
"AsyncTextToImageResourceWithRawResponse",
"TextToImageResourceWithStreamingResponse",
"AsyncTextToImageResourceWithStreamingResponse",
- "VideoUpscaleResource",
- "AsyncVideoUpscaleResource",
- "VideoUpscaleResourceWithRawResponse",
- "AsyncVideoUpscaleResourceWithRawResponse",
- "VideoUpscaleResourceWithStreamingResponse",
- "AsyncVideoUpscaleResourceWithStreamingResponse",
"CharacterPerformanceResource",
"AsyncCharacterPerformanceResource",
"CharacterPerformanceResourceWithRawResponse",
diff --git a/src/runwayml/resources/video_upscale.py b/src/runwayml/resources/video_upscale.py
deleted file mode 100644
index 3c5b1ea..0000000
--- a/src/runwayml/resources/video_upscale.py
+++ /dev/null
@@ -1,193 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from typing_extensions import Literal
-
-import httpx
-
-from ..types import video_upscale_create_params
-from .._types import Body, Query, Headers, NotGiven, not_given
-from .._utils import maybe_transform, async_maybe_transform
-from .._compat import cached_property
-from .._resource import SyncAPIResource, AsyncAPIResource
-from .._response import (
- to_raw_response_wrapper,
- to_streamed_response_wrapper,
- async_to_raw_response_wrapper,
- async_to_streamed_response_wrapper,
-)
-from ..lib.polling import (
- NewTaskCreatedResponse,
- AsyncNewTaskCreatedResponse,
- create_waitable_resource,
- create_async_waitable_resource,
-)
-from .._base_client import make_request_options
-from ..types.video_upscale_create_response import VideoUpscaleCreateResponse
-
-__all__ = ["VideoUpscaleResource", "AsyncVideoUpscaleResource"]
-
-
-class VideoUpscaleResource(SyncAPIResource):
- @cached_property
- def with_raw_response(self) -> VideoUpscaleResourceWithRawResponse:
- """
- This property can be used as a prefix for any HTTP method call to return
- the raw response object instead of the parsed content.
-
- For more information, see https://www.github.com/runwayml/sdk-python#accessing-raw-response-data-eg-headers
- """
- return VideoUpscaleResourceWithRawResponse(self)
-
- @cached_property
- def with_streaming_response(self) -> VideoUpscaleResourceWithStreamingResponse:
- """
- An alternative to `.with_raw_response` that doesn't eagerly read the response body.
-
- For more information, see https://www.github.com/runwayml/sdk-python#with_streaming_response
- """
- return VideoUpscaleResourceWithStreamingResponse(self)
-
- def create(
- self,
- *,
- model: Literal["upscale_v1"],
- video_uri: str,
- # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
- # The extra values given here take precedence over values defined on the client or passed to this method.
- extra_headers: Headers | None = None,
- extra_query: Query | None = None,
- extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> NewTaskCreatedResponse:
- """This endpoint will start a new task to upscale a video.
-
- Videos will be upscaled
- by a factor of 4X, capped at a maximum of 4096px along each side.
-
- Args:
- video_uri: A HTTPS URL.
-
- extra_headers: Send extra headers
-
- extra_query: Add additional query parameters to the request
-
- extra_body: Add additional JSON properties to the request
-
- timeout: Override the client-level default timeout for this request, in seconds
- """
- return self._post(
- "/v1/video_upscale",
- body=maybe_transform(
- {
- "model": model,
- "video_uri": video_uri,
- },
- video_upscale_create_params.VideoUpscaleCreateParams,
- ),
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=create_waitable_resource(VideoUpscaleCreateResponse, self._client),
- )
-
-
-class AsyncVideoUpscaleResource(AsyncAPIResource):
- @cached_property
- def with_raw_response(self) -> AsyncVideoUpscaleResourceWithRawResponse:
- """
- This property can be used as a prefix for any HTTP method call to return
- the raw response object instead of the parsed content.
-
- For more information, see https://www.github.com/runwayml/sdk-python#accessing-raw-response-data-eg-headers
- """
- return AsyncVideoUpscaleResourceWithRawResponse(self)
-
- @cached_property
- def with_streaming_response(self) -> AsyncVideoUpscaleResourceWithStreamingResponse:
- """
- An alternative to `.with_raw_response` that doesn't eagerly read the response body.
-
- For more information, see https://www.github.com/runwayml/sdk-python#with_streaming_response
- """
- return AsyncVideoUpscaleResourceWithStreamingResponse(self)
-
- async def create(
- self,
- *,
- model: Literal["upscale_v1"],
- video_uri: str,
- # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
- # The extra values given here take precedence over values defined on the client or passed to this method.
- extra_headers: Headers | None = None,
- extra_query: Query | None = None,
- extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> AsyncNewTaskCreatedResponse:
- """This endpoint will start a new task to upscale a video.
-
- Videos will be upscaled
- by a factor of 4X, capped at a maximum of 4096px along each side.
-
- Args:
- video_uri: A HTTPS URL.
-
- extra_headers: Send extra headers
-
- extra_query: Add additional query parameters to the request
-
- extra_body: Add additional JSON properties to the request
-
- timeout: Override the client-level default timeout for this request, in seconds
- """
- return await self._post(
- "/v1/video_upscale",
- body=await async_maybe_transform(
- {
- "model": model,
- "video_uri": video_uri,
- },
- video_upscale_create_params.VideoUpscaleCreateParams,
- ),
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=create_async_waitable_resource(VideoUpscaleCreateResponse, self._client),
- )
-
-
-class VideoUpscaleResourceWithRawResponse:
- def __init__(self, video_upscale: VideoUpscaleResource) -> None:
- self._video_upscale = video_upscale
-
- self.create = to_raw_response_wrapper(
- video_upscale.create,
- )
-
-
-class AsyncVideoUpscaleResourceWithRawResponse:
- def __init__(self, video_upscale: AsyncVideoUpscaleResource) -> None:
- self._video_upscale = video_upscale
-
- self.create = async_to_raw_response_wrapper(
- video_upscale.create,
- )
-
-
-class VideoUpscaleResourceWithStreamingResponse:
- def __init__(self, video_upscale: VideoUpscaleResource) -> None:
- self._video_upscale = video_upscale
-
- self.create = to_streamed_response_wrapper(
- video_upscale.create,
- )
-
-
-class AsyncVideoUpscaleResourceWithStreamingResponse:
- def __init__(self, video_upscale: AsyncVideoUpscaleResource) -> None:
- self._video_upscale = video_upscale
-
- self.create = async_to_streamed_response_wrapper(
- video_upscale.create,
- )
diff --git a/src/runwayml/types/__init__.py b/src/runwayml/types/__init__.py
index 4accfa0..7dd42d4 100644
--- a/src/runwayml/types/__init__.py
+++ b/src/runwayml/types/__init__.py
@@ -6,7 +6,6 @@
from .sound_effect_create_params import SoundEffectCreateParams as SoundEffectCreateParams
from .text_to_image_create_params import TextToImageCreateParams as TextToImageCreateParams
from .text_to_video_create_params import TextToVideoCreateParams as TextToVideoCreateParams
-from .video_upscale_create_params import VideoUpscaleCreateParams as VideoUpscaleCreateParams
from .voice_dubbing_create_params import VoiceDubbingCreateParams as VoiceDubbingCreateParams
from .image_to_video_create_params import ImageToVideoCreateParams as ImageToVideoCreateParams
from .sound_effect_create_response import SoundEffectCreateResponse as SoundEffectCreateResponse
@@ -14,7 +13,6 @@
from .video_to_video_create_params import VideoToVideoCreateParams as VideoToVideoCreateParams
from .text_to_image_create_response import TextToImageCreateResponse as TextToImageCreateResponse
from .text_to_video_create_response import TextToVideoCreateResponse as TextToVideoCreateResponse
-from .video_upscale_create_response import VideoUpscaleCreateResponse as VideoUpscaleCreateResponse
from .voice_dubbing_create_response import VoiceDubbingCreateResponse as VoiceDubbingCreateResponse
from .voice_isolation_create_params import VoiceIsolationCreateParams as VoiceIsolationCreateParams
from .image_to_video_create_response import ImageToVideoCreateResponse as ImageToVideoCreateResponse
diff --git a/src/runwayml/types/organization_retrieve_usage_response.py b/src/runwayml/types/organization_retrieve_usage_response.py
index bce820c..0e83260 100644
--- a/src/runwayml/types/organization_retrieve_usage_response.py
+++ b/src/runwayml/types/organization_retrieve_usage_response.py
@@ -20,7 +20,6 @@ class ResultUsedCredit(BaseModel):
"gen4_turbo",
"gen4_image",
"gen4_image_turbo",
- "upscale_v1",
"act_two",
"gen4_aleph",
"veo3",
@@ -54,7 +53,6 @@ class OrganizationRetrieveUsageResponse(BaseModel):
"gen4_turbo",
"gen4_image",
"gen4_image_turbo",
- "upscale_v1",
"act_two",
"gen4_aleph",
"veo3",
diff --git a/src/runwayml/types/video_upscale_create_params.py b/src/runwayml/types/video_upscale_create_params.py
deleted file mode 100644
index eee9e15..0000000
--- a/src/runwayml/types/video_upscale_create_params.py
+++ /dev/null
@@ -1,16 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from typing_extensions import Literal, Required, Annotated, TypedDict
-
-from .._utils import PropertyInfo
-
-__all__ = ["VideoUpscaleCreateParams"]
-
-
-class VideoUpscaleCreateParams(TypedDict, total=False):
- model: Required[Literal["upscale_v1"]]
-
- video_uri: Required[Annotated[str, PropertyInfo(alias="videoUri")]]
- """A HTTPS URL."""
diff --git a/src/runwayml/types/video_upscale_create_response.py b/src/runwayml/types/video_upscale_create_response.py
deleted file mode 100644
index 0cf0a9e..0000000
--- a/src/runwayml/types/video_upscale_create_response.py
+++ /dev/null
@@ -1,10 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from .._models import BaseModel
-
-__all__ = ["VideoUpscaleCreateResponse"]
-
-
-class VideoUpscaleCreateResponse(BaseModel):
- id: str
- """The ID of the task that was created. Use this to retrieve the task later."""
diff --git a/tests/api_resources/test_video_upscale.py b/tests/api_resources/test_video_upscale.py
deleted file mode 100644
index 9b2f1a8..0000000
--- a/tests/api_resources/test_video_upscale.py
+++ /dev/null
@@ -1,92 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-import os
-from typing import Any, cast
-
-import pytest
-
-from runwayml import RunwayML, AsyncRunwayML
-from tests.utils import assert_matches_type
-from runwayml.types import VideoUpscaleCreateResponse
-
-base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
-
-
-class TestVideoUpscale:
- parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
-
- @parametrize
- def test_method_create(self, client: RunwayML) -> None:
- video_upscale = client.video_upscale.create(
- model="upscale_v1",
- video_uri="https://example.com/video.mp4",
- )
- assert_matches_type(VideoUpscaleCreateResponse, video_upscale, path=["response"])
-
- @parametrize
- def test_raw_response_create(self, client: RunwayML) -> None:
- response = client.video_upscale.with_raw_response.create(
- model="upscale_v1",
- video_uri="https://example.com/video.mp4",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- video_upscale = response.parse()
- assert_matches_type(VideoUpscaleCreateResponse, video_upscale, path=["response"])
-
- @parametrize
- def test_streaming_response_create(self, client: RunwayML) -> None:
- with client.video_upscale.with_streaming_response.create(
- model="upscale_v1",
- video_uri="https://example.com/video.mp4",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- video_upscale = response.parse()
- assert_matches_type(VideoUpscaleCreateResponse, video_upscale, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
-
-class TestAsyncVideoUpscale:
- parametrize = pytest.mark.parametrize(
- "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"]
- )
-
- @parametrize
- async def test_method_create(self, async_client: AsyncRunwayML) -> None:
- video_upscale = await async_client.video_upscale.create(
- model="upscale_v1",
- video_uri="https://example.com/video.mp4",
- )
- assert_matches_type(VideoUpscaleCreateResponse, video_upscale, path=["response"])
-
- @parametrize
- async def test_raw_response_create(self, async_client: AsyncRunwayML) -> None:
- response = await async_client.video_upscale.with_raw_response.create(
- model="upscale_v1",
- video_uri="https://example.com/video.mp4",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- video_upscale = await response.parse()
- assert_matches_type(VideoUpscaleCreateResponse, video_upscale, path=["response"])
-
- @parametrize
- async def test_streaming_response_create(self, async_client: AsyncRunwayML) -> None:
- async with async_client.video_upscale.with_streaming_response.create(
- model="upscale_v1",
- video_uri="https://example.com/video.mp4",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- video_upscale = await response.parse()
- assert_matches_type(VideoUpscaleCreateResponse, video_upscale, path=["response"])
-
- assert cast(Any, response.is_closed) is True
From 501bd0aee752add4e2379b0bb444ca73f4f56e81 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Sat, 17 Jan 2026 00:15:35 +0000
Subject: [PATCH 10/11] codegen metadata
---
.stats.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.stats.yml b/.stats.yml
index 9ff44e1..31fdcde 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 14
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/runwayml%2Frunwayml-9cf1febc614000f72d4332f8bee51b6873b6bce49c9bdc02daae300e6882f9dd.yml
openapi_spec_hash: 03bc8d7e2d182e5a9aa9fdb7ca4f4e07
-config_hash: b98eed33f1bba05e3c2a3e20d85d582a
+config_hash: 33cae5198e16130c1534533c5200987c
From 3a9d400e7284d73ef5564b35908f1688c55dfc62 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Sat, 17 Jan 2026 00:17:43 +0000
Subject: [PATCH 11/11] release: 4.3.0
---
.release-please-manifest.json | 2 +-
CHANGELOG.md | 24 ++++++++++++++++++++++++
pyproject.toml | 2 +-
src/runwayml/_version.py | 2 +-
4 files changed, 27 insertions(+), 3 deletions(-)
diff --git a/.release-please-manifest.json b/.release-please-manifest.json
index bd7f384..29102ae 100644
--- a/.release-please-manifest.json
+++ b/.release-please-manifest.json
@@ -1,3 +1,3 @@
{
- ".": "4.2.0"
+ ".": "4.3.0"
}
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 02392b6..75e6626 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,29 @@
# Changelog
+## 4.3.0 (2026-01-17)
+
+Full Changelog: [v4.2.0...v4.3.0](https://github.com/runwayml/sdk-python/compare/v4.2.0...v4.3.0)
+
+### Features
+
+* **api:** Sunset upscale endpoint ([a0b9bbe](https://github.com/runwayml/sdk-python/commit/a0b9bbe40fcde1c6286a19b77c8ac1c8425b2327))
+* **client:** add support for binary request streaming ([384cd8b](https://github.com/runwayml/sdk-python/commit/384cd8bc9a23b0d9b7b37c737e8cb19d581f5198))
+
+
+### Bug Fixes
+
+* **types:** allow pyright to infer TypedDict types within SequenceNotStr ([9d4f77c](https://github.com/runwayml/sdk-python/commit/9d4f77c847837f20ef333a10e5a0d1d9e6a25cf5))
+* use async_to_httpx_files in patch method ([c6b8802](https://github.com/runwayml/sdk-python/commit/c6b880232812c60dce1b0b23678a70c7e158ae84))
+
+
+### Chores
+
+* add missing docstrings ([4c14222](https://github.com/runwayml/sdk-python/commit/4c142226410821c794e9e3bf43c7bf9a7d5bf6c1))
+* **internal:** add `--fix` argument to lint script ([4e5931e](https://github.com/runwayml/sdk-python/commit/4e5931e064f4596d31f9c5c71abb24ad5f8a1727))
+* **internal:** add missing files argument to base client ([1c5f3af](https://github.com/runwayml/sdk-python/commit/1c5f3af332fdd873865234b11c0b1b24aa9df688))
+* **internal:** codegen related update ([feac569](https://github.com/runwayml/sdk-python/commit/feac56919d1a635a1b3b577591d5a528c587c14e))
+* speedup initial import ([cfcc2e9](https://github.com/runwayml/sdk-python/commit/cfcc2e96de68498e8b1cbca4b02567283d8af207))
+
## 4.2.0 (2025-12-04)
Full Changelog: [v4.1.1...v4.2.0](https://github.com/runwayml/sdk-python/compare/v4.1.1...v4.2.0)
diff --git a/pyproject.toml b/pyproject.toml
index 668ea2e..1321ba8 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,6 +1,6 @@
[project]
name = "runwayml"
-version = "4.2.0"
+version = "4.3.0"
description = "The official Python library for the runwayml API"
dynamic = ["readme"]
license = "Apache-2.0"
diff --git a/src/runwayml/_version.py b/src/runwayml/_version.py
index 9e0ccac..15fc2a6 100644
--- a/src/runwayml/_version.py
+++ b/src/runwayml/_version.py
@@ -1,4 +1,4 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
__title__ = "runwayml"
-__version__ = "4.2.0" # x-release-please-version
+__version__ = "4.3.0" # x-release-please-version