From b85be28503c3ae03eea12945814a78af83030740 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Sat, 11 Oct 2025 02:04:55 +0000 Subject: [PATCH 1/4] chore(internal): detect missing future annotations with ruff --- pyproject.toml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index 83ceeef..9516a16 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -224,6 +224,8 @@ select = [ "B", # remove unused imports "F401", + # check for missing future annotations + "FA102", # bare except statements "E722", # unused arguments @@ -246,6 +248,8 @@ unfixable = [ "T203", ] +extend-safe-fixes = ["FA102"] + [tool.ruff.lint.flake8-tidy-imports.banned-api] "functools.lru_cache".msg = "This function does not retain type information for the wrapped function's arguments; The `lru_cache` function from `_utils` should be used instead" From 0bdaaedf44a1cd2231d229db9f9a4647caf58ad9 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 14 Oct 2025 21:10:33 +0000 Subject: [PATCH 2/4] feat(api): Voice dubbing and isolation --- .stats.yml | 8 +- api.md | 24 ++ src/runwayml/_client.py | 18 ++ src/runwayml/resources/__init__.py | 28 ++ src/runwayml/resources/voice_dubbing.py | 285 ++++++++++++++++++ src/runwayml/resources/voice_isolation.py | 189 ++++++++++++ src/runwayml/types/__init__.py | 4 + .../types/organization_retrieve_response.py | 42 +++ .../organization_retrieve_usage_response.py | 4 + .../types/voice_dubbing_create_params.py | 73 +++++ .../types/voice_dubbing_create_response.py | 10 + .../types/voice_isolation_create_params.py | 20 ++ .../types/voice_isolation_create_response.py | 10 + tests/api_resources/test_voice_dubbing.py | 122 ++++++++ tests/api_resources/test_voice_isolation.py | 92 ++++++ 15 files changed, 925 insertions(+), 4 deletions(-) create mode 100644 src/runwayml/resources/voice_dubbing.py create mode 100644 src/runwayml/resources/voice_isolation.py create mode 100644 src/runwayml/types/voice_dubbing_create_params.py create mode 100644 src/runwayml/types/voice_dubbing_create_response.py create mode 100644 src/runwayml/types/voice_isolation_create_params.py create mode 100644 src/runwayml/types/voice_isolation_create_response.py create mode 100644 tests/api_resources/test_voice_dubbing.py create mode 100644 tests/api_resources/test_voice_isolation.py diff --git a/.stats.yml b/.stats.yml index 6779c1e..c1e935b 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ -configured_endpoints: 12 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/runwayml%2Frunwayml-5279ac8612298fef5ba10f698044c50e5368533d98f7e0635e695fd6458f6407.yml -openapi_spec_hash: 73de6c32984fca19cbe5208c79aa2194 -config_hash: 9b8b1d9b0dd858cbb4ee228caed13ee6 +configured_endpoints: 14 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/runwayml%2Frunwayml-62779ce32ca8a091219b84d943b97a799daaccb6c5792a191b68be4cdd9117e1.yml +openapi_spec_hash: 42e41b0bec15ce4f46ff797748062484 +config_hash: ef699c0a3936550275ab6d77894a2c72 diff --git a/api.md b/api.md index acef374..0bef70f 100644 --- a/api.md +++ b/api.md @@ -107,6 +107,30 @@ Methods: - client.sound_effect.create(\*\*params) -> SoundEffectCreateResponse +# VoiceIsolation + +Types: + +```python +from runwayml.types import VoiceIsolationCreateResponse +``` + +Methods: + +- client.voice_isolation.create(\*\*params) -> VoiceIsolationCreateResponse + +# VoiceDubbing + +Types: + +```python +from runwayml.types import VoiceDubbingCreateResponse +``` + +Methods: + +- client.voice_dubbing.create(\*\*params) -> VoiceDubbingCreateResponse + # Organization Types: diff --git a/src/runwayml/_client.py b/src/runwayml/_client.py index 3e05e12..c643620 100644 --- a/src/runwayml/_client.py +++ b/src/runwayml/_client.py @@ -28,9 +28,11 @@ text_to_image, text_to_video, video_upscale, + voice_dubbing, image_to_video, text_to_speech, video_to_video, + voice_isolation, character_performance, ) from ._streaming import Stream as Stream, AsyncStream as AsyncStream @@ -63,6 +65,8 @@ class RunwayML(SyncAPIClient): 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 organization: organization.OrganizationResource with_raw_response: RunwayMLWithRawResponse with_streaming_response: RunwayMLWithStreamedResponse @@ -136,6 +140,8 @@ def __init__( 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.organization = organization.OrganizationResource(self) self.with_raw_response = RunwayMLWithRawResponse(self) self.with_streaming_response = RunwayMLWithStreamedResponse(self) @@ -258,6 +264,8 @@ class AsyncRunwayML(AsyncAPIClient): 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 organization: organization.AsyncOrganizationResource with_raw_response: AsyncRunwayMLWithRawResponse with_streaming_response: AsyncRunwayMLWithStreamedResponse @@ -331,6 +339,8 @@ def __init__( 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.organization = organization.AsyncOrganizationResource(self) self.with_raw_response = AsyncRunwayMLWithRawResponse(self) self.with_streaming_response = AsyncRunwayMLWithStreamedResponse(self) @@ -456,6 +466,8 @@ def __init__(self, client: RunwayML) -> None: ) 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.organization = organization.OrganizationResourceWithRawResponse(client.organization) @@ -472,6 +484,8 @@ def __init__(self, client: AsyncRunwayML) -> None: ) 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.organization = organization.AsyncOrganizationResourceWithRawResponse(client.organization) @@ -488,6 +502,8 @@ def __init__(self, client: RunwayML) -> None: ) 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.organization = organization.OrganizationResourceWithStreamingResponse(client.organization) @@ -504,6 +520,8 @@ def __init__(self, client: AsyncRunwayML) -> None: ) 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.organization = organization.AsyncOrganizationResourceWithStreamingResponse(client.organization) diff --git a/src/runwayml/resources/__init__.py b/src/runwayml/resources/__init__.py index d0d87a3..dc5784a 100644 --- a/src/runwayml/resources/__init__.py +++ b/src/runwayml/resources/__init__.py @@ -48,6 +48,14 @@ VideoUpscaleResourceWithStreamingResponse, AsyncVideoUpscaleResourceWithStreamingResponse, ) +from .voice_dubbing import ( + VoiceDubbingResource, + AsyncVoiceDubbingResource, + VoiceDubbingResourceWithRawResponse, + AsyncVoiceDubbingResourceWithRawResponse, + VoiceDubbingResourceWithStreamingResponse, + AsyncVoiceDubbingResourceWithStreamingResponse, +) from .image_to_video import ( ImageToVideoResource, AsyncImageToVideoResource, @@ -72,6 +80,14 @@ VideoToVideoResourceWithStreamingResponse, AsyncVideoToVideoResourceWithStreamingResponse, ) +from .voice_isolation import ( + VoiceIsolationResource, + AsyncVoiceIsolationResource, + VoiceIsolationResourceWithRawResponse, + AsyncVoiceIsolationResourceWithRawResponse, + VoiceIsolationResourceWithStreamingResponse, + AsyncVoiceIsolationResourceWithStreamingResponse, +) from .character_performance import ( CharacterPerformanceResource, AsyncCharacterPerformanceResource, @@ -136,6 +152,18 @@ "AsyncSoundEffectResourceWithRawResponse", "SoundEffectResourceWithStreamingResponse", "AsyncSoundEffectResourceWithStreamingResponse", + "VoiceIsolationResource", + "AsyncVoiceIsolationResource", + "VoiceIsolationResourceWithRawResponse", + "AsyncVoiceIsolationResourceWithRawResponse", + "VoiceIsolationResourceWithStreamingResponse", + "AsyncVoiceIsolationResourceWithStreamingResponse", + "VoiceDubbingResource", + "AsyncVoiceDubbingResource", + "VoiceDubbingResourceWithRawResponse", + "AsyncVoiceDubbingResourceWithRawResponse", + "VoiceDubbingResourceWithStreamingResponse", + "AsyncVoiceDubbingResourceWithStreamingResponse", "OrganizationResource", "AsyncOrganizationResource", "OrganizationResourceWithRawResponse", diff --git a/src/runwayml/resources/voice_dubbing.py b/src/runwayml/resources/voice_dubbing.py new file mode 100644 index 0000000..2b4ad3f --- /dev/null +++ b/src/runwayml/resources/voice_dubbing.py @@ -0,0 +1,285 @@ +# 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 voice_dubbing_create_params +from .._types import Body, Omit, Query, Headers, NotGiven, omit, 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 .._base_client import make_request_options +from ..types.voice_dubbing_create_response import VoiceDubbingCreateResponse + +__all__ = ["VoiceDubbingResource", "AsyncVoiceDubbingResource"] + + +class VoiceDubbingResource(SyncAPIResource): + @cached_property + def with_raw_response(self) -> VoiceDubbingResourceWithRawResponse: + """ + 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 VoiceDubbingResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> VoiceDubbingResourceWithStreamingResponse: + """ + 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 VoiceDubbingResourceWithStreamingResponse(self) + + def create( + self, + *, + audio_uri: str, + model: Literal["eleven_voice_dubbing"], + target_lang: Literal[ + "en", + "hi", + "pt", + "zh", + "es", + "fr", + "de", + "ja", + "ar", + "ru", + "ko", + "id", + "it", + "nl", + "tr", + "pl", + "sv", + "fil", + "ms", + "ro", + "uk", + "el", + "cs", + "da", + "fi", + "bg", + "hr", + "sk", + "ta", + ], + disable_voice_cloning: bool | Omit = omit, + drop_background_audio: bool | Omit = omit, + num_speakers: int | Omit = omit, + # 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, + ) -> VoiceDubbingCreateResponse: + """ + This endpoint will start a new task to dub audio content to a target language. + + Args: + audio_uri: A HTTPS URL or data URI containing the audio file to dub. See + [our docs](/assets/inputs#audio) on audio inputs for more information. + + model: The model variant to use. + + target_lang: The target language code to dub the audio to (e.g., "es" for Spanish, "fr" for + French). + + disable_voice_cloning: Whether to disable voice cloning and use a generic voice instead. + + drop_background_audio: Whether to remove background audio from the dubbed output. + + num_speakers: The number of speakers in the audio. If not provided, it will be detected + automatically. + + 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/voice_dubbing", + body=maybe_transform( + { + "audio_uri": audio_uri, + "model": model, + "target_lang": target_lang, + "disable_voice_cloning": disable_voice_cloning, + "drop_background_audio": drop_background_audio, + "num_speakers": num_speakers, + }, + voice_dubbing_create_params.VoiceDubbingCreateParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=VoiceDubbingCreateResponse, + ) + + +class AsyncVoiceDubbingResource(AsyncAPIResource): + @cached_property + def with_raw_response(self) -> AsyncVoiceDubbingResourceWithRawResponse: + """ + 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 AsyncVoiceDubbingResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncVoiceDubbingResourceWithStreamingResponse: + """ + 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 AsyncVoiceDubbingResourceWithStreamingResponse(self) + + async def create( + self, + *, + audio_uri: str, + model: Literal["eleven_voice_dubbing"], + target_lang: Literal[ + "en", + "hi", + "pt", + "zh", + "es", + "fr", + "de", + "ja", + "ar", + "ru", + "ko", + "id", + "it", + "nl", + "tr", + "pl", + "sv", + "fil", + "ms", + "ro", + "uk", + "el", + "cs", + "da", + "fi", + "bg", + "hr", + "sk", + "ta", + ], + disable_voice_cloning: bool | Omit = omit, + drop_background_audio: bool | Omit = omit, + num_speakers: int | Omit = omit, + # 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, + ) -> VoiceDubbingCreateResponse: + """ + This endpoint will start a new task to dub audio content to a target language. + + Args: + audio_uri: A HTTPS URL or data URI containing the audio file to dub. See + [our docs](/assets/inputs#audio) on audio inputs for more information. + + model: The model variant to use. + + target_lang: The target language code to dub the audio to (e.g., "es" for Spanish, "fr" for + French). + + disable_voice_cloning: Whether to disable voice cloning and use a generic voice instead. + + drop_background_audio: Whether to remove background audio from the dubbed output. + + num_speakers: The number of speakers in the audio. If not provided, it will be detected + automatically. + + 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/voice_dubbing", + body=await async_maybe_transform( + { + "audio_uri": audio_uri, + "model": model, + "target_lang": target_lang, + "disable_voice_cloning": disable_voice_cloning, + "drop_background_audio": drop_background_audio, + "num_speakers": num_speakers, + }, + voice_dubbing_create_params.VoiceDubbingCreateParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=VoiceDubbingCreateResponse, + ) + + +class VoiceDubbingResourceWithRawResponse: + def __init__(self, voice_dubbing: VoiceDubbingResource) -> None: + self._voice_dubbing = voice_dubbing + + self.create = to_raw_response_wrapper( + voice_dubbing.create, + ) + + +class AsyncVoiceDubbingResourceWithRawResponse: + def __init__(self, voice_dubbing: AsyncVoiceDubbingResource) -> None: + self._voice_dubbing = voice_dubbing + + self.create = async_to_raw_response_wrapper( + voice_dubbing.create, + ) + + +class VoiceDubbingResourceWithStreamingResponse: + def __init__(self, voice_dubbing: VoiceDubbingResource) -> None: + self._voice_dubbing = voice_dubbing + + self.create = to_streamed_response_wrapper( + voice_dubbing.create, + ) + + +class AsyncVoiceDubbingResourceWithStreamingResponse: + def __init__(self, voice_dubbing: AsyncVoiceDubbingResource) -> None: + self._voice_dubbing = voice_dubbing + + self.create = async_to_streamed_response_wrapper( + voice_dubbing.create, + ) diff --git a/src/runwayml/resources/voice_isolation.py b/src/runwayml/resources/voice_isolation.py new file mode 100644 index 0000000..6bd425e --- /dev/null +++ b/src/runwayml/resources/voice_isolation.py @@ -0,0 +1,189 @@ +# 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 voice_isolation_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 .._base_client import make_request_options +from ..types.voice_isolation_create_response import VoiceIsolationCreateResponse + +__all__ = ["VoiceIsolationResource", "AsyncVoiceIsolationResource"] + + +class VoiceIsolationResource(SyncAPIResource): + @cached_property + def with_raw_response(self) -> VoiceIsolationResourceWithRawResponse: + """ + 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 VoiceIsolationResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> VoiceIsolationResourceWithStreamingResponse: + """ + 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 VoiceIsolationResourceWithStreamingResponse(self) + + def create( + self, + *, + audio_url: str, + model: Literal["eleven_voice_isolation"], + # 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, + ) -> VoiceIsolationCreateResponse: + """ + This endpoint will start a new task to isolate and enhance voices in audio. + + Args: + audio_url: A HTTPS URL or data URI containing the audio file to process. See + [our docs](/assets/inputs#audio) on audio inputs for more information. + + model: The model variant to use. + + 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/voice_isolation", + body=maybe_transform( + { + "audio_url": audio_url, + "model": model, + }, + voice_isolation_create_params.VoiceIsolationCreateParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=VoiceIsolationCreateResponse, + ) + + +class AsyncVoiceIsolationResource(AsyncAPIResource): + @cached_property + def with_raw_response(self) -> AsyncVoiceIsolationResourceWithRawResponse: + """ + 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 AsyncVoiceIsolationResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncVoiceIsolationResourceWithStreamingResponse: + """ + 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 AsyncVoiceIsolationResourceWithStreamingResponse(self) + + async def create( + self, + *, + audio_url: str, + model: Literal["eleven_voice_isolation"], + # 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, + ) -> VoiceIsolationCreateResponse: + """ + This endpoint will start a new task to isolate and enhance voices in audio. + + Args: + audio_url: A HTTPS URL or data URI containing the audio file to process. See + [our docs](/assets/inputs#audio) on audio inputs for more information. + + model: The model variant to use. + + 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/voice_isolation", + body=await async_maybe_transform( + { + "audio_url": audio_url, + "model": model, + }, + voice_isolation_create_params.VoiceIsolationCreateParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=VoiceIsolationCreateResponse, + ) + + +class VoiceIsolationResourceWithRawResponse: + def __init__(self, voice_isolation: VoiceIsolationResource) -> None: + self._voice_isolation = voice_isolation + + self.create = to_raw_response_wrapper( + voice_isolation.create, + ) + + +class AsyncVoiceIsolationResourceWithRawResponse: + def __init__(self, voice_isolation: AsyncVoiceIsolationResource) -> None: + self._voice_isolation = voice_isolation + + self.create = async_to_raw_response_wrapper( + voice_isolation.create, + ) + + +class VoiceIsolationResourceWithStreamingResponse: + def __init__(self, voice_isolation: VoiceIsolationResource) -> None: + self._voice_isolation = voice_isolation + + self.create = to_streamed_response_wrapper( + voice_isolation.create, + ) + + +class AsyncVoiceIsolationResourceWithStreamingResponse: + def __init__(self, voice_isolation: AsyncVoiceIsolationResource) -> None: + self._voice_isolation = voice_isolation + + self.create = async_to_streamed_response_wrapper( + voice_isolation.create, + ) diff --git a/src/runwayml/types/__init__.py b/src/runwayml/types/__init__.py index d2ee73e..42f346b 100644 --- a/src/runwayml/types/__init__.py +++ b/src/runwayml/types/__init__.py @@ -7,6 +7,7 @@ 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 from .text_to_speech_create_params import TextToSpeechCreateParams as TextToSpeechCreateParams @@ -14,10 +15,13 @@ 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 from .organization_retrieve_response import OrganizationRetrieveResponse as OrganizationRetrieveResponse from .text_to_speech_create_response import TextToSpeechCreateResponse as TextToSpeechCreateResponse from .video_to_video_create_response import VideoToVideoCreateResponse as VideoToVideoCreateResponse +from .voice_isolation_create_response import VoiceIsolationCreateResponse as VoiceIsolationCreateResponse from .organization_retrieve_usage_params import OrganizationRetrieveUsageParams as OrganizationRetrieveUsageParams from .character_performance_create_params import CharacterPerformanceCreateParams as CharacterPerformanceCreateParams from .organization_retrieve_usage_response import OrganizationRetrieveUsageResponse as OrganizationRetrieveUsageResponse diff --git a/src/runwayml/types/organization_retrieve_response.py b/src/runwayml/types/organization_retrieve_response.py index e28091a..8669d39 100644 --- a/src/runwayml/types/organization_retrieve_response.py +++ b/src/runwayml/types/organization_retrieve_response.py @@ -13,6 +13,8 @@ "TierModelsActTwo", "TierModelsElevenMultilingualV2", "TierModelsElevenTextToSoundV2", + "TierModelsElevenVoiceDubbing", + "TierModelsElevenVoiceIsolation", "TierModelsGemini2_5Flash", "TierModelsGen3aTurbo", "TierModelsGen4Aleph", @@ -26,6 +28,8 @@ "UsageModelsActTwo", "UsageModelsElevenMultilingualV2", "UsageModelsElevenTextToSoundV2", + "UsageModelsElevenVoiceDubbing", + "UsageModelsElevenVoiceIsolation", "UsageModelsGemini2_5Flash", "UsageModelsGen3aTurbo", "UsageModelsGen4Aleph", @@ -61,6 +65,22 @@ class TierModelsElevenTextToSoundV2(BaseModel): """The maximum number of generations that can be created each day for this model.""" +class TierModelsElevenVoiceDubbing(BaseModel): + max_concurrent_generations: int = FieldInfo(alias="maxConcurrentGenerations") + """The maximum number of generations that can be run concurrently for this model.""" + + max_daily_generations: int = FieldInfo(alias="maxDailyGenerations") + """The maximum number of generations that can be created each day for this model.""" + + +class TierModelsElevenVoiceIsolation(BaseModel): + max_concurrent_generations: int = FieldInfo(alias="maxConcurrentGenerations") + """The maximum number of generations that can be run concurrently for this model.""" + + max_daily_generations: int = FieldInfo(alias="maxDailyGenerations") + """The maximum number of generations that can be created each day for this model.""" + + class TierModelsGemini2_5Flash(BaseModel): max_concurrent_generations: int = FieldInfo(alias="maxConcurrentGenerations") """The maximum number of generations that can be run concurrently for this model.""" @@ -135,6 +155,12 @@ class TierModels(BaseModel): eleven_text_to_sound_v2: Optional[TierModelsElevenTextToSoundV2] = None """Limits associated with the eleven_text_to_sound_v2 model.""" + eleven_voice_dubbing: Optional[TierModelsElevenVoiceDubbing] = None + """Limits associated with the eleven_voice_dubbing model.""" + + eleven_voice_isolation: Optional[TierModelsElevenVoiceIsolation] = None + """Limits associated with the eleven_voice_isolation model.""" + gemini_2_5_flash: Optional[TierModelsGemini2_5Flash] = FieldInfo(alias="gemini_2.5_flash", default=None) """Limits associated with the gemini_2.5_flash model.""" @@ -183,6 +209,16 @@ class UsageModelsElevenTextToSoundV2(BaseModel): """The number of generations that have been run for this model in the past day.""" +class UsageModelsElevenVoiceDubbing(BaseModel): + daily_generations: int = FieldInfo(alias="dailyGenerations") + """The number of generations that have been run for this model in the past day.""" + + +class UsageModelsElevenVoiceIsolation(BaseModel): + daily_generations: int = FieldInfo(alias="dailyGenerations") + """The number of generations that have been run for this model in the past day.""" + + class UsageModelsGemini2_5Flash(BaseModel): daily_generations: int = FieldInfo(alias="dailyGenerations") """The number of generations that have been run for this model in the past day.""" @@ -233,6 +269,12 @@ class UsageModels(BaseModel): eleven_text_to_sound_v2: Optional[UsageModelsElevenTextToSoundV2] = None """Usage data for the eleven_text_to_sound_v2 model.""" + eleven_voice_dubbing: Optional[UsageModelsElevenVoiceDubbing] = None + """Usage data for the eleven_voice_dubbing model.""" + + eleven_voice_isolation: Optional[UsageModelsElevenVoiceIsolation] = None + """Usage data for the eleven_voice_isolation model.""" + gemini_2_5_flash: Optional[UsageModelsGemini2_5Flash] = FieldInfo(alias="gemini_2.5_flash", default=None) """Usage data for the gemini_2.5_flash model.""" diff --git a/src/runwayml/types/organization_retrieve_usage_response.py b/src/runwayml/types/organization_retrieve_usage_response.py index 3573fe5..1fe8c45 100644 --- a/src/runwayml/types/organization_retrieve_usage_response.py +++ b/src/runwayml/types/organization_retrieve_usage_response.py @@ -19,6 +19,8 @@ class ResultUsedCredit(BaseModel): "act_two", "eleven_multilingual_v2", "eleven_text_to_sound_v2", + "eleven_voice_dubbing", + "eleven_voice_isolation", "gemini_2.5_flash", "gen3a_turbo", "gen4_aleph", @@ -48,6 +50,8 @@ class OrganizationRetrieveUsageResponse(BaseModel): "act_two", "eleven_multilingual_v2", "eleven_text_to_sound_v2", + "eleven_voice_dubbing", + "eleven_voice_isolation", "gemini_2.5_flash", "gen3a_turbo", "gen4_aleph", diff --git a/src/runwayml/types/voice_dubbing_create_params.py b/src/runwayml/types/voice_dubbing_create_params.py new file mode 100644 index 0000000..30b38c0 --- /dev/null +++ b/src/runwayml/types/voice_dubbing_create_params.py @@ -0,0 +1,73 @@ +# 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__ = ["VoiceDubbingCreateParams"] + + +class VoiceDubbingCreateParams(TypedDict, total=False): + audio_uri: Required[Annotated[str, PropertyInfo(alias="audioUri")]] + """A HTTPS URL or data URI containing the audio file to dub. + + See [our docs](/assets/inputs#audio) on audio inputs for more information. + """ + + model: Required[Literal["eleven_voice_dubbing"]] + """The model variant to use.""" + + target_lang: Required[ + Annotated[ + Literal[ + "en", + "hi", + "pt", + "zh", + "es", + "fr", + "de", + "ja", + "ar", + "ru", + "ko", + "id", + "it", + "nl", + "tr", + "pl", + "sv", + "fil", + "ms", + "ro", + "uk", + "el", + "cs", + "da", + "fi", + "bg", + "hr", + "sk", + "ta", + ], + PropertyInfo(alias="targetLang"), + ] + ] + """ + The target language code to dub the audio to (e.g., "es" for Spanish, "fr" for + French). + """ + + disable_voice_cloning: Annotated[bool, PropertyInfo(alias="disableVoiceCloning")] + """Whether to disable voice cloning and use a generic voice instead.""" + + drop_background_audio: Annotated[bool, PropertyInfo(alias="dropBackgroundAudio")] + """Whether to remove background audio from the dubbed output.""" + + num_speakers: Annotated[int, PropertyInfo(alias="numSpeakers")] + """The number of speakers in the audio. + + If not provided, it will be detected automatically. + """ diff --git a/src/runwayml/types/voice_dubbing_create_response.py b/src/runwayml/types/voice_dubbing_create_response.py new file mode 100644 index 0000000..1740b0a --- /dev/null +++ b/src/runwayml/types/voice_dubbing_create_response.py @@ -0,0 +1,10 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from .._models import BaseModel + +__all__ = ["VoiceDubbingCreateResponse"] + + +class VoiceDubbingCreateResponse(BaseModel): + id: str + """The ID of the newly created task.""" diff --git a/src/runwayml/types/voice_isolation_create_params.py b/src/runwayml/types/voice_isolation_create_params.py new file mode 100644 index 0000000..e994503 --- /dev/null +++ b/src/runwayml/types/voice_isolation_create_params.py @@ -0,0 +1,20 @@ +# 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__ = ["VoiceIsolationCreateParams"] + + +class VoiceIsolationCreateParams(TypedDict, total=False): + audio_url: Required[Annotated[str, PropertyInfo(alias="audioUrl")]] + """A HTTPS URL or data URI containing the audio file to process. + + See [our docs](/assets/inputs#audio) on audio inputs for more information. + """ + + model: Required[Literal["eleven_voice_isolation"]] + """The model variant to use.""" diff --git a/src/runwayml/types/voice_isolation_create_response.py b/src/runwayml/types/voice_isolation_create_response.py new file mode 100644 index 0000000..e64708a --- /dev/null +++ b/src/runwayml/types/voice_isolation_create_response.py @@ -0,0 +1,10 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from .._models import BaseModel + +__all__ = ["VoiceIsolationCreateResponse"] + + +class VoiceIsolationCreateResponse(BaseModel): + id: str + """The ID of the newly created task.""" diff --git a/tests/api_resources/test_voice_dubbing.py b/tests/api_resources/test_voice_dubbing.py new file mode 100644 index 0000000..8d23a6c --- /dev/null +++ b/tests/api_resources/test_voice_dubbing.py @@ -0,0 +1,122 @@ +# 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 VoiceDubbingCreateResponse + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestVoiceDubbing: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @parametrize + def test_method_create(self, client: RunwayML) -> None: + voice_dubbing = client.voice_dubbing.create( + audio_uri="https://example.com", + model="eleven_voice_dubbing", + target_lang="en", + ) + assert_matches_type(VoiceDubbingCreateResponse, voice_dubbing, path=["response"]) + + @parametrize + def test_method_create_with_all_params(self, client: RunwayML) -> None: + voice_dubbing = client.voice_dubbing.create( + audio_uri="https://example.com", + model="eleven_voice_dubbing", + target_lang="en", + disable_voice_cloning=True, + drop_background_audio=True, + num_speakers=1, + ) + assert_matches_type(VoiceDubbingCreateResponse, voice_dubbing, path=["response"]) + + @parametrize + def test_raw_response_create(self, client: RunwayML) -> None: + response = client.voice_dubbing.with_raw_response.create( + audio_uri="https://example.com", + model="eleven_voice_dubbing", + target_lang="en", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + voice_dubbing = response.parse() + assert_matches_type(VoiceDubbingCreateResponse, voice_dubbing, path=["response"]) + + @parametrize + def test_streaming_response_create(self, client: RunwayML) -> None: + with client.voice_dubbing.with_streaming_response.create( + audio_uri="https://example.com", + model="eleven_voice_dubbing", + target_lang="en", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + voice_dubbing = response.parse() + assert_matches_type(VoiceDubbingCreateResponse, voice_dubbing, path=["response"]) + + assert cast(Any, response.is_closed) is True + + +class TestAsyncVoiceDubbing: + 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: + voice_dubbing = await async_client.voice_dubbing.create( + audio_uri="https://example.com", + model="eleven_voice_dubbing", + target_lang="en", + ) + assert_matches_type(VoiceDubbingCreateResponse, voice_dubbing, path=["response"]) + + @parametrize + async def test_method_create_with_all_params(self, async_client: AsyncRunwayML) -> None: + voice_dubbing = await async_client.voice_dubbing.create( + audio_uri="https://example.com", + model="eleven_voice_dubbing", + target_lang="en", + disable_voice_cloning=True, + drop_background_audio=True, + num_speakers=1, + ) + assert_matches_type(VoiceDubbingCreateResponse, voice_dubbing, path=["response"]) + + @parametrize + async def test_raw_response_create(self, async_client: AsyncRunwayML) -> None: + response = await async_client.voice_dubbing.with_raw_response.create( + audio_uri="https://example.com", + model="eleven_voice_dubbing", + target_lang="en", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + voice_dubbing = await response.parse() + assert_matches_type(VoiceDubbingCreateResponse, voice_dubbing, path=["response"]) + + @parametrize + async def test_streaming_response_create(self, async_client: AsyncRunwayML) -> None: + async with async_client.voice_dubbing.with_streaming_response.create( + audio_uri="https://example.com", + model="eleven_voice_dubbing", + target_lang="en", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + voice_dubbing = await response.parse() + assert_matches_type(VoiceDubbingCreateResponse, voice_dubbing, path=["response"]) + + assert cast(Any, response.is_closed) is True diff --git a/tests/api_resources/test_voice_isolation.py b/tests/api_resources/test_voice_isolation.py new file mode 100644 index 0000000..dde7c4e --- /dev/null +++ b/tests/api_resources/test_voice_isolation.py @@ -0,0 +1,92 @@ +# 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 VoiceIsolationCreateResponse + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestVoiceIsolation: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @parametrize + def test_method_create(self, client: RunwayML) -> None: + voice_isolation = client.voice_isolation.create( + audio_url="https://example.com", + model="eleven_voice_isolation", + ) + assert_matches_type(VoiceIsolationCreateResponse, voice_isolation, path=["response"]) + + @parametrize + def test_raw_response_create(self, client: RunwayML) -> None: + response = client.voice_isolation.with_raw_response.create( + audio_url="https://example.com", + model="eleven_voice_isolation", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + voice_isolation = response.parse() + assert_matches_type(VoiceIsolationCreateResponse, voice_isolation, path=["response"]) + + @parametrize + def test_streaming_response_create(self, client: RunwayML) -> None: + with client.voice_isolation.with_streaming_response.create( + audio_url="https://example.com", + model="eleven_voice_isolation", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + voice_isolation = response.parse() + assert_matches_type(VoiceIsolationCreateResponse, voice_isolation, path=["response"]) + + assert cast(Any, response.is_closed) is True + + +class TestAsyncVoiceIsolation: + 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: + voice_isolation = await async_client.voice_isolation.create( + audio_url="https://example.com", + model="eleven_voice_isolation", + ) + assert_matches_type(VoiceIsolationCreateResponse, voice_isolation, path=["response"]) + + @parametrize + async def test_raw_response_create(self, async_client: AsyncRunwayML) -> None: + response = await async_client.voice_isolation.with_raw_response.create( + audio_url="https://example.com", + model="eleven_voice_isolation", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + voice_isolation = await response.parse() + assert_matches_type(VoiceIsolationCreateResponse, voice_isolation, path=["response"]) + + @parametrize + async def test_streaming_response_create(self, async_client: AsyncRunwayML) -> None: + async with async_client.voice_isolation.with_streaming_response.create( + audio_url="https://example.com", + model="eleven_voice_isolation", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + voice_isolation = await response.parse() + assert_matches_type(VoiceIsolationCreateResponse, voice_isolation, path=["response"]) + + assert cast(Any, response.is_closed) is True From 5518de4080470daed74d9140c0ae77f55f641927 Mon Sep 17 00:00:00 2001 From: Matt Basta Date: Tue, 14 Oct 2025 17:17:26 -0400 Subject: [PATCH 3/4] Make new voice endpoints awaitable --- src/runwayml/resources/voice_dubbing.py | 14 ++++++++++---- src/runwayml/resources/voice_isolation.py | 14 ++++++++++---- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/src/runwayml/resources/voice_dubbing.py b/src/runwayml/resources/voice_dubbing.py index 2b4ad3f..47dd906 100644 --- a/src/runwayml/resources/voice_dubbing.py +++ b/src/runwayml/resources/voice_dubbing.py @@ -17,6 +17,12 @@ 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.voice_dubbing_create_response import VoiceDubbingCreateResponse @@ -88,7 +94,7 @@ def create( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> VoiceDubbingCreateResponse: + ) -> NewTaskCreatedResponse: """ This endpoint will start a new task to dub audio content to a target language. @@ -132,7 +138,7 @@ def create( options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), - cast_to=VoiceDubbingCreateResponse, + cast_to=create_waitable_resource(VoiceDubbingCreateResponse, self._client), ) @@ -201,7 +207,7 @@ async def create( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> VoiceDubbingCreateResponse: + ) -> AsyncNewTaskCreatedResponse: """ This endpoint will start a new task to dub audio content to a target language. @@ -245,7 +251,7 @@ async def create( options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), - cast_to=VoiceDubbingCreateResponse, + cast_to=create_async_waitable_resource(VoiceDubbingCreateResponse, self._client), ) diff --git a/src/runwayml/resources/voice_isolation.py b/src/runwayml/resources/voice_isolation.py index 6bd425e..50ea086 100644 --- a/src/runwayml/resources/voice_isolation.py +++ b/src/runwayml/resources/voice_isolation.py @@ -17,6 +17,12 @@ 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.voice_isolation_create_response import VoiceIsolationCreateResponse @@ -54,7 +60,7 @@ def create( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> VoiceIsolationCreateResponse: + ) -> NewTaskCreatedResponse: """ This endpoint will start a new task to isolate and enhance voices in audio. @@ -84,7 +90,7 @@ def create( options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), - cast_to=VoiceIsolationCreateResponse, + cast_to=create_waitable_resource(VoiceIsolationCreateResponse, self._client), ) @@ -119,7 +125,7 @@ async def create( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> VoiceIsolationCreateResponse: + ) -> AsyncNewTaskCreatedResponse: """ This endpoint will start a new task to isolate and enhance voices in audio. @@ -149,7 +155,7 @@ async def create( options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), - cast_to=VoiceIsolationCreateResponse, + cast_to=create_async_waitable_resource(VoiceIsolationCreateResponse, self._client), ) From ff02398da3fab23a1bb169522c246f668a3e6ed5 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 14 Oct 2025 21:18:49 +0000 Subject: [PATCH 4/4] release: 3.18.0 --- .release-please-manifest.json | 2 +- CHANGELOG.md | 13 +++++++++++++ pyproject.toml | 2 +- src/runwayml/_version.py | 2 +- 4 files changed, 16 insertions(+), 3 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 5522caa..df3292b 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "3.17.0" + ".": "3.18.0" } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 0161597..2debb98 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,18 @@ # Changelog +## 3.18.0 (2025-10-14) + +Full Changelog: [v3.17.0...v3.18.0](https://github.com/runwayml/sdk-python/compare/v3.17.0...v3.18.0) + +### Features + +* **api:** Voice dubbing and isolation ([0bdaaed](https://github.com/runwayml/sdk-python/commit/0bdaaedf44a1cd2231d229db9f9a4647caf58ad9)) + + +### Chores + +* **internal:** detect missing future annotations with ruff ([b85be28](https://github.com/runwayml/sdk-python/commit/b85be28503c3ae03eea12945814a78af83030740)) + ## 3.17.0 (2025-10-09) Full Changelog: [v3.16.0...v3.17.0](https://github.com/runwayml/sdk-python/compare/v3.16.0...v3.17.0) diff --git a/pyproject.toml b/pyproject.toml index 9516a16..c22f641 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "runwayml" -version = "3.17.0" +version = "3.18.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 72167de..5392b07 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__ = "3.17.0" # x-release-please-version +__version__ = "3.18.0" # x-release-please-version