diff --git a/.release-please-manifest.json b/.release-please-manifest.json
index e42b9af..8f918e4 100644
--- a/.release-please-manifest.json
+++ b/.release-please-manifest.json
@@ -1,3 +1,3 @@
{
- ".": "5.11.0"
+ ".": "5.12.0"
}
\ No newline at end of file
diff --git a/.stats.yml b/.stats.yml
index 0cfcc15..5088d53 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
-configured_endpoints: 57
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/runwayml/runwayml-264e9b264bae2f906e06f33a5af492e19580bcd192f6094cfdb534fcbf70f5bc.yml
-openapi_spec_hash: 30ac92dee6f88c19ea1cdc174b05a260
-config_hash: 6bdea3c3109ee75952f779d566c229ea
+configured_endpoints: 59
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/runwayml/runwayml-a31e62dafc005582320d354e7aed335c8df690338ca539c055aa4a5637b9ad3b.yml
+openapi_spec_hash: ab95f9ae7163b960171e68f4ff95da4e
+config_hash: 95e64e640428abd4184a48762d9fd5f8
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8e78108..1cb8f58 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,24 @@
# Changelog
+## 5.12.0 (2026-07-23)
+
+Full Changelog: [v5.11.0...v5.12.0](https://github.com/runwayml/sdk-python/compare/v5.11.0...v5.12.0)
+
+### Features
+
+* **api:** add Model Router image and audio generation ([e9f38d4](https://github.com/runwayml/sdk-python/commit/e9f38d40cf90be9e1e0775e50db76bef1aac1969))
+* **api:** expose generate image and audio endpoints ([d19bc95](https://github.com/runwayml/sdk-python/commit/d19bc9510ae78e7be4c257703e0e06e068eef0a7))
+
+
+### Bug Fixes
+
+* **client:** make generate.image and generate.audio responses awaitable ([d4900ac](https://github.com/runwayml/sdk-python/commit/d4900aca61dbb0ee983331aba287ac0930e975ac))
+
+
+### Chores
+
+* **openapi:** keep generate.video SDK schema task-only ([4b6e6c4](https://github.com/runwayml/sdk-python/commit/4b6e6c4abf38ae0cad30ba73acbf7f03401e00ac))
+
## 5.11.0 (2026-07-21)
Full Changelog: [v5.10.0...v5.11.0](https://github.com/runwayml/sdk-python/compare/v5.10.0...v5.11.0)
diff --git a/api.md b/api.md
index 6bb94e6..5c23a57 100644
--- a/api.md
+++ b/api.md
@@ -169,6 +169,30 @@ Methods:
- client.generate.video.create(\*\*params) -> VideoCreateResponse
+## Image
+
+Types:
+
+```python
+from runwayml.types.generate import ImageCreateResponse
+```
+
+Methods:
+
+- client.generate.image.create(\*\*params) -> ImageCreateResponse
+
+## Audio
+
+Types:
+
+```python
+from runwayml.types.generate import AudioCreateResponse
+```
+
+Methods:
+
+- client.generate.audio.create(\*\*params) -> AudioCreateResponse
+
# Routers
Types:
diff --git a/pyproject.toml b/pyproject.toml
index 2ee47e8..7fd7a0c 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,6 +1,6 @@
[project]
name = "runwayml"
-version = "5.11.0"
+version = "5.12.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 e20c282..480bb51 100644
--- a/src/runwayml/_version.py
+++ b/src/runwayml/_version.py
@@ -1,4 +1,4 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
__title__ = "runwayml"
-__version__ = "5.11.0" # x-release-please-version
+__version__ = "5.12.0" # x-release-please-version
diff --git a/src/runwayml/resources/generate/__init__.py b/src/runwayml/resources/generate/__init__.py
index a52fcf1..60ca843 100644
--- a/src/runwayml/resources/generate/__init__.py
+++ b/src/runwayml/resources/generate/__init__.py
@@ -1,5 +1,21 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+from .audio import (
+ AudioResource,
+ AsyncAudioResource,
+ AudioResourceWithRawResponse,
+ AsyncAudioResourceWithRawResponse,
+ AudioResourceWithStreamingResponse,
+ AsyncAudioResourceWithStreamingResponse,
+)
+from .image import (
+ ImageResource,
+ AsyncImageResource,
+ ImageResourceWithRawResponse,
+ AsyncImageResourceWithRawResponse,
+ ImageResourceWithStreamingResponse,
+ AsyncImageResourceWithStreamingResponse,
+)
from .video import (
VideoResource,
AsyncVideoResource,
@@ -24,6 +40,18 @@
"AsyncVideoResourceWithRawResponse",
"VideoResourceWithStreamingResponse",
"AsyncVideoResourceWithStreamingResponse",
+ "ImageResource",
+ "AsyncImageResource",
+ "ImageResourceWithRawResponse",
+ "AsyncImageResourceWithRawResponse",
+ "ImageResourceWithStreamingResponse",
+ "AsyncImageResourceWithStreamingResponse",
+ "AudioResource",
+ "AsyncAudioResource",
+ "AudioResourceWithRawResponse",
+ "AsyncAudioResourceWithRawResponse",
+ "AudioResourceWithStreamingResponse",
+ "AsyncAudioResourceWithStreamingResponse",
"GenerateResource",
"AsyncGenerateResource",
"GenerateResourceWithRawResponse",
diff --git a/src/runwayml/resources/generate/audio.py b/src/runwayml/resources/generate/audio.py
new file mode 100644
index 0000000..8be60f6
--- /dev/null
+++ b/src/runwayml/resources/generate/audio.py
@@ -0,0 +1,198 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+import httpx
+
+from runwayml.lib.polling import (
+ NewTaskCreatedResponse,
+ AsyncNewTaskCreatedResponse,
+ create_waitable_resource,
+ create_async_waitable_resource,
+)
+
+from ..._types import Body, Query, Headers, NotGiven, not_given
+from ..._utils import maybe_transform, async_maybe_transform
+from ..._compat import cached_property
+from ..._resource import SyncAPIResource, AsyncAPIResource
+from ..._response import (
+ to_raw_response_wrapper,
+ to_streamed_response_wrapper,
+ async_to_raw_response_wrapper,
+ async_to_streamed_response_wrapper,
+)
+from ..._base_client import make_request_options
+from ...types.generate import audio_create_params
+from ...types.generate.audio_create_response import AudioCreateResponse
+
+__all__ = ["AudioResource", "AsyncAudioResource"]
+
+
+class AudioResource(SyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> AudioResourceWithRawResponse:
+ """
+ This property can be used as a prefix for any HTTP method call to return
+ the raw response object instead of the parsed content.
+
+ For more information, see https://www.github.com/runwayml/sdk-python#accessing-raw-response-data-eg-headers
+ """
+ return AudioResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AudioResourceWithStreamingResponse:
+ """
+ An alternative to `.with_raw_response` that doesn't eagerly read the response body.
+
+ For more information, see https://www.github.com/runwayml/sdk-python#with_streaming_response
+ """
+ return AudioResourceWithStreamingResponse(self)
+
+ def create(
+ self,
+ *,
+ config_id: str,
+ input: audio_create_params.Input,
+ # 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:
+ """
+ Start an audio generation task using a saved Model Router config instead of
+ naming a model. Set input.type to speech to speak promptText verbatim, or audio
+ to generate audio described by promptText.
+
+ Args:
+ config_id: The slug of a saved Model Router config to route this request with.
+
+ input: Model-agnostic audio generation input. The router selects a model and maps these
+ options to it.
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ return self._post(
+ "/v1/generate/audio",
+ body=maybe_transform(
+ {
+ "config_id": config_id,
+ "input": input,
+ },
+ audio_create_params.AudioCreateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=create_waitable_resource(AudioCreateResponse, self._client),
+ )
+
+
+class AsyncAudioResource(AsyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> AsyncAudioResourceWithRawResponse:
+ """
+ This property can be used as a prefix for any HTTP method call to return
+ the raw response object instead of the parsed content.
+
+ For more information, see https://www.github.com/runwayml/sdk-python#accessing-raw-response-data-eg-headers
+ """
+ return AsyncAudioResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncAudioResourceWithStreamingResponse:
+ """
+ An alternative to `.with_raw_response` that doesn't eagerly read the response body.
+
+ For more information, see https://www.github.com/runwayml/sdk-python#with_streaming_response
+ """
+ return AsyncAudioResourceWithStreamingResponse(self)
+
+ async def create(
+ self,
+ *,
+ config_id: str,
+ input: audio_create_params.Input,
+ # 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:
+ """
+ Start an audio generation task using a saved Model Router config instead of
+ naming a model. Set input.type to speech to speak promptText verbatim, or audio
+ to generate audio described by promptText.
+
+ Args:
+ config_id: The slug of a saved Model Router config to route this request with.
+
+ input: Model-agnostic audio generation input. The router selects a model and maps these
+ options to it.
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ return await self._post(
+ "/v1/generate/audio",
+ body=await async_maybe_transform(
+ {
+ "config_id": config_id,
+ "input": input,
+ },
+ audio_create_params.AudioCreateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=create_async_waitable_resource(AudioCreateResponse, self._client),
+ )
+
+
+class AudioResourceWithRawResponse:
+ def __init__(self, audio: AudioResource) -> None:
+ self._audio = audio
+
+ self.create = to_raw_response_wrapper(
+ audio.create,
+ )
+
+
+class AsyncAudioResourceWithRawResponse:
+ def __init__(self, audio: AsyncAudioResource) -> None:
+ self._audio = audio
+
+ self.create = async_to_raw_response_wrapper(
+ audio.create,
+ )
+
+
+class AudioResourceWithStreamingResponse:
+ def __init__(self, audio: AudioResource) -> None:
+ self._audio = audio
+
+ self.create = to_streamed_response_wrapper(
+ audio.create,
+ )
+
+
+class AsyncAudioResourceWithStreamingResponse:
+ def __init__(self, audio: AsyncAudioResource) -> None:
+ self._audio = audio
+
+ self.create = async_to_streamed_response_wrapper(
+ audio.create,
+ )
diff --git a/src/runwayml/resources/generate/generate.py b/src/runwayml/resources/generate/generate.py
index 02d0cbc..6081263 100644
--- a/src/runwayml/resources/generate/generate.py
+++ b/src/runwayml/resources/generate/generate.py
@@ -2,6 +2,22 @@
from __future__ import annotations
+from .audio import (
+ AudioResource,
+ AsyncAudioResource,
+ AudioResourceWithRawResponse,
+ AsyncAudioResourceWithRawResponse,
+ AudioResourceWithStreamingResponse,
+ AsyncAudioResourceWithStreamingResponse,
+)
+from .image import (
+ ImageResource,
+ AsyncImageResource,
+ ImageResourceWithRawResponse,
+ AsyncImageResourceWithRawResponse,
+ ImageResourceWithStreamingResponse,
+ AsyncImageResourceWithStreamingResponse,
+)
from .video import (
VideoResource,
AsyncVideoResource,
@@ -21,6 +37,14 @@ class GenerateResource(SyncAPIResource):
def video(self) -> VideoResource:
return VideoResource(self._client)
+ @cached_property
+ def image(self) -> ImageResource:
+ return ImageResource(self._client)
+
+ @cached_property
+ def audio(self) -> AudioResource:
+ return AudioResource(self._client)
+
@cached_property
def with_raw_response(self) -> GenerateResourceWithRawResponse:
"""
@@ -46,6 +70,14 @@ class AsyncGenerateResource(AsyncAPIResource):
def video(self) -> AsyncVideoResource:
return AsyncVideoResource(self._client)
+ @cached_property
+ def image(self) -> AsyncImageResource:
+ return AsyncImageResource(self._client)
+
+ @cached_property
+ def audio(self) -> AsyncAudioResource:
+ return AsyncAudioResource(self._client)
+
@cached_property
def with_raw_response(self) -> AsyncGenerateResourceWithRawResponse:
"""
@@ -74,6 +106,14 @@ def __init__(self, generate: GenerateResource) -> None:
def video(self) -> VideoResourceWithRawResponse:
return VideoResourceWithRawResponse(self._generate.video)
+ @cached_property
+ def image(self) -> ImageResourceWithRawResponse:
+ return ImageResourceWithRawResponse(self._generate.image)
+
+ @cached_property
+ def audio(self) -> AudioResourceWithRawResponse:
+ return AudioResourceWithRawResponse(self._generate.audio)
+
class AsyncGenerateResourceWithRawResponse:
def __init__(self, generate: AsyncGenerateResource) -> None:
@@ -83,6 +123,14 @@ def __init__(self, generate: AsyncGenerateResource) -> None:
def video(self) -> AsyncVideoResourceWithRawResponse:
return AsyncVideoResourceWithRawResponse(self._generate.video)
+ @cached_property
+ def image(self) -> AsyncImageResourceWithRawResponse:
+ return AsyncImageResourceWithRawResponse(self._generate.image)
+
+ @cached_property
+ def audio(self) -> AsyncAudioResourceWithRawResponse:
+ return AsyncAudioResourceWithRawResponse(self._generate.audio)
+
class GenerateResourceWithStreamingResponse:
def __init__(self, generate: GenerateResource) -> None:
@@ -92,6 +140,14 @@ def __init__(self, generate: GenerateResource) -> None:
def video(self) -> VideoResourceWithStreamingResponse:
return VideoResourceWithStreamingResponse(self._generate.video)
+ @cached_property
+ def image(self) -> ImageResourceWithStreamingResponse:
+ return ImageResourceWithStreamingResponse(self._generate.image)
+
+ @cached_property
+ def audio(self) -> AudioResourceWithStreamingResponse:
+ return AudioResourceWithStreamingResponse(self._generate.audio)
+
class AsyncGenerateResourceWithStreamingResponse:
def __init__(self, generate: AsyncGenerateResource) -> None:
@@ -100,3 +156,11 @@ def __init__(self, generate: AsyncGenerateResource) -> None:
@cached_property
def video(self) -> AsyncVideoResourceWithStreamingResponse:
return AsyncVideoResourceWithStreamingResponse(self._generate.video)
+
+ @cached_property
+ def image(self) -> AsyncImageResourceWithStreamingResponse:
+ return AsyncImageResourceWithStreamingResponse(self._generate.image)
+
+ @cached_property
+ def audio(self) -> AsyncAudioResourceWithStreamingResponse:
+ return AsyncAudioResourceWithStreamingResponse(self._generate.audio)
diff --git a/src/runwayml/resources/generate/image.py b/src/runwayml/resources/generate/image.py
new file mode 100644
index 0000000..05cefd7
--- /dev/null
+++ b/src/runwayml/resources/generate/image.py
@@ -0,0 +1,196 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+import httpx
+
+from runwayml.lib.polling import (
+ NewTaskCreatedResponse,
+ AsyncNewTaskCreatedResponse,
+ create_waitable_resource,
+ create_async_waitable_resource,
+)
+
+from ..._types import Body, Query, Headers, NotGiven, not_given
+from ..._utils import maybe_transform, async_maybe_transform
+from ..._compat import cached_property
+from ..._resource import SyncAPIResource, AsyncAPIResource
+from ..._response import (
+ to_raw_response_wrapper,
+ to_streamed_response_wrapper,
+ async_to_raw_response_wrapper,
+ async_to_streamed_response_wrapper,
+)
+from ..._base_client import make_request_options
+from ...types.generate import image_create_params
+from ...types.generate.image_create_response import ImageCreateResponse
+
+__all__ = ["ImageResource", "AsyncImageResource"]
+
+
+class ImageResource(SyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> ImageResourceWithRawResponse:
+ """
+ This property can be used as a prefix for any HTTP method call to return
+ the raw response object instead of the parsed content.
+
+ For more information, see https://www.github.com/runwayml/sdk-python#accessing-raw-response-data-eg-headers
+ """
+ return ImageResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> ImageResourceWithStreamingResponse:
+ """
+ An alternative to `.with_raw_response` that doesn't eagerly read the response body.
+
+ For more information, see https://www.github.com/runwayml/sdk-python#with_streaming_response
+ """
+ return ImageResourceWithStreamingResponse(self)
+
+ def create(
+ self,
+ *,
+ config_id: str,
+ input: image_create_params.Input,
+ # 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:
+ """
+ Start an image generation task using a saved Model Router config instead of
+ naming a model.
+
+ Args:
+ config_id: The slug of a saved Model Router config to route this request with.
+
+ input: Model-agnostic image generation input. The router selects a model and maps these
+ options to it.
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ return self._post(
+ "/v1/generate/image",
+ body=maybe_transform(
+ {
+ "config_id": config_id,
+ "input": input,
+ },
+ image_create_params.ImageCreateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=create_waitable_resource(ImageCreateResponse, self._client),
+ )
+
+
+class AsyncImageResource(AsyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> AsyncImageResourceWithRawResponse:
+ """
+ This property can be used as a prefix for any HTTP method call to return
+ the raw response object instead of the parsed content.
+
+ For more information, see https://www.github.com/runwayml/sdk-python#accessing-raw-response-data-eg-headers
+ """
+ return AsyncImageResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncImageResourceWithStreamingResponse:
+ """
+ An alternative to `.with_raw_response` that doesn't eagerly read the response body.
+
+ For more information, see https://www.github.com/runwayml/sdk-python#with_streaming_response
+ """
+ return AsyncImageResourceWithStreamingResponse(self)
+
+ async def create(
+ self,
+ *,
+ config_id: str,
+ input: image_create_params.Input,
+ # 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:
+ """
+ Start an image generation task using a saved Model Router config instead of
+ naming a model.
+
+ Args:
+ config_id: The slug of a saved Model Router config to route this request with.
+
+ input: Model-agnostic image generation input. The router selects a model and maps these
+ options to it.
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ return await self._post(
+ "/v1/generate/image",
+ body=await async_maybe_transform(
+ {
+ "config_id": config_id,
+ "input": input,
+ },
+ image_create_params.ImageCreateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=create_async_waitable_resource(ImageCreateResponse, self._client),
+ )
+
+
+class ImageResourceWithRawResponse:
+ def __init__(self, image: ImageResource) -> None:
+ self._image = image
+
+ self.create = to_raw_response_wrapper(
+ image.create,
+ )
+
+
+class AsyncImageResourceWithRawResponse:
+ def __init__(self, image: AsyncImageResource) -> None:
+ self._image = image
+
+ self.create = async_to_raw_response_wrapper(
+ image.create,
+ )
+
+
+class ImageResourceWithStreamingResponse:
+ def __init__(self, image: ImageResource) -> None:
+ self._image = image
+
+ self.create = to_streamed_response_wrapper(
+ image.create,
+ )
+
+
+class AsyncImageResourceWithStreamingResponse:
+ def __init__(self, image: AsyncImageResource) -> None:
+ self._image = image
+
+ self.create = async_to_streamed_response_wrapper(
+ image.create,
+ )
diff --git a/src/runwayml/resources/generate/video.py b/src/runwayml/resources/generate/video.py
index 3750712..ecf7cec 100644
--- a/src/runwayml/resources/generate/video.py
+++ b/src/runwayml/resources/generate/video.py
@@ -23,7 +23,7 @@
)
from ..._base_client import make_request_options
from ...types.generate import video_create_params
-from ...types.generate.video_create_response import RoutedVideoTaskCreated
+from ...types.generate.video_create_response import VideoCreateResponse
__all__ = ["VideoResource", "AsyncVideoResource"]
@@ -64,6 +64,9 @@ def create(
Start a video generation task using a saved Model Router config instead of
naming a model.
+ The SDK does not expose dry-run for this endpoint yet — use the HTTP API with
+ ``dry_run=True`` if you need a routing preview without creating a task.
+
Args:
config_id: The slug of a saved Model Router config to route this request with.
@@ -90,7 +93,7 @@ def create(
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
- cast_to=create_waitable_resource(RoutedVideoTaskCreated, self._client),
+ cast_to=create_waitable_resource(VideoCreateResponse, self._client),
)
@@ -130,6 +133,9 @@ async def create(
Start a video generation task using a saved Model Router config instead of
naming a model.
+ The SDK does not expose dry-run for this endpoint yet — use the HTTP API with
+ ``dry_run=True`` if you need a routing preview without creating a task.
+
Args:
config_id: The slug of a saved Model Router config to route this request with.
@@ -156,7 +162,7 @@ async def create(
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
- cast_to=create_async_waitable_resource(RoutedVideoTaskCreated, self._client),
+ cast_to=create_async_waitable_resource(VideoCreateResponse, self._client),
)
diff --git a/src/runwayml/types/generate/__init__.py b/src/runwayml/types/generate/__init__.py
index 809aa0d..721aead 100644
--- a/src/runwayml/types/generate/__init__.py
+++ b/src/runwayml/types/generate/__init__.py
@@ -2,5 +2,9 @@
from __future__ import annotations
+from .audio_create_params import AudioCreateParams as AudioCreateParams
+from .image_create_params import ImageCreateParams as ImageCreateParams
from .video_create_params import VideoCreateParams as VideoCreateParams
+from .audio_create_response import AudioCreateResponse as AudioCreateResponse
+from .image_create_response import ImageCreateResponse as ImageCreateResponse
from .video_create_response import VideoCreateResponse as VideoCreateResponse
diff --git a/src/runwayml/types/generate/audio_create_params.py b/src/runwayml/types/generate/audio_create_params.py
new file mode 100644
index 0000000..c5f8b12
--- /dev/null
+++ b/src/runwayml/types/generate/audio_create_params.py
@@ -0,0 +1,160 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Union, Iterable
+from typing_extensions import Literal, Required, Annotated, TypeAlias, TypedDict
+
+from ..._utils import PropertyInfo
+
+__all__ = [
+ "AudioCreateParams",
+ "Input",
+ "InputReferenceAudio",
+ "InputVoice",
+ "InputVoicePreset",
+ "InputVoiceReferenceAudio",
+]
+
+
+class AudioCreateParams(TypedDict, total=False):
+ config_id: Required[Annotated[str, PropertyInfo(alias="configId")]]
+ """The slug of a saved Model Router config to route this request with."""
+
+ input: Required[Input]
+ """Model-agnostic audio generation input.
+
+ The router selects a model and maps these options to it.
+ """
+
+
+class InputReferenceAudio(TypedDict, total=False):
+ uri: Required[str]
+ """A HTTPS URL."""
+
+
+class InputVoicePreset(TypedDict, total=False):
+ """A preset voice."""
+
+ preset_id: Required[
+ Annotated[
+ Literal[
+ "Maya",
+ "Arjun",
+ "Serene",
+ "Bernard",
+ "Billy",
+ "Mark",
+ "Clint",
+ "Mabel",
+ "Chad",
+ "Leslie",
+ "Eleanor",
+ "Elias",
+ "Elliot",
+ "Grungle",
+ "Brodie",
+ "Sandra",
+ "Kirk",
+ "Kylie",
+ "Lara",
+ "Lisa",
+ "Malachi",
+ "Marlene",
+ "Martin",
+ "Miriam",
+ "Monster",
+ "Paula",
+ "Pip",
+ "Rusty",
+ "Ragnar",
+ "Xylar",
+ "Maggie",
+ "Jack",
+ "Katie",
+ "Noah",
+ "James",
+ "Rina",
+ "Ella",
+ "Mariah",
+ "Frank",
+ "Claudia",
+ "Niki",
+ "Vincent",
+ "Kendrick",
+ "Myrna",
+ "Tom",
+ "Wanda",
+ "Benjamin",
+ "Kiana",
+ "Rachel",
+ ],
+ PropertyInfo(alias="presetId"),
+ ]
+ ]
+ """A Runway preset voice id.
+
+ Choosing a preset routes only to models that support preset voices.
+ """
+
+ type: Required[Literal["preset"]]
+
+
+class InputVoiceReferenceAudio(TypedDict, total=False):
+ """Clone a voice from a reference audio clip, then speak promptText in that voice.
+
+ Routes only to models that support voice cloning.
+ """
+
+ audio_uri: Required[Annotated[str, PropertyInfo(alias="audioUri")]]
+ """A HTTPS URL."""
+
+ type: Required[Literal["reference-audio"]]
+
+
+InputVoice: TypeAlias = Union[InputVoicePreset, InputVoiceReferenceAudio]
+
+
+class Input(TypedDict, total=False):
+ """Model-agnostic audio generation input.
+
+ The router selects a model and maps these options to it.
+ """
+
+ prompt_text: Required[Annotated[str, PropertyInfo(alias="promptText")]]
+ """For `speech`, the words to speak.
+
+ For `audio`, a description of the desired output.
+ """
+
+ type: Required[Literal["speech", "audio"]]
+ """
+ How promptText is interpreted: `speech` speaks it verbatim as a script; `audio`
+ treats it as a description of the desired audio, which may combine speech,
+ music, ambience, and sound effects.
+ """
+
+ duration: float
+ """Desired output duration in seconds for `audio` generation.
+
+ Models that cannot honor an explicit duration are excluded.
+ """
+
+ loop: bool
+ """When true, the `audio` output is designed to loop seamlessly.
+
+ Models without loop support are excluded.
+ """
+
+ reference_audios: Annotated[Iterable[InputReferenceAudio], PropertyInfo(alias="referenceAudios")]
+ """
+ Optional reference audio clips guiding `audio` generation, for models that
+ support them. Reference each clip in promptText as @Audio1, @Audio2, and @Audio3
+ in order.
+ """
+
+ voice: InputVoice
+ """The voice to speak with.
+
+ When omitted, models that support a default voice remain eligible.
+ """
diff --git a/src/runwayml/types/generate/audio_create_response.py b/src/runwayml/types/generate/audio_create_response.py
new file mode 100644
index 0000000..ebce1ce
--- /dev/null
+++ b/src/runwayml/types/generate/audio_create_response.py
@@ -0,0 +1,83 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import Optional
+from typing_extensions import Literal
+
+from pydantic import Field as FieldInfo
+
+from ..._models import BaseModel
+
+__all__ = ["AudioCreateResponse", "Routing", "RoutingEstimatedCost", "RoutingResolvedInput", "RoutingResolvedSettings"]
+
+
+class RoutingEstimatedCost(BaseModel):
+ """Estimated cost, computed against current pricing."""
+
+ credits: float
+ """Estimated cost of the generation in credits."""
+
+
+class RoutingResolvedInput(BaseModel):
+ """Request-side defaults resolved for the routing response.
+
+ Not necessarily identical to prepared model options.
+ """
+
+ type: Literal["speech", "audio"]
+ """The prompt mode the router routed for."""
+
+ voice: Literal["preset", "reference-audio", "default", "none"]
+ """
+ How the selected model resolves the voice: the requested preset or
+ reference-audio clone, the model default for voiceless speech, or none for
+ general audio.
+ """
+
+
+class RoutingResolvedSettings(BaseModel):
+ """The resolved config settings the router used for this request."""
+
+ optimize_for: Literal["cost", "latency", "quality"] = FieldInfo(alias="optimizeFor")
+ """
+ The single optimization preference the config selected, used as the soft
+ weighting when scoring eligible models.
+ """
+
+ price_ceiling: Optional[float] = FieldInfo(alias="priceCeiling", default=None)
+ """
+ The applied maximum credits per generation for this request’s modality, or null
+ if the config sets no ceiling.
+ """
+
+
+class Routing(BaseModel):
+ """Metadata describing which model the router selected and why."""
+
+ config_id: str = FieldInfo(alias="configId")
+ """The slug of the router config that was applied to this request."""
+
+ estimated_cost: RoutingEstimatedCost = FieldInfo(alias="estimatedCost")
+ """Estimated cost, computed against current pricing."""
+
+ model: str
+ """The public name of the model the router selected."""
+
+ provider: str
+ """The provider of the selected model."""
+
+ resolved_input: RoutingResolvedInput = FieldInfo(alias="resolvedInput")
+ """Request-side defaults resolved for the routing response.
+
+ Not necessarily identical to prepared model options.
+ """
+
+ resolved_settings: RoutingResolvedSettings = FieldInfo(alias="resolvedSettings")
+ """The resolved config settings the router used for this request."""
+
+
+class AudioCreateResponse(BaseModel):
+ id: str
+ """The ID of the created task. Poll GET /v1/tasks/:id for the result."""
+
+ routing: Routing
+ """Metadata describing which model the router selected and why."""
diff --git a/src/runwayml/types/generate/image_create_params.py b/src/runwayml/types/generate/image_create_params.py
new file mode 100644
index 0000000..5ac1a88
--- /dev/null
+++ b/src/runwayml/types/generate/image_create_params.py
@@ -0,0 +1,83 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Iterable
+from typing_extensions import Literal, Required, Annotated, TypedDict
+
+from ..._utils import PropertyInfo
+
+__all__ = ["ImageCreateParams", "Input", "InputContentModeration", "InputReferenceImage"]
+
+
+class ImageCreateParams(TypedDict, total=False):
+ config_id: Required[Annotated[str, PropertyInfo(alias="configId")]]
+ """The slug of a saved Model Router config to route this request with."""
+
+ input: Required[Input]
+ """Model-agnostic image generation input.
+
+ The router selects a model and maps these options to it.
+ """
+
+
+class InputContentModeration(TypedDict, total=False):
+ """Settings that affect the behavior of the content moderation system."""
+
+ public_figure_threshold: Annotated[Literal["auto", "low"], PropertyInfo(alias="publicFigureThreshold")]
+ """
+ When set to `low`, the content moderation system will be less strict about
+ preventing generations that include recognizable public figures.
+ """
+
+
+class InputReferenceImage(TypedDict, total=False):
+ uri: Required[str]
+ """A HTTPS URL."""
+
+
+class Input(TypedDict, total=False):
+ """Model-agnostic image generation input.
+
+ The router selects a model and maps these options to it.
+ """
+
+ prompt_text: Required[Annotated[str, PropertyInfo(alias="promptText")]]
+ """A text prompt describing the desired image."""
+
+ aspect_ratio: Annotated[
+ Literal["16:9", "9:16", "1:1", "4:3", "3:4", "21:9", "2:3", "3:2", "4:5", "5:4"],
+ PropertyInfo(alias="aspectRatio"),
+ ]
+ """Desired aspect ratio.
+
+ Models that do not support the requested aspect are excluded.
+ """
+
+ content_moderation: Annotated[InputContentModeration, PropertyInfo(alias="contentModeration")]
+ """Settings that affect the behavior of the content moderation system."""
+
+ output_count: Annotated[int, PropertyInfo(alias="outputCount")]
+ """Number of images to generate (1–10).
+
+ Models that cannot produce the exact count are excluded and cost scales with
+ this value.
+ """
+
+ reference_images: Annotated[Iterable[InputReferenceImage], PropertyInfo(alias="referenceImages")]
+ """Optional reference images for models that support them.
+
+ Tags are assigned per model when omitted.
+ """
+
+ resolution: Literal["1k", "2k", "4k"]
+ """Desired megapixel tier.
+
+ Models that do not support the requested tier are excluded.
+ """
+
+ seed: int
+ """A seed for reproducible generation.
+
+ Only gen4_image and gen4_image_turbo accept this field.
+ """
diff --git a/src/runwayml/types/generate/image_create_response.py b/src/runwayml/types/generate/image_create_response.py
new file mode 100644
index 0000000..fb415da
--- /dev/null
+++ b/src/runwayml/types/generate/image_create_response.py
@@ -0,0 +1,85 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import Optional
+from typing_extensions import Literal
+
+from pydantic import Field as FieldInfo
+
+from ..._models import BaseModel
+
+__all__ = ["ImageCreateResponse", "Routing", "RoutingEstimatedCost", "RoutingResolvedInput", "RoutingResolvedSettings"]
+
+
+class RoutingEstimatedCost(BaseModel):
+ """Estimated cost, computed against current pricing."""
+
+ credits: float
+ """Estimated cost of the generation in credits."""
+
+
+class RoutingResolvedInput(BaseModel):
+ """Request-side defaults resolved for the routing response.
+
+ Not necessarily identical to prepared model options.
+ """
+
+ aspect_ratio: str = FieldInfo(alias="aspectRatio")
+ """Aspect ratio used for routing display."""
+
+ ratio: str
+ """
+ Concrete output ratio derived from aspectRatio and resolution for the selected
+ model.
+ """
+
+ resolution: str
+ """Megapixel tier used for routing display."""
+
+
+class RoutingResolvedSettings(BaseModel):
+ """The resolved config settings the router used for this request."""
+
+ optimize_for: Literal["cost", "latency", "quality"] = FieldInfo(alias="optimizeFor")
+ """
+ The single optimization preference the config selected, used as the soft
+ weighting when scoring eligible models.
+ """
+
+ price_ceiling: Optional[float] = FieldInfo(alias="priceCeiling", default=None)
+ """
+ The applied maximum credits per generation for this request’s modality, or null
+ if the config sets no ceiling.
+ """
+
+
+class Routing(BaseModel):
+ """Metadata describing which model the router selected and why."""
+
+ config_id: str = FieldInfo(alias="configId")
+ """The slug of the router config that was applied to this request."""
+
+ estimated_cost: RoutingEstimatedCost = FieldInfo(alias="estimatedCost")
+ """Estimated cost, computed against current pricing."""
+
+ model: str
+ """The public name of the model the router selected."""
+
+ provider: str
+ """The provider of the selected model."""
+
+ resolved_input: RoutingResolvedInput = FieldInfo(alias="resolvedInput")
+ """Request-side defaults resolved for the routing response.
+
+ Not necessarily identical to prepared model options.
+ """
+
+ resolved_settings: RoutingResolvedSettings = FieldInfo(alias="resolvedSettings")
+ """The resolved config settings the router used for this request."""
+
+
+class ImageCreateResponse(BaseModel):
+ id: str
+ """The ID of the created task. Poll GET /v1/tasks/:id for the result."""
+
+ routing: Routing
+ """Metadata describing which model the router selected and why."""
diff --git a/src/runwayml/types/generate/video_create_params.py b/src/runwayml/types/generate/video_create_params.py
index e2b8ef2..1c9d81a 100644
--- a/src/runwayml/types/generate/video_create_params.py
+++ b/src/runwayml/types/generate/video_create_params.py
@@ -32,13 +32,6 @@ class VideoCreateParams(TypedDict, total=False):
Fields are optional; the router selects a model and maps these options to it.
"""
- dry_run: Annotated[bool, PropertyInfo(alias="dryRun")]
- """
- When true, run the full routing pipeline and return the decision and estimated
- cost without generating. No task is created, nothing is billed, and no asset is
- produced.
- """
-
class InputContentModeration(TypedDict, total=False):
"""Settings that affect the behavior of the content moderation system."""
diff --git a/src/runwayml/types/generate/video_create_response.py b/src/runwayml/types/generate/video_create_response.py
index 24fd33b..0624cc1 100644
--- a/src/runwayml/types/generate/video_create_response.py
+++ b/src/runwayml/types/generate/video_create_response.py
@@ -1,113 +1,23 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import Union, Optional
-from typing_extensions import Literal, Annotated, TypeAlias
+from typing import Optional
+from typing_extensions import Literal
from pydantic import Field as FieldInfo
-from ..._utils import PropertyInfo
from ..._models import BaseModel
-__all__ = [
- "VideoCreateResponse",
- "RoutedVideoTaskCreated",
- "RoutedVideoTaskCreatedRouting",
- "RoutedVideoTaskCreatedRoutingEstimatedCost",
- "RoutedVideoTaskCreatedRoutingResolvedInput",
- "RoutedVideoTaskCreatedRoutingResolvedSettings",
- "RoutedVideoDryRun",
- "RoutedVideoDryRunRouting",
- "RoutedVideoDryRunRoutingEstimatedCost",
- "RoutedVideoDryRunRoutingResolvedInput",
- "RoutedVideoDryRunRoutingResolvedSettings",
-]
-
-
-class RoutedVideoTaskCreatedRoutingEstimatedCost(BaseModel):
- """Estimated cost, computed against current pricing."""
-
- credits: float
- """Estimated cost of the generation in credits."""
-
-
-class RoutedVideoTaskCreatedRoutingResolvedInput(BaseModel):
- """Request-side defaults resolved for the routing response.
-
- Not necessarily identical to prepared model options.
- """
+__all__ = ["VideoCreateResponse", "Routing", "RoutingEstimatedCost", "RoutingResolvedInput", "RoutingResolvedSettings"]
- duration: float
- """Duration in seconds used for routing display (request value or router default)."""
-
- ratio: str
- """Concrete output ratio derived from aspectRatio (e.g.
-
- "1280:720"), or the router default.
- """
- resolution: str
- """Resolution tier from the request, or the router default when omitted."""
-
-
-class RoutedVideoTaskCreatedRoutingResolvedSettings(BaseModel):
- """The resolved config settings the router used for this request."""
-
- optimize_for: Literal["cost", "latency", "quality"] = FieldInfo(alias="optimizeFor")
- """
- The single optimization preference the config selected, used as the soft
- weighting when scoring eligible models.
- """
-
- price_ceiling: Optional[float] = FieldInfo(alias="priceCeiling", default=None)
- """
- The applied maximum credits per generation for this request’s modality, or null
- if the config sets no ceiling.
- """
-
-
-class RoutedVideoTaskCreatedRouting(BaseModel):
- """Metadata describing which model the router selected and why."""
-
- config_id: str = FieldInfo(alias="configId")
- """The slug of the router config that was applied to this request."""
-
- estimated_cost: RoutedVideoTaskCreatedRoutingEstimatedCost = FieldInfo(alias="estimatedCost")
- """Estimated cost, computed against current pricing."""
-
- model: str
- """The public name of the model the router selected."""
-
- provider: str
- """The provider of the selected model."""
-
- resolved_input: RoutedVideoTaskCreatedRoutingResolvedInput = FieldInfo(alias="resolvedInput")
- """Request-side defaults resolved for the routing response.
-
- Not necessarily identical to prepared model options.
- """
-
- resolved_settings: RoutedVideoTaskCreatedRoutingResolvedSettings = FieldInfo(alias="resolvedSettings")
- """The resolved config settings the router used for this request."""
-
-
-class RoutedVideoTaskCreated(BaseModel):
- id: str
- """The ID of the created task. Poll GET /v1/tasks/:id for the result."""
-
- dry_run: Literal[False] = FieldInfo(alias="dryRun")
-
- routing: RoutedVideoTaskCreatedRouting
- """Metadata describing which model the router selected and why."""
-
-
-class RoutedVideoDryRunRoutingEstimatedCost(BaseModel):
+class RoutingEstimatedCost(BaseModel):
"""Estimated cost, computed against current pricing."""
credits: float
"""Estimated cost of the generation in credits."""
-class RoutedVideoDryRunRoutingResolvedInput(BaseModel):
+class RoutingResolvedInput(BaseModel):
"""Request-side defaults resolved for the routing response.
Not necessarily identical to prepared model options.
@@ -126,7 +36,7 @@ class RoutedVideoDryRunRoutingResolvedInput(BaseModel):
"""Resolution tier from the request, or the router default when omitted."""
-class RoutedVideoDryRunRoutingResolvedSettings(BaseModel):
+class RoutingResolvedSettings(BaseModel):
"""The resolved config settings the router used for this request."""
optimize_for: Literal["cost", "latency", "quality"] = FieldInfo(alias="optimizeFor")
@@ -142,13 +52,13 @@ class RoutedVideoDryRunRoutingResolvedSettings(BaseModel):
"""
-class RoutedVideoDryRunRouting(BaseModel):
+class Routing(BaseModel):
"""Metadata describing which model the router selected and why."""
config_id: str = FieldInfo(alias="configId")
"""The slug of the router config that was applied to this request."""
- estimated_cost: RoutedVideoDryRunRoutingEstimatedCost = FieldInfo(alias="estimatedCost")
+ estimated_cost: RoutingEstimatedCost = FieldInfo(alias="estimatedCost")
"""Estimated cost, computed against current pricing."""
model: str
@@ -157,23 +67,19 @@ class RoutedVideoDryRunRouting(BaseModel):
provider: str
"""The provider of the selected model."""
- resolved_input: RoutedVideoDryRunRoutingResolvedInput = FieldInfo(alias="resolvedInput")
+ resolved_input: RoutingResolvedInput = FieldInfo(alias="resolvedInput")
"""Request-side defaults resolved for the routing response.
Not necessarily identical to prepared model options.
"""
- resolved_settings: RoutedVideoDryRunRoutingResolvedSettings = FieldInfo(alias="resolvedSettings")
+ resolved_settings: RoutingResolvedSettings = FieldInfo(alias="resolvedSettings")
"""The resolved config settings the router used for this request."""
-class RoutedVideoDryRun(BaseModel):
- dry_run: Literal[True] = FieldInfo(alias="dryRun")
+class VideoCreateResponse(BaseModel):
+ id: str
+ """The ID of the created task. Poll GET /v1/tasks/:id for the result."""
- routing: RoutedVideoDryRunRouting
+ routing: Routing
"""Metadata describing which model the router selected and why."""
-
-
-VideoCreateResponse: TypeAlias = Annotated[
- Union[RoutedVideoTaskCreated, RoutedVideoDryRun], PropertyInfo(discriminator="dry_run")
-]
diff --git a/src/runwayml/types/organization_retrieve_usage_response.py b/src/runwayml/types/organization_retrieve_usage_response.py
index 53971c4..549c750 100644
--- a/src/runwayml/types/organization_retrieve_usage_response.py
+++ b/src/runwayml/types/organization_retrieve_usage_response.py
@@ -1,14 +1,20 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
import datetime
-from typing import List
+from typing import List, Optional
from typing_extensions import Literal
from pydantic import Field as FieldInfo
from .._models import BaseModel
-__all__ = ["OrganizationRetrieveUsageResponse", "Result", "ResultUsedCredit"]
+__all__ = [
+ "OrganizationRetrieveUsageResponse",
+ "Result",
+ "ResultUsedCredit",
+ "ResultsByAPIKey",
+ "ResultsByAPIKeyUsedCredit",
+]
class ResultUsedCredit(BaseModel):
@@ -84,6 +90,18 @@ class Result(BaseModel):
"""The credits used per model for the given date."""
+class ResultsByAPIKeyUsedCredit(BaseModel):
+ amount: int
+
+ api_key_id: str = FieldInfo(alias="apiKeyId")
+
+
+class ResultsByAPIKey(BaseModel):
+ date: datetime.date
+
+ used_credits: List[ResultsByAPIKeyUsedCredit] = FieldInfo(alias="usedCredits")
+
+
class OrganizationRetrieveUsageResponse(BaseModel):
models: List[
Literal[
@@ -142,3 +160,9 @@ class OrganizationRetrieveUsageResponse(BaseModel):
"""The list of models with usage during the queried time range."""
results: List[Result]
+
+ api_keys: Optional[List[str]] = FieldInfo(alias="apiKeys", default=None)
+ """Reserved for future use."""
+
+ results_by_api_key: Optional[List[ResultsByAPIKey]] = FieldInfo(alias="resultsByApiKey", default=None)
+ """Reserved for future use."""
diff --git a/src/runwayml/types/router_create_params.py b/src/runwayml/types/router_create_params.py
index cc393ae..b10a7b3 100644
--- a/src/runwayml/types/router_create_params.py
+++ b/src/runwayml/types/router_create_params.py
@@ -50,7 +50,7 @@ class SettingsMaxCreditsPerGeneration(TypedDict, total=False):
class SettingsModels(TypedDict, total=False):
"""
- When mode is allow_new_except, ids are excluded; when allowlist_only, ids are the only allowed values. Each id must be a known public video model name (unknown ids are rejected on create/update).
+ When mode is allow_new_except, ids are excluded; when allowlist_only, ids are the only allowed values. Each id must be a known public video or image model name (unknown ids are rejected on create/update).
"""
ids: Required[SequenceNotStr[str]]
@@ -75,8 +75,8 @@ class Settings(TypedDict, total=False):
models: SettingsModels
"""
When mode is allow_new_except, ids are excluded; when allowlist_only, ids are
- the only allowed values. Each id must be a known public video model name
- (unknown ids are rejected on create/update).
+ the only allowed values. Each id must be a known public video or image model
+ name (unknown ids are rejected on create/update).
"""
optimize_for: Annotated[Literal["cost", "latency", "quality"], PropertyInfo(alias="optimizeFor")]
diff --git a/src/runwayml/types/router_create_response.py b/src/runwayml/types/router_create_response.py
index 75c7a94..2d1d33d 100644
--- a/src/runwayml/types/router_create_response.py
+++ b/src/runwayml/types/router_create_response.py
@@ -26,7 +26,7 @@ class SettingsMaxCreditsPerGeneration(BaseModel):
class SettingsModels(BaseModel):
"""
- When mode is allow_new_except, ids are excluded; when allowlist_only, ids are the only allowed values. Each id must be a known public video model name (unknown ids are rejected on create/update).
+ When mode is allow_new_except, ids are excluded; when allowlist_only, ids are the only allowed values. Each id must be a known public video or image model name (unknown ids are rejected on create/update).
"""
ids: List[str]
@@ -49,8 +49,8 @@ class Settings(BaseModel):
models: Optional[SettingsModels] = None
"""
When mode is allow_new_except, ids are excluded; when allowlist_only, ids are
- the only allowed values. Each id must be a known public video model name
- (unknown ids are rejected on create/update).
+ the only allowed values. Each id must be a known public video or image model
+ name (unknown ids are rejected on create/update).
"""
optimize_for: Optional[Literal["cost", "latency", "quality"]] = FieldInfo(alias="optimizeFor", default=None)
diff --git a/src/runwayml/types/router_list_response.py b/src/runwayml/types/router_list_response.py
index c465ef1..2e7e3c0 100644
--- a/src/runwayml/types/router_list_response.py
+++ b/src/runwayml/types/router_list_response.py
@@ -26,7 +26,7 @@ class SettingsMaxCreditsPerGeneration(BaseModel):
class SettingsModels(BaseModel):
"""
- When mode is allow_new_except, ids are excluded; when allowlist_only, ids are the only allowed values. Each id must be a known public video model name (unknown ids are rejected on create/update).
+ When mode is allow_new_except, ids are excluded; when allowlist_only, ids are the only allowed values. Each id must be a known public video or image model name (unknown ids are rejected on create/update).
"""
ids: List[str]
@@ -49,8 +49,8 @@ class Settings(BaseModel):
models: Optional[SettingsModels] = None
"""
When mode is allow_new_except, ids are excluded; when allowlist_only, ids are
- the only allowed values. Each id must be a known public video model name
- (unknown ids are rejected on create/update).
+ the only allowed values. Each id must be a known public video or image model
+ name (unknown ids are rejected on create/update).
"""
optimize_for: Optional[Literal["cost", "latency", "quality"]] = FieldInfo(alias="optimizeFor", default=None)
diff --git a/src/runwayml/types/router_retrieve_response.py b/src/runwayml/types/router_retrieve_response.py
index 84882b0..571c31b 100644
--- a/src/runwayml/types/router_retrieve_response.py
+++ b/src/runwayml/types/router_retrieve_response.py
@@ -26,7 +26,7 @@ class SettingsMaxCreditsPerGeneration(BaseModel):
class SettingsModels(BaseModel):
"""
- When mode is allow_new_except, ids are excluded; when allowlist_only, ids are the only allowed values. Each id must be a known public video model name (unknown ids are rejected on create/update).
+ When mode is allow_new_except, ids are excluded; when allowlist_only, ids are the only allowed values. Each id must be a known public video or image model name (unknown ids are rejected on create/update).
"""
ids: List[str]
@@ -49,8 +49,8 @@ class Settings(BaseModel):
models: Optional[SettingsModels] = None
"""
When mode is allow_new_except, ids are excluded; when allowlist_only, ids are
- the only allowed values. Each id must be a known public video model name
- (unknown ids are rejected on create/update).
+ the only allowed values. Each id must be a known public video or image model
+ name (unknown ids are rejected on create/update).
"""
optimize_for: Optional[Literal["cost", "latency", "quality"]] = FieldInfo(alias="optimizeFor", default=None)
diff --git a/src/runwayml/types/router_update_params.py b/src/runwayml/types/router_update_params.py
index c658374..f2a3628 100644
--- a/src/runwayml/types/router_update_params.py
+++ b/src/runwayml/types/router_update_params.py
@@ -40,7 +40,7 @@ class SettingsMaxCreditsPerGeneration(TypedDict, total=False):
class SettingsModels(TypedDict, total=False):
"""
- When mode is allow_new_except, ids are excluded; when allowlist_only, ids are the only allowed values. Each id must be a known public video model name (unknown ids are rejected on create/update).
+ When mode is allow_new_except, ids are excluded; when allowlist_only, ids are the only allowed values. Each id must be a known public video or image model name (unknown ids are rejected on create/update).
"""
ids: Required[SequenceNotStr[str]]
@@ -65,8 +65,8 @@ class Settings(TypedDict, total=False):
models: SettingsModels
"""
When mode is allow_new_except, ids are excluded; when allowlist_only, ids are
- the only allowed values. Each id must be a known public video model name
- (unknown ids are rejected on create/update).
+ the only allowed values. Each id must be a known public video or image model
+ name (unknown ids are rejected on create/update).
"""
optimize_for: Annotated[Literal["cost", "latency", "quality"], PropertyInfo(alias="optimizeFor")]
diff --git a/src/runwayml/types/router_update_response.py b/src/runwayml/types/router_update_response.py
index 01c607f..a421b05 100644
--- a/src/runwayml/types/router_update_response.py
+++ b/src/runwayml/types/router_update_response.py
@@ -26,7 +26,7 @@ class SettingsMaxCreditsPerGeneration(BaseModel):
class SettingsModels(BaseModel):
"""
- When mode is allow_new_except, ids are excluded; when allowlist_only, ids are the only allowed values. Each id must be a known public video model name (unknown ids are rejected on create/update).
+ When mode is allow_new_except, ids are excluded; when allowlist_only, ids are the only allowed values. Each id must be a known public video or image model name (unknown ids are rejected on create/update).
"""
ids: List[str]
@@ -49,8 +49,8 @@ class Settings(BaseModel):
models: Optional[SettingsModels] = None
"""
When mode is allow_new_except, ids are excluded; when allowlist_only, ids are
- the only allowed values. Each id must be a known public video model name
- (unknown ids are rejected on create/update).
+ the only allowed values. Each id must be a known public video or image model
+ name (unknown ids are rejected on create/update).
"""
optimize_for: Optional[Literal["cost", "latency", "quality"]] = FieldInfo(alias="optimizeFor", default=None)
diff --git a/tests/api_resources/generate/test_audio.py b/tests/api_resources/generate/test_audio.py
new file mode 100644
index 0000000..d35e73b
--- /dev/null
+++ b/tests/api_resources/generate/test_audio.py
@@ -0,0 +1,146 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+import os
+from typing import Any, cast
+
+import pytest
+
+from runwayml import RunwayML, AsyncRunwayML
+from tests.utils import assert_matches_type
+from runwayml.types.generate import AudioCreateResponse
+
+base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
+
+
+class TestAudio:
+ parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
+
+ @parametrize
+ def test_method_create(self, client: RunwayML) -> None:
+ audio = client.generate.audio.create(
+ config_id="n6_",
+ input={
+ "prompt_text": "x",
+ "type": "speech",
+ },
+ )
+ assert_matches_type(AudioCreateResponse, audio, path=["response"])
+
+ @parametrize
+ def test_method_create_with_all_params(self, client: RunwayML) -> None:
+ audio = client.generate.audio.create(
+ config_id="n6_",
+ input={
+ "prompt_text": "x",
+ "type": "speech",
+ "duration": 0.5,
+ "loop": True,
+ "reference_audios": [{"uri": "https://example.com/file"}],
+ "voice": {
+ "preset_id": "Maya",
+ "type": "preset",
+ },
+ },
+ )
+ assert_matches_type(AudioCreateResponse, audio, path=["response"])
+
+ @parametrize
+ def test_raw_response_create(self, client: RunwayML) -> None:
+ response = client.generate.audio.with_raw_response.create(
+ config_id="n6_",
+ input={
+ "prompt_text": "x",
+ "type": "speech",
+ },
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ audio = response.parse()
+ assert_matches_type(AudioCreateResponse, audio, path=["response"])
+
+ @parametrize
+ def test_streaming_response_create(self, client: RunwayML) -> None:
+ with client.generate.audio.with_streaming_response.create(
+ config_id="n6_",
+ input={
+ "prompt_text": "x",
+ "type": "speech",
+ },
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ audio = response.parse()
+ assert_matches_type(AudioCreateResponse, audio, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+
+class TestAsyncAudio:
+ parametrize = pytest.mark.parametrize(
+ "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"]
+ )
+
+ @parametrize
+ async def test_method_create(self, async_client: AsyncRunwayML) -> None:
+ audio = await async_client.generate.audio.create(
+ config_id="n6_",
+ input={
+ "prompt_text": "x",
+ "type": "speech",
+ },
+ )
+ assert_matches_type(AudioCreateResponse, audio, path=["response"])
+
+ @parametrize
+ async def test_method_create_with_all_params(self, async_client: AsyncRunwayML) -> None:
+ audio = await async_client.generate.audio.create(
+ config_id="n6_",
+ input={
+ "prompt_text": "x",
+ "type": "speech",
+ "duration": 0.5,
+ "loop": True,
+ "reference_audios": [{"uri": "https://example.com/file"}],
+ "voice": {
+ "preset_id": "Maya",
+ "type": "preset",
+ },
+ },
+ )
+ assert_matches_type(AudioCreateResponse, audio, path=["response"])
+
+ @parametrize
+ async def test_raw_response_create(self, async_client: AsyncRunwayML) -> None:
+ response = await async_client.generate.audio.with_raw_response.create(
+ config_id="n6_",
+ input={
+ "prompt_text": "x",
+ "type": "speech",
+ },
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ audio = await response.parse()
+ assert_matches_type(AudioCreateResponse, audio, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_create(self, async_client: AsyncRunwayML) -> None:
+ async with async_client.generate.audio.with_streaming_response.create(
+ config_id="n6_",
+ input={
+ "prompt_text": "x",
+ "type": "speech",
+ },
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ audio = await response.parse()
+ assert_matches_type(AudioCreateResponse, audio, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
diff --git a/tests/api_resources/generate/test_image.py b/tests/api_resources/generate/test_image.py
new file mode 100644
index 0000000..886edbc
--- /dev/null
+++ b/tests/api_resources/generate/test_image.py
@@ -0,0 +1,124 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+import os
+from typing import Any, cast
+
+import pytest
+
+from runwayml import RunwayML, AsyncRunwayML
+from tests.utils import assert_matches_type
+from runwayml.types.generate import ImageCreateResponse
+
+base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
+
+
+class TestImage:
+ parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
+
+ @parametrize
+ def test_method_create(self, client: RunwayML) -> None:
+ image = client.generate.image.create(
+ config_id="n6_",
+ input={"prompt_text": "x"},
+ )
+ assert_matches_type(ImageCreateResponse, image, path=["response"])
+
+ @parametrize
+ def test_method_create_with_all_params(self, client: RunwayML) -> None:
+ image = client.generate.image.create(
+ config_id="n6_",
+ input={
+ "prompt_text": "x",
+ "aspect_ratio": "16:9",
+ "content_moderation": {"public_figure_threshold": "auto"},
+ "output_count": 1,
+ "reference_images": [{"uri": "https://example.com/file"}],
+ "resolution": "1k",
+ "seed": 0,
+ },
+ )
+ assert_matches_type(ImageCreateResponse, image, path=["response"])
+
+ @parametrize
+ def test_raw_response_create(self, client: RunwayML) -> None:
+ response = client.generate.image.with_raw_response.create(
+ config_id="n6_",
+ input={"prompt_text": "x"},
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ image = response.parse()
+ assert_matches_type(ImageCreateResponse, image, path=["response"])
+
+ @parametrize
+ def test_streaming_response_create(self, client: RunwayML) -> None:
+ with client.generate.image.with_streaming_response.create(
+ config_id="n6_",
+ input={"prompt_text": "x"},
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ image = response.parse()
+ assert_matches_type(ImageCreateResponse, image, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+
+class TestAsyncImage:
+ parametrize = pytest.mark.parametrize(
+ "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"]
+ )
+
+ @parametrize
+ async def test_method_create(self, async_client: AsyncRunwayML) -> None:
+ image = await async_client.generate.image.create(
+ config_id="n6_",
+ input={"prompt_text": "x"},
+ )
+ assert_matches_type(ImageCreateResponse, image, path=["response"])
+
+ @parametrize
+ async def test_method_create_with_all_params(self, async_client: AsyncRunwayML) -> None:
+ image = await async_client.generate.image.create(
+ config_id="n6_",
+ input={
+ "prompt_text": "x",
+ "aspect_ratio": "16:9",
+ "content_moderation": {"public_figure_threshold": "auto"},
+ "output_count": 1,
+ "reference_images": [{"uri": "https://example.com/file"}],
+ "resolution": "1k",
+ "seed": 0,
+ },
+ )
+ assert_matches_type(ImageCreateResponse, image, path=["response"])
+
+ @parametrize
+ async def test_raw_response_create(self, async_client: AsyncRunwayML) -> None:
+ response = await async_client.generate.image.with_raw_response.create(
+ config_id="n6_",
+ input={"prompt_text": "x"},
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ image = await response.parse()
+ assert_matches_type(ImageCreateResponse, image, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_create(self, async_client: AsyncRunwayML) -> None:
+ async with async_client.generate.image.with_streaming_response.create(
+ config_id="n6_",
+ input={"prompt_text": "x"},
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ image = await response.parse()
+ assert_matches_type(ImageCreateResponse, image, path=["response"])
+
+ assert cast(Any, response.is_closed) is True