From 719958796a3c89ff20b2e4e2b0db1e375f836125 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 3 Dec 2025 03:28:58 +0000 Subject: [PATCH 01/11] chore: update lockfile --- pyproject.toml | 14 +++--- requirements-dev.lock | 108 +++++++++++++++++++++++------------------- requirements.lock | 31 ++++++------ 3 files changed, 83 insertions(+), 70 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index c18acaa..a7dd1ce 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,14 +7,16 @@ license = "Apache-2.0" authors = [ { name = "RunwayML", email = "dev-feedback@runwayml.com" }, ] + dependencies = [ - "httpx>=0.23.0, <1", - "pydantic>=1.9.0, <3", - "typing-extensions>=4.10, <5", - "anyio>=3.5.0, <5", - "distro>=1.7.0, <2", - "sniffio", + "httpx>=0.23.0, <1", + "pydantic>=1.9.0, <3", + "typing-extensions>=4.10, <5", + "anyio>=3.5.0, <5", + "distro>=1.7.0, <2", + "sniffio", ] + requires-python = ">= 3.9" classifiers = [ "Typing :: Typed", diff --git a/requirements-dev.lock b/requirements-dev.lock index c8a60e4..cd73af7 100644 --- a/requirements-dev.lock +++ b/requirements-dev.lock @@ -12,40 +12,45 @@ -e file:. aiohappyeyeballs==2.6.1 # via aiohttp -aiohttp==3.12.8 +aiohttp==3.13.2 # via httpx-aiohttp # via runwayml -aiosignal==1.3.2 +aiosignal==1.4.0 # via aiohttp -annotated-types==0.6.0 +annotated-types==0.7.0 # via pydantic -anyio==4.4.0 +anyio==4.12.0 # via httpx # via runwayml -argcomplete==3.1.2 +argcomplete==3.6.3 # via nox async-timeout==5.0.1 # via aiohttp -attrs==25.3.0 +attrs==25.4.0 # via aiohttp -certifi==2023.7.22 + # via nox +backports-asyncio-runner==1.2.0 + # via pytest-asyncio +certifi==2025.11.12 # via httpcore # via httpx -colorlog==6.7.0 +colorlog==6.10.1 + # via nox +dependency-groups==1.3.1 # via nox -dirty-equals==0.6.0 -distlib==0.3.7 +dirty-equals==0.11 +distlib==0.4.0 # via virtualenv -distro==1.8.0 +distro==1.9.0 # via runwayml -exceptiongroup==1.2.2 +exceptiongroup==1.3.1 # via anyio # via pytest -execnet==2.1.1 +execnet==2.1.2 # via pytest-xdist -filelock==3.12.4 +filelock==3.19.1 # via virtualenv -frozenlist==1.6.2 +frozenlist==1.8.0 # via aiohttp # via aiosignal h11==0.16.0 @@ -58,82 +63,87 @@ httpx==0.28.1 # via runwayml httpx-aiohttp==0.1.9 # via runwayml -idna==3.4 +humanize==4.13.0 + # via nox +idna==3.11 # via anyio # via httpx # via yarl -importlib-metadata==7.0.0 -iniconfig==2.0.0 +importlib-metadata==8.7.0 +iniconfig==2.1.0 # via pytest markdown-it-py==3.0.0 # via rich mdurl==0.1.2 # via markdown-it-py -multidict==6.4.4 +multidict==6.7.0 # via aiohttp # via yarl mypy==1.17.0 -mypy-extensions==1.0.0 +mypy-extensions==1.1.0 # via mypy -nodeenv==1.8.0 +nodeenv==1.9.1 # via pyright -nox==2023.4.22 -packaging==23.2 +nox==2025.11.12 +packaging==25.0 + # via dependency-groups # via nox # via pytest pathspec==0.12.1 # via mypy -platformdirs==3.11.0 +platformdirs==4.4.0 # via virtualenv -pluggy==1.5.0 +pluggy==1.6.0 # via pytest -propcache==0.3.1 +propcache==0.4.1 # via aiohttp # via yarl -pydantic==2.11.9 +pydantic==2.12.5 # via runwayml -pydantic-core==2.33.2 +pydantic-core==2.41.5 # via pydantic -pygments==2.18.0 +pygments==2.19.2 + # via pytest # via rich pyright==1.1.399 -pytest==8.3.3 +pytest==8.4.2 # via pytest-asyncio # via pytest-xdist -pytest-asyncio==0.24.0 -pytest-xdist==3.7.0 -python-dateutil==2.8.2 +pytest-asyncio==1.2.0 +pytest-xdist==3.8.0 +python-dateutil==2.9.0.post0 # via time-machine -pytz==2023.3.post1 - # via dirty-equals respx==0.22.0 -rich==13.7.1 -ruff==0.9.4 -setuptools==68.2.2 - # via nodeenv -six==1.16.0 +rich==14.2.0 +ruff==0.14.7 +six==1.17.0 # via python-dateutil -sniffio==1.3.0 - # via anyio +sniffio==1.3.1 # via runwayml -time-machine==2.9.0 -tomli==2.0.2 +time-machine==2.19.0 +tomli==2.3.0 + # via dependency-groups # via mypy + # via nox # via pytest -typing-extensions==4.12.2 +typing-extensions==4.15.0 + # via aiosignal # via anyio + # via exceptiongroup # via multidict # via mypy # via pydantic # via pydantic-core # via pyright + # via pytest-asyncio # via runwayml # via typing-inspection -typing-inspection==0.4.1 + # via virtualenv +typing-inspection==0.4.2 # via pydantic -virtualenv==20.24.5 +virtualenv==20.35.4 # via nox -yarl==1.20.0 +yarl==1.22.0 # via aiohttp -zipp==3.17.0 +zipp==3.23.0 # via importlib-metadata diff --git a/requirements.lock b/requirements.lock index a6ec1c3..3fd0b43 100644 --- a/requirements.lock +++ b/requirements.lock @@ -12,28 +12,28 @@ -e file:. aiohappyeyeballs==2.6.1 # via aiohttp -aiohttp==3.12.8 +aiohttp==3.13.2 # via httpx-aiohttp # via runwayml -aiosignal==1.3.2 +aiosignal==1.4.0 # via aiohttp -annotated-types==0.6.0 +annotated-types==0.7.0 # via pydantic -anyio==4.4.0 +anyio==4.12.0 # via httpx # via runwayml async-timeout==5.0.1 # via aiohttp -attrs==25.3.0 +attrs==25.4.0 # via aiohttp -certifi==2023.7.22 +certifi==2025.11.12 # via httpcore # via httpx -distro==1.8.0 +distro==1.9.0 # via runwayml -exceptiongroup==1.2.2 +exceptiongroup==1.3.1 # via anyio -frozenlist==1.6.2 +frozenlist==1.8.0 # via aiohttp # via aiosignal h11==0.16.0 @@ -45,25 +45,26 @@ httpx==0.28.1 # via runwayml httpx-aiohttp==0.1.9 # via runwayml -idna==3.4 +idna==3.11 # via anyio # via httpx # via yarl -multidict==6.4.4 +multidict==6.7.0 # via aiohttp # via yarl -propcache==0.3.1 +propcache==0.4.1 # via aiohttp # via yarl pydantic==2.12.5 # via runwayml pydantic-core==2.41.5 # via pydantic -sniffio==1.3.0 - # via anyio +sniffio==1.3.1 # via runwayml typing-extensions==4.15.0 + # via aiosignal # via anyio + # via exceptiongroup # via multidict # via pydantic # via pydantic-core @@ -71,5 +72,5 @@ typing-extensions==4.15.0 # via typing-inspection typing-inspection==0.4.2 # via pydantic -yarl==1.20.0 +yarl==1.22.0 # via aiohttp From cd6776ecdccbb9bebb88db16a4b3ef46b246d23d Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 3 Dec 2025 03:37:19 +0000 Subject: [PATCH 02/11] chore(docs): use environment variables for authentication in code snippets --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index b4dda86..50dfb5d 100644 --- a/README.md +++ b/README.md @@ -89,6 +89,7 @@ pip install runwayml[aiohttp] Then you can enable it by instantiating the client with `http_client=DefaultAioHttpClient()`: ```python +import os import asyncio from runwayml import DefaultAioHttpClient from runwayml import AsyncRunwayML @@ -96,7 +97,7 @@ from runwayml import AsyncRunwayML async def main() -> None: async with AsyncRunwayML( - api_key="My API Key", + api_key=os.environ.get("RUNWAYML_API_SECRET"), # This is the default and can be omitted http_client=DefaultAioHttpClient(), ) as client: image_to_video = await client.image_to_video.create( From ea8a4ec3e05e27e5b4db85481846678c0fc0c009 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 3 Dec 2025 21:15:29 +0000 Subject: [PATCH 03/11] feat(api): gemini_3_pro t2i --- .stats.yml | 4 +- src/runwayml/resources/tasks.py | 29 +- src/runwayml/resources/text_to_image.py | 218 ++++++++++- .../character_performance_create_response.py | 1 + .../types/image_to_video_create_response.py | 1 + .../types/organization_retrieve_response.py | 346 +----------------- .../organization_retrieve_usage_response.py | 42 ++- .../types/sound_effect_create_response.py | 1 + .../types/speech_to_speech_create_response.py | 1 + src/runwayml/types/task_retrieve_response.py | 108 ++++-- .../types/text_to_image_create_params.py | 88 ++++- .../types/text_to_image_create_response.py | 1 + .../types/text_to_speech_create_response.py | 1 + .../types/text_to_video_create_response.py | 1 + .../types/video_to_video_create_response.py | 1 + .../types/video_upscale_create_response.py | 1 + .../types/voice_dubbing_create_response.py | 1 + .../types/voice_isolation_create_response.py | 1 + tests/api_resources/test_text_to_image.py | 118 +++++- tests/api_resources/test_voice_dubbing.py | 4 +- 20 files changed, 553 insertions(+), 415 deletions(-) diff --git a/.stats.yml b/.stats.yml index f7f71cf..5e984fc 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 15 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/runwayml%2Frunwayml-c2a88516fa0c20ca73f742f8d876f5e773747b4f6903508b1824c0939b313b82.yml -openapi_spec_hash: 660d0eec8f3940727f541dd05121627b +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/runwayml%2Frunwayml-76b3962cf49e001b04b50d184ae502a1b58ddaa525f34a142fd3b0878262f934.yml +openapi_spec_hash: 148cd90ea90d29a01020741f4ae0fd5b config_hash: b98eed33f1bba05e3c2a3e20d85d582a diff --git a/src/runwayml/resources/tasks.py b/src/runwayml/resources/tasks.py index 496d1c4..24a7bc9 100644 --- a/src/runwayml/resources/tasks.py +++ b/src/runwayml/resources/tasks.py @@ -3,6 +3,7 @@ from __future__ import annotations from typing import cast +from typing import Any, cast import httpx @@ -74,10 +75,16 @@ def retrieve( """ if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") - return self._get( - f"/v1/tasks/{id}", - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + return cast( + TaskRetrieveResponse, + self._get( + f"/v1/tasks/{id}", + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=cast( + Any, TaskRetrieveResponse + ), # Union types cannot be passed in as arguments in the type system ), cast_to=cast( type[AwaitableTaskRetrieveResponse], create_waitable_resource(TaskRetrieveResponse, self._client) @@ -171,10 +178,16 @@ async def retrieve( """ if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") - return await self._get( - f"/v1/tasks/{id}", - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + return cast( + TaskRetrieveResponse, + await self._get( + f"/v1/tasks/{id}", + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=cast( + Any, TaskRetrieveResponse + ), # Union types cannot be passed in as arguments in the type system ), cast_to=cast( type[AsyncAwaitableTaskRetrieveResponse], diff --git a/src/runwayml/resources/text_to_image.py b/src/runwayml/resources/text_to_image.py index 9206ae8..064406a 100644 --- a/src/runwayml/resources/text_to_image.py +++ b/src/runwayml/resources/text_to_image.py @@ -174,6 +174,77 @@ def create( """ ... + @overload + def create( + self, + *, + model: Literal["gemini_3_pro"], + prompt_text: str, + ratio: Literal[ + "1344:768", + "768:1344", + "1024:1024", + "1184:864", + "864:1184", + "1536:672", + "832:1248", + "1248:832", + "896:1152", + "1152:896", + "2048:2048", + "1696:2528", + "2528:1696", + "1792:2400", + "2400:1792", + "1856:2304", + "2304:1856", + "1536:2752", + "2752:1536", + "3168:1344", + "4096:4096", + "3392:5056", + "5056:3392", + "3584:4800", + "4800:3584", + "3712:4608", + "4608:3712", + "3072:5504", + "5504:3072", + "6336:2688", + ], + reference_images: Iterable[text_to_image_create_params.Gemini3ProReferenceImage] | 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, + ) -> TextToImageCreateResponse: + """ + This endpoint will start a new task to generate images from text and/or image(s) + + Args: + prompt_text: A non-empty string up to 1000 characters (measured in UTF-16 code units). This + should describe in detail what should appear in the output. + + ratio: The resolution of the output image. + + reference_images: An array of up to 14 images to be used as references for the generated image + output. Up to five of those images can pass `subject: "human"` to maintain + character consistency, and up to nine of those images can pass + `subject: "object"` with high-fidelity images of objects to include in the + output. + + 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, @@ -226,7 +297,10 @@ def create( def create( self, *, - model: Literal["gen4_image_turbo"] | Literal["gen4_image"] | Literal["gemini_2.5_flash"], + model: Literal["gen4_image_turbo"] + | Literal["gen4_image"] + | Literal["gemini_3_pro"] + | Literal["gemini_2.5_flash"], prompt_text: str, ratio: Literal[ "1024:1024", @@ -246,6 +320,38 @@ def create( "720:960", "1680:720", ] + | Literal[ + "1344:768", + "768:1344", + "1024:1024", + "1184:864", + "864:1184", + "1536:672", + "832:1248", + "1248:832", + "896:1152", + "1152:896", + "2048:2048", + "1696:2528", + "2528:1696", + "1792:2400", + "2400:1792", + "1856:2304", + "2304:1856", + "1536:2752", + "2752:1536", + "3168:1344", + "4096:4096", + "3392:5056", + "5056:3392", + "3584:4800", + "4800:3584", + "3712:4608", + "4608:3712", + "3072:5504", + "5504:3072", + "6336:2688", + ] | Literal[ "1344:768", "768:1344", @@ -260,6 +366,7 @@ def create( ], reference_images: Iterable[text_to_image_create_params.Gen4ImageTurboReferenceImage] | Iterable[text_to_image_create_params.Gen4ImageReferenceImage] + | Iterable[text_to_image_create_params.Gemini3ProReferenceImage] | Iterable[text_to_image_create_params.Gemini2_5FlashReferenceImage] | Omit = omit, content_moderation: text_to_image_create_params.Gen4ImageTurboContentModeration @@ -437,6 +544,77 @@ async def create( """ ... + @overload + async def create( + self, + *, + model: Literal["gemini_3_pro"], + prompt_text: str, + ratio: Literal[ + "1344:768", + "768:1344", + "1024:1024", + "1184:864", + "864:1184", + "1536:672", + "832:1248", + "1248:832", + "896:1152", + "1152:896", + "2048:2048", + "1696:2528", + "2528:1696", + "1792:2400", + "2400:1792", + "1856:2304", + "2304:1856", + "1536:2752", + "2752:1536", + "3168:1344", + "4096:4096", + "3392:5056", + "5056:3392", + "3584:4800", + "4800:3584", + "3712:4608", + "4608:3712", + "3072:5504", + "5504:3072", + "6336:2688", + ], + reference_images: Iterable[text_to_image_create_params.Gemini3ProReferenceImage] | 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, + ) -> TextToImageCreateResponse: + """ + This endpoint will start a new task to generate images from text and/or image(s) + + Args: + prompt_text: A non-empty string up to 1000 characters (measured in UTF-16 code units). This + should describe in detail what should appear in the output. + + ratio: The resolution of the output image. + + reference_images: An array of up to 14 images to be used as references for the generated image + output. Up to five of those images can pass `subject: "human"` to maintain + character consistency, and up to nine of those images can pass + `subject: "object"` with high-fidelity images of objects to include in the + output. + + 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, @@ -489,7 +667,10 @@ async def create( async def create( self, *, - model: Literal["gen4_image_turbo"] | Literal["gen4_image"] | Literal["gemini_2.5_flash"], + model: Literal["gen4_image_turbo"] + | Literal["gen4_image"] + | Literal["gemini_3_pro"] + | Literal["gemini_2.5_flash"], prompt_text: str, ratio: Literal[ "1024:1024", @@ -509,6 +690,38 @@ async def create( "720:960", "1680:720", ] + | Literal[ + "1344:768", + "768:1344", + "1024:1024", + "1184:864", + "864:1184", + "1536:672", + "832:1248", + "1248:832", + "896:1152", + "1152:896", + "2048:2048", + "1696:2528", + "2528:1696", + "1792:2400", + "2400:1792", + "1856:2304", + "2304:1856", + "1536:2752", + "2752:1536", + "3168:1344", + "4096:4096", + "3392:5056", + "5056:3392", + "3584:4800", + "4800:3584", + "3712:4608", + "4608:3712", + "3072:5504", + "5504:3072", + "6336:2688", + ] | Literal[ "1344:768", "768:1344", @@ -523,6 +736,7 @@ async def create( ], reference_images: Iterable[text_to_image_create_params.Gen4ImageTurboReferenceImage] | Iterable[text_to_image_create_params.Gen4ImageReferenceImage] + | Iterable[text_to_image_create_params.Gemini3ProReferenceImage] | Iterable[text_to_image_create_params.Gemini2_5FlashReferenceImage] | Omit = omit, content_moderation: text_to_image_create_params.Gen4ImageTurboContentModeration diff --git a/src/runwayml/types/character_performance_create_response.py b/src/runwayml/types/character_performance_create_response.py index 61b4fff..48ab1c5 100644 --- a/src/runwayml/types/character_performance_create_response.py +++ b/src/runwayml/types/character_performance_create_response.py @@ -7,3 +7,4 @@ class CharacterPerformanceCreateResponse(BaseModel): id: str + """The ID of the task that was created. Use this to retrieve the task later.""" diff --git a/src/runwayml/types/image_to_video_create_response.py b/src/runwayml/types/image_to_video_create_response.py index 5c381da..8b03891 100644 --- a/src/runwayml/types/image_to_video_create_response.py +++ b/src/runwayml/types/image_to_video_create_response.py @@ -7,3 +7,4 @@ class ImageToVideoCreateResponse(BaseModel): id: str + """The ID of the task that was created. Use this to retrieve the task later.""" diff --git a/src/runwayml/types/organization_retrieve_response.py b/src/runwayml/types/organization_retrieve_response.py index 3621c54..f3a56ca 100644 --- a/src/runwayml/types/organization_retrieve_response.py +++ b/src/runwayml/types/organization_retrieve_response.py @@ -1,173 +1,15 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import Optional +from typing import Dict from pydantic import Field as FieldInfo from .._models import BaseModel -__all__ = [ - "OrganizationRetrieveResponse", - "Tier", - "TierModels", - "TierModelsActTwo", - "TierModelsElevenMultilingualStsV2", - "TierModelsElevenMultilingualV2", - "TierModelsElevenTextToSoundV2", - "TierModelsElevenVoiceDubbing", - "TierModelsElevenVoiceIsolation", - "TierModelsGemini2_5Flash", - "TierModelsGen3aTurbo", - "TierModelsGen4Aleph", - "TierModelsGen4Image", - "TierModelsGen4ImageTurbo", - "TierModelsGen4Turbo", - "TierModelsUpscaleV1", - "TierModelsVeo3", - "TierModelsVeo3_1", - "TierModelsVeo3_1Fast", - "Usage", - "UsageModels", - "UsageModelsActTwo", - "UsageModelsElevenMultilingualStsV2", - "UsageModelsElevenMultilingualV2", - "UsageModelsElevenTextToSoundV2", - "UsageModelsElevenVoiceDubbing", - "UsageModelsElevenVoiceIsolation", - "UsageModelsGemini2_5Flash", - "UsageModelsGen3aTurbo", - "UsageModelsGen4Aleph", - "UsageModelsGen4Image", - "UsageModelsGen4ImageTurbo", - "UsageModelsGen4Turbo", - "UsageModelsUpscaleV1", - "UsageModelsVeo3", - "UsageModelsVeo3_1", - "UsageModelsVeo3_1Fast", -] +__all__ = ["OrganizationRetrieveResponse", "Tier", "TierModels", "Usage", "UsageModels"] -class TierModelsActTwo(BaseModel): - max_concurrent_generations: int = FieldInfo(alias="maxConcurrentGenerations") - """The maximum number of generations that can be run concurrently for this model.""" - - max_daily_generations: int = FieldInfo(alias="maxDailyGenerations") - """The maximum number of generations that can be created each day for this model.""" - - -class TierModelsElevenMultilingualStsV2(BaseModel): - max_concurrent_generations: int = FieldInfo(alias="maxConcurrentGenerations") - """The maximum number of generations that can be run concurrently for this model.""" - - max_daily_generations: int = FieldInfo(alias="maxDailyGenerations") - """The maximum number of generations that can be created each day for this model.""" - - -class TierModelsElevenMultilingualV2(BaseModel): - max_concurrent_generations: int = FieldInfo(alias="maxConcurrentGenerations") - """The maximum number of generations that can be run concurrently for this model.""" - - max_daily_generations: int = FieldInfo(alias="maxDailyGenerations") - """The maximum number of generations that can be created each day for this model.""" - - -class TierModelsElevenTextToSoundV2(BaseModel): - max_concurrent_generations: int = FieldInfo(alias="maxConcurrentGenerations") - """The maximum number of generations that can be run concurrently for this model.""" - - max_daily_generations: int = FieldInfo(alias="maxDailyGenerations") - """The maximum number of generations that can be created each day for this model.""" - - -class TierModelsElevenVoiceDubbing(BaseModel): - max_concurrent_generations: int = FieldInfo(alias="maxConcurrentGenerations") - """The maximum number of generations that can be run concurrently for this model.""" - - max_daily_generations: int = FieldInfo(alias="maxDailyGenerations") - """The maximum number of generations that can be created each day for this model.""" - - -class TierModelsElevenVoiceIsolation(BaseModel): - max_concurrent_generations: int = FieldInfo(alias="maxConcurrentGenerations") - """The maximum number of generations that can be run concurrently for this model.""" - - max_daily_generations: int = FieldInfo(alias="maxDailyGenerations") - """The maximum number of generations that can be created each day for this model.""" - - -class TierModelsGemini2_5Flash(BaseModel): - max_concurrent_generations: int = FieldInfo(alias="maxConcurrentGenerations") - """The maximum number of generations that can be run concurrently for this model.""" - - max_daily_generations: int = FieldInfo(alias="maxDailyGenerations") - """The maximum number of generations that can be created each day for this model.""" - - -class TierModelsGen3aTurbo(BaseModel): - max_concurrent_generations: int = FieldInfo(alias="maxConcurrentGenerations") - """The maximum number of generations that can be run concurrently for this model.""" - - max_daily_generations: int = FieldInfo(alias="maxDailyGenerations") - """The maximum number of generations that can be created each day for this model.""" - - -class TierModelsGen4Aleph(BaseModel): - max_concurrent_generations: int = FieldInfo(alias="maxConcurrentGenerations") - """The maximum number of generations that can be run concurrently for this model.""" - - max_daily_generations: int = FieldInfo(alias="maxDailyGenerations") - """The maximum number of generations that can be created each day for this model.""" - - -class TierModelsGen4Image(BaseModel): - max_concurrent_generations: int = FieldInfo(alias="maxConcurrentGenerations") - """The maximum number of generations that can be run concurrently for this model.""" - - max_daily_generations: int = FieldInfo(alias="maxDailyGenerations") - """The maximum number of generations that can be created each day for this model.""" - - -class TierModelsGen4ImageTurbo(BaseModel): - max_concurrent_generations: int = FieldInfo(alias="maxConcurrentGenerations") - """The maximum number of generations that can be run concurrently for this model.""" - - max_daily_generations: int = FieldInfo(alias="maxDailyGenerations") - """The maximum number of generations that can be created each day for this model.""" - - -class TierModelsGen4Turbo(BaseModel): - max_concurrent_generations: int = FieldInfo(alias="maxConcurrentGenerations") - """The maximum number of generations that can be run concurrently for this model.""" - - max_daily_generations: int = FieldInfo(alias="maxDailyGenerations") - """The maximum number of generations that can be created each day for this model.""" - - -class TierModelsUpscaleV1(BaseModel): - max_concurrent_generations: int = FieldInfo(alias="maxConcurrentGenerations") - """The maximum number of generations that can be run concurrently for this model.""" - - max_daily_generations: int = FieldInfo(alias="maxDailyGenerations") - """The maximum number of generations that can be created each day for this model.""" - - -class TierModelsVeo3(BaseModel): - max_concurrent_generations: int = FieldInfo(alias="maxConcurrentGenerations") - """The maximum number of generations that can be run concurrently for this model.""" - - max_daily_generations: int = FieldInfo(alias="maxDailyGenerations") - """The maximum number of generations that can be created each day for this model.""" - - -class TierModelsVeo3_1(BaseModel): - max_concurrent_generations: int = FieldInfo(alias="maxConcurrentGenerations") - """The maximum number of generations that can be run concurrently for this model.""" - - max_daily_generations: int = FieldInfo(alias="maxDailyGenerations") - """The maximum number of generations that can be created each day for this model.""" - - -class TierModelsVeo3_1Fast(BaseModel): +class TierModels(BaseModel): max_concurrent_generations: int = FieldInfo(alias="maxConcurrentGenerations") """The maximum number of generations that can be run concurrently for this model.""" @@ -175,197 +17,21 @@ class TierModelsVeo3_1Fast(BaseModel): """The maximum number of generations that can be created each day for this model.""" -class TierModels(BaseModel): - act_two: Optional[TierModelsActTwo] = None - """Limits associated with the act_two model.""" - - eleven_multilingual_sts_v2: Optional[TierModelsElevenMultilingualStsV2] = None - """Limits associated with the eleven_multilingual_sts_v2 model.""" - - eleven_multilingual_v2: Optional[TierModelsElevenMultilingualV2] = None - """Limits associated with the eleven_multilingual_v2 model.""" - - eleven_text_to_sound_v2: Optional[TierModelsElevenTextToSoundV2] = None - """Limits associated with the eleven_text_to_sound_v2 model.""" - - eleven_voice_dubbing: Optional[TierModelsElevenVoiceDubbing] = None - """Limits associated with the eleven_voice_dubbing model.""" - - eleven_voice_isolation: Optional[TierModelsElevenVoiceIsolation] = None - """Limits associated with the eleven_voice_isolation model.""" - - gemini_2_5_flash: Optional[TierModelsGemini2_5Flash] = FieldInfo(alias="gemini_2.5_flash", default=None) - """Limits associated with the gemini_2.5_flash model.""" - - gen3a_turbo: Optional[TierModelsGen3aTurbo] = None - """Limits associated with the gen3a_turbo model.""" - - gen4_aleph: Optional[TierModelsGen4Aleph] = None - """Limits associated with the gen4_aleph model.""" - - gen4_image: Optional[TierModelsGen4Image] = None - """Limits associated with the gen4_image model.""" - - gen4_image_turbo: Optional[TierModelsGen4ImageTurbo] = None - """Limits associated with the gen4_image_turbo model.""" - - gen4_turbo: Optional[TierModelsGen4Turbo] = None - """Limits associated with the gen4_turbo model.""" - - upscale_v1: Optional[TierModelsUpscaleV1] = None - """Limits associated with the upscale_v1 model.""" - - veo3: Optional[TierModelsVeo3] = None - """Limits associated with the veo3 model.""" - - veo3_1: Optional[TierModelsVeo3_1] = FieldInfo(alias="veo3.1", default=None) - """Limits associated with the veo3.1 model.""" - - veo3_1_fast: Optional[TierModelsVeo3_1Fast] = FieldInfo(alias="veo3.1_fast", default=None) - """Limits associated with the veo3.1_fast model.""" - - class Tier(BaseModel): max_monthly_credit_spend: int = FieldInfo(alias="maxMonthlyCreditSpend") """The maximum number of credits that can be purchased in a month.""" - models: TierModels + models: Dict[str, TierModels] """An object containing model-specific limits. Each key represents a model.""" -class UsageModelsActTwo(BaseModel): - daily_generations: int = FieldInfo(alias="dailyGenerations") - """The number of generations that have been run for this model in the past day.""" - - -class UsageModelsElevenMultilingualStsV2(BaseModel): - daily_generations: int = FieldInfo(alias="dailyGenerations") - """The number of generations that have been run for this model in the past day.""" - - -class UsageModelsElevenMultilingualV2(BaseModel): - daily_generations: int = FieldInfo(alias="dailyGenerations") - """The number of generations that have been run for this model in the past day.""" - - -class UsageModelsElevenTextToSoundV2(BaseModel): - daily_generations: int = FieldInfo(alias="dailyGenerations") - """The number of generations that have been run for this model in the past day.""" - - -class UsageModelsElevenVoiceDubbing(BaseModel): - daily_generations: int = FieldInfo(alias="dailyGenerations") - """The number of generations that have been run for this model in the past day.""" - - -class UsageModelsElevenVoiceIsolation(BaseModel): - daily_generations: int = FieldInfo(alias="dailyGenerations") - """The number of generations that have been run for this model in the past day.""" - - -class UsageModelsGemini2_5Flash(BaseModel): - daily_generations: int = FieldInfo(alias="dailyGenerations") - """The number of generations that have been run for this model in the past day.""" - - -class UsageModelsGen3aTurbo(BaseModel): - daily_generations: int = FieldInfo(alias="dailyGenerations") - """The number of generations that have been run for this model in the past day.""" - - -class UsageModelsGen4Aleph(BaseModel): - daily_generations: int = FieldInfo(alias="dailyGenerations") - """The number of generations that have been run for this model in the past day.""" - - -class UsageModelsGen4Image(BaseModel): - daily_generations: int = FieldInfo(alias="dailyGenerations") - """The number of generations that have been run for this model in the past day.""" - - -class UsageModelsGen4ImageTurbo(BaseModel): - daily_generations: int = FieldInfo(alias="dailyGenerations") - """The number of generations that have been run for this model in the past day.""" - - -class UsageModelsGen4Turbo(BaseModel): - daily_generations: int = FieldInfo(alias="dailyGenerations") - """The number of generations that have been run for this model in the past day.""" - - -class UsageModelsUpscaleV1(BaseModel): - daily_generations: int = FieldInfo(alias="dailyGenerations") - """The number of generations that have been run for this model in the past day.""" - - -class UsageModelsVeo3(BaseModel): - daily_generations: int = FieldInfo(alias="dailyGenerations") - """The number of generations that have been run for this model in the past day.""" - - -class UsageModelsVeo3_1(BaseModel): - daily_generations: int = FieldInfo(alias="dailyGenerations") - """The number of generations that have been run for this model in the past day.""" - - -class UsageModelsVeo3_1Fast(BaseModel): +class UsageModels(BaseModel): daily_generations: int = FieldInfo(alias="dailyGenerations") """The number of generations that have been run for this model in the past day.""" -class UsageModels(BaseModel): - act_two: Optional[UsageModelsActTwo] = None - """Usage data for the act_two model.""" - - eleven_multilingual_sts_v2: Optional[UsageModelsElevenMultilingualStsV2] = None - """Usage data for the eleven_multilingual_sts_v2 model.""" - - eleven_multilingual_v2: Optional[UsageModelsElevenMultilingualV2] = None - """Usage data for the eleven_multilingual_v2 model.""" - - eleven_text_to_sound_v2: Optional[UsageModelsElevenTextToSoundV2] = None - """Usage data for the eleven_text_to_sound_v2 model.""" - - eleven_voice_dubbing: Optional[UsageModelsElevenVoiceDubbing] = None - """Usage data for the eleven_voice_dubbing model.""" - - eleven_voice_isolation: Optional[UsageModelsElevenVoiceIsolation] = None - """Usage data for the eleven_voice_isolation model.""" - - gemini_2_5_flash: Optional[UsageModelsGemini2_5Flash] = FieldInfo(alias="gemini_2.5_flash", default=None) - """Usage data for the gemini_2.5_flash model.""" - - gen3a_turbo: Optional[UsageModelsGen3aTurbo] = None - """Usage data for the gen3a_turbo model.""" - - gen4_aleph: Optional[UsageModelsGen4Aleph] = None - """Usage data for the gen4_aleph model.""" - - gen4_image: Optional[UsageModelsGen4Image] = None - """Usage data for the gen4_image model.""" - - gen4_image_turbo: Optional[UsageModelsGen4ImageTurbo] = None - """Usage data for the gen4_image_turbo model.""" - - gen4_turbo: Optional[UsageModelsGen4Turbo] = None - """Usage data for the gen4_turbo model.""" - - upscale_v1: Optional[UsageModelsUpscaleV1] = None - """Usage data for the upscale_v1 model.""" - - veo3: Optional[UsageModelsVeo3] = None - """Usage data for the veo3 model.""" - - veo3_1: Optional[UsageModelsVeo3_1] = FieldInfo(alias="veo3.1", default=None) - """Usage data for the veo3.1 model.""" - - veo3_1_fast: Optional[UsageModelsVeo3_1Fast] = FieldInfo(alias="veo3.1_fast", default=None) - """Usage data for the veo3.1_fast model.""" - - class Usage(BaseModel): - models: UsageModels - """Usage data for each model.""" + models: Dict[str, UsageModels] class OrganizationRetrieveResponse(BaseModel): diff --git a/src/runwayml/types/organization_retrieve_usage_response.py b/src/runwayml/types/organization_retrieve_usage_response.py index ad90712..fe20b8f 100644 --- a/src/runwayml/types/organization_retrieve_usage_response.py +++ b/src/runwayml/types/organization_retrieve_usage_response.py @@ -13,27 +13,28 @@ class ResultUsedCredit(BaseModel): amount: int - """The number of credits used for the model.""" + """The number of credits spent on the model.""" model: Literal[ - "act_two", - "eleven_multilingual_sts_v2", - "eleven_multilingual_v2", - "eleven_text_to_sound_v2", - "eleven_voice_dubbing", - "eleven_voice_isolation", - "gemini_2.5_flash", "gen3a_turbo", - "gen4_aleph", + "gen4_turbo", "gen4_image", "gen4_image_turbo", - "gen4_turbo", "upscale_v1", + "act_two", + "gen4_aleph", "veo3", "veo3.1", "veo3.1_fast", + "gemini_2.5_flash", + "gemini_3_pro", + "eleven_multilingual_v2", + "eleven_text_to_sound_v2", + "eleven_voice_isolation", + "eleven_voice_dubbing", + "eleven_multilingual_sts_v2", ] - """The model whose usage resulted in the credit usage.""" + """The model that credits were spent on.""" class Result(BaseModel): @@ -50,22 +51,23 @@ class Result(BaseModel): class OrganizationRetrieveUsageResponse(BaseModel): models: List[ Literal[ - "act_two", - "eleven_multilingual_sts_v2", - "eleven_multilingual_v2", - "eleven_text_to_sound_v2", - "eleven_voice_dubbing", - "eleven_voice_isolation", - "gemini_2.5_flash", "gen3a_turbo", - "gen4_aleph", + "gen4_turbo", "gen4_image", "gen4_image_turbo", - "gen4_turbo", "upscale_v1", + "act_two", + "gen4_aleph", "veo3", "veo3.1", "veo3.1_fast", + "gemini_2.5_flash", + "gemini_3_pro", + "eleven_multilingual_v2", + "eleven_text_to_sound_v2", + "eleven_voice_isolation", + "eleven_voice_dubbing", + "eleven_multilingual_sts_v2", ] ] """The list of models with usage during the queried time range.""" diff --git a/src/runwayml/types/sound_effect_create_response.py b/src/runwayml/types/sound_effect_create_response.py index 604a06d..0dc690b 100644 --- a/src/runwayml/types/sound_effect_create_response.py +++ b/src/runwayml/types/sound_effect_create_response.py @@ -7,3 +7,4 @@ class SoundEffectCreateResponse(BaseModel): id: str + """The ID of the task that was created. Use this to retrieve the task later.""" diff --git a/src/runwayml/types/speech_to_speech_create_response.py b/src/runwayml/types/speech_to_speech_create_response.py index 03a93b3..f682d47 100644 --- a/src/runwayml/types/speech_to_speech_create_response.py +++ b/src/runwayml/types/speech_to_speech_create_response.py @@ -7,3 +7,4 @@ class SpeechToSpeechCreateResponse(BaseModel): id: str + """The ID of the task that was created. Use this to retrieve the task later.""" diff --git a/src/runwayml/types/task_retrieve_response.py b/src/runwayml/types/task_retrieve_response.py index 47b9601..9284246 100644 --- a/src/runwayml/types/task_retrieve_response.py +++ b/src/runwayml/types/task_retrieve_response.py @@ -1,59 +1,99 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import List, Optional +from typing import List, Union, Optional from datetime import datetime -from typing_extensions import Literal +from typing_extensions import Literal, Annotated, TypeAlias from pydantic import Field as FieldInfo +from .._utils import PropertyInfo from .._models import BaseModel -__all__ = ["TaskRetrieveResponse"] +__all__ = ["TaskRetrieveResponse", "Pending", "Throttled", "Cancelled", "Running", "Failed", "Succeeded"] -class TaskRetrieveResponse(BaseModel): +class Pending(BaseModel): id: str """The ID of the task being returned.""" created_at: datetime = FieldInfo(alias="createdAt") """The timestamp that the task was submitted at.""" - status: Literal["RUNNING", "SUCCEEDED", "FAILED", "PENDING", "CANCELLED", "THROTTLED"] - """ - - `PENDING` tasks have been enqueued and are waiting to run. - - `THROTTLED` tasks are waiting to be enqueued until other jobs have finished - running. - - `RUNNING` tasks are currently being processed. - - `SUCCEEDED` tasks have completed successfully. - - `FAILED` tasks have failed. - - `CANCELLED` tasks have been aborted. - """ + status: Literal["PENDING"] - failure: Optional[str] = None - """ - If the status is `FAILED`, this will contain a human-friendly reason for the - failure. + +class Throttled(BaseModel): + id: str + """The ID of the task being returned.""" + + created_at: datetime = FieldInfo(alias="createdAt") + """The timestamp that the task was submitted at.""" + + status: Literal["THROTTLED"] + + +class Cancelled(BaseModel): + id: str + """The ID of the task being returned.""" + + created_at: datetime = FieldInfo(alias="createdAt") + """The timestamp that the task was submitted at.""" + + status: Literal["CANCELLED"] + + +class Running(BaseModel): + id: str + """The ID of the task being returned.""" + + created_at: datetime = FieldInfo(alias="createdAt") + """The timestamp that the task was submitted at.""" + + progress: float + + status: Literal["RUNNING"] + + +class Failed(BaseModel): + id: str + """The ID of the task being returned.""" + + created_at: datetime = FieldInfo(alias="createdAt") + """The timestamp that the task was submitted at.""" + + failure: str + """A human-friendly reason for the failure. + + We do not recommend returning this to users directly without adding context. """ + status: Literal["FAILED"] + failure_code: Optional[str] = FieldInfo(alias="failureCode", default=None) - """ - If the task has a status of `FAILED`, this contains a machine-readable error - code. This is a dot-separated string, with the leftmost segment being the most - generic and the rightmost segment being the most specific. For example, - `SAFETY.INPUT.TEXT` would indicate that the task failed due to a content - moderation error on the input text. + """A machine-readable error code for the failure. + + See https://docs.dev.runwayml.com/errors/task-failures/ for more information. """ - output: Optional[List[str]] = None - """If the status is `SUCCEEDED`, this will contain an array of strings. - Each string will be a URL that returns an output from the task. URLs expire - within 24-48 hours; fetch the task again to get fresh URLs. It is expected that - you download the assets at these URLs and store them in your own storage system. - """ +class Succeeded(BaseModel): + id: str + """The ID of the task being returned.""" - progress: Optional[float] = None - """ - If the task has a status of `RUNNING`, this will contain a floating point number - between 0 and 1 representing the progress of the generation. + created_at: datetime = FieldInfo(alias="createdAt") + """The timestamp that the task was submitted at.""" + + output: List[str] + """An array of URLs that return the output of the task. + + These URLs will expire within 24-48 hours; fetch the task again to get fresh + URLs. It is expected that you download the assets at these URLs and store them + in your own storage system. """ + + status: Literal["SUCCEEDED"] + + +TaskRetrieveResponse: TypeAlias = Annotated[ + Union[Pending, Throttled, Cancelled, Running, Failed, Succeeded], PropertyInfo(discriminator="status") +] diff --git a/src/runwayml/types/text_to_image_create_params.py b/src/runwayml/types/text_to_image_create_params.py index 164616c..1584fea 100644 --- a/src/runwayml/types/text_to_image_create_params.py +++ b/src/runwayml/types/text_to_image_create_params.py @@ -15,6 +15,8 @@ "Gen4Image", "Gen4ImageContentModeration", "Gen4ImageReferenceImage", + "Gemini3Pro", + "Gemini3ProReferenceImage", "Gemini2_5Flash", "Gemini2_5FlashReferenceImage", ] @@ -74,6 +76,10 @@ class Gen4ImageTurboReferenceImage(TypedDict, total=False): """A HTTPS URL.""" tag: str + """A tag to identify the reference image. + + This is used to reference the image in prompt text. + """ class Gen4ImageTurboContentModeration(TypedDict, total=False): @@ -146,6 +152,82 @@ class Gen4ImageReferenceImage(TypedDict, total=False): """A HTTPS URL.""" tag: str + """A tag to identify the reference image. + + This is used to reference the image in prompt text. + """ + + +class Gemini3Pro(TypedDict, total=False): + model: Required[Literal["gemini_3_pro"]] + + prompt_text: Required[Annotated[str, PropertyInfo(alias="promptText")]] + """A non-empty string up to 1000 characters (measured in UTF-16 code units). + + This should describe in detail what should appear in the output. + """ + + ratio: Required[ + Literal[ + "1344:768", + "768:1344", + "1024:1024", + "1184:864", + "864:1184", + "1536:672", + "832:1248", + "1248:832", + "896:1152", + "1152:896", + "2048:2048", + "1696:2528", + "2528:1696", + "1792:2400", + "2400:1792", + "1856:2304", + "2304:1856", + "1536:2752", + "2752:1536", + "3168:1344", + "4096:4096", + "3392:5056", + "5056:3392", + "3584:4800", + "4800:3584", + "3712:4608", + "4608:3712", + "3072:5504", + "5504:3072", + "6336:2688", + ] + ] + """The resolution of the output image.""" + + reference_images: Annotated[Iterable[Gemini3ProReferenceImage], PropertyInfo(alias="referenceImages")] + """ + An array of up to 14 images to be used as references for the generated image + output. Up to five of those images can pass `subject: "human"` to maintain + character consistency, and up to nine of those images can pass + `subject: "object"` with high-fidelity images of objects to include in the + output. + """ + + +class Gemini3ProReferenceImage(TypedDict, total=False): + subject: Required[Literal["object", "human"]] + """ + Whether this is a reference of a human subject (for character consistency) or an + object that appears in the output. + """ + + uri: Required[str] + """A HTTPS URL.""" + + tag: str + """A tag to identify the reference image. + + This is used to reference the image in prompt text. + """ class Gemini2_5Flash(TypedDict, total=False): @@ -185,6 +267,10 @@ class Gemini2_5FlashReferenceImage(TypedDict, total=False): """A HTTPS URL.""" tag: str + """A tag to identify the reference image. + + This is used to reference the image in prompt text. + """ -TextToImageCreateParams: TypeAlias = Union[Gen4ImageTurbo, Gen4Image, Gemini2_5Flash] +TextToImageCreateParams: TypeAlias = Union[Gen4ImageTurbo, Gen4Image, Gemini3Pro, Gemini2_5Flash] diff --git a/src/runwayml/types/text_to_image_create_response.py b/src/runwayml/types/text_to_image_create_response.py index 79f659e..353b565 100644 --- a/src/runwayml/types/text_to_image_create_response.py +++ b/src/runwayml/types/text_to_image_create_response.py @@ -7,3 +7,4 @@ class TextToImageCreateResponse(BaseModel): id: str + """The ID of the task that was created. Use this to retrieve the task later.""" diff --git a/src/runwayml/types/text_to_speech_create_response.py b/src/runwayml/types/text_to_speech_create_response.py index f7d45a6..3a97053 100644 --- a/src/runwayml/types/text_to_speech_create_response.py +++ b/src/runwayml/types/text_to_speech_create_response.py @@ -7,3 +7,4 @@ class TextToSpeechCreateResponse(BaseModel): id: str + """The ID of the task that was created. Use this to retrieve the task later.""" diff --git a/src/runwayml/types/text_to_video_create_response.py b/src/runwayml/types/text_to_video_create_response.py index d0c8bdf..61b1718 100644 --- a/src/runwayml/types/text_to_video_create_response.py +++ b/src/runwayml/types/text_to_video_create_response.py @@ -7,3 +7,4 @@ class TextToVideoCreateResponse(BaseModel): id: str + """The ID of the task that was created. Use this to retrieve the task later.""" diff --git a/src/runwayml/types/video_to_video_create_response.py b/src/runwayml/types/video_to_video_create_response.py index 6ab01a7..ad85b7b 100644 --- a/src/runwayml/types/video_to_video_create_response.py +++ b/src/runwayml/types/video_to_video_create_response.py @@ -7,3 +7,4 @@ class VideoToVideoCreateResponse(BaseModel): id: str + """The ID of the task that was created. Use this to retrieve the task later.""" diff --git a/src/runwayml/types/video_upscale_create_response.py b/src/runwayml/types/video_upscale_create_response.py index 73a0bd1..0cf0a9e 100644 --- a/src/runwayml/types/video_upscale_create_response.py +++ b/src/runwayml/types/video_upscale_create_response.py @@ -7,3 +7,4 @@ class VideoUpscaleCreateResponse(BaseModel): id: str + """The ID of the task that was created. Use this to retrieve the task later.""" diff --git a/src/runwayml/types/voice_dubbing_create_response.py b/src/runwayml/types/voice_dubbing_create_response.py index 3f105d6..1c8c4e5 100644 --- a/src/runwayml/types/voice_dubbing_create_response.py +++ b/src/runwayml/types/voice_dubbing_create_response.py @@ -7,3 +7,4 @@ class VoiceDubbingCreateResponse(BaseModel): id: str + """The ID of the task that was created. Use this to retrieve the task later.""" diff --git a/src/runwayml/types/voice_isolation_create_response.py b/src/runwayml/types/voice_isolation_create_response.py index e1eed57..ff24226 100644 --- a/src/runwayml/types/voice_isolation_create_response.py +++ b/src/runwayml/types/voice_isolation_create_response.py @@ -7,3 +7,4 @@ class VoiceIsolationCreateResponse(BaseModel): id: str + """The ID of the task that was created. Use this to retrieve the task later.""" diff --git a/tests/api_resources/test_text_to_image.py b/tests/api_resources/test_text_to_image.py index 95ddd30..b2a2ba1 100644 --- a/tests/api_resources/test_text_to_image.py +++ b/tests/api_resources/test_text_to_image.py @@ -131,7 +131,7 @@ def test_streaming_response_create_overload_2(self, client: RunwayML) -> None: @parametrize def test_method_create_overload_3(self, client: RunwayML) -> None: text_to_image = client.text_to_image.create( - model="gemini_2.5_flash", + model="gemini_3_pro", prompt_text="x", ratio="1344:768", ) @@ -140,11 +140,12 @@ def test_method_create_overload_3(self, client: RunwayML) -> None: @parametrize def test_method_create_with_all_params_overload_3(self, client: RunwayML) -> None: text_to_image = client.text_to_image.create( - model="gemini_2.5_flash", + model="gemini_3_pro", prompt_text="x", ratio="1344:768", reference_images=[ { + "subject": "object", "uri": "https://example.com/file", "tag": "tag", } @@ -155,7 +156,7 @@ def test_method_create_with_all_params_overload_3(self, client: RunwayML) -> Non @parametrize def test_raw_response_create_overload_3(self, client: RunwayML) -> None: response = client.text_to_image.with_raw_response.create( - model="gemini_2.5_flash", + model="gemini_3_pro", prompt_text="x", ratio="1344:768", ) @@ -167,6 +168,58 @@ def test_raw_response_create_overload_3(self, client: RunwayML) -> None: @parametrize def test_streaming_response_create_overload_3(self, client: RunwayML) -> None: + with client.text_to_image.with_streaming_response.create( + model="gemini_3_pro", + prompt_text="x", + ratio="1344:768", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + text_to_image = response.parse() + assert_matches_type(TextToImageCreateResponse, text_to_image, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_method_create_overload_4(self, client: RunwayML) -> None: + text_to_image = client.text_to_image.create( + model="gemini_2.5_flash", + prompt_text="x", + ratio="1344:768", + ) + assert_matches_type(TextToImageCreateResponse, text_to_image, path=["response"]) + + @parametrize + def test_method_create_with_all_params_overload_4(self, client: RunwayML) -> None: + text_to_image = client.text_to_image.create( + model="gemini_2.5_flash", + prompt_text="x", + ratio="1344:768", + reference_images=[ + { + "uri": "https://example.com/file", + "tag": "tag", + } + ], + ) + assert_matches_type(TextToImageCreateResponse, text_to_image, path=["response"]) + + @parametrize + def test_raw_response_create_overload_4(self, client: RunwayML) -> None: + response = client.text_to_image.with_raw_response.create( + model="gemini_2.5_flash", + prompt_text="x", + ratio="1344:768", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + text_to_image = response.parse() + assert_matches_type(TextToImageCreateResponse, text_to_image, path=["response"]) + + @parametrize + def test_streaming_response_create_overload_4(self, client: RunwayML) -> None: with client.text_to_image.with_streaming_response.create( model="gemini_2.5_flash", prompt_text="x", @@ -300,7 +353,7 @@ async def test_streaming_response_create_overload_2(self, async_client: AsyncRun @parametrize async def test_method_create_overload_3(self, async_client: AsyncRunwayML) -> None: text_to_image = await async_client.text_to_image.create( - model="gemini_2.5_flash", + model="gemini_3_pro", prompt_text="x", ratio="1344:768", ) @@ -309,11 +362,12 @@ async def test_method_create_overload_3(self, async_client: AsyncRunwayML) -> No @parametrize async def test_method_create_with_all_params_overload_3(self, async_client: AsyncRunwayML) -> None: text_to_image = await async_client.text_to_image.create( - model="gemini_2.5_flash", + model="gemini_3_pro", prompt_text="x", ratio="1344:768", reference_images=[ { + "subject": "object", "uri": "https://example.com/file", "tag": "tag", } @@ -324,7 +378,7 @@ async def test_method_create_with_all_params_overload_3(self, async_client: Asyn @parametrize async def test_raw_response_create_overload_3(self, async_client: AsyncRunwayML) -> None: response = await async_client.text_to_image.with_raw_response.create( - model="gemini_2.5_flash", + model="gemini_3_pro", prompt_text="x", ratio="1344:768", ) @@ -336,6 +390,58 @@ async def test_raw_response_create_overload_3(self, async_client: AsyncRunwayML) @parametrize async def test_streaming_response_create_overload_3(self, async_client: AsyncRunwayML) -> None: + async with async_client.text_to_image.with_streaming_response.create( + model="gemini_3_pro", + prompt_text="x", + ratio="1344:768", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + text_to_image = await response.parse() + assert_matches_type(TextToImageCreateResponse, text_to_image, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_method_create_overload_4(self, async_client: AsyncRunwayML) -> None: + text_to_image = await async_client.text_to_image.create( + model="gemini_2.5_flash", + prompt_text="x", + ratio="1344:768", + ) + assert_matches_type(TextToImageCreateResponse, text_to_image, path=["response"]) + + @parametrize + async def test_method_create_with_all_params_overload_4(self, async_client: AsyncRunwayML) -> None: + text_to_image = await async_client.text_to_image.create( + model="gemini_2.5_flash", + prompt_text="x", + ratio="1344:768", + reference_images=[ + { + "uri": "https://example.com/file", + "tag": "tag", + } + ], + ) + assert_matches_type(TextToImageCreateResponse, text_to_image, path=["response"]) + + @parametrize + async def test_raw_response_create_overload_4(self, async_client: AsyncRunwayML) -> None: + response = await async_client.text_to_image.with_raw_response.create( + model="gemini_2.5_flash", + prompt_text="x", + ratio="1344:768", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + text_to_image = await response.parse() + assert_matches_type(TextToImageCreateResponse, text_to_image, path=["response"]) + + @parametrize + async def test_streaming_response_create_overload_4(self, async_client: AsyncRunwayML) -> None: async with async_client.text_to_image.with_streaming_response.create( model="gemini_2.5_flash", prompt_text="x", diff --git a/tests/api_resources/test_voice_dubbing.py b/tests/api_resources/test_voice_dubbing.py index ac23d9f..aab73a9 100644 --- a/tests/api_resources/test_voice_dubbing.py +++ b/tests/api_resources/test_voice_dubbing.py @@ -34,7 +34,7 @@ def test_method_create_with_all_params(self, client: RunwayML) -> None: target_lang="en", disable_voice_cloning=True, drop_background_audio=True, - num_speakers=9007199254740991, + num_speakers=1, ) assert_matches_type(VoiceDubbingCreateResponse, voice_dubbing, path=["response"]) @@ -89,7 +89,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncRunwayML) target_lang="en", disable_voice_cloning=True, drop_background_audio=True, - num_speakers=9007199254740991, + num_speakers=1, ) assert_matches_type(VoiceDubbingCreateResponse, voice_dubbing, path=["response"]) From 60b9a8d5164a6a53129c85ed0b58f5f4c3b7c478 Mon Sep 17 00:00:00 2001 From: Matt Basta Date: Wed, 3 Dec 2025 18:23:31 -0500 Subject: [PATCH 04/11] Type fixes for task retrieve --- src/runwayml/lib/polling.py | 91 ++++++++++++++++++++++--- src/runwayml/resources/tasks.py | 45 ++++-------- src/runwayml/resources/text_to_image.py | 4 +- 3 files changed, 94 insertions(+), 46 deletions(-) diff --git a/src/runwayml/lib/polling.py b/src/runwayml/lib/polling.py index 5c40a6e..fbeecc9 100644 --- a/src/runwayml/lib/polling.py +++ b/src/runwayml/lib/polling.py @@ -1,12 +1,22 @@ import time import random -from typing import TYPE_CHECKING, Type, Union, TypeVar, cast -from typing_extensions import ParamSpec +from typing import TYPE_CHECKING, Type, Union, TypeVar, Annotated, cast +from typing_extensions import ParamSpec, TypeAlias import anyio +from runwayml._utils import PropertyInfo + from .._models import BaseModel -from ..types.task_retrieve_response import TaskRetrieveResponse +from ..types.task_retrieve_response import ( + Failed, + Pending, + Running, + Cancelled, + Succeeded, + Throttled, + TaskRetrieveResponse, +) if TYPE_CHECKING: from .._client import RunwayML, AsyncRunwayML @@ -40,10 +50,6 @@ class NewTaskCreatedResponse(AwaitableTaskResponseMixin, BaseModel): id: str -class AwaitableTaskRetrieveResponse(AwaitableTaskResponseMixin, TaskRetrieveResponse): - pass - - class AsyncAwaitableTaskResponseMixin: async def wait_for_task_output(self, timeout: Union[float, None] = 60 * 10) -> TaskRetrieveResponse: # type: ignore[empty-body] """ @@ -67,10 +73,6 @@ class AsyncNewTaskCreatedResponse(AsyncAwaitableTaskResponseMixin, BaseModel): id: str -class AsyncAwaitableTaskRetrieveResponse(AsyncAwaitableTaskResponseMixin, TaskRetrieveResponse): - pass - - def create_waitable_resource(base_class: Type[T], client: "RunwayML") -> Type[NewTaskCreatedResponse]: class WithClient(base_class): # type: ignore[valid-type,misc] id: str @@ -125,3 +127,70 @@ class TaskTimeoutError(Exception): def __init__(self, task_details: TaskRetrieveResponse): self.task_details = task_details super().__init__(f"Task timed out") + + + +class AwaitablePending(AwaitableTaskResponseMixin, Pending): ... +class AwaitableThrottled(AwaitableTaskResponseMixin, Throttled): ... +class AwaitableCancelled(AwaitableTaskResponseMixin, Cancelled): ... +class AwaitableRunning(AwaitableTaskResponseMixin, Running): ... +class AwaitableFailed(AwaitableTaskResponseMixin, Failed): ... +class AwaitableSucceeded(AwaitableTaskResponseMixin, Succeeded): ... + +AwaitableTaskRetrieveResponse: TypeAlias = Annotated[ + Union[AwaitablePending, AwaitableThrottled, AwaitableCancelled, AwaitableRunning, AwaitableFailed, AwaitableSucceeded], + PropertyInfo(discriminator="status") +] + +class AsyncAwaitablePending(AsyncAwaitableTaskResponseMixin, Pending): ... +class AsyncAwaitableThrottled(AsyncAwaitableTaskResponseMixin, Throttled): ... +class AsyncAwaitableCancelled(AsyncAwaitableTaskResponseMixin, Cancelled): ... +class AsyncAwaitableRunning(AsyncAwaitableTaskResponseMixin, Running): ... +class AsyncAwaitableFailed(AsyncAwaitableTaskResponseMixin, Failed): ... +class AsyncAwaitableSucceeded(AsyncAwaitableTaskResponseMixin, Succeeded): ... + +AsyncAwaitableTaskRetrieveResponse: TypeAlias = Annotated[ + Union[AsyncAwaitablePending, AsyncAwaitableThrottled, AsyncAwaitableCancelled, AsyncAwaitableRunning, AsyncAwaitableFailed, AsyncAwaitableSucceeded], + PropertyInfo(discriminator="status") +] + +def create_waitable_task_retrieve_response(client: "RunwayML") -> Type[AwaitableTaskRetrieveResponse]: + class WithClient(AwaitableTaskRetrieveResponse): # type: ignore[valid-type,misc] + id: str + + def wait_for_task_output(self, timeout: Union[float, None] = 60 * 10) -> TaskRetrieveResponse: + start_time = time.time() + while True: + time.sleep(POLL_TIME + random.random() * POLL_JITTER - POLL_JITTER / 2) + task_details = client.tasks.retrieve(self.id) + if task_details.status == "SUCCEEDED": + return task_details + if task_details.status == "FAILED": + raise TaskFailedError(task_details) + if timeout is not None and time.time() - start_time > timeout: + raise TaskTimeoutError(task_details) + + WithClient.__name__ = "TaskRetrieveResponse" + + return WithClient + + +def create_async_waitable_task_retrieve_response(client: "AsyncRunwayML") -> Type[AsyncAwaitableTaskRetrieveResponse]: + class WithClient(AsyncAwaitableTaskRetrieveResponse): # type: ignore[valid-type,misc] + id: str + + async def wait_for_task_output(self, timeout: Union[float, None] = 60 * 10) -> TaskRetrieveResponse: + start_time = anyio.current_time() + while True: + await anyio.sleep(POLL_TIME + random.random() * POLL_JITTER - POLL_JITTER / 2) + task_details = await client.tasks.retrieve(self.id) + if task_details.status == "SUCCEEDED": + return task_details + if task_details.status == "FAILED" or task_details.status == "CANCELLED": + raise TaskFailedError(task_details) + if timeout is not None and anyio.current_time() - start_time > timeout: + raise TaskTimeoutError(task_details) + + WithClient.__name__ = "TaskRetrieveResponse" + + return WithClient diff --git a/src/runwayml/resources/tasks.py b/src/runwayml/resources/tasks.py index 24a7bc9..c3ddea3 100644 --- a/src/runwayml/resources/tasks.py +++ b/src/runwayml/resources/tasks.py @@ -2,9 +2,6 @@ from __future__ import annotations -from typing import cast -from typing import Any, cast - import httpx from .._types import Body, Query, Headers, NoneType, NotGiven, not_given @@ -19,11 +16,10 @@ from ..lib.polling import ( AwaitableTaskRetrieveResponse, AsyncAwaitableTaskRetrieveResponse, - create_waitable_resource, - create_async_waitable_resource, + create_waitable_task_retrieve_response, + create_async_waitable_task_retrieve_response, ) from .._base_client import make_request_options -from ..types.task_retrieve_response import TaskRetrieveResponse __all__ = ["TasksResource", "AsyncTasksResource"] @@ -75,20 +71,12 @@ def retrieve( """ if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") - return cast( - TaskRetrieveResponse, - self._get( - f"/v1/tasks/{id}", - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - cast_to=cast( - Any, TaskRetrieveResponse - ), # Union types cannot be passed in as arguments in the type system - ), - cast_to=cast( - type[AwaitableTaskRetrieveResponse], create_waitable_resource(TaskRetrieveResponse, self._client) + return self._get( + f"/v1/tasks/{id}", + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), + cast_to=create_waitable_task_retrieve_response(self._client) ) def delete( @@ -178,21 +166,12 @@ async def retrieve( """ if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") - return cast( - TaskRetrieveResponse, - await self._get( - f"/v1/tasks/{id}", - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - cast_to=cast( - Any, TaskRetrieveResponse - ), # Union types cannot be passed in as arguments in the type system - ), - cast_to=cast( - type[AsyncAwaitableTaskRetrieveResponse], - create_async_waitable_resource(TaskRetrieveResponse, self._client), + return await self._get( + f"/v1/tasks/{id}", + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), + cast_to=create_async_waitable_task_retrieve_response(self._client) ) async def delete( diff --git a/src/runwayml/resources/text_to_image.py b/src/runwayml/resources/text_to_image.py index 064406a..be40988 100644 --- a/src/runwayml/resources/text_to_image.py +++ b/src/runwayml/resources/text_to_image.py @@ -219,7 +219,7 @@ def create( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> TextToImageCreateResponse: + ) -> NewTaskCreatedResponse: """ This endpoint will start a new task to generate images from text and/or image(s) @@ -589,7 +589,7 @@ async def create( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> TextToImageCreateResponse: + ) -> AsyncNewTaskCreatedResponse: """ This endpoint will start a new task to generate images from text and/or image(s) From e1e0a584085ad27439990771e6b38a4ed7ba0c88 Mon Sep 17 00:00:00 2001 From: Matt Basta Date: Wed, 3 Dec 2025 20:04:08 -0500 Subject: [PATCH 05/11] Inject wait method for task retrieve --- src/runwayml/lib/polling.py | 86 +++++++++++++++++---------------- src/runwayml/resources/tasks.py | 16 +++--- 2 files changed, 55 insertions(+), 47 deletions(-) diff --git a/src/runwayml/lib/polling.py b/src/runwayml/lib/polling.py index fbeecc9..d91c537 100644 --- a/src/runwayml/lib/polling.py +++ b/src/runwayml/lib/polling.py @@ -1,6 +1,6 @@ import time import random -from typing import TYPE_CHECKING, Type, Union, TypeVar, Annotated, cast +from typing import TYPE_CHECKING, Type, Union, TypeVar, Callable, Annotated, Coroutine, cast from typing_extensions import ParamSpec, TypeAlias import anyio @@ -154,43 +154,47 @@ class AsyncAwaitableSucceeded(AsyncAwaitableTaskResponseMixin, Succeeded): ... PropertyInfo(discriminator="status") ] -def create_waitable_task_retrieve_response(client: "RunwayML") -> Type[AwaitableTaskRetrieveResponse]: - class WithClient(AwaitableTaskRetrieveResponse): # type: ignore[valid-type,misc] - id: str - - def wait_for_task_output(self, timeout: Union[float, None] = 60 * 10) -> TaskRetrieveResponse: - start_time = time.time() - while True: - time.sleep(POLL_TIME + random.random() * POLL_JITTER - POLL_JITTER / 2) - task_details = client.tasks.retrieve(self.id) - if task_details.status == "SUCCEEDED": - return task_details - if task_details.status == "FAILED": - raise TaskFailedError(task_details) - if timeout is not None and time.time() - start_time > timeout: - raise TaskTimeoutError(task_details) - - WithClient.__name__ = "TaskRetrieveResponse" - - return WithClient - - -def create_async_waitable_task_retrieve_response(client: "AsyncRunwayML") -> Type[AsyncAwaitableTaskRetrieveResponse]: - class WithClient(AsyncAwaitableTaskRetrieveResponse): # type: ignore[valid-type,misc] - id: str - - async def wait_for_task_output(self, timeout: Union[float, None] = 60 * 10) -> TaskRetrieveResponse: - start_time = anyio.current_time() - while True: - await anyio.sleep(POLL_TIME + random.random() * POLL_JITTER - POLL_JITTER / 2) - task_details = await client.tasks.retrieve(self.id) - if task_details.status == "SUCCEEDED": - return task_details - if task_details.status == "FAILED" or task_details.status == "CANCELLED": - raise TaskFailedError(task_details) - if timeout is not None and anyio.current_time() - start_time > timeout: - raise TaskTimeoutError(task_details) - - WithClient.__name__ = "TaskRetrieveResponse" - - return WithClient +def _make_sync_wait_for_task_output(client: "RunwayML") -> Callable[["AwaitableTaskResponseMixin", Union[float, None]], TaskRetrieveResponse]: + """Create a wait_for_task_output method bound to the given client.""" + def wait_for_task_output(self: "AwaitableTaskResponseMixin", timeout: Union[float, None] = 60 * 10) -> TaskRetrieveResponse: + start_time = time.time() + while True: + time.sleep(POLL_TIME + random.random() * POLL_JITTER - POLL_JITTER / 2) + task_details = client.tasks.retrieve(self.id) # type: ignore[attr-defined] + if task_details.status == "SUCCEEDED": + return task_details + if task_details.status == "FAILED": + raise TaskFailedError(task_details) + if timeout is not None and time.time() - start_time > timeout: + raise TaskTimeoutError(task_details) + return wait_for_task_output + + +def inject_sync_wait_method(client: "RunwayML", response: T) -> T: + """Inject the wait_for_task_output method onto the response instance.""" + import types + response.wait_for_task_output = types.MethodType(_make_sync_wait_for_task_output(client), response) # type: ignore[attr-defined] + return response + + +def _make_async_wait_for_task_output(client: "AsyncRunwayML") -> Callable[["AsyncAwaitableTaskResponseMixin", Union[float, None]], Coroutine[None, None, TaskRetrieveResponse]]: + """Create an async wait_for_task_output method bound to the given client.""" + async def wait_for_task_output(self: "AsyncAwaitableTaskResponseMixin", timeout: Union[float, None] = 60 * 10) -> TaskRetrieveResponse: + start_time = anyio.current_time() + while True: + await anyio.sleep(POLL_TIME + random.random() * POLL_JITTER - POLL_JITTER / 2) + task_details = await client.tasks.retrieve(self.id) # type: ignore[attr-defined] + if task_details.status == "SUCCEEDED": + return task_details + if task_details.status == "FAILED" or task_details.status == "CANCELLED": + raise TaskFailedError(task_details) + if timeout is not None and anyio.current_time() - start_time > timeout: + raise TaskTimeoutError(task_details) + return wait_for_task_output + + +def inject_async_wait_method(client: "AsyncRunwayML", response: T) -> T: + """Inject the async wait_for_task_output method onto the response instance.""" + import types + response.wait_for_task_output = types.MethodType(_make_async_wait_for_task_output(client), response) # type: ignore[attr-defined] + return response diff --git a/src/runwayml/resources/tasks.py b/src/runwayml/resources/tasks.py index c3ddea3..a97d240 100644 --- a/src/runwayml/resources/tasks.py +++ b/src/runwayml/resources/tasks.py @@ -2,6 +2,8 @@ from __future__ import annotations +from typing import Any, cast + import httpx from .._types import Body, Query, Headers, NoneType, NotGiven, not_given @@ -16,8 +18,8 @@ from ..lib.polling import ( AwaitableTaskRetrieveResponse, AsyncAwaitableTaskRetrieveResponse, - create_waitable_task_retrieve_response, - create_async_waitable_task_retrieve_response, + inject_sync_wait_method, + inject_async_wait_method, ) from .._base_client import make_request_options @@ -71,13 +73,14 @@ def retrieve( """ if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") - return self._get( + response = self._get( f"/v1/tasks/{id}", options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), - cast_to=create_waitable_task_retrieve_response(self._client) + cast_to=cast(Any, AwaitableTaskRetrieveResponse), # Union types cannot be passed in as arguments in the type system ) + return inject_sync_wait_method(self._client, response) def delete( self, @@ -166,13 +169,14 @@ async def retrieve( """ if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") - return await self._get( + response = await self._get( f"/v1/tasks/{id}", options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), - cast_to=create_async_waitable_task_retrieve_response(self._client) + cast_to=cast(Any, AsyncAwaitableTaskRetrieveResponse) # Union types cannot be passed in as arguments in the type system ) + return inject_async_wait_method(self._client, response) async def delete( self, From 2225ef6ba6c638afa997f0b4b3c52ed12fce5e73 Mon Sep 17 00:00:00 2001 From: Matt Basta Date: Wed, 3 Dec 2025 20:07:42 -0500 Subject: [PATCH 06/11] Cast to not be any --- src/runwayml/resources/tasks.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/runwayml/resources/tasks.py b/src/runwayml/resources/tasks.py index a97d240..3803e98 100644 --- a/src/runwayml/resources/tasks.py +++ b/src/runwayml/resources/tasks.py @@ -80,7 +80,7 @@ def retrieve( ), cast_to=cast(Any, AwaitableTaskRetrieveResponse), # Union types cannot be passed in as arguments in the type system ) - return inject_sync_wait_method(self._client, response) + return cast(AwaitableTaskRetrieveResponse, inject_sync_wait_method(self._client, response)) def delete( self, @@ -174,9 +174,9 @@ async def retrieve( options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), - cast_to=cast(Any, AsyncAwaitableTaskRetrieveResponse) # Union types cannot be passed in as arguments in the type system + cast_to=cast(Any, AsyncAwaitableTaskRetrieveResponse), # Union types cannot be passed in as arguments in the type system ) - return inject_async_wait_method(self._client, response) + return cast(AsyncAwaitableTaskRetrieveResponse, inject_async_wait_method(self._client, response)) async def delete( self, From 1f1fcfa6bac257df24a383613389010d0c481f5d Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 4 Dec 2025 01:19:54 +0000 Subject: [PATCH 07/11] feat(api): gemini_3_pro t2i From 3959ddfb5bfee6a7beff2cd6d294b59204dd6fae Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 4 Dec 2025 01:44:07 +0000 Subject: [PATCH 08/11] feat(api): Revert G3P changes --- .stats.yml | 4 +- src/runwayml/lib/polling.py | 95 +---- src/runwayml/resources/tasks.py | 24 +- src/runwayml/resources/text_to_image.py | 218 +---------- .../character_performance_create_response.py | 1 - .../types/image_to_video_create_response.py | 1 - .../types/organization_retrieve_response.py | 346 +++++++++++++++++- .../organization_retrieve_usage_response.py | 42 +-- .../types/sound_effect_create_response.py | 1 - .../types/speech_to_speech_create_response.py | 1 - src/runwayml/types/task_retrieve_response.py | 108 ++---- .../types/text_to_image_create_params.py | 88 +---- .../types/text_to_image_create_response.py | 1 - .../types/text_to_speech_create_response.py | 1 - .../types/text_to_video_create_response.py | 1 - .../types/video_to_video_create_response.py | 1 - .../types/video_upscale_create_response.py | 1 - .../types/voice_dubbing_create_response.py | 1 - .../types/voice_isolation_create_response.py | 1 - tests/api_resources/test_text_to_image.py | 118 +----- tests/api_resources/test_voice_dubbing.py | 4 +- 21 files changed, 432 insertions(+), 626 deletions(-) diff --git a/.stats.yml b/.stats.yml index 5e984fc..f7f71cf 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 15 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/runwayml%2Frunwayml-76b3962cf49e001b04b50d184ae502a1b58ddaa525f34a142fd3b0878262f934.yml -openapi_spec_hash: 148cd90ea90d29a01020741f4ae0fd5b +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/runwayml%2Frunwayml-c2a88516fa0c20ca73f742f8d876f5e773747b4f6903508b1824c0939b313b82.yml +openapi_spec_hash: 660d0eec8f3940727f541dd05121627b config_hash: b98eed33f1bba05e3c2a3e20d85d582a diff --git a/src/runwayml/lib/polling.py b/src/runwayml/lib/polling.py index d91c537..5c40a6e 100644 --- a/src/runwayml/lib/polling.py +++ b/src/runwayml/lib/polling.py @@ -1,22 +1,12 @@ import time import random -from typing import TYPE_CHECKING, Type, Union, TypeVar, Callable, Annotated, Coroutine, cast -from typing_extensions import ParamSpec, TypeAlias +from typing import TYPE_CHECKING, Type, Union, TypeVar, cast +from typing_extensions import ParamSpec import anyio -from runwayml._utils import PropertyInfo - from .._models import BaseModel -from ..types.task_retrieve_response import ( - Failed, - Pending, - Running, - Cancelled, - Succeeded, - Throttled, - TaskRetrieveResponse, -) +from ..types.task_retrieve_response import TaskRetrieveResponse if TYPE_CHECKING: from .._client import RunwayML, AsyncRunwayML @@ -50,6 +40,10 @@ class NewTaskCreatedResponse(AwaitableTaskResponseMixin, BaseModel): id: str +class AwaitableTaskRetrieveResponse(AwaitableTaskResponseMixin, TaskRetrieveResponse): + pass + + class AsyncAwaitableTaskResponseMixin: async def wait_for_task_output(self, timeout: Union[float, None] = 60 * 10) -> TaskRetrieveResponse: # type: ignore[empty-body] """ @@ -73,6 +67,10 @@ class AsyncNewTaskCreatedResponse(AsyncAwaitableTaskResponseMixin, BaseModel): id: str +class AsyncAwaitableTaskRetrieveResponse(AsyncAwaitableTaskResponseMixin, TaskRetrieveResponse): + pass + + def create_waitable_resource(base_class: Type[T], client: "RunwayML") -> Type[NewTaskCreatedResponse]: class WithClient(base_class): # type: ignore[valid-type,misc] id: str @@ -127,74 +125,3 @@ class TaskTimeoutError(Exception): def __init__(self, task_details: TaskRetrieveResponse): self.task_details = task_details super().__init__(f"Task timed out") - - - -class AwaitablePending(AwaitableTaskResponseMixin, Pending): ... -class AwaitableThrottled(AwaitableTaskResponseMixin, Throttled): ... -class AwaitableCancelled(AwaitableTaskResponseMixin, Cancelled): ... -class AwaitableRunning(AwaitableTaskResponseMixin, Running): ... -class AwaitableFailed(AwaitableTaskResponseMixin, Failed): ... -class AwaitableSucceeded(AwaitableTaskResponseMixin, Succeeded): ... - -AwaitableTaskRetrieveResponse: TypeAlias = Annotated[ - Union[AwaitablePending, AwaitableThrottled, AwaitableCancelled, AwaitableRunning, AwaitableFailed, AwaitableSucceeded], - PropertyInfo(discriminator="status") -] - -class AsyncAwaitablePending(AsyncAwaitableTaskResponseMixin, Pending): ... -class AsyncAwaitableThrottled(AsyncAwaitableTaskResponseMixin, Throttled): ... -class AsyncAwaitableCancelled(AsyncAwaitableTaskResponseMixin, Cancelled): ... -class AsyncAwaitableRunning(AsyncAwaitableTaskResponseMixin, Running): ... -class AsyncAwaitableFailed(AsyncAwaitableTaskResponseMixin, Failed): ... -class AsyncAwaitableSucceeded(AsyncAwaitableTaskResponseMixin, Succeeded): ... - -AsyncAwaitableTaskRetrieveResponse: TypeAlias = Annotated[ - Union[AsyncAwaitablePending, AsyncAwaitableThrottled, AsyncAwaitableCancelled, AsyncAwaitableRunning, AsyncAwaitableFailed, AsyncAwaitableSucceeded], - PropertyInfo(discriminator="status") -] - -def _make_sync_wait_for_task_output(client: "RunwayML") -> Callable[["AwaitableTaskResponseMixin", Union[float, None]], TaskRetrieveResponse]: - """Create a wait_for_task_output method bound to the given client.""" - def wait_for_task_output(self: "AwaitableTaskResponseMixin", timeout: Union[float, None] = 60 * 10) -> TaskRetrieveResponse: - start_time = time.time() - while True: - time.sleep(POLL_TIME + random.random() * POLL_JITTER - POLL_JITTER / 2) - task_details = client.tasks.retrieve(self.id) # type: ignore[attr-defined] - if task_details.status == "SUCCEEDED": - return task_details - if task_details.status == "FAILED": - raise TaskFailedError(task_details) - if timeout is not None and time.time() - start_time > timeout: - raise TaskTimeoutError(task_details) - return wait_for_task_output - - -def inject_sync_wait_method(client: "RunwayML", response: T) -> T: - """Inject the wait_for_task_output method onto the response instance.""" - import types - response.wait_for_task_output = types.MethodType(_make_sync_wait_for_task_output(client), response) # type: ignore[attr-defined] - return response - - -def _make_async_wait_for_task_output(client: "AsyncRunwayML") -> Callable[["AsyncAwaitableTaskResponseMixin", Union[float, None]], Coroutine[None, None, TaskRetrieveResponse]]: - """Create an async wait_for_task_output method bound to the given client.""" - async def wait_for_task_output(self: "AsyncAwaitableTaskResponseMixin", timeout: Union[float, None] = 60 * 10) -> TaskRetrieveResponse: - start_time = anyio.current_time() - while True: - await anyio.sleep(POLL_TIME + random.random() * POLL_JITTER - POLL_JITTER / 2) - task_details = await client.tasks.retrieve(self.id) # type: ignore[attr-defined] - if task_details.status == "SUCCEEDED": - return task_details - if task_details.status == "FAILED" or task_details.status == "CANCELLED": - raise TaskFailedError(task_details) - if timeout is not None and anyio.current_time() - start_time > timeout: - raise TaskTimeoutError(task_details) - return wait_for_task_output - - -def inject_async_wait_method(client: "AsyncRunwayML", response: T) -> T: - """Inject the async wait_for_task_output method onto the response instance.""" - import types - response.wait_for_task_output = types.MethodType(_make_async_wait_for_task_output(client), response) # type: ignore[attr-defined] - return response diff --git a/src/runwayml/resources/tasks.py b/src/runwayml/resources/tasks.py index 3803e98..3cc981e 100644 --- a/src/runwayml/resources/tasks.py +++ b/src/runwayml/resources/tasks.py @@ -2,7 +2,7 @@ from __future__ import annotations -from typing import Any, cast +from typing import cast import httpx @@ -18,10 +18,11 @@ from ..lib.polling import ( AwaitableTaskRetrieveResponse, AsyncAwaitableTaskRetrieveResponse, - inject_sync_wait_method, - inject_async_wait_method, + create_waitable_resource, + create_async_waitable_resource, ) from .._base_client import make_request_options +from ..types.task_retrieve_response import TaskRetrieveResponse __all__ = ["TasksResource", "AsyncTasksResource"] @@ -73,14 +74,15 @@ def retrieve( """ if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") - response = self._get( + return self._get( f"/v1/tasks/{id}", options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), - cast_to=cast(Any, AwaitableTaskRetrieveResponse), # Union types cannot be passed in as arguments in the type system + cast_to=cast( + type[AwaitableTaskRetrieveResponse], create_waitable_resource(TaskRetrieveResponse, self._client) + ), ) - return cast(AwaitableTaskRetrieveResponse, inject_sync_wait_method(self._client, response)) def delete( self, @@ -169,14 +171,16 @@ async def retrieve( """ if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") - response = await self._get( + return await self._get( f"/v1/tasks/{id}", options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), - cast_to=cast(Any, AsyncAwaitableTaskRetrieveResponse), # Union types cannot be passed in as arguments in the type system + cast_to=cast( + type[AsyncAwaitableTaskRetrieveResponse], + create_async_waitable_resource(TaskRetrieveResponse, self._client), + ), ) - return cast(AsyncAwaitableTaskRetrieveResponse, inject_async_wait_method(self._client, response)) async def delete( self, @@ -263,4 +267,4 @@ def __init__(self, tasks: AsyncTasksResource) -> None: ) self.delete = async_to_streamed_response_wrapper( tasks.delete, - ) + ) \ No newline at end of file diff --git a/src/runwayml/resources/text_to_image.py b/src/runwayml/resources/text_to_image.py index be40988..9206ae8 100644 --- a/src/runwayml/resources/text_to_image.py +++ b/src/runwayml/resources/text_to_image.py @@ -174,77 +174,6 @@ def create( """ ... - @overload - def create( - self, - *, - model: Literal["gemini_3_pro"], - prompt_text: str, - ratio: Literal[ - "1344:768", - "768:1344", - "1024:1024", - "1184:864", - "864:1184", - "1536:672", - "832:1248", - "1248:832", - "896:1152", - "1152:896", - "2048:2048", - "1696:2528", - "2528:1696", - "1792:2400", - "2400:1792", - "1856:2304", - "2304:1856", - "1536:2752", - "2752:1536", - "3168:1344", - "4096:4096", - "3392:5056", - "5056:3392", - "3584:4800", - "4800:3584", - "3712:4608", - "4608:3712", - "3072:5504", - "5504:3072", - "6336:2688", - ], - reference_images: Iterable[text_to_image_create_params.Gemini3ProReferenceImage] | 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 images from text and/or image(s) - - Args: - prompt_text: A non-empty string up to 1000 characters (measured in UTF-16 code units). This - should describe in detail what should appear in the output. - - ratio: The resolution of the output image. - - reference_images: An array of up to 14 images to be used as references for the generated image - output. Up to five of those images can pass `subject: "human"` to maintain - character consistency, and up to nine of those images can pass - `subject: "object"` with high-fidelity images of objects to include in the - output. - - 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, @@ -297,10 +226,7 @@ def create( def create( self, *, - model: Literal["gen4_image_turbo"] - | Literal["gen4_image"] - | Literal["gemini_3_pro"] - | Literal["gemini_2.5_flash"], + model: Literal["gen4_image_turbo"] | Literal["gen4_image"] | Literal["gemini_2.5_flash"], prompt_text: str, ratio: Literal[ "1024:1024", @@ -320,38 +246,6 @@ def create( "720:960", "1680:720", ] - | Literal[ - "1344:768", - "768:1344", - "1024:1024", - "1184:864", - "864:1184", - "1536:672", - "832:1248", - "1248:832", - "896:1152", - "1152:896", - "2048:2048", - "1696:2528", - "2528:1696", - "1792:2400", - "2400:1792", - "1856:2304", - "2304:1856", - "1536:2752", - "2752:1536", - "3168:1344", - "4096:4096", - "3392:5056", - "5056:3392", - "3584:4800", - "4800:3584", - "3712:4608", - "4608:3712", - "3072:5504", - "5504:3072", - "6336:2688", - ] | Literal[ "1344:768", "768:1344", @@ -366,7 +260,6 @@ def create( ], reference_images: Iterable[text_to_image_create_params.Gen4ImageTurboReferenceImage] | Iterable[text_to_image_create_params.Gen4ImageReferenceImage] - | Iterable[text_to_image_create_params.Gemini3ProReferenceImage] | Iterable[text_to_image_create_params.Gemini2_5FlashReferenceImage] | Omit = omit, content_moderation: text_to_image_create_params.Gen4ImageTurboContentModeration @@ -544,77 +437,6 @@ async def create( """ ... - @overload - async def create( - self, - *, - model: Literal["gemini_3_pro"], - prompt_text: str, - ratio: Literal[ - "1344:768", - "768:1344", - "1024:1024", - "1184:864", - "864:1184", - "1536:672", - "832:1248", - "1248:832", - "896:1152", - "1152:896", - "2048:2048", - "1696:2528", - "2528:1696", - "1792:2400", - "2400:1792", - "1856:2304", - "2304:1856", - "1536:2752", - "2752:1536", - "3168:1344", - "4096:4096", - "3392:5056", - "5056:3392", - "3584:4800", - "4800:3584", - "3712:4608", - "4608:3712", - "3072:5504", - "5504:3072", - "6336:2688", - ], - reference_images: Iterable[text_to_image_create_params.Gemini3ProReferenceImage] | 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 images from text and/or image(s) - - Args: - prompt_text: A non-empty string up to 1000 characters (measured in UTF-16 code units). This - should describe in detail what should appear in the output. - - ratio: The resolution of the output image. - - reference_images: An array of up to 14 images to be used as references for the generated image - output. Up to five of those images can pass `subject: "human"` to maintain - character consistency, and up to nine of those images can pass - `subject: "object"` with high-fidelity images of objects to include in the - output. - - 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, @@ -667,10 +489,7 @@ async def create( async def create( self, *, - model: Literal["gen4_image_turbo"] - | Literal["gen4_image"] - | Literal["gemini_3_pro"] - | Literal["gemini_2.5_flash"], + model: Literal["gen4_image_turbo"] | Literal["gen4_image"] | Literal["gemini_2.5_flash"], prompt_text: str, ratio: Literal[ "1024:1024", @@ -690,38 +509,6 @@ async def create( "720:960", "1680:720", ] - | Literal[ - "1344:768", - "768:1344", - "1024:1024", - "1184:864", - "864:1184", - "1536:672", - "832:1248", - "1248:832", - "896:1152", - "1152:896", - "2048:2048", - "1696:2528", - "2528:1696", - "1792:2400", - "2400:1792", - "1856:2304", - "2304:1856", - "1536:2752", - "2752:1536", - "3168:1344", - "4096:4096", - "3392:5056", - "5056:3392", - "3584:4800", - "4800:3584", - "3712:4608", - "4608:3712", - "3072:5504", - "5504:3072", - "6336:2688", - ] | Literal[ "1344:768", "768:1344", @@ -736,7 +523,6 @@ async def create( ], reference_images: Iterable[text_to_image_create_params.Gen4ImageTurboReferenceImage] | Iterable[text_to_image_create_params.Gen4ImageReferenceImage] - | Iterable[text_to_image_create_params.Gemini3ProReferenceImage] | Iterable[text_to_image_create_params.Gemini2_5FlashReferenceImage] | Omit = omit, content_moderation: text_to_image_create_params.Gen4ImageTurboContentModeration diff --git a/src/runwayml/types/character_performance_create_response.py b/src/runwayml/types/character_performance_create_response.py index 48ab1c5..61b4fff 100644 --- a/src/runwayml/types/character_performance_create_response.py +++ b/src/runwayml/types/character_performance_create_response.py @@ -7,4 +7,3 @@ class CharacterPerformanceCreateResponse(BaseModel): id: str - """The ID of the task that was created. Use this to retrieve the task later.""" diff --git a/src/runwayml/types/image_to_video_create_response.py b/src/runwayml/types/image_to_video_create_response.py index 8b03891..5c381da 100644 --- a/src/runwayml/types/image_to_video_create_response.py +++ b/src/runwayml/types/image_to_video_create_response.py @@ -7,4 +7,3 @@ class ImageToVideoCreateResponse(BaseModel): id: str - """The ID of the task that was created. Use this to retrieve the task later.""" diff --git a/src/runwayml/types/organization_retrieve_response.py b/src/runwayml/types/organization_retrieve_response.py index f3a56ca..3621c54 100644 --- a/src/runwayml/types/organization_retrieve_response.py +++ b/src/runwayml/types/organization_retrieve_response.py @@ -1,15 +1,125 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import Dict +from typing import Optional from pydantic import Field as FieldInfo from .._models import BaseModel -__all__ = ["OrganizationRetrieveResponse", "Tier", "TierModels", "Usage", "UsageModels"] +__all__ = [ + "OrganizationRetrieveResponse", + "Tier", + "TierModels", + "TierModelsActTwo", + "TierModelsElevenMultilingualStsV2", + "TierModelsElevenMultilingualV2", + "TierModelsElevenTextToSoundV2", + "TierModelsElevenVoiceDubbing", + "TierModelsElevenVoiceIsolation", + "TierModelsGemini2_5Flash", + "TierModelsGen3aTurbo", + "TierModelsGen4Aleph", + "TierModelsGen4Image", + "TierModelsGen4ImageTurbo", + "TierModelsGen4Turbo", + "TierModelsUpscaleV1", + "TierModelsVeo3", + "TierModelsVeo3_1", + "TierModelsVeo3_1Fast", + "Usage", + "UsageModels", + "UsageModelsActTwo", + "UsageModelsElevenMultilingualStsV2", + "UsageModelsElevenMultilingualV2", + "UsageModelsElevenTextToSoundV2", + "UsageModelsElevenVoiceDubbing", + "UsageModelsElevenVoiceIsolation", + "UsageModelsGemini2_5Flash", + "UsageModelsGen3aTurbo", + "UsageModelsGen4Aleph", + "UsageModelsGen4Image", + "UsageModelsGen4ImageTurbo", + "UsageModelsGen4Turbo", + "UsageModelsUpscaleV1", + "UsageModelsVeo3", + "UsageModelsVeo3_1", + "UsageModelsVeo3_1Fast", +] -class TierModels(BaseModel): +class TierModelsActTwo(BaseModel): + max_concurrent_generations: int = FieldInfo(alias="maxConcurrentGenerations") + """The maximum number of generations that can be run concurrently for this model.""" + + max_daily_generations: int = FieldInfo(alias="maxDailyGenerations") + """The maximum number of generations that can be created each day for this model.""" + + +class TierModelsElevenMultilingualStsV2(BaseModel): + max_concurrent_generations: int = FieldInfo(alias="maxConcurrentGenerations") + """The maximum number of generations that can be run concurrently for this model.""" + + max_daily_generations: int = FieldInfo(alias="maxDailyGenerations") + """The maximum number of generations that can be created each day for this model.""" + + +class TierModelsElevenMultilingualV2(BaseModel): + max_concurrent_generations: int = FieldInfo(alias="maxConcurrentGenerations") + """The maximum number of generations that can be run concurrently for this model.""" + + max_daily_generations: int = FieldInfo(alias="maxDailyGenerations") + """The maximum number of generations that can be created each day for this model.""" + + +class TierModelsElevenTextToSoundV2(BaseModel): + max_concurrent_generations: int = FieldInfo(alias="maxConcurrentGenerations") + """The maximum number of generations that can be run concurrently for this model.""" + + max_daily_generations: int = FieldInfo(alias="maxDailyGenerations") + """The maximum number of generations that can be created each day for this model.""" + + +class TierModelsElevenVoiceDubbing(BaseModel): + max_concurrent_generations: int = FieldInfo(alias="maxConcurrentGenerations") + """The maximum number of generations that can be run concurrently for this model.""" + + max_daily_generations: int = FieldInfo(alias="maxDailyGenerations") + """The maximum number of generations that can be created each day for this model.""" + + +class TierModelsElevenVoiceIsolation(BaseModel): + max_concurrent_generations: int = FieldInfo(alias="maxConcurrentGenerations") + """The maximum number of generations that can be run concurrently for this model.""" + + max_daily_generations: int = FieldInfo(alias="maxDailyGenerations") + """The maximum number of generations that can be created each day for this model.""" + + +class TierModelsGemini2_5Flash(BaseModel): + max_concurrent_generations: int = FieldInfo(alias="maxConcurrentGenerations") + """The maximum number of generations that can be run concurrently for this model.""" + + max_daily_generations: int = FieldInfo(alias="maxDailyGenerations") + """The maximum number of generations that can be created each day for this model.""" + + +class TierModelsGen3aTurbo(BaseModel): + max_concurrent_generations: int = FieldInfo(alias="maxConcurrentGenerations") + """The maximum number of generations that can be run concurrently for this model.""" + + max_daily_generations: int = FieldInfo(alias="maxDailyGenerations") + """The maximum number of generations that can be created each day for this model.""" + + +class TierModelsGen4Aleph(BaseModel): + max_concurrent_generations: int = FieldInfo(alias="maxConcurrentGenerations") + """The maximum number of generations that can be run concurrently for this model.""" + + max_daily_generations: int = FieldInfo(alias="maxDailyGenerations") + """The maximum number of generations that can be created each day for this model.""" + + +class TierModelsGen4Image(BaseModel): max_concurrent_generations: int = FieldInfo(alias="maxConcurrentGenerations") """The maximum number of generations that can be run concurrently for this model.""" @@ -17,21 +127,245 @@ class TierModels(BaseModel): """The maximum number of generations that can be created each day for this model.""" +class TierModelsGen4ImageTurbo(BaseModel): + max_concurrent_generations: int = FieldInfo(alias="maxConcurrentGenerations") + """The maximum number of generations that can be run concurrently for this model.""" + + max_daily_generations: int = FieldInfo(alias="maxDailyGenerations") + """The maximum number of generations that can be created each day for this model.""" + + +class TierModelsGen4Turbo(BaseModel): + max_concurrent_generations: int = FieldInfo(alias="maxConcurrentGenerations") + """The maximum number of generations that can be run concurrently for this model.""" + + max_daily_generations: int = FieldInfo(alias="maxDailyGenerations") + """The maximum number of generations that can be created each day for this model.""" + + +class TierModelsUpscaleV1(BaseModel): + max_concurrent_generations: int = FieldInfo(alias="maxConcurrentGenerations") + """The maximum number of generations that can be run concurrently for this model.""" + + max_daily_generations: int = FieldInfo(alias="maxDailyGenerations") + """The maximum number of generations that can be created each day for this model.""" + + +class TierModelsVeo3(BaseModel): + max_concurrent_generations: int = FieldInfo(alias="maxConcurrentGenerations") + """The maximum number of generations that can be run concurrently for this model.""" + + max_daily_generations: int = FieldInfo(alias="maxDailyGenerations") + """The maximum number of generations that can be created each day for this model.""" + + +class TierModelsVeo3_1(BaseModel): + max_concurrent_generations: int = FieldInfo(alias="maxConcurrentGenerations") + """The maximum number of generations that can be run concurrently for this model.""" + + max_daily_generations: int = FieldInfo(alias="maxDailyGenerations") + """The maximum number of generations that can be created each day for this model.""" + + +class TierModelsVeo3_1Fast(BaseModel): + max_concurrent_generations: int = FieldInfo(alias="maxConcurrentGenerations") + """The maximum number of generations that can be run concurrently for this model.""" + + max_daily_generations: int = FieldInfo(alias="maxDailyGenerations") + """The maximum number of generations that can be created each day for this model.""" + + +class TierModels(BaseModel): + act_two: Optional[TierModelsActTwo] = None + """Limits associated with the act_two model.""" + + eleven_multilingual_sts_v2: Optional[TierModelsElevenMultilingualStsV2] = None + """Limits associated with the eleven_multilingual_sts_v2 model.""" + + eleven_multilingual_v2: Optional[TierModelsElevenMultilingualV2] = None + """Limits associated with the eleven_multilingual_v2 model.""" + + eleven_text_to_sound_v2: Optional[TierModelsElevenTextToSoundV2] = None + """Limits associated with the eleven_text_to_sound_v2 model.""" + + eleven_voice_dubbing: Optional[TierModelsElevenVoiceDubbing] = None + """Limits associated with the eleven_voice_dubbing model.""" + + eleven_voice_isolation: Optional[TierModelsElevenVoiceIsolation] = None + """Limits associated with the eleven_voice_isolation model.""" + + gemini_2_5_flash: Optional[TierModelsGemini2_5Flash] = FieldInfo(alias="gemini_2.5_flash", default=None) + """Limits associated with the gemini_2.5_flash model.""" + + gen3a_turbo: Optional[TierModelsGen3aTurbo] = None + """Limits associated with the gen3a_turbo model.""" + + gen4_aleph: Optional[TierModelsGen4Aleph] = None + """Limits associated with the gen4_aleph model.""" + + gen4_image: Optional[TierModelsGen4Image] = None + """Limits associated with the gen4_image model.""" + + gen4_image_turbo: Optional[TierModelsGen4ImageTurbo] = None + """Limits associated with the gen4_image_turbo model.""" + + gen4_turbo: Optional[TierModelsGen4Turbo] = None + """Limits associated with the gen4_turbo model.""" + + upscale_v1: Optional[TierModelsUpscaleV1] = None + """Limits associated with the upscale_v1 model.""" + + veo3: Optional[TierModelsVeo3] = None + """Limits associated with the veo3 model.""" + + veo3_1: Optional[TierModelsVeo3_1] = FieldInfo(alias="veo3.1", default=None) + """Limits associated with the veo3.1 model.""" + + veo3_1_fast: Optional[TierModelsVeo3_1Fast] = FieldInfo(alias="veo3.1_fast", default=None) + """Limits associated with the veo3.1_fast model.""" + + class Tier(BaseModel): max_monthly_credit_spend: int = FieldInfo(alias="maxMonthlyCreditSpend") """The maximum number of credits that can be purchased in a month.""" - models: Dict[str, TierModels] + models: TierModels """An object containing model-specific limits. Each key represents a model.""" -class UsageModels(BaseModel): +class UsageModelsActTwo(BaseModel): + daily_generations: int = FieldInfo(alias="dailyGenerations") + """The number of generations that have been run for this model in the past day.""" + + +class UsageModelsElevenMultilingualStsV2(BaseModel): + daily_generations: int = FieldInfo(alias="dailyGenerations") + """The number of generations that have been run for this model in the past day.""" + + +class UsageModelsElevenMultilingualV2(BaseModel): + daily_generations: int = FieldInfo(alias="dailyGenerations") + """The number of generations that have been run for this model in the past day.""" + + +class UsageModelsElevenTextToSoundV2(BaseModel): + daily_generations: int = FieldInfo(alias="dailyGenerations") + """The number of generations that have been run for this model in the past day.""" + + +class UsageModelsElevenVoiceDubbing(BaseModel): + daily_generations: int = FieldInfo(alias="dailyGenerations") + """The number of generations that have been run for this model in the past day.""" + + +class UsageModelsElevenVoiceIsolation(BaseModel): + daily_generations: int = FieldInfo(alias="dailyGenerations") + """The number of generations that have been run for this model in the past day.""" + + +class UsageModelsGemini2_5Flash(BaseModel): + daily_generations: int = FieldInfo(alias="dailyGenerations") + """The number of generations that have been run for this model in the past day.""" + + +class UsageModelsGen3aTurbo(BaseModel): daily_generations: int = FieldInfo(alias="dailyGenerations") """The number of generations that have been run for this model in the past day.""" +class UsageModelsGen4Aleph(BaseModel): + daily_generations: int = FieldInfo(alias="dailyGenerations") + """The number of generations that have been run for this model in the past day.""" + + +class UsageModelsGen4Image(BaseModel): + daily_generations: int = FieldInfo(alias="dailyGenerations") + """The number of generations that have been run for this model in the past day.""" + + +class UsageModelsGen4ImageTurbo(BaseModel): + daily_generations: int = FieldInfo(alias="dailyGenerations") + """The number of generations that have been run for this model in the past day.""" + + +class UsageModelsGen4Turbo(BaseModel): + daily_generations: int = FieldInfo(alias="dailyGenerations") + """The number of generations that have been run for this model in the past day.""" + + +class UsageModelsUpscaleV1(BaseModel): + daily_generations: int = FieldInfo(alias="dailyGenerations") + """The number of generations that have been run for this model in the past day.""" + + +class UsageModelsVeo3(BaseModel): + daily_generations: int = FieldInfo(alias="dailyGenerations") + """The number of generations that have been run for this model in the past day.""" + + +class UsageModelsVeo3_1(BaseModel): + daily_generations: int = FieldInfo(alias="dailyGenerations") + """The number of generations that have been run for this model in the past day.""" + + +class UsageModelsVeo3_1Fast(BaseModel): + daily_generations: int = FieldInfo(alias="dailyGenerations") + """The number of generations that have been run for this model in the past day.""" + + +class UsageModels(BaseModel): + act_two: Optional[UsageModelsActTwo] = None + """Usage data for the act_two model.""" + + eleven_multilingual_sts_v2: Optional[UsageModelsElevenMultilingualStsV2] = None + """Usage data for the eleven_multilingual_sts_v2 model.""" + + eleven_multilingual_v2: Optional[UsageModelsElevenMultilingualV2] = None + """Usage data for the eleven_multilingual_v2 model.""" + + eleven_text_to_sound_v2: Optional[UsageModelsElevenTextToSoundV2] = None + """Usage data for the eleven_text_to_sound_v2 model.""" + + eleven_voice_dubbing: Optional[UsageModelsElevenVoiceDubbing] = None + """Usage data for the eleven_voice_dubbing model.""" + + eleven_voice_isolation: Optional[UsageModelsElevenVoiceIsolation] = None + """Usage data for the eleven_voice_isolation model.""" + + gemini_2_5_flash: Optional[UsageModelsGemini2_5Flash] = FieldInfo(alias="gemini_2.5_flash", default=None) + """Usage data for the gemini_2.5_flash model.""" + + gen3a_turbo: Optional[UsageModelsGen3aTurbo] = None + """Usage data for the gen3a_turbo model.""" + + gen4_aleph: Optional[UsageModelsGen4Aleph] = None + """Usage data for the gen4_aleph model.""" + + gen4_image: Optional[UsageModelsGen4Image] = None + """Usage data for the gen4_image model.""" + + gen4_image_turbo: Optional[UsageModelsGen4ImageTurbo] = None + """Usage data for the gen4_image_turbo model.""" + + gen4_turbo: Optional[UsageModelsGen4Turbo] = None + """Usage data for the gen4_turbo model.""" + + upscale_v1: Optional[UsageModelsUpscaleV1] = None + """Usage data for the upscale_v1 model.""" + + veo3: Optional[UsageModelsVeo3] = None + """Usage data for the veo3 model.""" + + veo3_1: Optional[UsageModelsVeo3_1] = FieldInfo(alias="veo3.1", default=None) + """Usage data for the veo3.1 model.""" + + veo3_1_fast: Optional[UsageModelsVeo3_1Fast] = FieldInfo(alias="veo3.1_fast", default=None) + """Usage data for the veo3.1_fast model.""" + + class Usage(BaseModel): - models: Dict[str, UsageModels] + models: UsageModels + """Usage data for each model.""" class OrganizationRetrieveResponse(BaseModel): diff --git a/src/runwayml/types/organization_retrieve_usage_response.py b/src/runwayml/types/organization_retrieve_usage_response.py index fe20b8f..ad90712 100644 --- a/src/runwayml/types/organization_retrieve_usage_response.py +++ b/src/runwayml/types/organization_retrieve_usage_response.py @@ -13,28 +13,27 @@ class ResultUsedCredit(BaseModel): amount: int - """The number of credits spent on the model.""" + """The number of credits used for the model.""" model: Literal[ + "act_two", + "eleven_multilingual_sts_v2", + "eleven_multilingual_v2", + "eleven_text_to_sound_v2", + "eleven_voice_dubbing", + "eleven_voice_isolation", + "gemini_2.5_flash", "gen3a_turbo", - "gen4_turbo", + "gen4_aleph", "gen4_image", "gen4_image_turbo", + "gen4_turbo", "upscale_v1", - "act_two", - "gen4_aleph", "veo3", "veo3.1", "veo3.1_fast", - "gemini_2.5_flash", - "gemini_3_pro", - "eleven_multilingual_v2", - "eleven_text_to_sound_v2", - "eleven_voice_isolation", - "eleven_voice_dubbing", - "eleven_multilingual_sts_v2", ] - """The model that credits were spent on.""" + """The model whose usage resulted in the credit usage.""" class Result(BaseModel): @@ -51,23 +50,22 @@ class Result(BaseModel): class OrganizationRetrieveUsageResponse(BaseModel): models: List[ Literal[ + "act_two", + "eleven_multilingual_sts_v2", + "eleven_multilingual_v2", + "eleven_text_to_sound_v2", + "eleven_voice_dubbing", + "eleven_voice_isolation", + "gemini_2.5_flash", "gen3a_turbo", - "gen4_turbo", + "gen4_aleph", "gen4_image", "gen4_image_turbo", + "gen4_turbo", "upscale_v1", - "act_two", - "gen4_aleph", "veo3", "veo3.1", "veo3.1_fast", - "gemini_2.5_flash", - "gemini_3_pro", - "eleven_multilingual_v2", - "eleven_text_to_sound_v2", - "eleven_voice_isolation", - "eleven_voice_dubbing", - "eleven_multilingual_sts_v2", ] ] """The list of models with usage during the queried time range.""" diff --git a/src/runwayml/types/sound_effect_create_response.py b/src/runwayml/types/sound_effect_create_response.py index 0dc690b..604a06d 100644 --- a/src/runwayml/types/sound_effect_create_response.py +++ b/src/runwayml/types/sound_effect_create_response.py @@ -7,4 +7,3 @@ class SoundEffectCreateResponse(BaseModel): id: str - """The ID of the task that was created. Use this to retrieve the task later.""" diff --git a/src/runwayml/types/speech_to_speech_create_response.py b/src/runwayml/types/speech_to_speech_create_response.py index f682d47..03a93b3 100644 --- a/src/runwayml/types/speech_to_speech_create_response.py +++ b/src/runwayml/types/speech_to_speech_create_response.py @@ -7,4 +7,3 @@ class SpeechToSpeechCreateResponse(BaseModel): id: str - """The ID of the task that was created. Use this to retrieve the task later.""" diff --git a/src/runwayml/types/task_retrieve_response.py b/src/runwayml/types/task_retrieve_response.py index 9284246..47b9601 100644 --- a/src/runwayml/types/task_retrieve_response.py +++ b/src/runwayml/types/task_retrieve_response.py @@ -1,99 +1,59 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import List, Union, Optional +from typing import List, Optional from datetime import datetime -from typing_extensions import Literal, Annotated, TypeAlias +from typing_extensions import Literal from pydantic import Field as FieldInfo -from .._utils import PropertyInfo from .._models import BaseModel -__all__ = ["TaskRetrieveResponse", "Pending", "Throttled", "Cancelled", "Running", "Failed", "Succeeded"] +__all__ = ["TaskRetrieveResponse"] -class Pending(BaseModel): +class TaskRetrieveResponse(BaseModel): id: str """The ID of the task being returned.""" created_at: datetime = FieldInfo(alias="createdAt") """The timestamp that the task was submitted at.""" - status: Literal["PENDING"] - - -class Throttled(BaseModel): - id: str - """The ID of the task being returned.""" - - created_at: datetime = FieldInfo(alias="createdAt") - """The timestamp that the task was submitted at.""" - - status: Literal["THROTTLED"] - - -class Cancelled(BaseModel): - id: str - """The ID of the task being returned.""" - - created_at: datetime = FieldInfo(alias="createdAt") - """The timestamp that the task was submitted at.""" - - status: Literal["CANCELLED"] - - -class Running(BaseModel): - id: str - """The ID of the task being returned.""" - - created_at: datetime = FieldInfo(alias="createdAt") - """The timestamp that the task was submitted at.""" - - progress: float - - status: Literal["RUNNING"] - - -class Failed(BaseModel): - id: str - """The ID of the task being returned.""" - - created_at: datetime = FieldInfo(alias="createdAt") - """The timestamp that the task was submitted at.""" - - failure: str - """A human-friendly reason for the failure. - - We do not recommend returning this to users directly without adding context. + status: Literal["RUNNING", "SUCCEEDED", "FAILED", "PENDING", "CANCELLED", "THROTTLED"] + """ + - `PENDING` tasks have been enqueued and are waiting to run. + - `THROTTLED` tasks are waiting to be enqueued until other jobs have finished + running. + - `RUNNING` tasks are currently being processed. + - `SUCCEEDED` tasks have completed successfully. + - `FAILED` tasks have failed. + - `CANCELLED` tasks have been aborted. """ - status: Literal["FAILED"] + failure: Optional[str] = None + """ + If the status is `FAILED`, this will contain a human-friendly reason for the + failure. + """ failure_code: Optional[str] = FieldInfo(alias="failureCode", default=None) - """A machine-readable error code for the failure. - - See https://docs.dev.runwayml.com/errors/task-failures/ for more information. """ - - -class Succeeded(BaseModel): - id: str - """The ID of the task being returned.""" - - created_at: datetime = FieldInfo(alias="createdAt") - """The timestamp that the task was submitted at.""" - - output: List[str] - """An array of URLs that return the output of the task. - - These URLs will expire within 24-48 hours; fetch the task again to get fresh - URLs. It is expected that you download the assets at these URLs and store them - in your own storage system. + If the task has a status of `FAILED`, this contains a machine-readable error + code. This is a dot-separated string, with the leftmost segment being the most + generic and the rightmost segment being the most specific. For example, + `SAFETY.INPUT.TEXT` would indicate that the task failed due to a content + moderation error on the input text. """ - status: Literal["SUCCEEDED"] + output: Optional[List[str]] = None + """If the status is `SUCCEEDED`, this will contain an array of strings. + Each string will be a URL that returns an output from the task. URLs expire + within 24-48 hours; fetch the task again to get fresh URLs. It is expected that + you download the assets at these URLs and store them in your own storage system. + """ -TaskRetrieveResponse: TypeAlias = Annotated[ - Union[Pending, Throttled, Cancelled, Running, Failed, Succeeded], PropertyInfo(discriminator="status") -] + progress: Optional[float] = None + """ + If the task has a status of `RUNNING`, this will contain a floating point number + between 0 and 1 representing the progress of the generation. + """ diff --git a/src/runwayml/types/text_to_image_create_params.py b/src/runwayml/types/text_to_image_create_params.py index 1584fea..164616c 100644 --- a/src/runwayml/types/text_to_image_create_params.py +++ b/src/runwayml/types/text_to_image_create_params.py @@ -15,8 +15,6 @@ "Gen4Image", "Gen4ImageContentModeration", "Gen4ImageReferenceImage", - "Gemini3Pro", - "Gemini3ProReferenceImage", "Gemini2_5Flash", "Gemini2_5FlashReferenceImage", ] @@ -76,10 +74,6 @@ class Gen4ImageTurboReferenceImage(TypedDict, total=False): """A HTTPS URL.""" tag: str - """A tag to identify the reference image. - - This is used to reference the image in prompt text. - """ class Gen4ImageTurboContentModeration(TypedDict, total=False): @@ -152,82 +146,6 @@ class Gen4ImageReferenceImage(TypedDict, total=False): """A HTTPS URL.""" tag: str - """A tag to identify the reference image. - - This is used to reference the image in prompt text. - """ - - -class Gemini3Pro(TypedDict, total=False): - model: Required[Literal["gemini_3_pro"]] - - prompt_text: Required[Annotated[str, PropertyInfo(alias="promptText")]] - """A non-empty string up to 1000 characters (measured in UTF-16 code units). - - This should describe in detail what should appear in the output. - """ - - ratio: Required[ - Literal[ - "1344:768", - "768:1344", - "1024:1024", - "1184:864", - "864:1184", - "1536:672", - "832:1248", - "1248:832", - "896:1152", - "1152:896", - "2048:2048", - "1696:2528", - "2528:1696", - "1792:2400", - "2400:1792", - "1856:2304", - "2304:1856", - "1536:2752", - "2752:1536", - "3168:1344", - "4096:4096", - "3392:5056", - "5056:3392", - "3584:4800", - "4800:3584", - "3712:4608", - "4608:3712", - "3072:5504", - "5504:3072", - "6336:2688", - ] - ] - """The resolution of the output image.""" - - reference_images: Annotated[Iterable[Gemini3ProReferenceImage], PropertyInfo(alias="referenceImages")] - """ - An array of up to 14 images to be used as references for the generated image - output. Up to five of those images can pass `subject: "human"` to maintain - character consistency, and up to nine of those images can pass - `subject: "object"` with high-fidelity images of objects to include in the - output. - """ - - -class Gemini3ProReferenceImage(TypedDict, total=False): - subject: Required[Literal["object", "human"]] - """ - Whether this is a reference of a human subject (for character consistency) or an - object that appears in the output. - """ - - uri: Required[str] - """A HTTPS URL.""" - - tag: str - """A tag to identify the reference image. - - This is used to reference the image in prompt text. - """ class Gemini2_5Flash(TypedDict, total=False): @@ -267,10 +185,6 @@ class Gemini2_5FlashReferenceImage(TypedDict, total=False): """A HTTPS URL.""" tag: str - """A tag to identify the reference image. - - This is used to reference the image in prompt text. - """ -TextToImageCreateParams: TypeAlias = Union[Gen4ImageTurbo, Gen4Image, Gemini3Pro, Gemini2_5Flash] +TextToImageCreateParams: TypeAlias = Union[Gen4ImageTurbo, Gen4Image, Gemini2_5Flash] diff --git a/src/runwayml/types/text_to_image_create_response.py b/src/runwayml/types/text_to_image_create_response.py index 353b565..79f659e 100644 --- a/src/runwayml/types/text_to_image_create_response.py +++ b/src/runwayml/types/text_to_image_create_response.py @@ -7,4 +7,3 @@ class TextToImageCreateResponse(BaseModel): id: str - """The ID of the task that was created. Use this to retrieve the task later.""" diff --git a/src/runwayml/types/text_to_speech_create_response.py b/src/runwayml/types/text_to_speech_create_response.py index 3a97053..f7d45a6 100644 --- a/src/runwayml/types/text_to_speech_create_response.py +++ b/src/runwayml/types/text_to_speech_create_response.py @@ -7,4 +7,3 @@ class TextToSpeechCreateResponse(BaseModel): id: str - """The ID of the task that was created. Use this to retrieve the task later.""" diff --git a/src/runwayml/types/text_to_video_create_response.py b/src/runwayml/types/text_to_video_create_response.py index 61b1718..d0c8bdf 100644 --- a/src/runwayml/types/text_to_video_create_response.py +++ b/src/runwayml/types/text_to_video_create_response.py @@ -7,4 +7,3 @@ class TextToVideoCreateResponse(BaseModel): id: str - """The ID of the task that was created. Use this to retrieve the task later.""" diff --git a/src/runwayml/types/video_to_video_create_response.py b/src/runwayml/types/video_to_video_create_response.py index ad85b7b..6ab01a7 100644 --- a/src/runwayml/types/video_to_video_create_response.py +++ b/src/runwayml/types/video_to_video_create_response.py @@ -7,4 +7,3 @@ class VideoToVideoCreateResponse(BaseModel): id: str - """The ID of the task that was created. Use this to retrieve the task later.""" diff --git a/src/runwayml/types/video_upscale_create_response.py b/src/runwayml/types/video_upscale_create_response.py index 0cf0a9e..73a0bd1 100644 --- a/src/runwayml/types/video_upscale_create_response.py +++ b/src/runwayml/types/video_upscale_create_response.py @@ -7,4 +7,3 @@ class VideoUpscaleCreateResponse(BaseModel): id: str - """The ID of the task that was created. Use this to retrieve the task later.""" diff --git a/src/runwayml/types/voice_dubbing_create_response.py b/src/runwayml/types/voice_dubbing_create_response.py index 1c8c4e5..3f105d6 100644 --- a/src/runwayml/types/voice_dubbing_create_response.py +++ b/src/runwayml/types/voice_dubbing_create_response.py @@ -7,4 +7,3 @@ class VoiceDubbingCreateResponse(BaseModel): id: str - """The ID of the task that was created. Use this to retrieve the task later.""" diff --git a/src/runwayml/types/voice_isolation_create_response.py b/src/runwayml/types/voice_isolation_create_response.py index ff24226..e1eed57 100644 --- a/src/runwayml/types/voice_isolation_create_response.py +++ b/src/runwayml/types/voice_isolation_create_response.py @@ -7,4 +7,3 @@ class VoiceIsolationCreateResponse(BaseModel): id: str - """The ID of the task that was created. Use this to retrieve the task later.""" diff --git a/tests/api_resources/test_text_to_image.py b/tests/api_resources/test_text_to_image.py index b2a2ba1..95ddd30 100644 --- a/tests/api_resources/test_text_to_image.py +++ b/tests/api_resources/test_text_to_image.py @@ -130,59 +130,6 @@ def test_streaming_response_create_overload_2(self, client: RunwayML) -> None: @parametrize def test_method_create_overload_3(self, client: RunwayML) -> None: - text_to_image = client.text_to_image.create( - model="gemini_3_pro", - prompt_text="x", - ratio="1344:768", - ) - assert_matches_type(TextToImageCreateResponse, text_to_image, path=["response"]) - - @parametrize - def test_method_create_with_all_params_overload_3(self, client: RunwayML) -> None: - text_to_image = client.text_to_image.create( - model="gemini_3_pro", - prompt_text="x", - ratio="1344:768", - reference_images=[ - { - "subject": "object", - "uri": "https://example.com/file", - "tag": "tag", - } - ], - ) - assert_matches_type(TextToImageCreateResponse, text_to_image, path=["response"]) - - @parametrize - def test_raw_response_create_overload_3(self, client: RunwayML) -> None: - response = client.text_to_image.with_raw_response.create( - model="gemini_3_pro", - prompt_text="x", - ratio="1344:768", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - text_to_image = response.parse() - assert_matches_type(TextToImageCreateResponse, text_to_image, path=["response"]) - - @parametrize - def test_streaming_response_create_overload_3(self, client: RunwayML) -> None: - with client.text_to_image.with_streaming_response.create( - model="gemini_3_pro", - prompt_text="x", - ratio="1344:768", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - text_to_image = response.parse() - assert_matches_type(TextToImageCreateResponse, text_to_image, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @parametrize - def test_method_create_overload_4(self, client: RunwayML) -> None: text_to_image = client.text_to_image.create( model="gemini_2.5_flash", prompt_text="x", @@ -191,7 +138,7 @@ def test_method_create_overload_4(self, client: RunwayML) -> None: assert_matches_type(TextToImageCreateResponse, text_to_image, path=["response"]) @parametrize - def test_method_create_with_all_params_overload_4(self, client: RunwayML) -> None: + def test_method_create_with_all_params_overload_3(self, client: RunwayML) -> None: text_to_image = client.text_to_image.create( model="gemini_2.5_flash", prompt_text="x", @@ -206,7 +153,7 @@ def test_method_create_with_all_params_overload_4(self, client: RunwayML) -> Non assert_matches_type(TextToImageCreateResponse, text_to_image, path=["response"]) @parametrize - def test_raw_response_create_overload_4(self, client: RunwayML) -> None: + def test_raw_response_create_overload_3(self, client: RunwayML) -> None: response = client.text_to_image.with_raw_response.create( model="gemini_2.5_flash", prompt_text="x", @@ -219,7 +166,7 @@ def test_raw_response_create_overload_4(self, client: RunwayML) -> None: assert_matches_type(TextToImageCreateResponse, text_to_image, path=["response"]) @parametrize - def test_streaming_response_create_overload_4(self, client: RunwayML) -> None: + def test_streaming_response_create_overload_3(self, client: RunwayML) -> None: with client.text_to_image.with_streaming_response.create( model="gemini_2.5_flash", prompt_text="x", @@ -352,59 +299,6 @@ async def test_streaming_response_create_overload_2(self, async_client: AsyncRun @parametrize async def test_method_create_overload_3(self, async_client: AsyncRunwayML) -> None: - text_to_image = await async_client.text_to_image.create( - model="gemini_3_pro", - prompt_text="x", - ratio="1344:768", - ) - assert_matches_type(TextToImageCreateResponse, text_to_image, path=["response"]) - - @parametrize - async def test_method_create_with_all_params_overload_3(self, async_client: AsyncRunwayML) -> None: - text_to_image = await async_client.text_to_image.create( - model="gemini_3_pro", - prompt_text="x", - ratio="1344:768", - reference_images=[ - { - "subject": "object", - "uri": "https://example.com/file", - "tag": "tag", - } - ], - ) - assert_matches_type(TextToImageCreateResponse, text_to_image, path=["response"]) - - @parametrize - async def test_raw_response_create_overload_3(self, async_client: AsyncRunwayML) -> None: - response = await async_client.text_to_image.with_raw_response.create( - model="gemini_3_pro", - prompt_text="x", - ratio="1344:768", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - text_to_image = await response.parse() - assert_matches_type(TextToImageCreateResponse, text_to_image, path=["response"]) - - @parametrize - async def test_streaming_response_create_overload_3(self, async_client: AsyncRunwayML) -> None: - async with async_client.text_to_image.with_streaming_response.create( - model="gemini_3_pro", - prompt_text="x", - ratio="1344:768", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - text_to_image = await response.parse() - assert_matches_type(TextToImageCreateResponse, text_to_image, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @parametrize - async def test_method_create_overload_4(self, async_client: AsyncRunwayML) -> None: text_to_image = await async_client.text_to_image.create( model="gemini_2.5_flash", prompt_text="x", @@ -413,7 +307,7 @@ async def test_method_create_overload_4(self, async_client: AsyncRunwayML) -> No assert_matches_type(TextToImageCreateResponse, text_to_image, path=["response"]) @parametrize - async def test_method_create_with_all_params_overload_4(self, async_client: AsyncRunwayML) -> None: + async def test_method_create_with_all_params_overload_3(self, async_client: AsyncRunwayML) -> None: text_to_image = await async_client.text_to_image.create( model="gemini_2.5_flash", prompt_text="x", @@ -428,7 +322,7 @@ async def test_method_create_with_all_params_overload_4(self, async_client: Asyn assert_matches_type(TextToImageCreateResponse, text_to_image, path=["response"]) @parametrize - async def test_raw_response_create_overload_4(self, async_client: AsyncRunwayML) -> None: + async def test_raw_response_create_overload_3(self, async_client: AsyncRunwayML) -> None: response = await async_client.text_to_image.with_raw_response.create( model="gemini_2.5_flash", prompt_text="x", @@ -441,7 +335,7 @@ async def test_raw_response_create_overload_4(self, async_client: AsyncRunwayML) assert_matches_type(TextToImageCreateResponse, text_to_image, path=["response"]) @parametrize - async def test_streaming_response_create_overload_4(self, async_client: AsyncRunwayML) -> None: + async def test_streaming_response_create_overload_3(self, async_client: AsyncRunwayML) -> None: async with async_client.text_to_image.with_streaming_response.create( model="gemini_2.5_flash", prompt_text="x", diff --git a/tests/api_resources/test_voice_dubbing.py b/tests/api_resources/test_voice_dubbing.py index aab73a9..ac23d9f 100644 --- a/tests/api_resources/test_voice_dubbing.py +++ b/tests/api_resources/test_voice_dubbing.py @@ -34,7 +34,7 @@ def test_method_create_with_all_params(self, client: RunwayML) -> None: target_lang="en", disable_voice_cloning=True, drop_background_audio=True, - num_speakers=1, + num_speakers=9007199254740991, ) assert_matches_type(VoiceDubbingCreateResponse, voice_dubbing, path=["response"]) @@ -89,7 +89,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncRunwayML) target_lang="en", disable_voice_cloning=True, drop_background_audio=True, - num_speakers=1, + num_speakers=9007199254740991, ) assert_matches_type(VoiceDubbingCreateResponse, voice_dubbing, path=["response"]) From e9d2114b819a6a641e716c0823ba1f182c3b5400 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 4 Dec 2025 00:31:54 +0000 Subject: [PATCH 09/11] feat(api): Autogen spec updates --- .stats.yml | 4 +- src/runwayml/lib/polling.py | 95 ++++- src/runwayml/resources/tasks.py | 24 +- src/runwayml/resources/text_to_image.py | 64 ++++ .../character_performance_create_response.py | 1 + .../types/image_to_video_create_response.py | 1 + .../types/organization_retrieve_response.py | 346 +----------------- .../organization_retrieve_usage_response.py | 40 +- .../types/sound_effect_create_response.py | 1 + .../types/speech_to_speech_create_response.py | 1 + src/runwayml/types/task_retrieve_response.py | 108 ++++-- .../types/text_to_image_create_params.py | 12 + .../types/text_to_image_create_response.py | 1 + .../types/text_to_speech_create_response.py | 1 + .../types/text_to_video_create_response.py | 1 + .../types/video_to_video_create_response.py | 1 + .../types/video_upscale_create_response.py | 1 + .../types/voice_dubbing_create_response.py | 1 + .../types/voice_isolation_create_response.py | 1 + tests/api_resources/test_text_to_image.py | 16 +- tests/api_resources/test_voice_dubbing.py | 4 +- 21 files changed, 293 insertions(+), 431 deletions(-) diff --git a/.stats.yml b/.stats.yml index f7f71cf..d0d8fc0 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 15 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/runwayml%2Frunwayml-c2a88516fa0c20ca73f742f8d876f5e773747b4f6903508b1824c0939b313b82.yml -openapi_spec_hash: 660d0eec8f3940727f541dd05121627b +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/runwayml%2Frunwayml-6dab1bdab5d3264fa80bccb641a17fbf0944197c00c08b826fbd17e29ba250a1.yml +openapi_spec_hash: 846f29a2fd9ceb6867c2343494e1c319 config_hash: b98eed33f1bba05e3c2a3e20d85d582a diff --git a/src/runwayml/lib/polling.py b/src/runwayml/lib/polling.py index 5c40a6e..d91c537 100644 --- a/src/runwayml/lib/polling.py +++ b/src/runwayml/lib/polling.py @@ -1,12 +1,22 @@ import time import random -from typing import TYPE_CHECKING, Type, Union, TypeVar, cast -from typing_extensions import ParamSpec +from typing import TYPE_CHECKING, Type, Union, TypeVar, Callable, Annotated, Coroutine, cast +from typing_extensions import ParamSpec, TypeAlias import anyio +from runwayml._utils import PropertyInfo + from .._models import BaseModel -from ..types.task_retrieve_response import TaskRetrieveResponse +from ..types.task_retrieve_response import ( + Failed, + Pending, + Running, + Cancelled, + Succeeded, + Throttled, + TaskRetrieveResponse, +) if TYPE_CHECKING: from .._client import RunwayML, AsyncRunwayML @@ -40,10 +50,6 @@ class NewTaskCreatedResponse(AwaitableTaskResponseMixin, BaseModel): id: str -class AwaitableTaskRetrieveResponse(AwaitableTaskResponseMixin, TaskRetrieveResponse): - pass - - class AsyncAwaitableTaskResponseMixin: async def wait_for_task_output(self, timeout: Union[float, None] = 60 * 10) -> TaskRetrieveResponse: # type: ignore[empty-body] """ @@ -67,10 +73,6 @@ class AsyncNewTaskCreatedResponse(AsyncAwaitableTaskResponseMixin, BaseModel): id: str -class AsyncAwaitableTaskRetrieveResponse(AsyncAwaitableTaskResponseMixin, TaskRetrieveResponse): - pass - - def create_waitable_resource(base_class: Type[T], client: "RunwayML") -> Type[NewTaskCreatedResponse]: class WithClient(base_class): # type: ignore[valid-type,misc] id: str @@ -125,3 +127,74 @@ class TaskTimeoutError(Exception): def __init__(self, task_details: TaskRetrieveResponse): self.task_details = task_details super().__init__(f"Task timed out") + + + +class AwaitablePending(AwaitableTaskResponseMixin, Pending): ... +class AwaitableThrottled(AwaitableTaskResponseMixin, Throttled): ... +class AwaitableCancelled(AwaitableTaskResponseMixin, Cancelled): ... +class AwaitableRunning(AwaitableTaskResponseMixin, Running): ... +class AwaitableFailed(AwaitableTaskResponseMixin, Failed): ... +class AwaitableSucceeded(AwaitableTaskResponseMixin, Succeeded): ... + +AwaitableTaskRetrieveResponse: TypeAlias = Annotated[ + Union[AwaitablePending, AwaitableThrottled, AwaitableCancelled, AwaitableRunning, AwaitableFailed, AwaitableSucceeded], + PropertyInfo(discriminator="status") +] + +class AsyncAwaitablePending(AsyncAwaitableTaskResponseMixin, Pending): ... +class AsyncAwaitableThrottled(AsyncAwaitableTaskResponseMixin, Throttled): ... +class AsyncAwaitableCancelled(AsyncAwaitableTaskResponseMixin, Cancelled): ... +class AsyncAwaitableRunning(AsyncAwaitableTaskResponseMixin, Running): ... +class AsyncAwaitableFailed(AsyncAwaitableTaskResponseMixin, Failed): ... +class AsyncAwaitableSucceeded(AsyncAwaitableTaskResponseMixin, Succeeded): ... + +AsyncAwaitableTaskRetrieveResponse: TypeAlias = Annotated[ + Union[AsyncAwaitablePending, AsyncAwaitableThrottled, AsyncAwaitableCancelled, AsyncAwaitableRunning, AsyncAwaitableFailed, AsyncAwaitableSucceeded], + PropertyInfo(discriminator="status") +] + +def _make_sync_wait_for_task_output(client: "RunwayML") -> Callable[["AwaitableTaskResponseMixin", Union[float, None]], TaskRetrieveResponse]: + """Create a wait_for_task_output method bound to the given client.""" + def wait_for_task_output(self: "AwaitableTaskResponseMixin", timeout: Union[float, None] = 60 * 10) -> TaskRetrieveResponse: + start_time = time.time() + while True: + time.sleep(POLL_TIME + random.random() * POLL_JITTER - POLL_JITTER / 2) + task_details = client.tasks.retrieve(self.id) # type: ignore[attr-defined] + if task_details.status == "SUCCEEDED": + return task_details + if task_details.status == "FAILED": + raise TaskFailedError(task_details) + if timeout is not None and time.time() - start_time > timeout: + raise TaskTimeoutError(task_details) + return wait_for_task_output + + +def inject_sync_wait_method(client: "RunwayML", response: T) -> T: + """Inject the wait_for_task_output method onto the response instance.""" + import types + response.wait_for_task_output = types.MethodType(_make_sync_wait_for_task_output(client), response) # type: ignore[attr-defined] + return response + + +def _make_async_wait_for_task_output(client: "AsyncRunwayML") -> Callable[["AsyncAwaitableTaskResponseMixin", Union[float, None]], Coroutine[None, None, TaskRetrieveResponse]]: + """Create an async wait_for_task_output method bound to the given client.""" + async def wait_for_task_output(self: "AsyncAwaitableTaskResponseMixin", timeout: Union[float, None] = 60 * 10) -> TaskRetrieveResponse: + start_time = anyio.current_time() + while True: + await anyio.sleep(POLL_TIME + random.random() * POLL_JITTER - POLL_JITTER / 2) + task_details = await client.tasks.retrieve(self.id) # type: ignore[attr-defined] + if task_details.status == "SUCCEEDED": + return task_details + if task_details.status == "FAILED" or task_details.status == "CANCELLED": + raise TaskFailedError(task_details) + if timeout is not None and anyio.current_time() - start_time > timeout: + raise TaskTimeoutError(task_details) + return wait_for_task_output + + +def inject_async_wait_method(client: "AsyncRunwayML", response: T) -> T: + """Inject the async wait_for_task_output method onto the response instance.""" + import types + response.wait_for_task_output = types.MethodType(_make_async_wait_for_task_output(client), response) # type: ignore[attr-defined] + return response diff --git a/src/runwayml/resources/tasks.py b/src/runwayml/resources/tasks.py index 3cc981e..3803e98 100644 --- a/src/runwayml/resources/tasks.py +++ b/src/runwayml/resources/tasks.py @@ -2,7 +2,7 @@ from __future__ import annotations -from typing import cast +from typing import Any, cast import httpx @@ -18,11 +18,10 @@ from ..lib.polling import ( AwaitableTaskRetrieveResponse, AsyncAwaitableTaskRetrieveResponse, - create_waitable_resource, - create_async_waitable_resource, + inject_sync_wait_method, + inject_async_wait_method, ) from .._base_client import make_request_options -from ..types.task_retrieve_response import TaskRetrieveResponse __all__ = ["TasksResource", "AsyncTasksResource"] @@ -74,15 +73,14 @@ def retrieve( """ if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") - return self._get( + response = self._get( f"/v1/tasks/{id}", options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), - cast_to=cast( - type[AwaitableTaskRetrieveResponse], create_waitable_resource(TaskRetrieveResponse, self._client) - ), + cast_to=cast(Any, AwaitableTaskRetrieveResponse), # Union types cannot be passed in as arguments in the type system ) + return cast(AwaitableTaskRetrieveResponse, inject_sync_wait_method(self._client, response)) def delete( self, @@ -171,16 +169,14 @@ async def retrieve( """ if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") - return await self._get( + response = await self._get( f"/v1/tasks/{id}", options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), - cast_to=cast( - type[AsyncAwaitableTaskRetrieveResponse], - create_async_waitable_resource(TaskRetrieveResponse, self._client), - ), + cast_to=cast(Any, AsyncAwaitableTaskRetrieveResponse), # Union types cannot be passed in as arguments in the type system ) + return cast(AsyncAwaitableTaskRetrieveResponse, inject_async_wait_method(self._client, response)) async def delete( self, @@ -267,4 +263,4 @@ def __init__(self, tasks: AsyncTasksResource) -> None: ) self.delete = async_to_streamed_response_wrapper( tasks.delete, - ) \ No newline at end of file + ) diff --git a/src/runwayml/resources/text_to_image.py b/src/runwayml/resources/text_to_image.py index 9206ae8..ff9a847 100644 --- a/src/runwayml/resources/text_to_image.py +++ b/src/runwayml/resources/text_to_image.py @@ -246,6 +246,38 @@ def create( "720:960", "1680:720", ] + | Literal[ + "1344:768", + "768:1344", + "1024:1024", + "1184:864", + "864:1184", + "1536:672", + "832:1248", + "1248:832", + "896:1152", + "1152:896", + "2048:2048", + "1696:2528", + "2528:1696", + "1792:2400", + "2400:1792", + "1856:2304", + "2304:1856", + "1536:2752", + "2752:1536", + "3168:1344", + "4096:4096", + "3392:5056", + "5056:3392", + "3584:4800", + "4800:3584", + "3712:4608", + "4608:3712", + "3072:5504", + "5504:3072", + "6336:2688", + ] | Literal[ "1344:768", "768:1344", @@ -509,6 +541,38 @@ async def create( "720:960", "1680:720", ] + | Literal[ + "1344:768", + "768:1344", + "1024:1024", + "1184:864", + "864:1184", + "1536:672", + "832:1248", + "1248:832", + "896:1152", + "1152:896", + "2048:2048", + "1696:2528", + "2528:1696", + "1792:2400", + "2400:1792", + "1856:2304", + "2304:1856", + "1536:2752", + "2752:1536", + "3168:1344", + "4096:4096", + "3392:5056", + "5056:3392", + "3584:4800", + "4800:3584", + "3712:4608", + "4608:3712", + "3072:5504", + "5504:3072", + "6336:2688", + ] | Literal[ "1344:768", "768:1344", diff --git a/src/runwayml/types/character_performance_create_response.py b/src/runwayml/types/character_performance_create_response.py index 61b4fff..48ab1c5 100644 --- a/src/runwayml/types/character_performance_create_response.py +++ b/src/runwayml/types/character_performance_create_response.py @@ -7,3 +7,4 @@ class CharacterPerformanceCreateResponse(BaseModel): id: str + """The ID of the task that was created. Use this to retrieve the task later.""" diff --git a/src/runwayml/types/image_to_video_create_response.py b/src/runwayml/types/image_to_video_create_response.py index 5c381da..8b03891 100644 --- a/src/runwayml/types/image_to_video_create_response.py +++ b/src/runwayml/types/image_to_video_create_response.py @@ -7,3 +7,4 @@ class ImageToVideoCreateResponse(BaseModel): id: str + """The ID of the task that was created. Use this to retrieve the task later.""" diff --git a/src/runwayml/types/organization_retrieve_response.py b/src/runwayml/types/organization_retrieve_response.py index 3621c54..f3a56ca 100644 --- a/src/runwayml/types/organization_retrieve_response.py +++ b/src/runwayml/types/organization_retrieve_response.py @@ -1,173 +1,15 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import Optional +from typing import Dict from pydantic import Field as FieldInfo from .._models import BaseModel -__all__ = [ - "OrganizationRetrieveResponse", - "Tier", - "TierModels", - "TierModelsActTwo", - "TierModelsElevenMultilingualStsV2", - "TierModelsElevenMultilingualV2", - "TierModelsElevenTextToSoundV2", - "TierModelsElevenVoiceDubbing", - "TierModelsElevenVoiceIsolation", - "TierModelsGemini2_5Flash", - "TierModelsGen3aTurbo", - "TierModelsGen4Aleph", - "TierModelsGen4Image", - "TierModelsGen4ImageTurbo", - "TierModelsGen4Turbo", - "TierModelsUpscaleV1", - "TierModelsVeo3", - "TierModelsVeo3_1", - "TierModelsVeo3_1Fast", - "Usage", - "UsageModels", - "UsageModelsActTwo", - "UsageModelsElevenMultilingualStsV2", - "UsageModelsElevenMultilingualV2", - "UsageModelsElevenTextToSoundV2", - "UsageModelsElevenVoiceDubbing", - "UsageModelsElevenVoiceIsolation", - "UsageModelsGemini2_5Flash", - "UsageModelsGen3aTurbo", - "UsageModelsGen4Aleph", - "UsageModelsGen4Image", - "UsageModelsGen4ImageTurbo", - "UsageModelsGen4Turbo", - "UsageModelsUpscaleV1", - "UsageModelsVeo3", - "UsageModelsVeo3_1", - "UsageModelsVeo3_1Fast", -] +__all__ = ["OrganizationRetrieveResponse", "Tier", "TierModels", "Usage", "UsageModels"] -class TierModelsActTwo(BaseModel): - max_concurrent_generations: int = FieldInfo(alias="maxConcurrentGenerations") - """The maximum number of generations that can be run concurrently for this model.""" - - max_daily_generations: int = FieldInfo(alias="maxDailyGenerations") - """The maximum number of generations that can be created each day for this model.""" - - -class TierModelsElevenMultilingualStsV2(BaseModel): - max_concurrent_generations: int = FieldInfo(alias="maxConcurrentGenerations") - """The maximum number of generations that can be run concurrently for this model.""" - - max_daily_generations: int = FieldInfo(alias="maxDailyGenerations") - """The maximum number of generations that can be created each day for this model.""" - - -class TierModelsElevenMultilingualV2(BaseModel): - max_concurrent_generations: int = FieldInfo(alias="maxConcurrentGenerations") - """The maximum number of generations that can be run concurrently for this model.""" - - max_daily_generations: int = FieldInfo(alias="maxDailyGenerations") - """The maximum number of generations that can be created each day for this model.""" - - -class TierModelsElevenTextToSoundV2(BaseModel): - max_concurrent_generations: int = FieldInfo(alias="maxConcurrentGenerations") - """The maximum number of generations that can be run concurrently for this model.""" - - max_daily_generations: int = FieldInfo(alias="maxDailyGenerations") - """The maximum number of generations that can be created each day for this model.""" - - -class TierModelsElevenVoiceDubbing(BaseModel): - max_concurrent_generations: int = FieldInfo(alias="maxConcurrentGenerations") - """The maximum number of generations that can be run concurrently for this model.""" - - max_daily_generations: int = FieldInfo(alias="maxDailyGenerations") - """The maximum number of generations that can be created each day for this model.""" - - -class TierModelsElevenVoiceIsolation(BaseModel): - max_concurrent_generations: int = FieldInfo(alias="maxConcurrentGenerations") - """The maximum number of generations that can be run concurrently for this model.""" - - max_daily_generations: int = FieldInfo(alias="maxDailyGenerations") - """The maximum number of generations that can be created each day for this model.""" - - -class TierModelsGemini2_5Flash(BaseModel): - max_concurrent_generations: int = FieldInfo(alias="maxConcurrentGenerations") - """The maximum number of generations that can be run concurrently for this model.""" - - max_daily_generations: int = FieldInfo(alias="maxDailyGenerations") - """The maximum number of generations that can be created each day for this model.""" - - -class TierModelsGen3aTurbo(BaseModel): - max_concurrent_generations: int = FieldInfo(alias="maxConcurrentGenerations") - """The maximum number of generations that can be run concurrently for this model.""" - - max_daily_generations: int = FieldInfo(alias="maxDailyGenerations") - """The maximum number of generations that can be created each day for this model.""" - - -class TierModelsGen4Aleph(BaseModel): - max_concurrent_generations: int = FieldInfo(alias="maxConcurrentGenerations") - """The maximum number of generations that can be run concurrently for this model.""" - - max_daily_generations: int = FieldInfo(alias="maxDailyGenerations") - """The maximum number of generations that can be created each day for this model.""" - - -class TierModelsGen4Image(BaseModel): - max_concurrent_generations: int = FieldInfo(alias="maxConcurrentGenerations") - """The maximum number of generations that can be run concurrently for this model.""" - - max_daily_generations: int = FieldInfo(alias="maxDailyGenerations") - """The maximum number of generations that can be created each day for this model.""" - - -class TierModelsGen4ImageTurbo(BaseModel): - max_concurrent_generations: int = FieldInfo(alias="maxConcurrentGenerations") - """The maximum number of generations that can be run concurrently for this model.""" - - max_daily_generations: int = FieldInfo(alias="maxDailyGenerations") - """The maximum number of generations that can be created each day for this model.""" - - -class TierModelsGen4Turbo(BaseModel): - max_concurrent_generations: int = FieldInfo(alias="maxConcurrentGenerations") - """The maximum number of generations that can be run concurrently for this model.""" - - max_daily_generations: int = FieldInfo(alias="maxDailyGenerations") - """The maximum number of generations that can be created each day for this model.""" - - -class TierModelsUpscaleV1(BaseModel): - max_concurrent_generations: int = FieldInfo(alias="maxConcurrentGenerations") - """The maximum number of generations that can be run concurrently for this model.""" - - max_daily_generations: int = FieldInfo(alias="maxDailyGenerations") - """The maximum number of generations that can be created each day for this model.""" - - -class TierModelsVeo3(BaseModel): - max_concurrent_generations: int = FieldInfo(alias="maxConcurrentGenerations") - """The maximum number of generations that can be run concurrently for this model.""" - - max_daily_generations: int = FieldInfo(alias="maxDailyGenerations") - """The maximum number of generations that can be created each day for this model.""" - - -class TierModelsVeo3_1(BaseModel): - max_concurrent_generations: int = FieldInfo(alias="maxConcurrentGenerations") - """The maximum number of generations that can be run concurrently for this model.""" - - max_daily_generations: int = FieldInfo(alias="maxDailyGenerations") - """The maximum number of generations that can be created each day for this model.""" - - -class TierModelsVeo3_1Fast(BaseModel): +class TierModels(BaseModel): max_concurrent_generations: int = FieldInfo(alias="maxConcurrentGenerations") """The maximum number of generations that can be run concurrently for this model.""" @@ -175,197 +17,21 @@ class TierModelsVeo3_1Fast(BaseModel): """The maximum number of generations that can be created each day for this model.""" -class TierModels(BaseModel): - act_two: Optional[TierModelsActTwo] = None - """Limits associated with the act_two model.""" - - eleven_multilingual_sts_v2: Optional[TierModelsElevenMultilingualStsV2] = None - """Limits associated with the eleven_multilingual_sts_v2 model.""" - - eleven_multilingual_v2: Optional[TierModelsElevenMultilingualV2] = None - """Limits associated with the eleven_multilingual_v2 model.""" - - eleven_text_to_sound_v2: Optional[TierModelsElevenTextToSoundV2] = None - """Limits associated with the eleven_text_to_sound_v2 model.""" - - eleven_voice_dubbing: Optional[TierModelsElevenVoiceDubbing] = None - """Limits associated with the eleven_voice_dubbing model.""" - - eleven_voice_isolation: Optional[TierModelsElevenVoiceIsolation] = None - """Limits associated with the eleven_voice_isolation model.""" - - gemini_2_5_flash: Optional[TierModelsGemini2_5Flash] = FieldInfo(alias="gemini_2.5_flash", default=None) - """Limits associated with the gemini_2.5_flash model.""" - - gen3a_turbo: Optional[TierModelsGen3aTurbo] = None - """Limits associated with the gen3a_turbo model.""" - - gen4_aleph: Optional[TierModelsGen4Aleph] = None - """Limits associated with the gen4_aleph model.""" - - gen4_image: Optional[TierModelsGen4Image] = None - """Limits associated with the gen4_image model.""" - - gen4_image_turbo: Optional[TierModelsGen4ImageTurbo] = None - """Limits associated with the gen4_image_turbo model.""" - - gen4_turbo: Optional[TierModelsGen4Turbo] = None - """Limits associated with the gen4_turbo model.""" - - upscale_v1: Optional[TierModelsUpscaleV1] = None - """Limits associated with the upscale_v1 model.""" - - veo3: Optional[TierModelsVeo3] = None - """Limits associated with the veo3 model.""" - - veo3_1: Optional[TierModelsVeo3_1] = FieldInfo(alias="veo3.1", default=None) - """Limits associated with the veo3.1 model.""" - - veo3_1_fast: Optional[TierModelsVeo3_1Fast] = FieldInfo(alias="veo3.1_fast", default=None) - """Limits associated with the veo3.1_fast model.""" - - class Tier(BaseModel): max_monthly_credit_spend: int = FieldInfo(alias="maxMonthlyCreditSpend") """The maximum number of credits that can be purchased in a month.""" - models: TierModels + models: Dict[str, TierModels] """An object containing model-specific limits. Each key represents a model.""" -class UsageModelsActTwo(BaseModel): - daily_generations: int = FieldInfo(alias="dailyGenerations") - """The number of generations that have been run for this model in the past day.""" - - -class UsageModelsElevenMultilingualStsV2(BaseModel): - daily_generations: int = FieldInfo(alias="dailyGenerations") - """The number of generations that have been run for this model in the past day.""" - - -class UsageModelsElevenMultilingualV2(BaseModel): - daily_generations: int = FieldInfo(alias="dailyGenerations") - """The number of generations that have been run for this model in the past day.""" - - -class UsageModelsElevenTextToSoundV2(BaseModel): - daily_generations: int = FieldInfo(alias="dailyGenerations") - """The number of generations that have been run for this model in the past day.""" - - -class UsageModelsElevenVoiceDubbing(BaseModel): - daily_generations: int = FieldInfo(alias="dailyGenerations") - """The number of generations that have been run for this model in the past day.""" - - -class UsageModelsElevenVoiceIsolation(BaseModel): - daily_generations: int = FieldInfo(alias="dailyGenerations") - """The number of generations that have been run for this model in the past day.""" - - -class UsageModelsGemini2_5Flash(BaseModel): - daily_generations: int = FieldInfo(alias="dailyGenerations") - """The number of generations that have been run for this model in the past day.""" - - -class UsageModelsGen3aTurbo(BaseModel): - daily_generations: int = FieldInfo(alias="dailyGenerations") - """The number of generations that have been run for this model in the past day.""" - - -class UsageModelsGen4Aleph(BaseModel): - daily_generations: int = FieldInfo(alias="dailyGenerations") - """The number of generations that have been run for this model in the past day.""" - - -class UsageModelsGen4Image(BaseModel): - daily_generations: int = FieldInfo(alias="dailyGenerations") - """The number of generations that have been run for this model in the past day.""" - - -class UsageModelsGen4ImageTurbo(BaseModel): - daily_generations: int = FieldInfo(alias="dailyGenerations") - """The number of generations that have been run for this model in the past day.""" - - -class UsageModelsGen4Turbo(BaseModel): - daily_generations: int = FieldInfo(alias="dailyGenerations") - """The number of generations that have been run for this model in the past day.""" - - -class UsageModelsUpscaleV1(BaseModel): - daily_generations: int = FieldInfo(alias="dailyGenerations") - """The number of generations that have been run for this model in the past day.""" - - -class UsageModelsVeo3(BaseModel): - daily_generations: int = FieldInfo(alias="dailyGenerations") - """The number of generations that have been run for this model in the past day.""" - - -class UsageModelsVeo3_1(BaseModel): - daily_generations: int = FieldInfo(alias="dailyGenerations") - """The number of generations that have been run for this model in the past day.""" - - -class UsageModelsVeo3_1Fast(BaseModel): +class UsageModels(BaseModel): daily_generations: int = FieldInfo(alias="dailyGenerations") """The number of generations that have been run for this model in the past day.""" -class UsageModels(BaseModel): - act_two: Optional[UsageModelsActTwo] = None - """Usage data for the act_two model.""" - - eleven_multilingual_sts_v2: Optional[UsageModelsElevenMultilingualStsV2] = None - """Usage data for the eleven_multilingual_sts_v2 model.""" - - eleven_multilingual_v2: Optional[UsageModelsElevenMultilingualV2] = None - """Usage data for the eleven_multilingual_v2 model.""" - - eleven_text_to_sound_v2: Optional[UsageModelsElevenTextToSoundV2] = None - """Usage data for the eleven_text_to_sound_v2 model.""" - - eleven_voice_dubbing: Optional[UsageModelsElevenVoiceDubbing] = None - """Usage data for the eleven_voice_dubbing model.""" - - eleven_voice_isolation: Optional[UsageModelsElevenVoiceIsolation] = None - """Usage data for the eleven_voice_isolation model.""" - - gemini_2_5_flash: Optional[UsageModelsGemini2_5Flash] = FieldInfo(alias="gemini_2.5_flash", default=None) - """Usage data for the gemini_2.5_flash model.""" - - gen3a_turbo: Optional[UsageModelsGen3aTurbo] = None - """Usage data for the gen3a_turbo model.""" - - gen4_aleph: Optional[UsageModelsGen4Aleph] = None - """Usage data for the gen4_aleph model.""" - - gen4_image: Optional[UsageModelsGen4Image] = None - """Usage data for the gen4_image model.""" - - gen4_image_turbo: Optional[UsageModelsGen4ImageTurbo] = None - """Usage data for the gen4_image_turbo model.""" - - gen4_turbo: Optional[UsageModelsGen4Turbo] = None - """Usage data for the gen4_turbo model.""" - - upscale_v1: Optional[UsageModelsUpscaleV1] = None - """Usage data for the upscale_v1 model.""" - - veo3: Optional[UsageModelsVeo3] = None - """Usage data for the veo3 model.""" - - veo3_1: Optional[UsageModelsVeo3_1] = FieldInfo(alias="veo3.1", default=None) - """Usage data for the veo3.1 model.""" - - veo3_1_fast: Optional[UsageModelsVeo3_1Fast] = FieldInfo(alias="veo3.1_fast", default=None) - """Usage data for the veo3.1_fast model.""" - - class Usage(BaseModel): - models: UsageModels - """Usage data for each model.""" + models: Dict[str, UsageModels] class OrganizationRetrieveResponse(BaseModel): diff --git a/src/runwayml/types/organization_retrieve_usage_response.py b/src/runwayml/types/organization_retrieve_usage_response.py index ad90712..bce820c 100644 --- a/src/runwayml/types/organization_retrieve_usage_response.py +++ b/src/runwayml/types/organization_retrieve_usage_response.py @@ -13,27 +13,27 @@ class ResultUsedCredit(BaseModel): amount: int - """The number of credits used for the model.""" + """The number of credits spent on the model.""" model: Literal[ - "act_two", - "eleven_multilingual_sts_v2", - "eleven_multilingual_v2", - "eleven_text_to_sound_v2", - "eleven_voice_dubbing", - "eleven_voice_isolation", - "gemini_2.5_flash", "gen3a_turbo", - "gen4_aleph", + "gen4_turbo", "gen4_image", "gen4_image_turbo", - "gen4_turbo", "upscale_v1", + "act_two", + "gen4_aleph", "veo3", "veo3.1", "veo3.1_fast", + "gemini_2.5_flash", + "eleven_multilingual_v2", + "eleven_text_to_sound_v2", + "eleven_voice_isolation", + "eleven_voice_dubbing", + "eleven_multilingual_sts_v2", ] - """The model whose usage resulted in the credit usage.""" + """The model that credits were spent on.""" class Result(BaseModel): @@ -50,22 +50,22 @@ class Result(BaseModel): class OrganizationRetrieveUsageResponse(BaseModel): models: List[ Literal[ - "act_two", - "eleven_multilingual_sts_v2", - "eleven_multilingual_v2", - "eleven_text_to_sound_v2", - "eleven_voice_dubbing", - "eleven_voice_isolation", - "gemini_2.5_flash", "gen3a_turbo", - "gen4_aleph", + "gen4_turbo", "gen4_image", "gen4_image_turbo", - "gen4_turbo", "upscale_v1", + "act_two", + "gen4_aleph", "veo3", "veo3.1", "veo3.1_fast", + "gemini_2.5_flash", + "eleven_multilingual_v2", + "eleven_text_to_sound_v2", + "eleven_voice_isolation", + "eleven_voice_dubbing", + "eleven_multilingual_sts_v2", ] ] """The list of models with usage during the queried time range.""" diff --git a/src/runwayml/types/sound_effect_create_response.py b/src/runwayml/types/sound_effect_create_response.py index 604a06d..0dc690b 100644 --- a/src/runwayml/types/sound_effect_create_response.py +++ b/src/runwayml/types/sound_effect_create_response.py @@ -7,3 +7,4 @@ class SoundEffectCreateResponse(BaseModel): id: str + """The ID of the task that was created. Use this to retrieve the task later.""" diff --git a/src/runwayml/types/speech_to_speech_create_response.py b/src/runwayml/types/speech_to_speech_create_response.py index 03a93b3..f682d47 100644 --- a/src/runwayml/types/speech_to_speech_create_response.py +++ b/src/runwayml/types/speech_to_speech_create_response.py @@ -7,3 +7,4 @@ class SpeechToSpeechCreateResponse(BaseModel): id: str + """The ID of the task that was created. Use this to retrieve the task later.""" diff --git a/src/runwayml/types/task_retrieve_response.py b/src/runwayml/types/task_retrieve_response.py index 47b9601..9284246 100644 --- a/src/runwayml/types/task_retrieve_response.py +++ b/src/runwayml/types/task_retrieve_response.py @@ -1,59 +1,99 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import List, Optional +from typing import List, Union, Optional from datetime import datetime -from typing_extensions import Literal +from typing_extensions import Literal, Annotated, TypeAlias from pydantic import Field as FieldInfo +from .._utils import PropertyInfo from .._models import BaseModel -__all__ = ["TaskRetrieveResponse"] +__all__ = ["TaskRetrieveResponse", "Pending", "Throttled", "Cancelled", "Running", "Failed", "Succeeded"] -class TaskRetrieveResponse(BaseModel): +class Pending(BaseModel): id: str """The ID of the task being returned.""" created_at: datetime = FieldInfo(alias="createdAt") """The timestamp that the task was submitted at.""" - status: Literal["RUNNING", "SUCCEEDED", "FAILED", "PENDING", "CANCELLED", "THROTTLED"] - """ - - `PENDING` tasks have been enqueued and are waiting to run. - - `THROTTLED` tasks are waiting to be enqueued until other jobs have finished - running. - - `RUNNING` tasks are currently being processed. - - `SUCCEEDED` tasks have completed successfully. - - `FAILED` tasks have failed. - - `CANCELLED` tasks have been aborted. - """ + status: Literal["PENDING"] - failure: Optional[str] = None - """ - If the status is `FAILED`, this will contain a human-friendly reason for the - failure. + +class Throttled(BaseModel): + id: str + """The ID of the task being returned.""" + + created_at: datetime = FieldInfo(alias="createdAt") + """The timestamp that the task was submitted at.""" + + status: Literal["THROTTLED"] + + +class Cancelled(BaseModel): + id: str + """The ID of the task being returned.""" + + created_at: datetime = FieldInfo(alias="createdAt") + """The timestamp that the task was submitted at.""" + + status: Literal["CANCELLED"] + + +class Running(BaseModel): + id: str + """The ID of the task being returned.""" + + created_at: datetime = FieldInfo(alias="createdAt") + """The timestamp that the task was submitted at.""" + + progress: float + + status: Literal["RUNNING"] + + +class Failed(BaseModel): + id: str + """The ID of the task being returned.""" + + created_at: datetime = FieldInfo(alias="createdAt") + """The timestamp that the task was submitted at.""" + + failure: str + """A human-friendly reason for the failure. + + We do not recommend returning this to users directly without adding context. """ + status: Literal["FAILED"] + failure_code: Optional[str] = FieldInfo(alias="failureCode", default=None) - """ - If the task has a status of `FAILED`, this contains a machine-readable error - code. This is a dot-separated string, with the leftmost segment being the most - generic and the rightmost segment being the most specific. For example, - `SAFETY.INPUT.TEXT` would indicate that the task failed due to a content - moderation error on the input text. + """A machine-readable error code for the failure. + + See https://docs.dev.runwayml.com/errors/task-failures/ for more information. """ - output: Optional[List[str]] = None - """If the status is `SUCCEEDED`, this will contain an array of strings. - Each string will be a URL that returns an output from the task. URLs expire - within 24-48 hours; fetch the task again to get fresh URLs. It is expected that - you download the assets at these URLs and store them in your own storage system. - """ +class Succeeded(BaseModel): + id: str + """The ID of the task being returned.""" - progress: Optional[float] = None - """ - If the task has a status of `RUNNING`, this will contain a floating point number - between 0 and 1 representing the progress of the generation. + created_at: datetime = FieldInfo(alias="createdAt") + """The timestamp that the task was submitted at.""" + + output: List[str] + """An array of URLs that return the output of the task. + + These URLs will expire within 24-48 hours; fetch the task again to get fresh + URLs. It is expected that you download the assets at these URLs and store them + in your own storage system. """ + + status: Literal["SUCCEEDED"] + + +TaskRetrieveResponse: TypeAlias = Annotated[ + Union[Pending, Throttled, Cancelled, Running, Failed, Succeeded], PropertyInfo(discriminator="status") +] diff --git a/src/runwayml/types/text_to_image_create_params.py b/src/runwayml/types/text_to_image_create_params.py index 164616c..8a1e6c6 100644 --- a/src/runwayml/types/text_to_image_create_params.py +++ b/src/runwayml/types/text_to_image_create_params.py @@ -74,6 +74,10 @@ class Gen4ImageTurboReferenceImage(TypedDict, total=False): """A HTTPS URL.""" tag: str + """A tag to identify the reference image. + + This is used to reference the image in prompt text. + """ class Gen4ImageTurboContentModeration(TypedDict, total=False): @@ -146,6 +150,10 @@ class Gen4ImageReferenceImage(TypedDict, total=False): """A HTTPS URL.""" tag: str + """A tag to identify the reference image. + + This is used to reference the image in prompt text. + """ class Gemini2_5Flash(TypedDict, total=False): @@ -185,6 +193,10 @@ class Gemini2_5FlashReferenceImage(TypedDict, total=False): """A HTTPS URL.""" tag: str + """A tag to identify the reference image. + + This is used to reference the image in prompt text. + """ TextToImageCreateParams: TypeAlias = Union[Gen4ImageTurbo, Gen4Image, Gemini2_5Flash] diff --git a/src/runwayml/types/text_to_image_create_response.py b/src/runwayml/types/text_to_image_create_response.py index 79f659e..353b565 100644 --- a/src/runwayml/types/text_to_image_create_response.py +++ b/src/runwayml/types/text_to_image_create_response.py @@ -7,3 +7,4 @@ class TextToImageCreateResponse(BaseModel): id: str + """The ID of the task that was created. Use this to retrieve the task later.""" diff --git a/src/runwayml/types/text_to_speech_create_response.py b/src/runwayml/types/text_to_speech_create_response.py index f7d45a6..3a97053 100644 --- a/src/runwayml/types/text_to_speech_create_response.py +++ b/src/runwayml/types/text_to_speech_create_response.py @@ -7,3 +7,4 @@ class TextToSpeechCreateResponse(BaseModel): id: str + """The ID of the task that was created. Use this to retrieve the task later.""" diff --git a/src/runwayml/types/text_to_video_create_response.py b/src/runwayml/types/text_to_video_create_response.py index d0c8bdf..61b1718 100644 --- a/src/runwayml/types/text_to_video_create_response.py +++ b/src/runwayml/types/text_to_video_create_response.py @@ -7,3 +7,4 @@ class TextToVideoCreateResponse(BaseModel): id: str + """The ID of the task that was created. Use this to retrieve the task later.""" diff --git a/src/runwayml/types/video_to_video_create_response.py b/src/runwayml/types/video_to_video_create_response.py index 6ab01a7..ad85b7b 100644 --- a/src/runwayml/types/video_to_video_create_response.py +++ b/src/runwayml/types/video_to_video_create_response.py @@ -7,3 +7,4 @@ class VideoToVideoCreateResponse(BaseModel): id: str + """The ID of the task that was created. Use this to retrieve the task later.""" diff --git a/src/runwayml/types/video_upscale_create_response.py b/src/runwayml/types/video_upscale_create_response.py index 73a0bd1..0cf0a9e 100644 --- a/src/runwayml/types/video_upscale_create_response.py +++ b/src/runwayml/types/video_upscale_create_response.py @@ -7,3 +7,4 @@ class VideoUpscaleCreateResponse(BaseModel): id: str + """The ID of the task that was created. Use this to retrieve the task later.""" diff --git a/src/runwayml/types/voice_dubbing_create_response.py b/src/runwayml/types/voice_dubbing_create_response.py index 3f105d6..1c8c4e5 100644 --- a/src/runwayml/types/voice_dubbing_create_response.py +++ b/src/runwayml/types/voice_dubbing_create_response.py @@ -7,3 +7,4 @@ class VoiceDubbingCreateResponse(BaseModel): id: str + """The ID of the task that was created. Use this to retrieve the task later.""" diff --git a/src/runwayml/types/voice_isolation_create_response.py b/src/runwayml/types/voice_isolation_create_response.py index e1eed57..ff24226 100644 --- a/src/runwayml/types/voice_isolation_create_response.py +++ b/src/runwayml/types/voice_isolation_create_response.py @@ -7,3 +7,4 @@ class VoiceIsolationCreateResponse(BaseModel): id: str + """The ID of the task that was created. Use this to retrieve the task later.""" diff --git a/tests/api_resources/test_text_to_image.py b/tests/api_resources/test_text_to_image.py index 95ddd30..e915d46 100644 --- a/tests/api_resources/test_text_to_image.py +++ b/tests/api_resources/test_text_to_image.py @@ -129,7 +129,7 @@ def test_streaming_response_create_overload_2(self, client: RunwayML) -> None: assert cast(Any, response.is_closed) is True @parametrize - def test_method_create_overload_3(self, client: RunwayML) -> None: + def test_method_create_overload_4(self, client: RunwayML) -> None: text_to_image = client.text_to_image.create( model="gemini_2.5_flash", prompt_text="x", @@ -138,7 +138,7 @@ def test_method_create_overload_3(self, client: RunwayML) -> None: assert_matches_type(TextToImageCreateResponse, text_to_image, path=["response"]) @parametrize - def test_method_create_with_all_params_overload_3(self, client: RunwayML) -> None: + def test_method_create_with_all_params_overload_4(self, client: RunwayML) -> None: text_to_image = client.text_to_image.create( model="gemini_2.5_flash", prompt_text="x", @@ -153,7 +153,7 @@ def test_method_create_with_all_params_overload_3(self, client: RunwayML) -> Non assert_matches_type(TextToImageCreateResponse, text_to_image, path=["response"]) @parametrize - def test_raw_response_create_overload_3(self, client: RunwayML) -> None: + def test_raw_response_create_overload_4(self, client: RunwayML) -> None: response = client.text_to_image.with_raw_response.create( model="gemini_2.5_flash", prompt_text="x", @@ -166,7 +166,7 @@ def test_raw_response_create_overload_3(self, client: RunwayML) -> None: assert_matches_type(TextToImageCreateResponse, text_to_image, path=["response"]) @parametrize - def test_streaming_response_create_overload_3(self, client: RunwayML) -> None: + def test_streaming_response_create_overload_4(self, client: RunwayML) -> None: with client.text_to_image.with_streaming_response.create( model="gemini_2.5_flash", prompt_text="x", @@ -298,7 +298,7 @@ async def test_streaming_response_create_overload_2(self, async_client: AsyncRun assert cast(Any, response.is_closed) is True @parametrize - async def test_method_create_overload_3(self, async_client: AsyncRunwayML) -> None: + async def test_method_create_overload_4(self, async_client: AsyncRunwayML) -> None: text_to_image = await async_client.text_to_image.create( model="gemini_2.5_flash", prompt_text="x", @@ -307,7 +307,7 @@ async def test_method_create_overload_3(self, async_client: AsyncRunwayML) -> No assert_matches_type(TextToImageCreateResponse, text_to_image, path=["response"]) @parametrize - async def test_method_create_with_all_params_overload_3(self, async_client: AsyncRunwayML) -> None: + async def test_method_create_with_all_params_overload_4(self, async_client: AsyncRunwayML) -> None: text_to_image = await async_client.text_to_image.create( model="gemini_2.5_flash", prompt_text="x", @@ -322,7 +322,7 @@ async def test_method_create_with_all_params_overload_3(self, async_client: Asyn assert_matches_type(TextToImageCreateResponse, text_to_image, path=["response"]) @parametrize - async def test_raw_response_create_overload_3(self, async_client: AsyncRunwayML) -> None: + async def test_raw_response_create_overload_4(self, async_client: AsyncRunwayML) -> None: response = await async_client.text_to_image.with_raw_response.create( model="gemini_2.5_flash", prompt_text="x", @@ -335,7 +335,7 @@ async def test_raw_response_create_overload_3(self, async_client: AsyncRunwayML) assert_matches_type(TextToImageCreateResponse, text_to_image, path=["response"]) @parametrize - async def test_streaming_response_create_overload_3(self, async_client: AsyncRunwayML) -> None: + async def test_streaming_response_create_overload_4(self, async_client: AsyncRunwayML) -> None: async with async_client.text_to_image.with_streaming_response.create( model="gemini_2.5_flash", prompt_text="x", diff --git a/tests/api_resources/test_voice_dubbing.py b/tests/api_resources/test_voice_dubbing.py index ac23d9f..aab73a9 100644 --- a/tests/api_resources/test_voice_dubbing.py +++ b/tests/api_resources/test_voice_dubbing.py @@ -34,7 +34,7 @@ def test_method_create_with_all_params(self, client: RunwayML) -> None: target_lang="en", disable_voice_cloning=True, drop_background_audio=True, - num_speakers=9007199254740991, + num_speakers=1, ) assert_matches_type(VoiceDubbingCreateResponse, voice_dubbing, path=["response"]) @@ -89,7 +89,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncRunwayML) target_lang="en", disable_voice_cloning=True, drop_background_audio=True, - num_speakers=9007199254740991, + num_speakers=1, ) assert_matches_type(VoiceDubbingCreateResponse, voice_dubbing, path=["response"]) From ee474d50717cd5517f2bbcb072fd044205587260 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 4 Dec 2025 02:18:54 +0000 Subject: [PATCH 10/11] feat(api): Remove unreleased model --- .stats.yml | 4 +- src/runwayml/resources/text_to_image.py | 64 ----------------------- tests/api_resources/test_text_to_image.py | 16 +++--- 3 files changed, 10 insertions(+), 74 deletions(-) diff --git a/.stats.yml b/.stats.yml index d0d8fc0..cfa3db4 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 15 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/runwayml%2Frunwayml-6dab1bdab5d3264fa80bccb641a17fbf0944197c00c08b826fbd17e29ba250a1.yml -openapi_spec_hash: 846f29a2fd9ceb6867c2343494e1c319 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/runwayml%2Frunwayml-f1f066255f00c8db87d86efaff73852278f21c2619f83dcf9f4e5cf54ef146b0.yml +openapi_spec_hash: af56570f2801ec4bfc94a05ca5393f9c config_hash: b98eed33f1bba05e3c2a3e20d85d582a diff --git a/src/runwayml/resources/text_to_image.py b/src/runwayml/resources/text_to_image.py index ff9a847..9206ae8 100644 --- a/src/runwayml/resources/text_to_image.py +++ b/src/runwayml/resources/text_to_image.py @@ -246,38 +246,6 @@ def create( "720:960", "1680:720", ] - | Literal[ - "1344:768", - "768:1344", - "1024:1024", - "1184:864", - "864:1184", - "1536:672", - "832:1248", - "1248:832", - "896:1152", - "1152:896", - "2048:2048", - "1696:2528", - "2528:1696", - "1792:2400", - "2400:1792", - "1856:2304", - "2304:1856", - "1536:2752", - "2752:1536", - "3168:1344", - "4096:4096", - "3392:5056", - "5056:3392", - "3584:4800", - "4800:3584", - "3712:4608", - "4608:3712", - "3072:5504", - "5504:3072", - "6336:2688", - ] | Literal[ "1344:768", "768:1344", @@ -541,38 +509,6 @@ async def create( "720:960", "1680:720", ] - | Literal[ - "1344:768", - "768:1344", - "1024:1024", - "1184:864", - "864:1184", - "1536:672", - "832:1248", - "1248:832", - "896:1152", - "1152:896", - "2048:2048", - "1696:2528", - "2528:1696", - "1792:2400", - "2400:1792", - "1856:2304", - "2304:1856", - "1536:2752", - "2752:1536", - "3168:1344", - "4096:4096", - "3392:5056", - "5056:3392", - "3584:4800", - "4800:3584", - "3712:4608", - "4608:3712", - "3072:5504", - "5504:3072", - "6336:2688", - ] | Literal[ "1344:768", "768:1344", diff --git a/tests/api_resources/test_text_to_image.py b/tests/api_resources/test_text_to_image.py index e915d46..95ddd30 100644 --- a/tests/api_resources/test_text_to_image.py +++ b/tests/api_resources/test_text_to_image.py @@ -129,7 +129,7 @@ def test_streaming_response_create_overload_2(self, client: RunwayML) -> None: assert cast(Any, response.is_closed) is True @parametrize - def test_method_create_overload_4(self, client: RunwayML) -> None: + def test_method_create_overload_3(self, client: RunwayML) -> None: text_to_image = client.text_to_image.create( model="gemini_2.5_flash", prompt_text="x", @@ -138,7 +138,7 @@ def test_method_create_overload_4(self, client: RunwayML) -> None: assert_matches_type(TextToImageCreateResponse, text_to_image, path=["response"]) @parametrize - def test_method_create_with_all_params_overload_4(self, client: RunwayML) -> None: + def test_method_create_with_all_params_overload_3(self, client: RunwayML) -> None: text_to_image = client.text_to_image.create( model="gemini_2.5_flash", prompt_text="x", @@ -153,7 +153,7 @@ def test_method_create_with_all_params_overload_4(self, client: RunwayML) -> Non assert_matches_type(TextToImageCreateResponse, text_to_image, path=["response"]) @parametrize - def test_raw_response_create_overload_4(self, client: RunwayML) -> None: + def test_raw_response_create_overload_3(self, client: RunwayML) -> None: response = client.text_to_image.with_raw_response.create( model="gemini_2.5_flash", prompt_text="x", @@ -166,7 +166,7 @@ def test_raw_response_create_overload_4(self, client: RunwayML) -> None: assert_matches_type(TextToImageCreateResponse, text_to_image, path=["response"]) @parametrize - def test_streaming_response_create_overload_4(self, client: RunwayML) -> None: + def test_streaming_response_create_overload_3(self, client: RunwayML) -> None: with client.text_to_image.with_streaming_response.create( model="gemini_2.5_flash", prompt_text="x", @@ -298,7 +298,7 @@ async def test_streaming_response_create_overload_2(self, async_client: AsyncRun assert cast(Any, response.is_closed) is True @parametrize - async def test_method_create_overload_4(self, async_client: AsyncRunwayML) -> None: + async def test_method_create_overload_3(self, async_client: AsyncRunwayML) -> None: text_to_image = await async_client.text_to_image.create( model="gemini_2.5_flash", prompt_text="x", @@ -307,7 +307,7 @@ async def test_method_create_overload_4(self, async_client: AsyncRunwayML) -> No assert_matches_type(TextToImageCreateResponse, text_to_image, path=["response"]) @parametrize - async def test_method_create_with_all_params_overload_4(self, async_client: AsyncRunwayML) -> None: + async def test_method_create_with_all_params_overload_3(self, async_client: AsyncRunwayML) -> None: text_to_image = await async_client.text_to_image.create( model="gemini_2.5_flash", prompt_text="x", @@ -322,7 +322,7 @@ async def test_method_create_with_all_params_overload_4(self, async_client: Asyn assert_matches_type(TextToImageCreateResponse, text_to_image, path=["response"]) @parametrize - async def test_raw_response_create_overload_4(self, async_client: AsyncRunwayML) -> None: + async def test_raw_response_create_overload_3(self, async_client: AsyncRunwayML) -> None: response = await async_client.text_to_image.with_raw_response.create( model="gemini_2.5_flash", prompt_text="x", @@ -335,7 +335,7 @@ async def test_raw_response_create_overload_4(self, async_client: AsyncRunwayML) assert_matches_type(TextToImageCreateResponse, text_to_image, path=["response"]) @parametrize - async def test_streaming_response_create_overload_4(self, async_client: AsyncRunwayML) -> None: + async def test_streaming_response_create_overload_3(self, async_client: AsyncRunwayML) -> None: async with async_client.text_to_image.with_streaming_response.create( model="gemini_2.5_flash", prompt_text="x", From 52439f28be6f3da0d8f890d333bbd4481b62dc55 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 4 Dec 2025 02:44:43 +0000 Subject: [PATCH 11/11] release: 4.2.0 --- .release-please-manifest.json | 2 +- CHANGELOG.md | 18 ++++++++++++++++++ pyproject.toml | 2 +- src/runwayml/_version.py | 2 +- 4 files changed, 21 insertions(+), 3 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 3c9ae23..bd7f384 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "4.1.1" + ".": "4.2.0" } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index c1be736..02392b6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,23 @@ # Changelog +## 4.2.0 (2025-12-04) + +Full Changelog: [v4.1.1...v4.2.0](https://github.com/runwayml/sdk-python/compare/v4.1.1...v4.2.0) + +### Features + +* **api:** Autogen spec updates ([e9d2114](https://github.com/runwayml/sdk-python/commit/e9d2114b819a6a641e716c0823ba1f182c3b5400)) +* **api:** gemini_3_pro t2i ([1f1fcfa](https://github.com/runwayml/sdk-python/commit/1f1fcfa6bac257df24a383613389010d0c481f5d)) +* **api:** gemini_3_pro t2i ([ea8a4ec](https://github.com/runwayml/sdk-python/commit/ea8a4ec3e05e27e5b4db85481846678c0fc0c009)) +* **api:** Remove unreleased model ([ee474d5](https://github.com/runwayml/sdk-python/commit/ee474d50717cd5517f2bbcb072fd044205587260)) +* **api:** Revert G3P changes ([3959ddf](https://github.com/runwayml/sdk-python/commit/3959ddfb5bfee6a7beff2cd6d294b59204dd6fae)) + + +### Chores + +* **docs:** use environment variables for authentication in code snippets ([cd6776e](https://github.com/runwayml/sdk-python/commit/cd6776ecdccbb9bebb88db16a4b3ef46b246d23d)) +* update lockfile ([7199587](https://github.com/runwayml/sdk-python/commit/719958796a3c89ff20b2e4e2b0db1e375f836125)) + ## 4.1.1 (2025-11-28) Full Changelog: [v4.1.0...v4.1.1](https://github.com/runwayml/sdk-python/compare/v4.1.0...v4.1.1) diff --git a/pyproject.toml b/pyproject.toml index a7dd1ce..668ea2e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "runwayml" -version = "4.1.1" +version = "4.2.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 ab67098..9e0ccac 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.1.1" # x-release-please-version +__version__ = "4.2.0" # x-release-please-version