From f1def200362842d3bd5ea611527be894e65babf6 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 6 Jul 2026 18:47:37 +0000 Subject: [PATCH 1/2] feat(api): add seed_audio model Add seed_audio to text_to_speech and sound_effect endpoints. --- .stats.yml | 4 +- src/runwayml/resources/sound_effect.py | 168 +++++++++++++++++- src/runwayml/resources/text_to_speech.py | 166 ++++++++++++++++- .../types/sound_effect_create_params.py | 44 ++++- .../types/text_to_speech_create_params.py | 58 +++++- tests/api_resources/test_sound_effect.py | 112 +++++++++++- tests/api_resources/test_text_to_speech.py | 114 +++++++++++- 7 files changed, 634 insertions(+), 32 deletions(-) diff --git a/.stats.yml b/.stats.yml index 9ce5d4b..732af71 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 50 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/runwayml/runwayml-a3fa61e8bca261af3c51886ce551ccb5442a8c34758a00433e0002acace60acd.yml -openapi_spec_hash: 930007b00f9d434127cba847bd5c4a8e +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/runwayml/runwayml-6891f36f2cfa06dc53ee188ca0ab127f30f849d15ac7cf45d4a1eb27c9ab3868.yml +openapi_spec_hash: e2e91001c6f699c4fbe971c44043950f config_hash: 955a0e451964a44778c5c0f54ca1c994 diff --git a/src/runwayml/resources/sound_effect.py b/src/runwayml/resources/sound_effect.py index d26979b..57d0f6c 100644 --- a/src/runwayml/resources/sound_effect.py +++ b/src/runwayml/resources/sound_effect.py @@ -2,13 +2,13 @@ from __future__ import annotations -from typing_extensions import Literal +from typing_extensions import Literal, overload import httpx from ..types import sound_effect_create_params -from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given -from .._utils import maybe_transform, async_maybe_transform +from .._types import Body, Omit, Query, Headers, NotGiven, SequenceNotStr, omit, not_given +from .._utils import required_args, maybe_transform, async_maybe_transform from .._compat import cached_property from .._resource import SyncAPIResource, AsyncAPIResource from .._response import ( @@ -51,6 +51,58 @@ def with_streaming_response(self) -> SoundEffectResourceWithStreamingResponse: """ return SoundEffectResourceWithStreamingResponse(self) + @overload + def create( + self, + *, + model: Literal["seed_audio"], + prompt_text: str, + loudness_rate: int | Omit = omit, + output_format: Literal["wav", "mp3", "ogg_opus"] | Omit = omit, + pitch_rate: int | Omit = omit, + reference_audios: SequenceNotStr[str] | Omit = omit, + sample_rate: Literal[8000, 16000, 24000, 32000, 44100, 48000] | Omit = omit, + speech_rate: 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, + ) -> NewTaskCreatedResponse: + """ + This endpoint will start a new task to generate sound effects from a text + description. + + Args: + prompt_text: A non-empty text prompt. For text-to-speech, the words to speak. For + text-to-audio, a scene description that can include voice direction, dialogue, + music, and sound effects. + + loudness_rate: Relative output loudness. Negative is quieter, positive is louder; 0 is normal. + + output_format: Output audio container/format. + + pitch_rate: Pitch shift in semitones. Negative lowers, positive raises; 0 is unchanged. + + reference_audios: Up to three reference audio clips. When provided, reference them in promptText + as @Audio1, @Audio2, and @Audio3 in order. + + sample_rate: Output sample rate in Hz. + + speech_rate: Relative speech speed. Negative is slower, positive is faster; 0 is normal. + + 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 + """ + ... + + @overload def create( self, *, @@ -86,12 +138,41 @@ def create( timeout: Override the client-level default timeout for this request, in seconds """ + ... + + @required_args(["model", "prompt_text"]) + def create( + self, + *, + model: Literal["seed_audio"] | Literal["eleven_text_to_sound_v2"], + prompt_text: str, + loudness_rate: int | Omit = omit, + output_format: Literal["wav", "mp3", "ogg_opus"] | Omit = omit, + pitch_rate: int | Omit = omit, + reference_audios: SequenceNotStr[str] | Omit = omit, + sample_rate: Literal[8000, 16000, 24000, 32000, 44100, 48000] | Omit = omit, + speech_rate: int | Omit = omit, + duration: float | Omit = omit, + loop: bool | 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, + ) -> NewTaskCreatedResponse: return self._post( "/v1/sound_effect", body=maybe_transform( { "model": model, "prompt_text": prompt_text, + "loudness_rate": loudness_rate, + "output_format": output_format, + "pitch_rate": pitch_rate, + "reference_audios": reference_audios, + "sample_rate": sample_rate, + "speech_rate": speech_rate, "duration": duration, "loop": loop, }, @@ -126,6 +207,58 @@ def with_streaming_response(self) -> AsyncSoundEffectResourceWithStreamingRespon """ return AsyncSoundEffectResourceWithStreamingResponse(self) + @overload + async def create( + self, + *, + model: Literal["seed_audio"], + prompt_text: str, + loudness_rate: int | Omit = omit, + output_format: Literal["wav", "mp3", "ogg_opus"] | Omit = omit, + pitch_rate: int | Omit = omit, + reference_audios: SequenceNotStr[str] | Omit = omit, + sample_rate: Literal[8000, 16000, 24000, 32000, 44100, 48000] | Omit = omit, + speech_rate: 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, + ) -> AsyncNewTaskCreatedResponse: + """ + This endpoint will start a new task to generate sound effects from a text + description. + + Args: + prompt_text: A non-empty text prompt. For text-to-speech, the words to speak. For + text-to-audio, a scene description that can include voice direction, dialogue, + music, and sound effects. + + loudness_rate: Relative output loudness. Negative is quieter, positive is louder; 0 is normal. + + output_format: Output audio container/format. + + pitch_rate: Pitch shift in semitones. Negative lowers, positive raises; 0 is unchanged. + + reference_audios: Up to three reference audio clips. When provided, reference them in promptText + as @Audio1, @Audio2, and @Audio3 in order. + + sample_rate: Output sample rate in Hz. + + speech_rate: Relative speech speed. Negative is slower, positive is faster; 0 is normal. + + 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 + """ + ... + + @overload async def create( self, *, @@ -161,12 +294,41 @@ async def create( timeout: Override the client-level default timeout for this request, in seconds """ + ... + + @required_args(["model", "prompt_text"]) + async def create( + self, + *, + model: Literal["seed_audio"] | Literal["eleven_text_to_sound_v2"], + prompt_text: str, + loudness_rate: int | Omit = omit, + output_format: Literal["wav", "mp3", "ogg_opus"] | Omit = omit, + pitch_rate: int | Omit = omit, + reference_audios: SequenceNotStr[str] | Omit = omit, + sample_rate: Literal[8000, 16000, 24000, 32000, 44100, 48000] | Omit = omit, + speech_rate: int | Omit = omit, + duration: float | Omit = omit, + loop: bool | 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, + ) -> AsyncNewTaskCreatedResponse: return await self._post( "/v1/sound_effect", body=await async_maybe_transform( { "model": model, "prompt_text": prompt_text, + "loudness_rate": loudness_rate, + "output_format": output_format, + "pitch_rate": pitch_rate, + "reference_audios": reference_audios, + "sample_rate": sample_rate, + "speech_rate": speech_rate, "duration": duration, "loop": loop, }, diff --git a/src/runwayml/resources/text_to_speech.py b/src/runwayml/resources/text_to_speech.py index 47aabd2..235baa8 100644 --- a/src/runwayml/resources/text_to_speech.py +++ b/src/runwayml/resources/text_to_speech.py @@ -2,13 +2,13 @@ from __future__ import annotations -from typing_extensions import Literal +from typing_extensions import Literal, overload import httpx from ..types import text_to_speech_create_params -from .._types import Body, Query, Headers, NotGiven, not_given -from .._utils import maybe_transform, async_maybe_transform +from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given +from .._utils import required_args, maybe_transform, async_maybe_transform from .._compat import cached_property from .._resource import SyncAPIResource, AsyncAPIResource from .._response import ( @@ -51,12 +51,62 @@ def with_streaming_response(self) -> TextToSpeechResourceWithStreamingResponse: """ return TextToSpeechResourceWithStreamingResponse(self) + @overload + def create( + self, + *, + model: Literal["seed_audio"], + prompt_text: str, + loudness_rate: int | Omit = omit, + output_format: Literal["wav", "mp3", "ogg_opus"] | Omit = omit, + pitch_rate: int | Omit = omit, + sample_rate: Literal[8000, 16000, 24000, 32000, 44100, 48000] | Omit = omit, + speech_rate: int | Omit = omit, + voice: text_to_speech_create_params.SeedAudioVoice | 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, + ) -> NewTaskCreatedResponse: + """ + This endpoint will start a new task to generate speech from text. + + Args: + prompt_text: A non-empty text prompt. For text-to-speech, the words to speak. For + text-to-audio, a scene description that can include voice direction, dialogue, + music, and sound effects. + + loudness_rate: Relative output loudness. Negative is quieter, positive is louder; 0 is normal. + + output_format: Output audio container/format. + + pitch_rate: Pitch shift in semitones. Negative lowers, positive raises; 0 is unchanged. + + sample_rate: Output sample rate in Hz. + + speech_rate: Relative speech speed. Negative is slower, positive is faster; 0 is normal. + + voice: Clone from a single reference audio clip, then speak promptText in that voice. + + 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 + """ + ... + + @overload def create( self, *, model: Literal["eleven_multilingual_v2"], prompt_text: str, - voice: text_to_speech_create_params.Voice, + voice: text_to_speech_create_params.ElevenMultilingualV2Voice, # 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, @@ -81,12 +131,40 @@ def create( timeout: Override the client-level default timeout for this request, in seconds """ + ... + + @required_args(["model", "prompt_text"], ["model", "prompt_text", "voice"]) + def create( + self, + *, + model: Literal["seed_audio"] | Literal["eleven_multilingual_v2"], + prompt_text: str, + loudness_rate: int | Omit = omit, + output_format: Literal["wav", "mp3", "ogg_opus"] | Omit = omit, + pitch_rate: int | Omit = omit, + sample_rate: Literal[8000, 16000, 24000, 32000, 44100, 48000] | Omit = omit, + speech_rate: int | Omit = omit, + voice: text_to_speech_create_params.SeedAudioVoice + | text_to_speech_create_params.ElevenMultilingualV2Voice + | 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, + ) -> NewTaskCreatedResponse: return self._post( "/v1/text_to_speech", body=maybe_transform( { "model": model, "prompt_text": prompt_text, + "loudness_rate": loudness_rate, + "output_format": output_format, + "pitch_rate": pitch_rate, + "sample_rate": sample_rate, + "speech_rate": speech_rate, "voice": voice, }, text_to_speech_create_params.TextToSpeechCreateParams, @@ -120,12 +198,62 @@ def with_streaming_response(self) -> AsyncTextToSpeechResourceWithStreamingRespo """ return AsyncTextToSpeechResourceWithStreamingResponse(self) + @overload + async def create( + self, + *, + model: Literal["seed_audio"], + prompt_text: str, + loudness_rate: int | Omit = omit, + output_format: Literal["wav", "mp3", "ogg_opus"] | Omit = omit, + pitch_rate: int | Omit = omit, + sample_rate: Literal[8000, 16000, 24000, 32000, 44100, 48000] | Omit = omit, + speech_rate: int | Omit = omit, + voice: text_to_speech_create_params.SeedAudioVoice | 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, + ) -> AsyncNewTaskCreatedResponse: + """ + This endpoint will start a new task to generate speech from text. + + Args: + prompt_text: A non-empty text prompt. For text-to-speech, the words to speak. For + text-to-audio, a scene description that can include voice direction, dialogue, + music, and sound effects. + + loudness_rate: Relative output loudness. Negative is quieter, positive is louder; 0 is normal. + + output_format: Output audio container/format. + + pitch_rate: Pitch shift in semitones. Negative lowers, positive raises; 0 is unchanged. + + sample_rate: Output sample rate in Hz. + + speech_rate: Relative speech speed. Negative is slower, positive is faster; 0 is normal. + + voice: Clone from a single reference audio clip, then speak promptText in that voice. + + 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 + """ + ... + + @overload async def create( self, *, model: Literal["eleven_multilingual_v2"], prompt_text: str, - voice: text_to_speech_create_params.Voice, + voice: text_to_speech_create_params.ElevenMultilingualV2Voice, # 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, @@ -150,12 +278,40 @@ async def create( timeout: Override the client-level default timeout for this request, in seconds """ + ... + + @required_args(["model", "prompt_text"], ["model", "prompt_text", "voice"]) + async def create( + self, + *, + model: Literal["seed_audio"] | Literal["eleven_multilingual_v2"], + prompt_text: str, + loudness_rate: int | Omit = omit, + output_format: Literal["wav", "mp3", "ogg_opus"] | Omit = omit, + pitch_rate: int | Omit = omit, + sample_rate: Literal[8000, 16000, 24000, 32000, 44100, 48000] | Omit = omit, + speech_rate: int | Omit = omit, + voice: text_to_speech_create_params.SeedAudioVoice + | text_to_speech_create_params.ElevenMultilingualV2Voice + | 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, + ) -> AsyncNewTaskCreatedResponse: return await self._post( "/v1/text_to_speech", body=await async_maybe_transform( { "model": model, "prompt_text": prompt_text, + "loudness_rate": loudness_rate, + "output_format": output_format, + "pitch_rate": pitch_rate, + "sample_rate": sample_rate, + "speech_rate": speech_rate, "voice": voice, }, text_to_speech_create_params.TextToSpeechCreateParams, diff --git a/src/runwayml/types/sound_effect_create_params.py b/src/runwayml/types/sound_effect_create_params.py index 1d75950..81ba046 100644 --- a/src/runwayml/types/sound_effect_create_params.py +++ b/src/runwayml/types/sound_effect_create_params.py @@ -2,14 +2,49 @@ from __future__ import annotations -from typing_extensions import Literal, Required, Annotated, TypedDict +from typing import Union +from typing_extensions import Literal, Required, Annotated, TypeAlias, TypedDict +from .._types import SequenceNotStr from .._utils import PropertyInfo -__all__ = ["SoundEffectCreateParams"] +__all__ = ["SoundEffectCreateParams", "SeedAudio", "ElevenTextToSoundV2"] -class SoundEffectCreateParams(TypedDict, total=False): +class SeedAudio(TypedDict, total=False): + model: Required[Literal["seed_audio"]] + + prompt_text: Required[Annotated[str, PropertyInfo(alias="promptText")]] + """A non-empty text prompt. + + For text-to-speech, the words to speak. For text-to-audio, a scene description + that can include voice direction, dialogue, music, and sound effects. + """ + + loudness_rate: Annotated[int, PropertyInfo(alias="loudnessRate")] + """Relative output loudness. Negative is quieter, positive is louder; 0 is normal.""" + + output_format: Annotated[Literal["wav", "mp3", "ogg_opus"], PropertyInfo(alias="outputFormat")] + """Output audio container/format.""" + + pitch_rate: Annotated[int, PropertyInfo(alias="pitchRate")] + """Pitch shift in semitones. Negative lowers, positive raises; 0 is unchanged.""" + + reference_audios: Annotated[SequenceNotStr[str], PropertyInfo(alias="referenceAudios")] + """Up to three reference audio clips. + + When provided, reference them in promptText as @Audio1, @Audio2, and @Audio3 in + order. + """ + + sample_rate: Annotated[Literal[8000, 16000, 24000, 32000, 44100, 48000], PropertyInfo(alias="sampleRate")] + """Output sample rate in Hz.""" + + speech_rate: Annotated[int, PropertyInfo(alias="speechRate")] + """Relative speech speed. Negative is slower, positive is faster; 0 is normal.""" + + +class ElevenTextToSoundV2(TypedDict, total=False): model: Required[Literal["eleven_text_to_sound_v2"]] prompt_text: Required[Annotated[str, PropertyInfo(alias="promptText")]] @@ -24,3 +59,6 @@ class SoundEffectCreateParams(TypedDict, total=False): loop: bool """Whether the output sound effect should be designed to loop seamlessly.""" + + +SoundEffectCreateParams: TypeAlias = Union[SeedAudio, ElevenTextToSoundV2] diff --git a/src/runwayml/types/text_to_speech_create_params.py b/src/runwayml/types/text_to_speech_create_params.py index 3940a85..13b4fbb 100644 --- a/src/runwayml/types/text_to_speech_create_params.py +++ b/src/runwayml/types/text_to_speech_create_params.py @@ -2,14 +2,59 @@ from __future__ import annotations -from typing_extensions import Literal, Required, Annotated, TypedDict +from typing import Union +from typing_extensions import Literal, Required, Annotated, TypeAlias, TypedDict from .._utils import PropertyInfo -__all__ = ["TextToSpeechCreateParams", "Voice"] +__all__ = [ + "TextToSpeechCreateParams", + "SeedAudio", + "SeedAudioVoice", + "ElevenMultilingualV2", + "ElevenMultilingualV2Voice", +] -class TextToSpeechCreateParams(TypedDict, total=False): +class SeedAudio(TypedDict, total=False): + model: Required[Literal["seed_audio"]] + + prompt_text: Required[Annotated[str, PropertyInfo(alias="promptText")]] + """A non-empty text prompt. + + For text-to-speech, the words to speak. For text-to-audio, a scene description + that can include voice direction, dialogue, music, and sound effects. + """ + + loudness_rate: Annotated[int, PropertyInfo(alias="loudnessRate")] + """Relative output loudness. Negative is quieter, positive is louder; 0 is normal.""" + + output_format: Annotated[Literal["wav", "mp3", "ogg_opus"], PropertyInfo(alias="outputFormat")] + """Output audio container/format.""" + + pitch_rate: Annotated[int, PropertyInfo(alias="pitchRate")] + """Pitch shift in semitones. Negative lowers, positive raises; 0 is unchanged.""" + + sample_rate: Annotated[Literal[8000, 16000, 24000, 32000, 44100, 48000], PropertyInfo(alias="sampleRate")] + """Output sample rate in Hz.""" + + speech_rate: Annotated[int, PropertyInfo(alias="speechRate")] + """Relative speech speed. Negative is slower, positive is faster; 0 is normal.""" + + voice: SeedAudioVoice + """Clone from a single reference audio clip, then speak promptText in that voice.""" + + +class SeedAudioVoice(TypedDict, total=False): + """Clone from a single reference audio clip, then speak promptText in that voice.""" + + audio_uri: Required[Annotated[str, PropertyInfo(alias="audioUri")]] + """A HTTPS URL.""" + + type: Required[Literal["reference-audio"]] + + +class ElevenMultilingualV2(TypedDict, total=False): model: Required[Literal["eleven_multilingual_v2"]] prompt_text: Required[Annotated[str, PropertyInfo(alias="promptText")]] @@ -18,11 +63,11 @@ class TextToSpeechCreateParams(TypedDict, total=False): This should describe in detail what should appear in the output. """ - voice: Required[Voice] + voice: Required[ElevenMultilingualV2Voice] """A voice preset from the RunwayML API.""" -class Voice(TypedDict, total=False): +class ElevenMultilingualV2Voice(TypedDict, total=False): """A voice preset from the RunwayML API.""" preset_id: Required[ @@ -84,3 +129,6 @@ class Voice(TypedDict, total=False): """The preset voice ID to use for the generated speech.""" type: Required[Literal["runway-preset"]] + + +TextToSpeechCreateParams: TypeAlias = Union[SeedAudio, ElevenMultilingualV2] diff --git a/tests/api_resources/test_sound_effect.py b/tests/api_resources/test_sound_effect.py index 9b5e79e..07fe0f1 100644 --- a/tests/api_resources/test_sound_effect.py +++ b/tests/api_resources/test_sound_effect.py @@ -18,7 +18,55 @@ class TestSoundEffect: parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) @parametrize - def test_method_create(self, client: RunwayML) -> None: + def test_method_create_overload_1(self, client: RunwayML) -> None: + sound_effect = client.sound_effect.create( + model="seed_audio", + prompt_text="x", + ) + assert_matches_type(SoundEffectCreateResponse, sound_effect, path=["response"]) + + @parametrize + def test_method_create_with_all_params_overload_1(self, client: RunwayML) -> None: + sound_effect = client.sound_effect.create( + model="seed_audio", + prompt_text="x", + loudness_rate=-50, + output_format="wav", + pitch_rate=-12, + reference_audios=["https://example.com/file"], + sample_rate=8000, + speech_rate=-50, + ) + assert_matches_type(SoundEffectCreateResponse, sound_effect, path=["response"]) + + @parametrize + def test_raw_response_create_overload_1(self, client: RunwayML) -> None: + response = client.sound_effect.with_raw_response.create( + model="seed_audio", + prompt_text="x", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + sound_effect = response.parse() + assert_matches_type(SoundEffectCreateResponse, sound_effect, path=["response"]) + + @parametrize + def test_streaming_response_create_overload_1(self, client: RunwayML) -> None: + with client.sound_effect.with_streaming_response.create( + model="seed_audio", + prompt_text="x", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + sound_effect = response.parse() + assert_matches_type(SoundEffectCreateResponse, sound_effect, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_method_create_overload_2(self, client: RunwayML) -> None: sound_effect = client.sound_effect.create( model="eleven_text_to_sound_v2", prompt_text="x", @@ -26,7 +74,7 @@ def test_method_create(self, client: RunwayML) -> None: assert_matches_type(SoundEffectCreateResponse, sound_effect, path=["response"]) @parametrize - def test_method_create_with_all_params(self, client: RunwayML) -> None: + def test_method_create_with_all_params_overload_2(self, client: RunwayML) -> None: sound_effect = client.sound_effect.create( model="eleven_text_to_sound_v2", prompt_text="x", @@ -36,7 +84,7 @@ def test_method_create_with_all_params(self, client: RunwayML) -> None: assert_matches_type(SoundEffectCreateResponse, sound_effect, path=["response"]) @parametrize - def test_raw_response_create(self, client: RunwayML) -> None: + def test_raw_response_create_overload_2(self, client: RunwayML) -> None: response = client.sound_effect.with_raw_response.create( model="eleven_text_to_sound_v2", prompt_text="x", @@ -48,7 +96,7 @@ def test_raw_response_create(self, client: RunwayML) -> None: assert_matches_type(SoundEffectCreateResponse, sound_effect, path=["response"]) @parametrize - def test_streaming_response_create(self, client: RunwayML) -> None: + def test_streaming_response_create_overload_2(self, client: RunwayML) -> None: with client.sound_effect.with_streaming_response.create( model="eleven_text_to_sound_v2", prompt_text="x", @@ -68,7 +116,55 @@ class TestAsyncSoundEffect: ) @parametrize - async def test_method_create(self, async_client: AsyncRunwayML) -> None: + async def test_method_create_overload_1(self, async_client: AsyncRunwayML) -> None: + sound_effect = await async_client.sound_effect.create( + model="seed_audio", + prompt_text="x", + ) + assert_matches_type(SoundEffectCreateResponse, sound_effect, path=["response"]) + + @parametrize + async def test_method_create_with_all_params_overload_1(self, async_client: AsyncRunwayML) -> None: + sound_effect = await async_client.sound_effect.create( + model="seed_audio", + prompt_text="x", + loudness_rate=-50, + output_format="wav", + pitch_rate=-12, + reference_audios=["https://example.com/file"], + sample_rate=8000, + speech_rate=-50, + ) + assert_matches_type(SoundEffectCreateResponse, sound_effect, path=["response"]) + + @parametrize + async def test_raw_response_create_overload_1(self, async_client: AsyncRunwayML) -> None: + response = await async_client.sound_effect.with_raw_response.create( + model="seed_audio", + prompt_text="x", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + sound_effect = await response.parse() + assert_matches_type(SoundEffectCreateResponse, sound_effect, path=["response"]) + + @parametrize + async def test_streaming_response_create_overload_1(self, async_client: AsyncRunwayML) -> None: + async with async_client.sound_effect.with_streaming_response.create( + model="seed_audio", + prompt_text="x", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + sound_effect = await response.parse() + assert_matches_type(SoundEffectCreateResponse, sound_effect, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_method_create_overload_2(self, async_client: AsyncRunwayML) -> None: sound_effect = await async_client.sound_effect.create( model="eleven_text_to_sound_v2", prompt_text="x", @@ -76,7 +172,7 @@ async def test_method_create(self, async_client: AsyncRunwayML) -> None: assert_matches_type(SoundEffectCreateResponse, sound_effect, path=["response"]) @parametrize - async def test_method_create_with_all_params(self, async_client: AsyncRunwayML) -> None: + async def test_method_create_with_all_params_overload_2(self, async_client: AsyncRunwayML) -> None: sound_effect = await async_client.sound_effect.create( model="eleven_text_to_sound_v2", prompt_text="x", @@ -86,7 +182,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncRunwayML) assert_matches_type(SoundEffectCreateResponse, sound_effect, path=["response"]) @parametrize - async def test_raw_response_create(self, async_client: AsyncRunwayML) -> None: + async def test_raw_response_create_overload_2(self, async_client: AsyncRunwayML) -> None: response = await async_client.sound_effect.with_raw_response.create( model="eleven_text_to_sound_v2", prompt_text="x", @@ -98,7 +194,7 @@ async def test_raw_response_create(self, async_client: AsyncRunwayML) -> None: assert_matches_type(SoundEffectCreateResponse, sound_effect, path=["response"]) @parametrize - async def test_streaming_response_create(self, async_client: AsyncRunwayML) -> None: + async def test_streaming_response_create_overload_2(self, async_client: AsyncRunwayML) -> None: async with async_client.sound_effect.with_streaming_response.create( model="eleven_text_to_sound_v2", prompt_text="x", diff --git a/tests/api_resources/test_text_to_speech.py b/tests/api_resources/test_text_to_speech.py index 29b5dd5..3666898 100644 --- a/tests/api_resources/test_text_to_speech.py +++ b/tests/api_resources/test_text_to_speech.py @@ -18,7 +18,58 @@ class TestTextToSpeech: parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) @parametrize - def test_method_create(self, client: RunwayML) -> None: + def test_method_create_overload_1(self, client: RunwayML) -> None: + text_to_speech = client.text_to_speech.create( + model="seed_audio", + prompt_text="x", + ) + assert_matches_type(TextToSpeechCreateResponse, text_to_speech, path=["response"]) + + @parametrize + def test_method_create_with_all_params_overload_1(self, client: RunwayML) -> None: + text_to_speech = client.text_to_speech.create( + model="seed_audio", + prompt_text="x", + loudness_rate=-50, + output_format="wav", + pitch_rate=-12, + sample_rate=8000, + speech_rate=-50, + voice={ + "audio_uri": "https://example.com/file", + "type": "reference-audio", + }, + ) + assert_matches_type(TextToSpeechCreateResponse, text_to_speech, path=["response"]) + + @parametrize + def test_raw_response_create_overload_1(self, client: RunwayML) -> None: + response = client.text_to_speech.with_raw_response.create( + model="seed_audio", + prompt_text="x", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + text_to_speech = response.parse() + assert_matches_type(TextToSpeechCreateResponse, text_to_speech, path=["response"]) + + @parametrize + def test_streaming_response_create_overload_1(self, client: RunwayML) -> None: + with client.text_to_speech.with_streaming_response.create( + model="seed_audio", + prompt_text="x", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + text_to_speech = response.parse() + assert_matches_type(TextToSpeechCreateResponse, text_to_speech, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_method_create_overload_2(self, client: RunwayML) -> None: text_to_speech = client.text_to_speech.create( model="eleven_multilingual_v2", prompt_text="x", @@ -30,7 +81,7 @@ def test_method_create(self, client: RunwayML) -> None: assert_matches_type(TextToSpeechCreateResponse, text_to_speech, path=["response"]) @parametrize - def test_raw_response_create(self, client: RunwayML) -> None: + def test_raw_response_create_overload_2(self, client: RunwayML) -> None: response = client.text_to_speech.with_raw_response.create( model="eleven_multilingual_v2", prompt_text="x", @@ -46,7 +97,7 @@ def test_raw_response_create(self, client: RunwayML) -> None: assert_matches_type(TextToSpeechCreateResponse, text_to_speech, path=["response"]) @parametrize - def test_streaming_response_create(self, client: RunwayML) -> None: + def test_streaming_response_create_overload_2(self, client: RunwayML) -> None: with client.text_to_speech.with_streaming_response.create( model="eleven_multilingual_v2", prompt_text="x", @@ -70,7 +121,58 @@ class TestAsyncTextToSpeech: ) @parametrize - async def test_method_create(self, async_client: AsyncRunwayML) -> None: + async def test_method_create_overload_1(self, async_client: AsyncRunwayML) -> None: + text_to_speech = await async_client.text_to_speech.create( + model="seed_audio", + prompt_text="x", + ) + assert_matches_type(TextToSpeechCreateResponse, text_to_speech, path=["response"]) + + @parametrize + async def test_method_create_with_all_params_overload_1(self, async_client: AsyncRunwayML) -> None: + text_to_speech = await async_client.text_to_speech.create( + model="seed_audio", + prompt_text="x", + loudness_rate=-50, + output_format="wav", + pitch_rate=-12, + sample_rate=8000, + speech_rate=-50, + voice={ + "audio_uri": "https://example.com/file", + "type": "reference-audio", + }, + ) + assert_matches_type(TextToSpeechCreateResponse, text_to_speech, path=["response"]) + + @parametrize + async def test_raw_response_create_overload_1(self, async_client: AsyncRunwayML) -> None: + response = await async_client.text_to_speech.with_raw_response.create( + model="seed_audio", + prompt_text="x", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + text_to_speech = await response.parse() + assert_matches_type(TextToSpeechCreateResponse, text_to_speech, path=["response"]) + + @parametrize + async def test_streaming_response_create_overload_1(self, async_client: AsyncRunwayML) -> None: + async with async_client.text_to_speech.with_streaming_response.create( + model="seed_audio", + prompt_text="x", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + text_to_speech = await response.parse() + assert_matches_type(TextToSpeechCreateResponse, text_to_speech, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_method_create_overload_2(self, async_client: AsyncRunwayML) -> None: text_to_speech = await async_client.text_to_speech.create( model="eleven_multilingual_v2", prompt_text="x", @@ -82,7 +184,7 @@ async def test_method_create(self, async_client: AsyncRunwayML) -> None: assert_matches_type(TextToSpeechCreateResponse, text_to_speech, path=["response"]) @parametrize - async def test_raw_response_create(self, async_client: AsyncRunwayML) -> None: + async def test_raw_response_create_overload_2(self, async_client: AsyncRunwayML) -> None: response = await async_client.text_to_speech.with_raw_response.create( model="eleven_multilingual_v2", prompt_text="x", @@ -98,7 +200,7 @@ async def test_raw_response_create(self, async_client: AsyncRunwayML) -> None: assert_matches_type(TextToSpeechCreateResponse, text_to_speech, path=["response"]) @parametrize - async def test_streaming_response_create(self, async_client: AsyncRunwayML) -> None: + async def test_streaming_response_create_overload_2(self, async_client: AsyncRunwayML) -> None: async with async_client.text_to_speech.with_streaming_response.create( model="eleven_multilingual_v2", prompt_text="x", From f8ed19e26be38c4420e91ed215059bfb490ec783 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 6 Jul 2026 18:53:55 +0000 Subject: [PATCH 2/2] release: 5.7.0 --- .release-please-manifest.json | 2 +- CHANGELOG.md | 8 ++++++++ pyproject.toml | 2 +- src/runwayml/_version.py | 2 +- 4 files changed, 11 insertions(+), 3 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 8d05042..4a0511b 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "5.6.0" + ".": "5.7.0" } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 5a9a997..11350b9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## 5.7.0 (2026-07-06) + +Full Changelog: [v5.6.0...v5.7.0](https://github.com/runwayml/sdk-python/compare/v5.6.0...v5.7.0) + +### Features + +* **api:** add seed_audio model ([f1def20](https://github.com/runwayml/sdk-python/commit/f1def200362842d3bd5ea611527be894e65babf6)) + ## 5.6.0 (2026-07-06) Full Changelog: [v5.5.0...v5.6.0](https://github.com/runwayml/sdk-python/compare/v5.5.0...v5.6.0) diff --git a/pyproject.toml b/pyproject.toml index d112ec5..763c78a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "runwayml" -version = "5.6.0" +version = "5.7.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 1df66e6..0b3d514 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__ = "5.6.0" # x-release-please-version +__version__ = "5.7.0" # x-release-please-version