diff --git a/.release-please-manifest.json b/.release-please-manifest.json index a43b15a..03276cf 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "4.11.0" + ".": "4.12.0" } \ No newline at end of file diff --git a/.stats.yml b/.stats.yml index 4a5de71..7425a52 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 37 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/runwayml%2Frunwayml-ee023fb84f0e74914e23b019b4c0951108b7ff83b983563c91ae07986524b674.yml -openapi_spec_hash: 2472895eb74737ecef2cbee707e50cac +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/runwayml%2Frunwayml-87bdf413b984e6050236628a1fb9585a5f749c18671b15821f6f556ce4419c4b.yml +openapi_spec_hash: d4a8307f67a1539b1a4f14dac1b285c4 config_hash: 3063a17ad98d447287f6f7eab9d6d1d6 diff --git a/CHANGELOG.md b/CHANGELOG.md index 401169b..ea8fc7c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,20 @@ # Changelog +## 4.12.0 (2026-04-15) + +Full Changelog: [v4.11.0...v4.12.0](https://github.com/runwayml/sdk-python/compare/v4.11.0...v4.12.0) + +### Features + +* **api:** seedance2 ([5004f1d](https://github.com/runwayml/sdk-python/commit/5004f1d931a4bf5e53c8b67cefa098bc85fa4ef5)) +* **client:** awaitable task support for seedance2 ([c3f73ee](https://github.com/runwayml/sdk-python/commit/c3f73ee879ed425e1ecb4917d11df32d3313f782)) + + +### Bug Fixes + +* **api:** remove spurious api param ([92173b3](https://github.com/runwayml/sdk-python/commit/92173b323f113a36d28386ec5ea096b4ee940be3)) +* ensure file data are only sent as 1 parameter ([fc5a5ef](https://github.com/runwayml/sdk-python/commit/fc5a5efba2d71af553c8cd0c7b0024bd15db0a16)) + ## 4.11.0 (2026-04-10) Full Changelog: [v4.10.0...v4.11.0](https://github.com/runwayml/sdk-python/compare/v4.10.0...v4.11.0) diff --git a/pyproject.toml b/pyproject.toml index c8a9c2f..a68070a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "runwayml" -version = "4.11.0" +version = "4.12.0" description = "The official Python library for the runwayml API" dynamic = ["readme"] license = "Apache-2.0" diff --git a/src/runwayml/_utils/_utils.py b/src/runwayml/_utils/_utils.py index eec7f4a..63b8cd6 100644 --- a/src/runwayml/_utils/_utils.py +++ b/src/runwayml/_utils/_utils.py @@ -86,8 +86,9 @@ def _extract_items( index += 1 if is_dict(obj): try: - # We are at the last entry in the path so we must remove the field - if (len(path)) == index: + # Remove the field if there are no more dict keys in the path, + # only "" traversal markers or end. + if all(p == "" for p in path[index:]): item = obj.pop(key) else: item = obj[key] diff --git a/src/runwayml/_version.py b/src/runwayml/_version.py index 2d1640a..bf8a7b6 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.11.0" # x-release-please-version +__version__ = "4.12.0" # x-release-please-version diff --git a/src/runwayml/resources/documents.py b/src/runwayml/resources/documents.py index 93d1746..82c5165 100644 --- a/src/runwayml/resources/documents.py +++ b/src/runwayml/resources/documents.py @@ -2,6 +2,8 @@ from __future__ import annotations +from typing_extensions import Literal + import httpx from ..types import document_list_params, document_create_params, document_update_params @@ -175,6 +177,8 @@ def list( self, *, limit: int, + order: Literal["asc", "desc"], + sort: Literal["createdAt", "updatedAt"], cursor: str | 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. @@ -190,6 +194,10 @@ def list( Args: limit: The maximum number of items to return per page. + order: Sort direction. + + sort: Field to sort results by. + cursor: Cursor from a previous response for fetching the next page of results. extra_headers: Send extra headers @@ -211,6 +219,8 @@ def list( query=maybe_transform( { "limit": limit, + "order": order, + "sort": sort, "cursor": cursor, }, document_list_params.DocumentListParams, @@ -407,6 +417,8 @@ def list( self, *, limit: int, + order: Literal["asc", "desc"], + sort: Literal["createdAt", "updatedAt"], cursor: str | 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. @@ -422,6 +434,10 @@ def list( Args: limit: The maximum number of items to return per page. + order: Sort direction. + + sort: Field to sort results by. + cursor: Cursor from a previous response for fetching the next page of results. extra_headers: Send extra headers @@ -443,6 +459,8 @@ def list( query=maybe_transform( { "limit": limit, + "order": order, + "sort": sort, "cursor": cursor, }, document_list_params.DocumentListParams, diff --git a/src/runwayml/resources/image_to_video.py b/src/runwayml/resources/image_to_video.py index a4f0278..af90335 100644 --- a/src/runwayml/resources/image_to_video.py +++ b/src/runwayml/resources/image_to_video.py @@ -282,6 +282,66 @@ def create( """ ... + @overload + def create( + self, + *, + model: Literal["seedance2"], + prompt_image: Union[str, Iterable[image_to_video_create_params.Seedance2PromptImagePromptImage]], + audio: bool | Omit = omit, + duration: int | Omit = omit, + output_count: int | Omit = omit, + prompt_text: str | Omit = omit, + ratio: Literal[ + "992:432", + "864:496", + "752:560", + "640:640", + "560:752", + "496:864", + "1470:630", + "1280:720", + "1112:834", + "960:960", + "834:1112", + "720:1280", + ] + | 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 a video from an image. + + Args: + prompt_image: An image or array of images. Use position `first`/`last` for keyframe mode, or + omit position for reference images. The two modes cannot be mixed. + + audio: Whether to generate audio for the video. Audio inclusion affects pricing. + + duration: The number of seconds of duration for the output video. + + output_count: The number of video generations to produce. + + prompt_text: An optional text prompt up to 3500 characters (measured in UTF-16 code units). + This should describe in detail what should appear in the output. + + ratio: The resolution of the output video. + + 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, @@ -325,6 +385,7 @@ def create( ["duration", "model", "prompt_image", "prompt_text", "ratio"], ["model", "prompt_image", "ratio"], ["model", "prompt_image", "prompt_text"], + ["model", "prompt_image"], ["duration", "model", "prompt_image", "ratio"], ) def create( @@ -336,18 +397,34 @@ def create( | Literal["gen3a_turbo"] | Literal["veo3.1"] | Literal["veo3.1_fast"] + | Literal["seedance2"] | Literal["veo3"], prompt_image: Union[str, Iterable[image_to_video_create_params.Gen4_5PromptImagePromptImage]] | Union[str, Iterable[image_to_video_create_params.Gen4TurboPromptImagePromptImage]] | Union[str, Iterable[image_to_video_create_params.Gen3aTurboPromptImagePromptImage]] | Union[str, Iterable[image_to_video_create_params.Veo3_1PromptImagePromptImage]] | Union[str, Iterable[image_to_video_create_params.Veo3_1FastPromptImagePromptImage]] + | Union[str, Iterable[image_to_video_create_params.Seedance2PromptImagePromptImage]] | Union[str, Iterable[image_to_video_create_params.Veo3PromptImagePromptImage]], prompt_text: str | Omit = omit, ratio: Literal["1280:720", "720:1280", "1104:832", "960:960", "832:1104", "1584:672"] | Literal["1280:720", "720:1280", "1104:832", "832:1104", "960:960", "1584:672"] | Literal["768:1280", "1280:768"] | Literal["1280:720", "720:1280", "1080:1920", "1920:1080"] + | Literal[ + "992:432", + "864:496", + "752:560", + "640:640", + "560:752", + "496:864", + "1470:630", + "1280:720", + "1112:834", + "960:960", + "834:1112", + "720:1280", + ] | Omit = omit, content_moderation: image_to_video_create_params.Gen4_5ContentModeration | image_to_video_create_params.Gen4TurboContentModeration @@ -355,6 +432,7 @@ def create( | Omit = omit, seed: int | Omit = omit, audio: bool | Omit = omit, + output_count: 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, @@ -374,6 +452,7 @@ def create( "content_moderation": content_moderation, "seed": seed, "audio": audio, + "output_count": output_count, }, image_to_video_create_params.ImageToVideoCreateParams, ), @@ -636,6 +715,66 @@ async def create( """ ... + @overload + async def create( + self, + *, + model: Literal["seedance2"], + prompt_image: Union[str, Iterable[image_to_video_create_params.Seedance2PromptImagePromptImage]], + audio: bool | Omit = omit, + duration: int | Omit = omit, + output_count: int | Omit = omit, + prompt_text: str | Omit = omit, + ratio: Literal[ + "992:432", + "864:496", + "752:560", + "640:640", + "560:752", + "496:864", + "1470:630", + "1280:720", + "1112:834", + "960:960", + "834:1112", + "720:1280", + ] + | 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 a video from an image. + + Args: + prompt_image: An image or array of images. Use position `first`/`last` for keyframe mode, or + omit position for reference images. The two modes cannot be mixed. + + audio: Whether to generate audio for the video. Audio inclusion affects pricing. + + duration: The number of seconds of duration for the output video. + + output_count: The number of video generations to produce. + + prompt_text: An optional text prompt up to 3500 characters (measured in UTF-16 code units). + This should describe in detail what should appear in the output. + + ratio: The resolution of the output video. + + 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, @@ -679,6 +818,7 @@ async def create( ["duration", "model", "prompt_image", "prompt_text", "ratio"], ["model", "prompt_image", "ratio"], ["model", "prompt_image", "prompt_text"], + ["model", "prompt_image"], ["duration", "model", "prompt_image", "ratio"], ) async def create( @@ -690,18 +830,34 @@ async def create( | Literal["gen3a_turbo"] | Literal["veo3.1"] | Literal["veo3.1_fast"] + | Literal["seedance2"] | Literal["veo3"], prompt_image: Union[str, Iterable[image_to_video_create_params.Gen4_5PromptImagePromptImage]] | Union[str, Iterable[image_to_video_create_params.Gen4TurboPromptImagePromptImage]] | Union[str, Iterable[image_to_video_create_params.Gen3aTurboPromptImagePromptImage]] | Union[str, Iterable[image_to_video_create_params.Veo3_1PromptImagePromptImage]] | Union[str, Iterable[image_to_video_create_params.Veo3_1FastPromptImagePromptImage]] + | Union[str, Iterable[image_to_video_create_params.Seedance2PromptImagePromptImage]] | Union[str, Iterable[image_to_video_create_params.Veo3PromptImagePromptImage]], prompt_text: str | Omit = omit, ratio: Literal["1280:720", "720:1280", "1104:832", "960:960", "832:1104", "1584:672"] | Literal["1280:720", "720:1280", "1104:832", "832:1104", "960:960", "1584:672"] | Literal["768:1280", "1280:768"] | Literal["1280:720", "720:1280", "1080:1920", "1920:1080"] + | Literal[ + "992:432", + "864:496", + "752:560", + "640:640", + "560:752", + "496:864", + "1470:630", + "1280:720", + "1112:834", + "960:960", + "834:1112", + "720:1280", + ] | Omit = omit, content_moderation: image_to_video_create_params.Gen4_5ContentModeration | image_to_video_create_params.Gen4TurboContentModeration @@ -709,6 +865,7 @@ async def create( | Omit = omit, seed: int | Omit = omit, audio: bool | Omit = omit, + output_count: 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, @@ -728,6 +885,7 @@ async def create( "content_moderation": content_moderation, "seed": seed, "audio": audio, + "output_count": output_count, }, image_to_video_create_params.ImageToVideoCreateParams, ), diff --git a/src/runwayml/resources/realtime_sessions.py b/src/runwayml/resources/realtime_sessions.py index 5921881..0dfa3d1 100644 --- a/src/runwayml/resources/realtime_sessions.py +++ b/src/runwayml/resources/realtime_sessions.py @@ -61,8 +61,11 @@ def create( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> RealtimeSessionCreateResponse: - """ - Create a new realtime session with the specified model configuration. + """Create a new realtime session with the specified model configuration. + + The + returned ID is also the conversation ID used later to fetch transcripts and + recordings from the avatar conversation endpoints. Args: avatar: The avatar configuration for the session. @@ -117,8 +120,10 @@ def retrieve( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> RealtimeSessionRetrieveResponse: - """ - Get the status of a realtime session. + """Get the status of a realtime session. + + This endpoint uses the same ID that the + avatar conversation endpoints later expose as the conversation ID. Args: extra_headers: Send extra headers @@ -215,8 +220,11 @@ async def create( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> RealtimeSessionCreateResponse: - """ - Create a new realtime session with the specified model configuration. + """Create a new realtime session with the specified model configuration. + + The + returned ID is also the conversation ID used later to fetch transcripts and + recordings from the avatar conversation endpoints. Args: avatar: The avatar configuration for the session. @@ -271,8 +279,10 @@ async def retrieve( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> RealtimeSessionRetrieveResponse: - """ - Get the status of a realtime session. + """Get the status of a realtime session. + + This endpoint uses the same ID that the + avatar conversation endpoints later expose as the conversation ID. Args: extra_headers: Send extra headers diff --git a/src/runwayml/resources/text_to_video.py b/src/runwayml/resources/text_to_video.py index f4e197f..02ab10a 100644 --- a/src/runwayml/resources/text_to_video.py +++ b/src/runwayml/resources/text_to_video.py @@ -174,6 +174,62 @@ def create( """ ... + @overload + def create( + self, + *, + model: Literal["seedance2"], + prompt_text: str, + audio: bool | Omit = omit, + duration: int | Omit = omit, + output_count: int | Omit = omit, + ratio: Literal[ + "992:432", + "864:496", + "752:560", + "640:640", + "560:752", + "496:864", + "1470:630", + "1280:720", + "1112:834", + "960:960", + "834:1112", + "720:1280", + ] + | 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 a video from a text prompt. + + Args: + prompt_text: A non-empty string up to 3500 characters (measured in UTF-16 code units). This + should describe in detail what should appear in the output. + + audio: Whether to generate audio for the video. Audio inclusion affects pricing. + + duration: The number of seconds of duration for the output video. + + output_count: The number of video generations to produce. + + ratio: The resolution of the output video. + + 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, @@ -210,17 +266,36 @@ def create( """ ... - @required_args(["duration", "model", "prompt_text", "ratio"], ["model", "prompt_text", "ratio"]) + @required_args( + ["duration", "model", "prompt_text", "ratio"], ["model", "prompt_text", "ratio"], ["model", "prompt_text"] + ) def create( self, *, duration: int | Literal[4, 6, 8] | Literal[8] | Omit = omit, - model: Literal["gen4.5"] | Literal["veo3.1"] | Literal["veo3.1_fast"] | Literal["veo3"], + model: Literal["gen4.5"] | Literal["veo3.1"] | Literal["veo3.1_fast"] | Literal["seedance2"] | Literal["veo3"], prompt_text: str, - ratio: Literal["1280:720", "720:1280"] | Literal["1280:720", "720:1280", "1080:1920", "1920:1080"], + ratio: Literal["1280:720", "720:1280"] + | Literal["1280:720", "720:1280", "1080:1920", "1920:1080"] + | Literal[ + "992:432", + "864:496", + "752:560", + "640:640", + "560:752", + "496:864", + "1470:630", + "1280:720", + "1112:834", + "960:960", + "834:1112", + "720:1280", + ] + | Omit = omit, content_moderation: text_to_video_create_params.Gen4_5ContentModeration | Omit = omit, seed: int | Omit = omit, audio: bool | Omit = omit, + output_count: 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, @@ -239,6 +314,7 @@ def create( "content_moderation": content_moderation, "seed": seed, "audio": audio, + "output_count": output_count, }, text_to_video_create_params.TextToVideoCreateParams, ), @@ -394,6 +470,62 @@ async def create( """ ... + @overload + async def create( + self, + *, + model: Literal["seedance2"], + prompt_text: str, + audio: bool | Omit = omit, + duration: int | Omit = omit, + output_count: int | Omit = omit, + ratio: Literal[ + "992:432", + "864:496", + "752:560", + "640:640", + "560:752", + "496:864", + "1470:630", + "1280:720", + "1112:834", + "960:960", + "834:1112", + "720:1280", + ] + | 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 a video from a text prompt. + + Args: + prompt_text: A non-empty string up to 3500 characters (measured in UTF-16 code units). This + should describe in detail what should appear in the output. + + audio: Whether to generate audio for the video. Audio inclusion affects pricing. + + duration: The number of seconds of duration for the output video. + + output_count: The number of video generations to produce. + + ratio: The resolution of the output video. + + 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, @@ -430,17 +562,36 @@ async def create( """ ... - @required_args(["duration", "model", "prompt_text", "ratio"], ["model", "prompt_text", "ratio"]) + @required_args( + ["duration", "model", "prompt_text", "ratio"], ["model", "prompt_text", "ratio"], ["model", "prompt_text"] + ) async def create( self, *, duration: int | Literal[4, 6, 8] | Literal[8] | Omit = omit, - model: Literal["gen4.5"] | Literal["veo3.1"] | Literal["veo3.1_fast"] | Literal["veo3"], + model: Literal["gen4.5"] | Literal["veo3.1"] | Literal["veo3.1_fast"] | Literal["seedance2"] | Literal["veo3"], prompt_text: str, - ratio: Literal["1280:720", "720:1280"] | Literal["1280:720", "720:1280", "1080:1920", "1920:1080"], + ratio: Literal["1280:720", "720:1280"] + | Literal["1280:720", "720:1280", "1080:1920", "1920:1080"] + | Literal[ + "992:432", + "864:496", + "752:560", + "640:640", + "560:752", + "496:864", + "1470:630", + "1280:720", + "1112:834", + "960:960", + "834:1112", + "720:1280", + ] + | Omit = omit, content_moderation: text_to_video_create_params.Gen4_5ContentModeration | Omit = omit, seed: int | Omit = omit, audio: bool | Omit = omit, + output_count: 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, @@ -459,6 +610,7 @@ async def create( "content_moderation": content_moderation, "seed": seed, "audio": audio, + "output_count": output_count, }, text_to_video_create_params.TextToVideoCreateParams, ), diff --git a/src/runwayml/resources/video_to_video.py b/src/runwayml/resources/video_to_video.py index b09e799..74bf609 100644 --- a/src/runwayml/resources/video_to_video.py +++ b/src/runwayml/resources/video_to_video.py @@ -2,14 +2,14 @@ from __future__ import annotations -from typing import Iterable -from typing_extensions import Literal +from typing import Union, Iterable +from typing_extensions import Literal, overload import httpx from ..types import video_to_video_create_params from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given -from .._utils import maybe_transform, async_maybe_transform +from .._utils import required_args, maybe_transform, async_maybe_transform from .._compat import cached_property from .._resource import SyncAPIResource, AsyncAPIResource from .._response import ( @@ -52,16 +52,17 @@ def with_streaming_response(self) -> VideoToVideoResourceWithStreamingResponse: """ return VideoToVideoResourceWithStreamingResponse(self) + @overload def create( self, *, model: Literal["gen4_aleph"], prompt_text: str, video_uri: str, - content_moderation: video_to_video_create_params.ContentModeration | Omit = omit, + content_moderation: video_to_video_create_params.Gen4AlephContentModeration | Omit = omit, ratio: Literal["1280:720", "720:1280", "1104:832", "960:960", "832:1104", "1584:672", "848:480", "640:480"] | Omit = omit, - references: Iterable[video_to_video_create_params.Reference] | Omit = omit, + references: Iterable[video_to_video_create_params.Gen4AlephReference] | Omit = omit, seed: 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. @@ -99,6 +100,116 @@ def create( timeout: Override the client-level default timeout for this request, in seconds """ + ... + + @overload + def create( + self, + *, + model: Literal["seedance2"], + prompt_video: str, + audio: bool | Omit = omit, + duration: int | Omit = omit, + output_count: int | Omit = omit, + prompt_text: str | Omit = omit, + ratio: Literal[ + "992:432", + "864:496", + "752:560", + "640:640", + "560:752", + "496:864", + "1470:630", + "1280:720", + "1112:834", + "960:960", + "834:1112", + "720:1280", + ] + | Omit = omit, + references: Union[str, Iterable[video_to_video_create_params.Seedance2ReferencesPromptImage]] | Omit = omit, + reference_videos: Iterable[video_to_video_create_params.Seedance2ReferenceVideo] | 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 a video from a video. + + Args: + prompt_video: A HTTPS URL. + + audio: Whether to generate audio for the video. Audio inclusion affects pricing. + + duration: The number of seconds of duration for the output video. Must be an integer from + 4 to 15. + + output_count: The number of video generations to produce. + + prompt_text: An optional text prompt up to 3500 characters describing what should appear in + the output video. + + ratio: The resolution of the output video. + + references: An optional array of image references (up to 9). See + [our docs](/assets/inputs#images) on image inputs for more information. + + reference_videos: An optional array of up to 3 video references. See + [our docs](/assets/inputs#videos) on video inputs for more information. + + 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 + """ + ... + + @required_args(["model", "prompt_text", "video_uri"], ["model", "prompt_video"]) + def create( + self, + *, + model: Literal["gen4_aleph"] | Literal["seedance2"], + prompt_text: str | Omit = omit, + video_uri: str | Omit = omit, + content_moderation: video_to_video_create_params.Gen4AlephContentModeration | Omit = omit, + ratio: Literal["1280:720", "720:1280", "1104:832", "960:960", "832:1104", "1584:672", "848:480", "640:480"] + | Literal[ + "992:432", + "864:496", + "752:560", + "640:640", + "560:752", + "496:864", + "1470:630", + "1280:720", + "1112:834", + "960:960", + "834:1112", + "720:1280", + ] + | Omit = omit, + references: Iterable[video_to_video_create_params.Gen4AlephReference] + | Union[str, Iterable[video_to_video_create_params.Seedance2ReferencesPromptImage]] + | Omit = omit, + seed: int | Omit = omit, + prompt_video: str | Omit = omit, + audio: bool | Omit = omit, + duration: int | Omit = omit, + output_count: int | Omit = omit, + reference_videos: Iterable[video_to_video_create_params.Seedance2ReferenceVideo] | 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/video_to_video", body=maybe_transform( @@ -110,6 +221,11 @@ def create( "ratio": ratio, "references": references, "seed": seed, + "prompt_video": prompt_video, + "audio": audio, + "duration": duration, + "output_count": output_count, + "reference_videos": reference_videos, }, video_to_video_create_params.VideoToVideoCreateParams, ), @@ -142,16 +258,17 @@ def with_streaming_response(self) -> AsyncVideoToVideoResourceWithStreamingRespo """ return AsyncVideoToVideoResourceWithStreamingResponse(self) + @overload async def create( self, *, model: Literal["gen4_aleph"], prompt_text: str, video_uri: str, - content_moderation: video_to_video_create_params.ContentModeration | Omit = omit, + content_moderation: video_to_video_create_params.Gen4AlephContentModeration | Omit = omit, ratio: Literal["1280:720", "720:1280", "1104:832", "960:960", "832:1104", "1584:672", "848:480", "640:480"] | Omit = omit, - references: Iterable[video_to_video_create_params.Reference] | Omit = omit, + references: Iterable[video_to_video_create_params.Gen4AlephReference] | Omit = omit, seed: 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. @@ -189,6 +306,116 @@ async def create( timeout: Override the client-level default timeout for this request, in seconds """ + ... + + @overload + async def create( + self, + *, + model: Literal["seedance2"], + prompt_video: str, + audio: bool | Omit = omit, + duration: int | Omit = omit, + output_count: int | Omit = omit, + prompt_text: str | Omit = omit, + ratio: Literal[ + "992:432", + "864:496", + "752:560", + "640:640", + "560:752", + "496:864", + "1470:630", + "1280:720", + "1112:834", + "960:960", + "834:1112", + "720:1280", + ] + | Omit = omit, + references: Union[str, Iterable[video_to_video_create_params.Seedance2ReferencesPromptImage]] | Omit = omit, + reference_videos: Iterable[video_to_video_create_params.Seedance2ReferenceVideo] | 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 a video from a video. + + Args: + prompt_video: A HTTPS URL. + + audio: Whether to generate audio for the video. Audio inclusion affects pricing. + + duration: The number of seconds of duration for the output video. Must be an integer from + 4 to 15. + + output_count: The number of video generations to produce. + + prompt_text: An optional text prompt up to 3500 characters describing what should appear in + the output video. + + ratio: The resolution of the output video. + + references: An optional array of image references (up to 9). See + [our docs](/assets/inputs#images) on image inputs for more information. + + reference_videos: An optional array of up to 3 video references. See + [our docs](/assets/inputs#videos) on video inputs for more information. + + 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 + """ + ... + + @required_args(["model", "prompt_text", "video_uri"], ["model", "prompt_video"]) + async def create( + self, + *, + model: Literal["gen4_aleph"] | Literal["seedance2"], + prompt_text: str | Omit = omit, + video_uri: str | Omit = omit, + content_moderation: video_to_video_create_params.Gen4AlephContentModeration | Omit = omit, + ratio: Literal["1280:720", "720:1280", "1104:832", "960:960", "832:1104", "1584:672", "848:480", "640:480"] + | Literal[ + "992:432", + "864:496", + "752:560", + "640:640", + "560:752", + "496:864", + "1470:630", + "1280:720", + "1112:834", + "960:960", + "834:1112", + "720:1280", + ] + | Omit = omit, + references: Iterable[video_to_video_create_params.Gen4AlephReference] + | Union[str, Iterable[video_to_video_create_params.Seedance2ReferencesPromptImage]] + | Omit = omit, + seed: int | Omit = omit, + prompt_video: str | Omit = omit, + audio: bool | Omit = omit, + duration: int | Omit = omit, + output_count: int | Omit = omit, + reference_videos: Iterable[video_to_video_create_params.Seedance2ReferenceVideo] | 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/video_to_video", body=await async_maybe_transform( @@ -200,6 +427,11 @@ async def create( "ratio": ratio, "references": references, "seed": seed, + "prompt_video": prompt_video, + "audio": audio, + "duration": duration, + "output_count": output_count, + "reference_videos": reference_videos, }, video_to_video_create_params.VideoToVideoCreateParams, ), diff --git a/src/runwayml/resources/voices.py b/src/runwayml/resources/voices.py index bd7ec81..39da22a 100644 --- a/src/runwayml/resources/voices.py +++ b/src/runwayml/resources/voices.py @@ -66,8 +66,6 @@ def create( sample. Args: - from_: The source configuration for creating the voice. - name: A name for the voice. description: An optional description of the voice. @@ -302,8 +300,6 @@ async def create( sample. Args: - from_: The source configuration for creating the voice. - name: A name for the voice. description: An optional description of the voice. diff --git a/src/runwayml/types/document_list_params.py b/src/runwayml/types/document_list_params.py index 97e5b63..064bd43 100644 --- a/src/runwayml/types/document_list_params.py +++ b/src/runwayml/types/document_list_params.py @@ -2,7 +2,7 @@ from __future__ import annotations -from typing_extensions import Required, TypedDict +from typing_extensions import Literal, Required, TypedDict __all__ = ["DocumentListParams"] @@ -11,5 +11,11 @@ class DocumentListParams(TypedDict, total=False): limit: Required[int] """The maximum number of items to return per page.""" + order: Required[Literal["asc", "desc"]] + """Sort direction.""" + + sort: Required[Literal["createdAt", "updatedAt"]] + """Field to sort results by.""" + cursor: str """Cursor from a previous response for fetching the next page of results.""" diff --git a/src/runwayml/types/image_to_video_create_params.py b/src/runwayml/types/image_to_video_create_params.py index 84ab383..74d3702 100644 --- a/src/runwayml/types/image_to_video_create_params.py +++ b/src/runwayml/types/image_to_video_create_params.py @@ -22,6 +22,8 @@ "Veo3_1PromptImagePromptImage", "Veo3_1Fast", "Veo3_1FastPromptImagePromptImage", + "Seedance2", + "Seedance2PromptImagePromptImage", "Veo3", "Veo3PromptImagePromptImage", ] @@ -270,6 +272,62 @@ class Veo3_1FastPromptImagePromptImage(TypedDict, total=False): """A HTTPS URL.""" +class Seedance2(TypedDict, total=False): + model: Required[Literal["seedance2"]] + + prompt_image: Required[ + Annotated[Union[str, Iterable[Seedance2PromptImagePromptImage]], PropertyInfo(alias="promptImage")] + ] + """An image or array of images. + + Use position `first`/`last` for keyframe mode, or omit position for reference + images. The two modes cannot be mixed. + """ + + audio: bool + """Whether to generate audio for the video. Audio inclusion affects pricing.""" + + duration: int + """The number of seconds of duration for the output video.""" + + output_count: Annotated[int, PropertyInfo(alias="outputCount")] + """The number of video generations to produce.""" + + prompt_text: Annotated[str, PropertyInfo(alias="promptText")] + """An optional text prompt up to 3500 characters (measured in UTF-16 code units). + + This should describe in detail what should appear in the output. + """ + + ratio: Literal[ + "992:432", + "864:496", + "752:560", + "640:640", + "560:752", + "496:864", + "1470:630", + "1280:720", + "1112:834", + "960:960", + "834:1112", + "720:1280", + ] + """The resolution of the output video.""" + + +class Seedance2PromptImagePromptImage(TypedDict, total=False): + uri: Required[str] + """A HTTPS URL.""" + + position: Literal["first", "last"] + """The position of the image in the output video. + + "first" will use the image as the first frame, "last" as the last frame. Omit + for a reference image. + """ + + class Veo3(TypedDict, total=False): duration: Required[Literal[8]] """The number of seconds of duration for the output video.""" @@ -302,4 +360,4 @@ class Veo3PromptImagePromptImage(TypedDict, total=False): """A HTTPS URL.""" -ImageToVideoCreateParams: TypeAlias = Union[Gen4_5, Gen4Turbo, Gen3aTurbo, Veo3_1, Veo3_1Fast, Veo3] +ImageToVideoCreateParams: TypeAlias = Union[Gen4_5, Gen4Turbo, Gen3aTurbo, Veo3_1, Veo3_1Fast, Seedance2, Veo3] diff --git a/src/runwayml/types/organization_retrieve_usage_response.py b/src/runwayml/types/organization_retrieve_usage_response.py index c5b2587..0c76bed 100644 --- a/src/runwayml/types/organization_retrieve_usage_response.py +++ b/src/runwayml/types/organization_retrieve_usage_response.py @@ -13,7 +13,10 @@ class ResultUsedCredit(BaseModel): amount: int - """The number of credits spent on the model.""" + """The net number of credits spent on the model. + + May be negative if refunds exceeded charges on this day. + """ model: Literal[ "gen4.5", @@ -27,14 +30,20 @@ class ResultUsedCredit(BaseModel): "veo3.1", "veo3.1_fast", "gemini_2.5_flash", + "gemini_image3_pro", + "gemini_image3.1_flash", "eleven_multilingual_v2", + "eleven_v3", "eleven_text_to_sound_v2", "eleven_voice_isolation", "eleven_voice_dubbing", "eleven_multilingual_sts_v2", + "eleven_scribe_v2", "gwm1_avatars", "gwm1_avatar_async_audio_to_video", + "gwm1_avatar_async_text_to_video", "voice_processing", + "seedance2", ] """The model that credits were spent on.""" @@ -64,14 +73,20 @@ class OrganizationRetrieveUsageResponse(BaseModel): "veo3.1", "veo3.1_fast", "gemini_2.5_flash", + "gemini_image3_pro", + "gemini_image3.1_flash", "eleven_multilingual_v2", + "eleven_v3", "eleven_text_to_sound_v2", "eleven_voice_isolation", "eleven_voice_dubbing", "eleven_multilingual_sts_v2", + "eleven_scribe_v2", "gwm1_avatars", "gwm1_avatar_async_audio_to_video", + "gwm1_avatar_async_text_to_video", "voice_processing", + "seedance2", ] ] """The list of models with usage during the queried time range.""" diff --git a/src/runwayml/types/realtime_session_create_response.py b/src/runwayml/types/realtime_session_create_response.py index 434f3ba..ef31d8d 100644 --- a/src/runwayml/types/realtime_session_create_response.py +++ b/src/runwayml/types/realtime_session_create_response.py @@ -7,4 +7,8 @@ class RealtimeSessionCreateResponse(BaseModel): id: str - """The ID of the created realtime session.""" + """The ID of the created realtime session. + + This same value is later used as the conversation ID in the avatar conversation + endpoints. + """ diff --git a/src/runwayml/types/realtime_session_retrieve_response.py b/src/runwayml/types/realtime_session_retrieve_response.py index 2956214..16f62a4 100644 --- a/src/runwayml/types/realtime_session_retrieve_response.py +++ b/src/runwayml/types/realtime_session_retrieve_response.py @@ -16,7 +16,11 @@ class NotReady(BaseModel): """A session that is being provisioned.""" id: str - """The realtime session ID.""" + """The realtime session ID. + + This same value is later used as the conversation ID in the avatar conversation + endpoints. + """ created_at: datetime = FieldInfo(alias="createdAt") """When the session was created.""" @@ -34,7 +38,11 @@ class Ready(BaseModel): """A session that is ready to connect.""" id: str - """The realtime session ID.""" + """The realtime session ID. + + This same value is later used as the conversation ID in the avatar conversation + endpoints. + """ created_at: datetime = FieldInfo(alias="createdAt") """When the session was created.""" @@ -52,7 +60,11 @@ class Running(BaseModel): """A session with an active WebRTC connection.""" id: str - """The realtime session ID.""" + """The realtime session ID. + + This same value is later used as the conversation ID in the avatar conversation + endpoints. + """ created_at: datetime = FieldInfo(alias="createdAt") """When the session was created.""" @@ -64,7 +76,11 @@ class Completed(BaseModel): """A session that ended normally.""" id: str - """The realtime session ID.""" + """The realtime session ID. + + This same value is later used as the conversation ID in the avatar conversation + endpoints. + """ created_at: datetime = FieldInfo(alias="createdAt") """When the session was created.""" @@ -79,7 +95,11 @@ class Failed(BaseModel): """A session that encountered an error.""" id: str - """The realtime session ID.""" + """The realtime session ID. + + This same value is later used as the conversation ID in the avatar conversation + endpoints. + """ created_at: datetime = FieldInfo(alias="createdAt") """When the session was created.""" @@ -103,7 +123,11 @@ class Cancelled(BaseModel): """A session that was explicitly cancelled.""" id: str - """The realtime session ID.""" + """The realtime session ID. + + This same value is later used as the conversation ID in the avatar conversation + endpoints. + """ created_at: datetime = FieldInfo(alias="createdAt") """When the session was created.""" diff --git a/src/runwayml/types/text_to_video_create_params.py b/src/runwayml/types/text_to_video_create_params.py index 7a964b3..ec7871f 100644 --- a/src/runwayml/types/text_to_video_create_params.py +++ b/src/runwayml/types/text_to_video_create_params.py @@ -7,7 +7,7 @@ from .._utils import PropertyInfo -__all__ = ["TextToVideoCreateParams", "Gen4_5", "Gen4_5ContentModeration", "Veo3_1", "Veo3_1Fast", "Veo3"] +__all__ = ["TextToVideoCreateParams", "Gen4_5", "Gen4_5ContentModeration", "Veo3_1", "Veo3_1Fast", "Seedance2", "Veo3"] class Gen4_5(TypedDict, total=False): @@ -88,6 +88,41 @@ class Veo3_1Fast(TypedDict, total=False): """The number of seconds of duration for the output video.""" +class Seedance2(TypedDict, total=False): + model: Required[Literal["seedance2"]] + + prompt_text: Required[Annotated[str, PropertyInfo(alias="promptText")]] + """A non-empty string up to 3500 characters (measured in UTF-16 code units). + + This should describe in detail what should appear in the output. + """ + + audio: bool + """Whether to generate audio for the video. Audio inclusion affects pricing.""" + + duration: int + """The number of seconds of duration for the output video.""" + + output_count: Annotated[int, PropertyInfo(alias="outputCount")] + """The number of video generations to produce.""" + + ratio: Literal[ + "992:432", + "864:496", + "752:560", + "640:640", + "560:752", + "496:864", + "1470:630", + "1280:720", + "1112:834", + "960:960", + "834:1112", + "720:1280", + ] + """The resolution of the output video.""" + + class Veo3(TypedDict, total=False): duration: Required[Literal[8]] """The number of seconds of duration for the output video.""" @@ -104,4 +139,4 @@ class Veo3(TypedDict, total=False): """The resolution of the output video.""" -TextToVideoCreateParams: TypeAlias = Union[Gen4_5, Veo3_1, Veo3_1Fast, Veo3] +TextToVideoCreateParams: TypeAlias = Union[Gen4_5, Veo3_1, Veo3_1Fast, Seedance2, Veo3] diff --git a/src/runwayml/types/video_to_video_create_params.py b/src/runwayml/types/video_to_video_create_params.py index e251396..3198cd9 100644 --- a/src/runwayml/types/video_to_video_create_params.py +++ b/src/runwayml/types/video_to_video_create_params.py @@ -2,15 +2,23 @@ from __future__ import annotations -from typing import Iterable -from typing_extensions import Literal, Required, Annotated, TypedDict +from typing import Union, Iterable +from typing_extensions import Literal, Required, Annotated, TypeAlias, TypedDict from .._utils import PropertyInfo -__all__ = ["VideoToVideoCreateParams", "ContentModeration", "Reference"] +__all__ = [ + "VideoToVideoCreateParams", + "Gen4Aleph", + "Gen4AlephContentModeration", + "Gen4AlephReference", + "Seedance2", + "Seedance2ReferencesPromptImage", + "Seedance2ReferenceVideo", +] -class VideoToVideoCreateParams(TypedDict, total=False): +class Gen4Aleph(TypedDict, total=False): model: Required[Literal["gen4_aleph"]] prompt_text: Required[Annotated[str, PropertyInfo(alias="promptText")]] @@ -22,7 +30,7 @@ class VideoToVideoCreateParams(TypedDict, total=False): video_uri: Required[Annotated[str, PropertyInfo(alias="videoUri")]] """A HTTPS URL.""" - content_moderation: Annotated[ContentModeration, PropertyInfo(alias="contentModeration")] + content_moderation: Annotated[Gen4AlephContentModeration, PropertyInfo(alias="contentModeration")] """Settings that affect the behavior of the content moderation system.""" ratio: Literal["1280:720", "720:1280", "1104:832", "960:960", "832:1104", "1584:672", "848:480", "640:480"] @@ -32,7 +40,7 @@ class VideoToVideoCreateParams(TypedDict, total=False): input video. """ - references: Iterable[Reference] + references: Iterable[Gen4AlephReference] """An array of references. Currently up to one reference is supported. See @@ -48,7 +56,7 @@ class VideoToVideoCreateParams(TypedDict, total=False): """ -class ContentModeration(TypedDict, total=False): +class Gen4AlephContentModeration(TypedDict, total=False): """Settings that affect the behavior of the content moderation system.""" public_figure_threshold: Annotated[Literal["auto", "low"], PropertyInfo(alias="publicFigureThreshold")] @@ -58,7 +66,7 @@ class ContentModeration(TypedDict, total=False): """ -class Reference(TypedDict, total=False): +class Gen4AlephReference(TypedDict, total=False): """ Passing an image reference allows the model to emulate the style or content of the reference in the output. """ @@ -67,3 +75,82 @@ class Reference(TypedDict, total=False): uri: Required[str] """A HTTPS URL.""" + + +class Seedance2(TypedDict, total=False): + model: Required[Literal["seedance2"]] + + prompt_video: Required[Annotated[str, PropertyInfo(alias="promptVideo")]] + """A HTTPS URL.""" + + audio: bool + """Whether to generate audio for the video. Audio inclusion affects pricing.""" + + duration: int + """The number of seconds of duration for the output video. + + Must be an integer from 4 to 15. + """ + + output_count: Annotated[int, PropertyInfo(alias="outputCount")] + """The number of video generations to produce.""" + + prompt_text: Annotated[str, PropertyInfo(alias="promptText")] + """ + An optional text prompt up to 3500 characters describing what should appear in + the output video. + """ + + ratio: Literal[ + "992:432", + "864:496", + "752:560", + "640:640", + "560:752", + "496:864", + "1470:630", + "1280:720", + "1112:834", + "960:960", + "834:1112", + "720:1280", + ] + """The resolution of the output video.""" + + references: Union[str, Iterable[Seedance2ReferencesPromptImage]] + """An optional array of image references (up to 9). + + See [our docs](/assets/inputs#images) on image inputs for more information. + """ + + reference_videos: Annotated[Iterable[Seedance2ReferenceVideo], PropertyInfo(alias="referenceVideos")] + """An optional array of up to 3 video references. + + See [our docs](/assets/inputs#videos) on video inputs for more information. + """ + + +class Seedance2ReferencesPromptImage(TypedDict, total=False): + uri: Required[str] + """A HTTPS URL.""" + + position: Literal["first", "last"] + """The position of the image in the output video. + + "first" will use the image as the first frame, "last" as the last frame. Omit + for a reference image. + """ + + +class Seedance2ReferenceVideo(TypedDict, total=False): + """ + A video reference allows the model to use the video as additional context for the output. + """ + + type: Required[Literal["video"]] + + uri: Required[str] + """A HTTPS URL.""" + + +VideoToVideoCreateParams: TypeAlias = Union[Gen4Aleph, Seedance2] diff --git a/src/runwayml/types/voice_create_params.py b/src/runwayml/types/voice_create_params.py index c7acad5..09e472b 100644 --- a/src/runwayml/types/voice_create_params.py +++ b/src/runwayml/types/voice_create_params.py @@ -7,12 +7,11 @@ from .._utils import PropertyInfo -__all__ = ["VoiceCreateParams", "From", "FromText", "FromAudio"] +__all__ = ["VoiceCreateParams", "From", "FromAudio", "FromText"] class VoiceCreateParams(TypedDict, total=False): from_: Required[Annotated[From, PropertyInfo(alias="from")]] - """The source configuration for creating the voice.""" name: Required[str] """A name for the voice.""" @@ -21,9 +20,14 @@ class VoiceCreateParams(TypedDict, total=False): """An optional description of the voice.""" -class FromText(TypedDict, total=False): - """The source configuration for creating the voice.""" +class FromAudio(TypedDict, total=False): + audio: Required[str] + """A HTTPS URL.""" + type: Required[Literal["audio"]] + + +class FromText(TypedDict, total=False): model: Required[Literal["eleven_ttv_v3", "eleven_multilingual_ttv_v2"]] """The voice design model to use. @@ -40,11 +44,4 @@ class FromText(TypedDict, total=False): type: Required[Literal["text"]] -class FromAudio(TypedDict, total=False): - audio: Required[str] - """A HTTPS URL.""" - - type: Required[Literal["audio"]] - - -From: TypeAlias = Union[FromText, FromAudio] +From: TypeAlias = Union[FromAudio, FromText] diff --git a/tests/api_resources/test_documents.py b/tests/api_resources/test_documents.py index 7152e7f..b360d5c 100644 --- a/tests/api_resources/test_documents.py +++ b/tests/api_resources/test_documents.py @@ -145,6 +145,8 @@ def test_path_params_update(self, client: RunwayML) -> None: def test_method_list(self, client: RunwayML) -> None: document = client.documents.list( limit=1, + order="asc", + sort="createdAt", ) assert_matches_type(SyncCursorPage[DocumentListResponse], document, path=["response"]) @@ -152,6 +154,8 @@ def test_method_list(self, client: RunwayML) -> None: def test_method_list_with_all_params(self, client: RunwayML) -> None: document = client.documents.list( limit=1, + order="asc", + sort="createdAt", cursor="x", ) assert_matches_type(SyncCursorPage[DocumentListResponse], document, path=["response"]) @@ -160,6 +164,8 @@ def test_method_list_with_all_params(self, client: RunwayML) -> None: def test_raw_response_list(self, client: RunwayML) -> None: response = client.documents.with_raw_response.list( limit=1, + order="asc", + sort="createdAt", ) assert response.is_closed is True @@ -171,6 +177,8 @@ def test_raw_response_list(self, client: RunwayML) -> None: def test_streaming_response_list(self, client: RunwayML) -> None: with client.documents.with_streaming_response.list( limit=1, + order="asc", + sort="createdAt", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -347,6 +355,8 @@ async def test_path_params_update(self, async_client: AsyncRunwayML) -> None: async def test_method_list(self, async_client: AsyncRunwayML) -> None: document = await async_client.documents.list( limit=1, + order="asc", + sort="createdAt", ) assert_matches_type(AsyncCursorPage[DocumentListResponse], document, path=["response"]) @@ -354,6 +364,8 @@ async def test_method_list(self, async_client: AsyncRunwayML) -> None: async def test_method_list_with_all_params(self, async_client: AsyncRunwayML) -> None: document = await async_client.documents.list( limit=1, + order="asc", + sort="createdAt", cursor="x", ) assert_matches_type(AsyncCursorPage[DocumentListResponse], document, path=["response"]) @@ -362,6 +374,8 @@ async def test_method_list_with_all_params(self, async_client: AsyncRunwayML) -> async def test_raw_response_list(self, async_client: AsyncRunwayML) -> None: response = await async_client.documents.with_raw_response.list( limit=1, + order="asc", + sort="createdAt", ) assert response.is_closed is True @@ -373,6 +387,8 @@ async def test_raw_response_list(self, async_client: AsyncRunwayML) -> None: async def test_streaming_response_list(self, async_client: AsyncRunwayML) -> None: async with async_client.documents.with_streaming_response.list( limit=1, + order="asc", + sort="createdAt", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" diff --git a/tests/api_resources/test_image_to_video.py b/tests/api_resources/test_image_to_video.py index 2a74d7b..8f45c80 100644 --- a/tests/api_resources/test_image_to_video.py +++ b/tests/api_resources/test_image_to_video.py @@ -273,6 +273,53 @@ def test_streaming_response_create_overload_5(self, client: RunwayML) -> None: @parametrize def test_method_create_overload_6(self, client: RunwayML) -> None: + image_to_video = client.image_to_video.create( + model="seedance2", + prompt_image="https://example.com/file", + ) + assert_matches_type(ImageToVideoCreateResponse, image_to_video, path=["response"]) + + @parametrize + def test_method_create_with_all_params_overload_6(self, client: RunwayML) -> None: + image_to_video = client.image_to_video.create( + model="seedance2", + prompt_image="https://example.com/file", + audio=True, + duration=4, + output_count=1, + prompt_text="x", + ratio="992:432", + ) + assert_matches_type(ImageToVideoCreateResponse, image_to_video, path=["response"]) + + @parametrize + def test_raw_response_create_overload_6(self, client: RunwayML) -> None: + response = client.image_to_video.with_raw_response.create( + model="seedance2", + prompt_image="https://example.com/file", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + image_to_video = response.parse() + assert_matches_type(ImageToVideoCreateResponse, image_to_video, path=["response"]) + + @parametrize + def test_streaming_response_create_overload_6(self, client: RunwayML) -> None: + with client.image_to_video.with_streaming_response.create( + model="seedance2", + prompt_image="https://example.com/file", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + image_to_video = response.parse() + assert_matches_type(ImageToVideoCreateResponse, image_to_video, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_method_create_overload_7(self, client: RunwayML) -> None: image_to_video = client.image_to_video.create( duration=8, model="veo3", @@ -282,7 +329,7 @@ def test_method_create_overload_6(self, client: RunwayML) -> None: assert_matches_type(ImageToVideoCreateResponse, image_to_video, path=["response"]) @parametrize - def test_method_create_with_all_params_overload_6(self, client: RunwayML) -> None: + def test_method_create_with_all_params_overload_7(self, client: RunwayML) -> None: image_to_video = client.image_to_video.create( duration=8, model="veo3", @@ -293,7 +340,7 @@ def test_method_create_with_all_params_overload_6(self, client: RunwayML) -> Non assert_matches_type(ImageToVideoCreateResponse, image_to_video, path=["response"]) @parametrize - def test_raw_response_create_overload_6(self, client: RunwayML) -> None: + def test_raw_response_create_overload_7(self, client: RunwayML) -> None: response = client.image_to_video.with_raw_response.create( duration=8, model="veo3", @@ -307,7 +354,7 @@ def test_raw_response_create_overload_6(self, client: RunwayML) -> None: assert_matches_type(ImageToVideoCreateResponse, image_to_video, path=["response"]) @parametrize - def test_streaming_response_create_overload_6(self, client: RunwayML) -> None: + def test_streaming_response_create_overload_7(self, client: RunwayML) -> None: with client.image_to_video.with_streaming_response.create( duration=8, model="veo3", @@ -584,6 +631,53 @@ async def test_streaming_response_create_overload_5(self, async_client: AsyncRun @parametrize async def test_method_create_overload_6(self, async_client: AsyncRunwayML) -> None: + image_to_video = await async_client.image_to_video.create( + model="seedance2", + prompt_image="https://example.com/file", + ) + assert_matches_type(ImageToVideoCreateResponse, image_to_video, path=["response"]) + + @parametrize + async def test_method_create_with_all_params_overload_6(self, async_client: AsyncRunwayML) -> None: + image_to_video = await async_client.image_to_video.create( + model="seedance2", + prompt_image="https://example.com/file", + audio=True, + duration=4, + output_count=1, + prompt_text="x", + ratio="992:432", + ) + assert_matches_type(ImageToVideoCreateResponse, image_to_video, path=["response"]) + + @parametrize + async def test_raw_response_create_overload_6(self, async_client: AsyncRunwayML) -> None: + response = await async_client.image_to_video.with_raw_response.create( + model="seedance2", + prompt_image="https://example.com/file", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + image_to_video = await response.parse() + assert_matches_type(ImageToVideoCreateResponse, image_to_video, path=["response"]) + + @parametrize + async def test_streaming_response_create_overload_6(self, async_client: AsyncRunwayML) -> None: + async with async_client.image_to_video.with_streaming_response.create( + model="seedance2", + prompt_image="https://example.com/file", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + image_to_video = await response.parse() + assert_matches_type(ImageToVideoCreateResponse, image_to_video, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_method_create_overload_7(self, async_client: AsyncRunwayML) -> None: image_to_video = await async_client.image_to_video.create( duration=8, model="veo3", @@ -593,7 +687,7 @@ async def test_method_create_overload_6(self, async_client: AsyncRunwayML) -> No assert_matches_type(ImageToVideoCreateResponse, image_to_video, path=["response"]) @parametrize - async def test_method_create_with_all_params_overload_6(self, async_client: AsyncRunwayML) -> None: + async def test_method_create_with_all_params_overload_7(self, async_client: AsyncRunwayML) -> None: image_to_video = await async_client.image_to_video.create( duration=8, model="veo3", @@ -604,7 +698,7 @@ async def test_method_create_with_all_params_overload_6(self, async_client: Asyn assert_matches_type(ImageToVideoCreateResponse, image_to_video, path=["response"]) @parametrize - async def test_raw_response_create_overload_6(self, async_client: AsyncRunwayML) -> None: + async def test_raw_response_create_overload_7(self, async_client: AsyncRunwayML) -> None: response = await async_client.image_to_video.with_raw_response.create( duration=8, model="veo3", @@ -618,7 +712,7 @@ async def test_raw_response_create_overload_6(self, async_client: AsyncRunwayML) assert_matches_type(ImageToVideoCreateResponse, image_to_video, path=["response"]) @parametrize - async def test_streaming_response_create_overload_6(self, async_client: AsyncRunwayML) -> None: + async def test_streaming_response_create_overload_7(self, async_client: AsyncRunwayML) -> None: async with async_client.image_to_video.with_streaming_response.create( duration=8, model="veo3", diff --git a/tests/api_resources/test_text_to_video.py b/tests/api_resources/test_text_to_video.py index 8ee3497..03d4fe2 100644 --- a/tests/api_resources/test_text_to_video.py +++ b/tests/api_resources/test_text_to_video.py @@ -167,6 +167,52 @@ def test_streaming_response_create_overload_3(self, client: RunwayML) -> None: @parametrize def test_method_create_overload_4(self, client: RunwayML) -> None: + text_to_video = client.text_to_video.create( + model="seedance2", + prompt_text="x", + ) + assert_matches_type(TextToVideoCreateResponse, text_to_video, path=["response"]) + + @parametrize + def test_method_create_with_all_params_overload_4(self, client: RunwayML) -> None: + text_to_video = client.text_to_video.create( + model="seedance2", + prompt_text="x", + audio=True, + duration=4, + output_count=1, + ratio="992:432", + ) + assert_matches_type(TextToVideoCreateResponse, text_to_video, path=["response"]) + + @parametrize + def test_raw_response_create_overload_4(self, client: RunwayML) -> None: + response = client.text_to_video.with_raw_response.create( + model="seedance2", + prompt_text="x", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + text_to_video = response.parse() + assert_matches_type(TextToVideoCreateResponse, text_to_video, path=["response"]) + + @parametrize + def test_streaming_response_create_overload_4(self, client: RunwayML) -> None: + with client.text_to_video.with_streaming_response.create( + model="seedance2", + prompt_text="x", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + text_to_video = response.parse() + assert_matches_type(TextToVideoCreateResponse, text_to_video, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_method_create_overload_5(self, client: RunwayML) -> None: text_to_video = client.text_to_video.create( duration=8, model="veo3", @@ -176,7 +222,7 @@ def test_method_create_overload_4(self, client: RunwayML) -> None: assert_matches_type(TextToVideoCreateResponse, text_to_video, path=["response"]) @parametrize - def test_raw_response_create_overload_4(self, client: RunwayML) -> None: + def test_raw_response_create_overload_5(self, client: RunwayML) -> None: response = client.text_to_video.with_raw_response.create( duration=8, model="veo3", @@ -190,7 +236,7 @@ def test_raw_response_create_overload_4(self, client: RunwayML) -> None: assert_matches_type(TextToVideoCreateResponse, text_to_video, path=["response"]) @parametrize - def test_streaming_response_create_overload_4(self, client: RunwayML) -> None: + def test_streaming_response_create_overload_5(self, client: RunwayML) -> None: with client.text_to_video.with_streaming_response.create( duration=8, model="veo3", @@ -361,6 +407,52 @@ async def test_streaming_response_create_overload_3(self, async_client: AsyncRun @parametrize async def test_method_create_overload_4(self, async_client: AsyncRunwayML) -> None: + text_to_video = await async_client.text_to_video.create( + model="seedance2", + prompt_text="x", + ) + assert_matches_type(TextToVideoCreateResponse, text_to_video, path=["response"]) + + @parametrize + async def test_method_create_with_all_params_overload_4(self, async_client: AsyncRunwayML) -> None: + text_to_video = await async_client.text_to_video.create( + model="seedance2", + prompt_text="x", + audio=True, + duration=4, + output_count=1, + ratio="992:432", + ) + assert_matches_type(TextToVideoCreateResponse, text_to_video, path=["response"]) + + @parametrize + async def test_raw_response_create_overload_4(self, async_client: AsyncRunwayML) -> None: + response = await async_client.text_to_video.with_raw_response.create( + model="seedance2", + prompt_text="x", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + text_to_video = await response.parse() + assert_matches_type(TextToVideoCreateResponse, text_to_video, path=["response"]) + + @parametrize + async def test_streaming_response_create_overload_4(self, async_client: AsyncRunwayML) -> None: + async with async_client.text_to_video.with_streaming_response.create( + model="seedance2", + prompt_text="x", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + text_to_video = await response.parse() + assert_matches_type(TextToVideoCreateResponse, text_to_video, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_method_create_overload_5(self, async_client: AsyncRunwayML) -> None: text_to_video = await async_client.text_to_video.create( duration=8, model="veo3", @@ -370,7 +462,7 @@ async def test_method_create_overload_4(self, async_client: AsyncRunwayML) -> No assert_matches_type(TextToVideoCreateResponse, text_to_video, path=["response"]) @parametrize - async def test_raw_response_create_overload_4(self, async_client: AsyncRunwayML) -> None: + async def test_raw_response_create_overload_5(self, async_client: AsyncRunwayML) -> None: response = await async_client.text_to_video.with_raw_response.create( duration=8, model="veo3", @@ -384,7 +476,7 @@ async def test_raw_response_create_overload_4(self, async_client: AsyncRunwayML) assert_matches_type(TextToVideoCreateResponse, text_to_video, path=["response"]) @parametrize - async def test_streaming_response_create_overload_4(self, async_client: AsyncRunwayML) -> None: + async def test_streaming_response_create_overload_5(self, async_client: AsyncRunwayML) -> None: async with async_client.text_to_video.with_streaming_response.create( duration=8, model="veo3", diff --git a/tests/api_resources/test_video_to_video.py b/tests/api_resources/test_video_to_video.py index d66d911..79f183d 100644 --- a/tests/api_resources/test_video_to_video.py +++ b/tests/api_resources/test_video_to_video.py @@ -18,7 +18,7 @@ class TestVideoToVideo: 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: video_to_video = client.video_to_video.create( model="gen4_aleph", prompt_text="x", @@ -27,7 +27,7 @@ def test_method_create(self, client: RunwayML) -> None: assert_matches_type(VideoToVideoCreateResponse, video_to_video, path=["response"]) @parametrize - def test_method_create_with_all_params(self, client: RunwayML) -> None: + def test_method_create_with_all_params_overload_1(self, client: RunwayML) -> None: video_to_video = client.video_to_video.create( model="gen4_aleph", prompt_text="x", @@ -45,7 +45,7 @@ def test_method_create_with_all_params(self, client: RunwayML) -> None: assert_matches_type(VideoToVideoCreateResponse, video_to_video, path=["response"]) @parametrize - def test_raw_response_create(self, client: RunwayML) -> None: + def test_raw_response_create_overload_1(self, client: RunwayML) -> None: response = client.video_to_video.with_raw_response.create( model="gen4_aleph", prompt_text="x", @@ -58,7 +58,7 @@ def test_raw_response_create(self, client: RunwayML) -> None: assert_matches_type(VideoToVideoCreateResponse, video_to_video, path=["response"]) @parametrize - def test_streaming_response_create(self, client: RunwayML) -> None: + def test_streaming_response_create_overload_1(self, client: RunwayML) -> None: with client.video_to_video.with_streaming_response.create( model="gen4_aleph", prompt_text="x", @@ -72,6 +72,60 @@ def test_streaming_response_create(self, client: RunwayML) -> None: assert cast(Any, response.is_closed) is True + @parametrize + def test_method_create_overload_2(self, client: RunwayML) -> None: + video_to_video = client.video_to_video.create( + model="seedance2", + prompt_video="https://example.com/video.mp4", + ) + assert_matches_type(VideoToVideoCreateResponse, video_to_video, path=["response"]) + + @parametrize + def test_method_create_with_all_params_overload_2(self, client: RunwayML) -> None: + video_to_video = client.video_to_video.create( + model="seedance2", + prompt_video="https://example.com/video.mp4", + audio=True, + duration=4, + output_count=1, + prompt_text="x", + ratio="992:432", + references="https://example.com/file", + reference_videos=[ + { + "type": "video", + "uri": "https://example.com/file", + } + ], + ) + assert_matches_type(VideoToVideoCreateResponse, video_to_video, path=["response"]) + + @parametrize + def test_raw_response_create_overload_2(self, client: RunwayML) -> None: + response = client.video_to_video.with_raw_response.create( + model="seedance2", + prompt_video="https://example.com/video.mp4", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + video_to_video = response.parse() + assert_matches_type(VideoToVideoCreateResponse, video_to_video, path=["response"]) + + @parametrize + def test_streaming_response_create_overload_2(self, client: RunwayML) -> None: + with client.video_to_video.with_streaming_response.create( + model="seedance2", + prompt_video="https://example.com/video.mp4", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + video_to_video = response.parse() + assert_matches_type(VideoToVideoCreateResponse, video_to_video, path=["response"]) + + assert cast(Any, response.is_closed) is True + class TestAsyncVideoToVideo: parametrize = pytest.mark.parametrize( @@ -79,7 +133,7 @@ class TestAsyncVideoToVideo: ) @parametrize - async def test_method_create(self, async_client: AsyncRunwayML) -> None: + async def test_method_create_overload_1(self, async_client: AsyncRunwayML) -> None: video_to_video = await async_client.video_to_video.create( model="gen4_aleph", prompt_text="x", @@ -88,7 +142,7 @@ async def test_method_create(self, async_client: AsyncRunwayML) -> None: assert_matches_type(VideoToVideoCreateResponse, video_to_video, 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_1(self, async_client: AsyncRunwayML) -> None: video_to_video = await async_client.video_to_video.create( model="gen4_aleph", prompt_text="x", @@ -106,7 +160,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncRunwayML) assert_matches_type(VideoToVideoCreateResponse, video_to_video, path=["response"]) @parametrize - async def test_raw_response_create(self, async_client: AsyncRunwayML) -> None: + async def test_raw_response_create_overload_1(self, async_client: AsyncRunwayML) -> None: response = await async_client.video_to_video.with_raw_response.create( model="gen4_aleph", prompt_text="x", @@ -119,7 +173,7 @@ async def test_raw_response_create(self, async_client: AsyncRunwayML) -> None: assert_matches_type(VideoToVideoCreateResponse, video_to_video, path=["response"]) @parametrize - async def test_streaming_response_create(self, async_client: AsyncRunwayML) -> None: + async def test_streaming_response_create_overload_1(self, async_client: AsyncRunwayML) -> None: async with async_client.video_to_video.with_streaming_response.create( model="gen4_aleph", prompt_text="x", @@ -132,3 +186,57 @@ async def test_streaming_response_create(self, async_client: AsyncRunwayML) -> N assert_matches_type(VideoToVideoCreateResponse, video_to_video, path=["response"]) assert cast(Any, response.is_closed) is True + + @parametrize + async def test_method_create_overload_2(self, async_client: AsyncRunwayML) -> None: + video_to_video = await async_client.video_to_video.create( + model="seedance2", + prompt_video="https://example.com/video.mp4", + ) + assert_matches_type(VideoToVideoCreateResponse, video_to_video, path=["response"]) + + @parametrize + async def test_method_create_with_all_params_overload_2(self, async_client: AsyncRunwayML) -> None: + video_to_video = await async_client.video_to_video.create( + model="seedance2", + prompt_video="https://example.com/video.mp4", + audio=True, + duration=4, + output_count=1, + prompt_text="x", + ratio="992:432", + references="https://example.com/file", + reference_videos=[ + { + "type": "video", + "uri": "https://example.com/file", + } + ], + ) + assert_matches_type(VideoToVideoCreateResponse, video_to_video, path=["response"]) + + @parametrize + async def test_raw_response_create_overload_2(self, async_client: AsyncRunwayML) -> None: + response = await async_client.video_to_video.with_raw_response.create( + model="seedance2", + prompt_video="https://example.com/video.mp4", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + video_to_video = await response.parse() + assert_matches_type(VideoToVideoCreateResponse, video_to_video, path=["response"]) + + @parametrize + async def test_streaming_response_create_overload_2(self, async_client: AsyncRunwayML) -> None: + async with async_client.video_to_video.with_streaming_response.create( + model="seedance2", + prompt_video="https://example.com/video.mp4", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + video_to_video = await response.parse() + assert_matches_type(VideoToVideoCreateResponse, video_to_video, path=["response"]) + + assert cast(Any, response.is_closed) is True diff --git a/tests/api_resources/test_voices.py b/tests/api_resources/test_voices.py index 9076209..3ac744b 100644 --- a/tests/api_resources/test_voices.py +++ b/tests/api_resources/test_voices.py @@ -27,9 +27,8 @@ class TestVoices: def test_method_create(self, client: RunwayML) -> None: voice = client.voices.create( from_={ - "model": "eleven_ttv_v3", - "prompt": "xxxxxxxxxxxxxxxxxxxx", - "type": "text", + "audio": "https://example.com/file", + "type": "audio", }, name="x", ) @@ -39,9 +38,8 @@ def test_method_create(self, client: RunwayML) -> None: def test_method_create_with_all_params(self, client: RunwayML) -> None: voice = client.voices.create( from_={ - "model": "eleven_ttv_v3", - "prompt": "xxxxxxxxxxxxxxxxxxxx", - "type": "text", + "audio": "https://example.com/file", + "type": "audio", }, name="x", description="x", @@ -52,9 +50,8 @@ def test_method_create_with_all_params(self, client: RunwayML) -> None: def test_raw_response_create(self, client: RunwayML) -> None: response = client.voices.with_raw_response.create( from_={ - "model": "eleven_ttv_v3", - "prompt": "xxxxxxxxxxxxxxxxxxxx", - "type": "text", + "audio": "https://example.com/file", + "type": "audio", }, name="x", ) @@ -68,9 +65,8 @@ def test_raw_response_create(self, client: RunwayML) -> None: def test_streaming_response_create(self, client: RunwayML) -> None: with client.voices.with_streaming_response.create( from_={ - "model": "eleven_ttv_v3", - "prompt": "xxxxxxxxxxxxxxxxxxxx", - "type": "text", + "audio": "https://example.com/file", + "type": "audio", }, name="x", ) as response: @@ -241,9 +237,8 @@ class TestAsyncVoices: async def test_method_create(self, async_client: AsyncRunwayML) -> None: voice = await async_client.voices.create( from_={ - "model": "eleven_ttv_v3", - "prompt": "xxxxxxxxxxxxxxxxxxxx", - "type": "text", + "audio": "https://example.com/file", + "type": "audio", }, name="x", ) @@ -253,9 +248,8 @@ async def test_method_create(self, async_client: AsyncRunwayML) -> None: async def test_method_create_with_all_params(self, async_client: AsyncRunwayML) -> None: voice = await async_client.voices.create( from_={ - "model": "eleven_ttv_v3", - "prompt": "xxxxxxxxxxxxxxxxxxxx", - "type": "text", + "audio": "https://example.com/file", + "type": "audio", }, name="x", description="x", @@ -266,9 +260,8 @@ async def test_method_create_with_all_params(self, async_client: AsyncRunwayML) async def test_raw_response_create(self, async_client: AsyncRunwayML) -> None: response = await async_client.voices.with_raw_response.create( from_={ - "model": "eleven_ttv_v3", - "prompt": "xxxxxxxxxxxxxxxxxxxx", - "type": "text", + "audio": "https://example.com/file", + "type": "audio", }, name="x", ) @@ -282,9 +275,8 @@ async def test_raw_response_create(self, async_client: AsyncRunwayML) -> None: async def test_streaming_response_create(self, async_client: AsyncRunwayML) -> None: async with async_client.voices.with_streaming_response.create( from_={ - "model": "eleven_ttv_v3", - "prompt": "xxxxxxxxxxxxxxxxxxxx", - "type": "text", + "audio": "https://example.com/file", + "type": "audio", }, name="x", ) as response: diff --git a/tests/test_extract_files.py b/tests/test_extract_files.py index e29e11b..0c5eade 100644 --- a/tests/test_extract_files.py +++ b/tests/test_extract_files.py @@ -35,6 +35,15 @@ def test_multiple_files() -> None: assert query == {"documents": [{}, {}]} +def test_top_level_file_array() -> None: + query = {"files": [b"file one", b"file two"], "title": "hello"} + assert extract_files(query, paths=[["files", ""]]) == [ + ("files[]", b"file one"), + ("files[]", b"file two"), + ] + assert query == {"title": "hello"} + + @pytest.mark.parametrize( "query,paths,expected", [