diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 34f6b41..a5dd041 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "4.15.0" + ".": "4.16.0" } \ No newline at end of file diff --git a/.stats.yml b/.stats.yml index a2303a1..b6b14bc 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ -configured_endpoints: 37 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/runwayml/runwayml-ed8d0c17e291217781d37e1e60b969f2950d2fedaa182d41d80aac9945d1ff85.yml -openapi_spec_hash: 083b5c74652bfd7ba82748e1c04f8bc2 -config_hash: 3063a17ad98d447287f6f7eab9d6d1d6 +configured_endpoints: 38 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/runwayml/runwayml-cfb6e42f50c5de798cb44d95bb8e1e0b378a1cad932b937b249aca35136c7758.yml +openapi_spec_hash: 2d2bb8ab56561238e5415dbbd3e4d725 +config_hash: 6d8ca402de13857362ee587c404baca9 diff --git a/CHANGELOG.md b/CHANGELOG.md index 4dc8f5b..064cb33 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,20 @@ # Changelog +## 4.16.0 (2026-06-02) + +Full Changelog: [v4.15.0...v4.16.0](https://github.com/runwayml/sdk-python/compare/v4.15.0...v4.16.0) + +### Features + +* **api:** Aleph2 ([b36110b](https://github.com/runwayml/sdk-python/commit/b36110bebc1812e5d8a4e682b6af818cefcceed4)) +* **api:** Image upscale endpoint ([00f2d0b](https://github.com/runwayml/sdk-python/commit/00f2d0b573c0d282e2096eb1f22e053d9d5a506b)) + + +### Bug Fixes + +* **client:** Awaitable image upscale also ([346f07f](https://github.com/runwayml/sdk-python/commit/346f07ffc39d18ace05839d59550b5c72bcef941)) +* **client:** Updating typing for awaitable task output ([485c29c](https://github.com/runwayml/sdk-python/commit/485c29c031c84340742c27af823c9a28cc596d09)) + ## 4.15.0 (2026-05-11) Full Changelog: [v4.14.0...v4.15.0](https://github.com/runwayml/sdk-python/compare/v4.14.0...v4.15.0) diff --git a/api.md b/api.md index 14ba311..45069e1 100644 --- a/api.md +++ b/api.md @@ -131,6 +131,18 @@ Methods: - client.speech_to_speech.create(\*\*params) -> SpeechToSpeechCreateResponse +# ImageUpscale + +Types: + +```python +from runwayml.types import ImageUpscaleCreateResponse +``` + +Methods: + +- client.image_upscale.create(\*\*params) -> ImageUpscaleCreateResponse + # Organization Types: diff --git a/pyproject.toml b/pyproject.toml index ed2a7a4..9fc28f2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "runwayml" -version = "4.15.0" +version = "4.16.0" description = "The official Python library for the runwayml API" dynamic = ["readme"] license = "Apache-2.0" diff --git a/src/runwayml/_client.py b/src/runwayml/_client.py index 91f6d53..348e902 100644 --- a/src/runwayml/_client.py +++ b/src/runwayml/_client.py @@ -45,6 +45,7 @@ organization, sound_effect, avatar_videos, + image_upscale, text_to_image, text_to_video, voice_dubbing, @@ -66,6 +67,7 @@ from .resources.organization import OrganizationResource, AsyncOrganizationResource from .resources.sound_effect import SoundEffectResource, AsyncSoundEffectResource from .resources.avatar_videos import AvatarVideosResource, AsyncAvatarVideosResource + from .resources.image_upscale import ImageUpscaleResource, AsyncImageUpscaleResource from .resources.text_to_image import TextToImageResource, AsyncTextToImageResource from .resources.text_to_video import TextToVideoResource, AsyncTextToVideoResource from .resources.voice_dubbing import VoiceDubbingResource, AsyncVoiceDubbingResource @@ -243,6 +245,13 @@ def speech_to_speech(self) -> SpeechToSpeechResource: return SpeechToSpeechResource(self) + @cached_property + def image_upscale(self) -> ImageUpscaleResource: + """These endpoints all kick off tasks to create generations.""" + from .resources.image_upscale import ImageUpscaleResource + + return ImageUpscaleResource(self) + @cached_property def organization(self) -> OrganizationResource: from .resources.organization import OrganizationResource @@ -560,6 +569,13 @@ def speech_to_speech(self) -> AsyncSpeechToSpeechResource: return AsyncSpeechToSpeechResource(self) + @cached_property + def image_upscale(self) -> AsyncImageUpscaleResource: + """These endpoints all kick off tasks to create generations.""" + from .resources.image_upscale import AsyncImageUpscaleResource + + return AsyncImageUpscaleResource(self) + @cached_property def organization(self) -> AsyncOrganizationResource: from .resources.organization import AsyncOrganizationResource @@ -813,6 +829,13 @@ def speech_to_speech(self) -> speech_to_speech.SpeechToSpeechResourceWithRawResp return SpeechToSpeechResourceWithRawResponse(self._client.speech_to_speech) + @cached_property + def image_upscale(self) -> image_upscale.ImageUpscaleResourceWithRawResponse: + """These endpoints all kick off tasks to create generations.""" + from .resources.image_upscale import ImageUpscaleResourceWithRawResponse + + return ImageUpscaleResourceWithRawResponse(self._client.image_upscale) + @cached_property def organization(self) -> organization.OrganizationResourceWithRawResponse: from .resources.organization import OrganizationResourceWithRawResponse @@ -951,6 +974,13 @@ def speech_to_speech(self) -> speech_to_speech.AsyncSpeechToSpeechResourceWithRa return AsyncSpeechToSpeechResourceWithRawResponse(self._client.speech_to_speech) + @cached_property + def image_upscale(self) -> image_upscale.AsyncImageUpscaleResourceWithRawResponse: + """These endpoints all kick off tasks to create generations.""" + from .resources.image_upscale import AsyncImageUpscaleResourceWithRawResponse + + return AsyncImageUpscaleResourceWithRawResponse(self._client.image_upscale) + @cached_property def organization(self) -> organization.AsyncOrganizationResourceWithRawResponse: from .resources.organization import AsyncOrganizationResourceWithRawResponse @@ -1089,6 +1119,13 @@ def speech_to_speech(self) -> speech_to_speech.SpeechToSpeechResourceWithStreami return SpeechToSpeechResourceWithStreamingResponse(self._client.speech_to_speech) + @cached_property + def image_upscale(self) -> image_upscale.ImageUpscaleResourceWithStreamingResponse: + """These endpoints all kick off tasks to create generations.""" + from .resources.image_upscale import ImageUpscaleResourceWithStreamingResponse + + return ImageUpscaleResourceWithStreamingResponse(self._client.image_upscale) + @cached_property def organization(self) -> organization.OrganizationResourceWithStreamingResponse: from .resources.organization import OrganizationResourceWithStreamingResponse @@ -1227,6 +1264,13 @@ def speech_to_speech(self) -> speech_to_speech.AsyncSpeechToSpeechResourceWithSt return AsyncSpeechToSpeechResourceWithStreamingResponse(self._client.speech_to_speech) + @cached_property + def image_upscale(self) -> image_upscale.AsyncImageUpscaleResourceWithStreamingResponse: + """These endpoints all kick off tasks to create generations.""" + from .resources.image_upscale import AsyncImageUpscaleResourceWithStreamingResponse + + return AsyncImageUpscaleResourceWithStreamingResponse(self._client.image_upscale) + @cached_property def organization(self) -> organization.AsyncOrganizationResourceWithStreamingResponse: from .resources.organization import AsyncOrganizationResourceWithStreamingResponse diff --git a/src/runwayml/_version.py b/src/runwayml/_version.py index 84a72e7..48c10b2 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.15.0" # x-release-please-version +__version__ = "4.16.0" # x-release-please-version diff --git a/src/runwayml/resources/__init__.py b/src/runwayml/resources/__init__.py index 9f06fac..1aea4ab 100644 --- a/src/runwayml/resources/__init__.py +++ b/src/runwayml/resources/__init__.py @@ -72,6 +72,14 @@ AvatarVideosResourceWithStreamingResponse, AsyncAvatarVideosResourceWithStreamingResponse, ) +from .image_upscale import ( + ImageUpscaleResource, + AsyncImageUpscaleResource, + ImageUpscaleResourceWithRawResponse, + AsyncImageUpscaleResourceWithRawResponse, + ImageUpscaleResourceWithStreamingResponse, + AsyncImageUpscaleResourceWithStreamingResponse, +) from .text_to_image import ( TextToImageResource, AsyncTextToImageResource, @@ -228,6 +236,12 @@ "AsyncSpeechToSpeechResourceWithRawResponse", "SpeechToSpeechResourceWithStreamingResponse", "AsyncSpeechToSpeechResourceWithStreamingResponse", + "ImageUpscaleResource", + "AsyncImageUpscaleResource", + "ImageUpscaleResourceWithRawResponse", + "AsyncImageUpscaleResourceWithRawResponse", + "ImageUpscaleResourceWithStreamingResponse", + "AsyncImageUpscaleResourceWithStreamingResponse", "OrganizationResource", "AsyncOrganizationResource", "OrganizationResourceWithRawResponse", diff --git a/src/runwayml/resources/image_upscale.py b/src/runwayml/resources/image_upscale.py new file mode 100644 index 0000000..3534e97 --- /dev/null +++ b/src/runwayml/resources/image_upscale.py @@ -0,0 +1,246 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Literal + +import httpx + +from runwayml.lib.polling import ( + NewTaskCreatedResponse, + AsyncNewTaskCreatedResponse, + create_waitable_resource, + create_async_waitable_resource, +) + +from ..types import image_upscale_create_params +from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given +from .._utils import maybe_transform, async_maybe_transform +from .._compat import cached_property +from .._resource import SyncAPIResource, AsyncAPIResource +from .._response import ( + to_raw_response_wrapper, + to_streamed_response_wrapper, + async_to_raw_response_wrapper, + async_to_streamed_response_wrapper, +) +from .._base_client import make_request_options +from ..types.image_upscale_create_response import ImageUpscaleCreateResponse + +__all__ = ["ImageUpscaleResource", "AsyncImageUpscaleResource"] + + +class ImageUpscaleResource(SyncAPIResource): + """These endpoints all kick off tasks to create generations.""" + + @cached_property + def with_raw_response(self) -> ImageUpscaleResourceWithRawResponse: + """ + 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 ImageUpscaleResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> ImageUpscaleResourceWithStreamingResponse: + """ + 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 ImageUpscaleResourceWithStreamingResponse(self) + + def create( + self, + *, + image_uri: str, + model: Literal["magnific_precision_upscaler_v2"], + flavor: Literal["sublime", "photo", "photo_denoiser"] | Omit = omit, + scale_factor: Literal[2, 4, 8, 16] | Omit = omit, + sharpen: int | Omit = omit, + smart_grain: int | Omit = omit, + ultra_detail: int | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> NewTaskCreatedResponse: + """Upscale an image with Magnific precision upscaling. + + Each input dimension must be + between 300px and 8000px. Output width and height are the input dimensions + multiplied by `scaleFactor` (default 2). Output width times height cannot exceed + 25,300,000 pixels (~25.3 million). + + Args: + image_uri: A HTTPS URL. + + flavor: Optimization preset: `sublime` (illustration), `photo` (photographic), or + `photo_denoiser` (noisy photos). + + scale_factor: Multiplies each input dimension to produce output width and height. Defaults + to 2. + + sharpen: Sharpness intensity from 0 (none) to 100. + + smart_grain: Grain and texture enhancement from 0 to 100. + + ultra_detail: Fine detail enhancement from 0 to 100. + + 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/image_upscale", + body=maybe_transform( + { + "image_uri": image_uri, + "model": model, + "flavor": flavor, + "scale_factor": scale_factor, + "sharpen": sharpen, + "smart_grain": smart_grain, + "ultra_detail": ultra_detail, + }, + image_upscale_create_params.ImageUpscaleCreateParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=create_waitable_resource(ImageUpscaleCreateResponse, self._client), + ) + + +class AsyncImageUpscaleResource(AsyncAPIResource): + """These endpoints all kick off tasks to create generations.""" + + @cached_property + def with_raw_response(self) -> AsyncImageUpscaleResourceWithRawResponse: + """ + 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 AsyncImageUpscaleResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncImageUpscaleResourceWithStreamingResponse: + """ + 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 AsyncImageUpscaleResourceWithStreamingResponse(self) + + async def create( + self, + *, + image_uri: str, + model: Literal["magnific_precision_upscaler_v2"], + flavor: Literal["sublime", "photo", "photo_denoiser"] | Omit = omit, + scale_factor: Literal[2, 4, 8, 16] | Omit = omit, + sharpen: int | Omit = omit, + smart_grain: int | Omit = omit, + ultra_detail: int | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> AsyncNewTaskCreatedResponse: + """Upscale an image with Magnific precision upscaling. + + Each input dimension must be + between 300px and 8000px. Output width and height are the input dimensions + multiplied by `scaleFactor` (default 2). Output width times height cannot exceed + 25,300,000 pixels (~25.3 million). + + Args: + image_uri: A HTTPS URL. + + flavor: Optimization preset: `sublime` (illustration), `photo` (photographic), or + `photo_denoiser` (noisy photos). + + scale_factor: Multiplies each input dimension to produce output width and height. Defaults + to 2. + + sharpen: Sharpness intensity from 0 (none) to 100. + + smart_grain: Grain and texture enhancement from 0 to 100. + + ultra_detail: Fine detail enhancement from 0 to 100. + + 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/image_upscale", + body=await async_maybe_transform( + { + "image_uri": image_uri, + "model": model, + "flavor": flavor, + "scale_factor": scale_factor, + "sharpen": sharpen, + "smart_grain": smart_grain, + "ultra_detail": ultra_detail, + }, + image_upscale_create_params.ImageUpscaleCreateParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=create_async_waitable_resource(ImageUpscaleCreateResponse, self._client), + ) + + +class ImageUpscaleResourceWithRawResponse: + def __init__(self, image_upscale: ImageUpscaleResource) -> None: + self._image_upscale = image_upscale + + self.create = to_raw_response_wrapper( + image_upscale.create, + ) + + +class AsyncImageUpscaleResourceWithRawResponse: + def __init__(self, image_upscale: AsyncImageUpscaleResource) -> None: + self._image_upscale = image_upscale + + self.create = async_to_raw_response_wrapper( + image_upscale.create, + ) + + +class ImageUpscaleResourceWithStreamingResponse: + def __init__(self, image_upscale: ImageUpscaleResource) -> None: + self._image_upscale = image_upscale + + self.create = to_streamed_response_wrapper( + image_upscale.create, + ) + + +class AsyncImageUpscaleResourceWithStreamingResponse: + def __init__(self, image_upscale: AsyncImageUpscaleResource) -> None: + self._image_upscale = image_upscale + + self.create = async_to_streamed_response_wrapper( + image_upscale.create, + ) diff --git a/src/runwayml/resources/text_to_image.py b/src/runwayml/resources/text_to_image.py index 1455237..8b82bfc 100644 --- a/src/runwayml/resources/text_to_image.py +++ b/src/runwayml/resources/text_to_image.py @@ -332,6 +332,108 @@ def create( """ ... + @overload + def create( + self, + *, + model: Literal["gemini_image3.1_flash"], + prompt_text: str, + ratio: Literal[ + "512:512", + "416:624", + "624:416", + "432:592", + "592:432", + "448:576", + "576:448", + "384:672", + "672:384", + "768:336", + "256:1024", + "1024:256", + "176:1408", + "1408:176", + "1024:1024", + "832:1248", + "1248:832", + "864:1184", + "1184:864", + "896:1152", + "1152:896", + "768:1344", + "1344:768", + "1536:672", + "512:2048", + "2048:512", + "352:2816", + "2816:352", + "2048:2048", + "1696:2528", + "2528:1696", + "1792:2400", + "2400:1792", + "1856:2304", + "2304:1856", + "1536:2752", + "2752:1536", + "3168:1344", + "1024:4096", + "4096:1024", + "704:5632", + "5632:704", + "4096:4096", + "3392:5056", + "5056:3392", + "3584:4800", + "4800:3584", + "3712:4608", + "4608:3712", + "3072:5504", + "5504:3072", + "6336:2688", + "2048:8192", + "8192:2048", + "1408:11264", + "11264:1408", + ], + output_count: Literal[1, 4] | Omit = omit, + reference_images: Iterable[text_to_image_create_params.GeminiImage3_1FlashReferenceImage] | 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. + + output_count: The number of images to generate. Increasing this number will affect the number + of credits consumed by the generation. Up to four images can be generated at + once. + + 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, @@ -388,6 +490,7 @@ def create( | Literal["gen4_image"] | Literal["gpt_image_2"] | Literal["gemini_image3_pro"] + | Literal["gemini_image3.1_flash"] | Literal["gemini_2.5_flash"], prompt_text: str, ratio: Literal[ @@ -473,6 +576,64 @@ def create( "5504:3072", "6336:2688", ] + | Literal[ + "512:512", + "416:624", + "624:416", + "432:592", + "592:432", + "448:576", + "576:448", + "384:672", + "672:384", + "768:336", + "256:1024", + "1024:256", + "176:1408", + "1408:176", + "1024:1024", + "832:1248", + "1248:832", + "864:1184", + "1184:864", + "896:1152", + "1152:896", + "768:1344", + "1344:768", + "1536:672", + "512:2048", + "2048:512", + "352:2816", + "2816:352", + "2048:2048", + "1696:2528", + "2528:1696", + "1792:2400", + "2400:1792", + "1856:2304", + "2304:1856", + "1536:2752", + "2752:1536", + "3168:1344", + "1024:4096", + "4096:1024", + "704:5632", + "5632:704", + "4096:4096", + "3392:5056", + "5056:3392", + "3584:4800", + "4800:3584", + "3712:4608", + "4608:3712", + "3072:5504", + "5504:3072", + "6336:2688", + "2048:8192", + "8192:2048", + "1408:11264", + "11264:1408", + ] | Literal[ "1344:768", "768:1344", @@ -489,6 +650,7 @@ def create( | Iterable[text_to_image_create_params.Gen4ImageReferenceImage] | Iterable[text_to_image_create_params.GptImage2ReferenceImage] | Iterable[text_to_image_create_params.GeminiImage3ProReferenceImage] + | Iterable[text_to_image_create_params.GeminiImage3_1FlashReferenceImage] | Iterable[text_to_image_create_params.Gemini2_5FlashReferenceImage] | Omit = omit, content_moderation: text_to_image_create_params.Gen4ImageTurboContentModeration @@ -830,6 +992,108 @@ async def create( """ ... + @overload + async def create( + self, + *, + model: Literal["gemini_image3.1_flash"], + prompt_text: str, + ratio: Literal[ + "512:512", + "416:624", + "624:416", + "432:592", + "592:432", + "448:576", + "576:448", + "384:672", + "672:384", + "768:336", + "256:1024", + "1024:256", + "176:1408", + "1408:176", + "1024:1024", + "832:1248", + "1248:832", + "864:1184", + "1184:864", + "896:1152", + "1152:896", + "768:1344", + "1344:768", + "1536:672", + "512:2048", + "2048:512", + "352:2816", + "2816:352", + "2048:2048", + "1696:2528", + "2528:1696", + "1792:2400", + "2400:1792", + "1856:2304", + "2304:1856", + "1536:2752", + "2752:1536", + "3168:1344", + "1024:4096", + "4096:1024", + "704:5632", + "5632:704", + "4096:4096", + "3392:5056", + "5056:3392", + "3584:4800", + "4800:3584", + "3712:4608", + "4608:3712", + "3072:5504", + "5504:3072", + "6336:2688", + "2048:8192", + "8192:2048", + "1408:11264", + "11264:1408", + ], + output_count: Literal[1, 4] | Omit = omit, + reference_images: Iterable[text_to_image_create_params.GeminiImage3_1FlashReferenceImage] | 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. + + output_count: The number of images to generate. Increasing this number will affect the number + of credits consumed by the generation. Up to four images can be generated at + once. + + 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, @@ -886,6 +1150,7 @@ async def create( | Literal["gen4_image"] | Literal["gpt_image_2"] | Literal["gemini_image3_pro"] + | Literal["gemini_image3.1_flash"] | Literal["gemini_2.5_flash"], prompt_text: str, ratio: Literal[ @@ -971,6 +1236,64 @@ async def create( "5504:3072", "6336:2688", ] + | Literal[ + "512:512", + "416:624", + "624:416", + "432:592", + "592:432", + "448:576", + "576:448", + "384:672", + "672:384", + "768:336", + "256:1024", + "1024:256", + "176:1408", + "1408:176", + "1024:1024", + "832:1248", + "1248:832", + "864:1184", + "1184:864", + "896:1152", + "1152:896", + "768:1344", + "1344:768", + "1536:672", + "512:2048", + "2048:512", + "352:2816", + "2816:352", + "2048:2048", + "1696:2528", + "2528:1696", + "1792:2400", + "2400:1792", + "1856:2304", + "2304:1856", + "1536:2752", + "2752:1536", + "3168:1344", + "1024:4096", + "4096:1024", + "704:5632", + "5632:704", + "4096:4096", + "3392:5056", + "5056:3392", + "3584:4800", + "4800:3584", + "3712:4608", + "4608:3712", + "3072:5504", + "5504:3072", + "6336:2688", + "2048:8192", + "8192:2048", + "1408:11264", + "11264:1408", + ] | Literal[ "1344:768", "768:1344", @@ -987,6 +1310,7 @@ async def create( | Iterable[text_to_image_create_params.Gen4ImageReferenceImage] | Iterable[text_to_image_create_params.GptImage2ReferenceImage] | Iterable[text_to_image_create_params.GeminiImage3ProReferenceImage] + | Iterable[text_to_image_create_params.GeminiImage3_1FlashReferenceImage] | Iterable[text_to_image_create_params.Gemini2_5FlashReferenceImage] | Omit = omit, content_moderation: text_to_image_create_params.Gen4ImageTurboContentModeration diff --git a/src/runwayml/resources/video_to_video.py b/src/runwayml/resources/video_to_video.py index b09e799..ca6c2bb 100644 --- a/src/runwayml/resources/video_to_video.py +++ b/src/runwayml/resources/video_to_video.py @@ -3,13 +3,13 @@ from __future__ import annotations from typing import Iterable -from typing_extensions import Literal +from typing_extensions import Literal, overload import httpx from ..types import video_to_video_create_params from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given -from .._utils import maybe_transform, async_maybe_transform +from .._utils import required_args, maybe_transform, async_maybe_transform from .._compat import cached_property from .._resource import SyncAPIResource, AsyncAPIResource from .._response import ( @@ -52,16 +52,17 @@ def with_streaming_response(self) -> VideoToVideoResourceWithStreamingResponse: """ return VideoToVideoResourceWithStreamingResponse(self) + @overload def create( self, *, model: Literal["gen4_aleph"], prompt_text: str, video_uri: str, - content_moderation: video_to_video_create_params.ContentModeration | Omit = omit, + content_moderation: video_to_video_create_params.Gen4AlephContentModeration | Omit = omit, ratio: Literal["1280:720", "720:1280", "1104:832", "960:960", "832:1104", "1584:672", "848:480", "640:480"] | Omit = omit, - references: Iterable[video_to_video_create_params.Reference] | Omit = omit, + references: Iterable[video_to_video_create_params.Gen4AlephReference] | Omit = omit, seed: int | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. @@ -99,6 +100,80 @@ def create( timeout: Override the client-level default timeout for this request, in seconds """ + ... + + @overload + def create( + self, + *, + model: Literal["aleph2"], + prompt_text: str, + video_uri: str, + content_moderation: video_to_video_create_params.Aleph2ContentModeration | Omit = omit, + keyframes: Iterable[video_to_video_create_params.Aleph2Keyframe] | Omit = omit, + prompt_image: Iterable[video_to_video_create_params.Aleph2PromptImage] | Omit = omit, + seed: int | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> NewTaskCreatedResponse: + """ + This endpoint will start a new task to generate a video from a video. + + Args: + prompt_text: A non-empty string up to 1000 characters describing what should appear in the + output. + + video_uri: A HTTPS URL. + + content_moderation: Settings that affect the behavior of the content moderation system. + + keyframes: Timed guidance images placed at specific points in the input video. Up to 5 + keyframes. + + prompt_image: A list of up to 5 image keyframes for guiding the edit at specific points in the + video. + + seed: If unspecified, a random number is chosen. Varying the seed integer is a way to + get different results for the same other request parameters. Using the same seed + integer for an identical request will produce similar results. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + ... + + @required_args(["model", "prompt_text", "video_uri"]) + def create( + self, + *, + model: Literal["gen4_aleph"] | Literal["aleph2"], + prompt_text: str, + video_uri: str, + content_moderation: video_to_video_create_params.Gen4AlephContentModeration + | video_to_video_create_params.Aleph2ContentModeration + | Omit = omit, + ratio: Literal["1280:720", "720:1280", "1104:832", "960:960", "832:1104", "1584:672", "848:480", "640:480"] + | Omit = omit, + references: Iterable[video_to_video_create_params.Gen4AlephReference] | Omit = omit, + seed: int | Omit = omit, + keyframes: Iterable[video_to_video_create_params.Aleph2Keyframe] | Omit = omit, + prompt_image: Iterable[video_to_video_create_params.Aleph2PromptImage] | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> NewTaskCreatedResponse: return self._post( "/v1/video_to_video", body=maybe_transform( @@ -110,6 +185,8 @@ def create( "ratio": ratio, "references": references, "seed": seed, + "keyframes": keyframes, + "prompt_image": prompt_image, }, video_to_video_create_params.VideoToVideoCreateParams, ), @@ -142,16 +219,17 @@ def with_streaming_response(self) -> AsyncVideoToVideoResourceWithStreamingRespo """ return AsyncVideoToVideoResourceWithStreamingResponse(self) + @overload async def create( self, *, model: Literal["gen4_aleph"], prompt_text: str, video_uri: str, - content_moderation: video_to_video_create_params.ContentModeration | Omit = omit, + content_moderation: video_to_video_create_params.Gen4AlephContentModeration | Omit = omit, ratio: Literal["1280:720", "720:1280", "1104:832", "960:960", "832:1104", "1584:672", "848:480", "640:480"] | Omit = omit, - references: Iterable[video_to_video_create_params.Reference] | Omit = omit, + references: Iterable[video_to_video_create_params.Gen4AlephReference] | Omit = omit, seed: int | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. @@ -189,6 +267,80 @@ async def create( timeout: Override the client-level default timeout for this request, in seconds """ + ... + + @overload + async def create( + self, + *, + model: Literal["aleph2"], + prompt_text: str, + video_uri: str, + content_moderation: video_to_video_create_params.Aleph2ContentModeration | Omit = omit, + keyframes: Iterable[video_to_video_create_params.Aleph2Keyframe] | Omit = omit, + prompt_image: Iterable[video_to_video_create_params.Aleph2PromptImage] | Omit = omit, + seed: int | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> AsyncNewTaskCreatedResponse: + """ + This endpoint will start a new task to generate a video from a video. + + Args: + prompt_text: A non-empty string up to 1000 characters describing what should appear in the + output. + + video_uri: A HTTPS URL. + + content_moderation: Settings that affect the behavior of the content moderation system. + + keyframes: Timed guidance images placed at specific points in the input video. Up to 5 + keyframes. + + prompt_image: A list of up to 5 image keyframes for guiding the edit at specific points in the + video. + + seed: If unspecified, a random number is chosen. Varying the seed integer is a way to + get different results for the same other request parameters. Using the same seed + integer for an identical request will produce similar results. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + ... + + @required_args(["model", "prompt_text", "video_uri"]) + async def create( + self, + *, + model: Literal["gen4_aleph"] | Literal["aleph2"], + prompt_text: str, + video_uri: str, + content_moderation: video_to_video_create_params.Gen4AlephContentModeration + | video_to_video_create_params.Aleph2ContentModeration + | Omit = omit, + ratio: Literal["1280:720", "720:1280", "1104:832", "960:960", "832:1104", "1584:672", "848:480", "640:480"] + | Omit = omit, + references: Iterable[video_to_video_create_params.Gen4AlephReference] | Omit = omit, + seed: int | Omit = omit, + keyframes: Iterable[video_to_video_create_params.Aleph2Keyframe] | Omit = omit, + prompt_image: Iterable[video_to_video_create_params.Aleph2PromptImage] | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> AsyncNewTaskCreatedResponse: return await self._post( "/v1/video_to_video", body=await async_maybe_transform( @@ -200,6 +352,8 @@ async def create( "ratio": ratio, "references": references, "seed": seed, + "keyframes": keyframes, + "prompt_image": prompt_image, }, video_to_video_create_params.VideoToVideoCreateParams, ), diff --git a/src/runwayml/types/__init__.py b/src/runwayml/types/__init__.py index 16995b4..411b3fa 100644 --- a/src/runwayml/types/__init__.py +++ b/src/runwayml/types/__init__.py @@ -29,6 +29,7 @@ from .document_retrieve_response import DocumentRetrieveResponse as DocumentRetrieveResponse from .sound_effect_create_params import SoundEffectCreateParams as SoundEffectCreateParams from .workflow_retrieve_response import WorkflowRetrieveResponse as WorkflowRetrieveResponse +from .image_upscale_create_params import ImageUpscaleCreateParams as ImageUpscaleCreateParams from .text_to_image_create_params import TextToImageCreateParams as TextToImageCreateParams from .text_to_video_create_params import TextToVideoCreateParams as TextToVideoCreateParams from .voice_dubbing_create_params import VoiceDubbingCreateParams as VoiceDubbingCreateParams @@ -37,6 +38,7 @@ from .sound_effect_create_response import SoundEffectCreateResponse as SoundEffectCreateResponse from .text_to_speech_create_params import TextToSpeechCreateParams as TextToSpeechCreateParams from .video_to_video_create_params import VideoToVideoCreateParams as VideoToVideoCreateParams +from .image_upscale_create_response import ImageUpscaleCreateResponse as ImageUpscaleCreateResponse from .text_to_image_create_response import TextToImageCreateResponse as TextToImageCreateResponse from .text_to_video_create_response import TextToVideoCreateResponse as TextToVideoCreateResponse from .voice_dubbing_create_response import VoiceDubbingCreateResponse as VoiceDubbingCreateResponse diff --git a/src/runwayml/types/image_upscale_create_params.py b/src/runwayml/types/image_upscale_create_params.py new file mode 100644 index 0000000..247cac6 --- /dev/null +++ b/src/runwayml/types/image_upscale_create_params.py @@ -0,0 +1,37 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Literal, Required, Annotated, TypedDict + +from .._utils import PropertyInfo + +__all__ = ["ImageUpscaleCreateParams"] + + +class ImageUpscaleCreateParams(TypedDict, total=False): + image_uri: Required[Annotated[str, PropertyInfo(alias="imageUri")]] + """A HTTPS URL.""" + + model: Required[Literal["magnific_precision_upscaler_v2"]] + + flavor: Literal["sublime", "photo", "photo_denoiser"] + """ + Optimization preset: `sublime` (illustration), `photo` (photographic), or + `photo_denoiser` (noisy photos). + """ + + scale_factor: Annotated[Literal[2, 4, 8, 16], PropertyInfo(alias="scaleFactor")] + """Multiplies each input dimension to produce output width and height. + + Defaults to 2. + """ + + sharpen: int + """Sharpness intensity from 0 (none) to 100.""" + + smart_grain: Annotated[int, PropertyInfo(alias="smartGrain")] + """Grain and texture enhancement from 0 to 100.""" + + ultra_detail: Annotated[int, PropertyInfo(alias="ultraDetail")] + """Fine detail enhancement from 0 to 100.""" diff --git a/src/runwayml/types/image_upscale_create_response.py b/src/runwayml/types/image_upscale_create_response.py new file mode 100644 index 0000000..e783c09 --- /dev/null +++ b/src/runwayml/types/image_upscale_create_response.py @@ -0,0 +1,10 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from .._models import BaseModel + +__all__ = ["ImageUpscaleCreateResponse"] + + +class ImageUpscaleCreateResponse(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_usage_response.py b/src/runwayml/types/organization_retrieve_usage_response.py index c9ea5fc..d79de7c 100644 --- a/src/runwayml/types/organization_retrieve_usage_response.py +++ b/src/runwayml/types/organization_retrieve_usage_response.py @@ -45,6 +45,16 @@ class ResultUsedCredit(BaseModel): "gwm1_avatar_async_text_to_video", "voice_processing", "seedance2", + "magnific_precision_upscaler_v2", + "kling2.5_turbo_pro", + "kling3.0_pro", + "kling3.0_4k", + "kling3.0_standard", + "klingO3_pro", + "klingO3_standard", + "klingO3_4k", + "happyhorse_1_0", + "aleph2", ] """The model that credits were spent on.""" @@ -89,6 +99,16 @@ class OrganizationRetrieveUsageResponse(BaseModel): "gwm1_avatar_async_text_to_video", "voice_processing", "seedance2", + "magnific_precision_upscaler_v2", + "kling2.5_turbo_pro", + "kling3.0_pro", + "kling3.0_4k", + "kling3.0_standard", + "klingO3_pro", + "klingO3_standard", + "klingO3_4k", + "happyhorse_1_0", + "aleph2", ] ] """The list of models with usage during the queried time range.""" diff --git a/src/runwayml/types/text_to_image_create_params.py b/src/runwayml/types/text_to_image_create_params.py index 17eea05..2d9d9b9 100644 --- a/src/runwayml/types/text_to_image_create_params.py +++ b/src/runwayml/types/text_to_image_create_params.py @@ -19,6 +19,8 @@ "GptImage2ReferenceImage", "GeminiImage3Pro", "GeminiImage3ProReferenceImage", + "GeminiImage3_1Flash", + "GeminiImage3_1FlashReferenceImage", "Gemini2_5Flash", "Gemini2_5FlashReferenceImage", ] @@ -324,6 +326,111 @@ class GeminiImage3ProReferenceImage(TypedDict, total=False): """ +class GeminiImage3_1Flash(TypedDict, total=False): + model: Required[Literal["gemini_image3.1_flash"]] + + 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[ + "512:512", + "416:624", + "624:416", + "432:592", + "592:432", + "448:576", + "576:448", + "384:672", + "672:384", + "768:336", + "256:1024", + "1024:256", + "176:1408", + "1408:176", + "1024:1024", + "832:1248", + "1248:832", + "864:1184", + "1184:864", + "896:1152", + "1152:896", + "768:1344", + "1344:768", + "1536:672", + "512:2048", + "2048:512", + "352:2816", + "2816:352", + "2048:2048", + "1696:2528", + "2528:1696", + "1792:2400", + "2400:1792", + "1856:2304", + "2304:1856", + "1536:2752", + "2752:1536", + "3168:1344", + "1024:4096", + "4096:1024", + "704:5632", + "5632:704", + "4096:4096", + "3392:5056", + "5056:3392", + "3584:4800", + "4800:3584", + "3712:4608", + "4608:3712", + "3072:5504", + "5504:3072", + "6336:2688", + "2048:8192", + "8192:2048", + "1408:11264", + "11264:1408", + ] + ] + """The resolution of the output image.""" + + output_count: Annotated[Literal[1, 4], PropertyInfo(alias="outputCount")] + """The number of images to generate. + + Increasing this number will affect the number of credits consumed by the + generation. Up to four images can be generated at once. + """ + + reference_images: Annotated[Iterable[GeminiImage3_1FlashReferenceImage], 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 GeminiImage3_1FlashReferenceImage(TypedDict, total=False): + uri: Required[str] + """A HTTPS URL.""" + + subject: Literal["object", "human"] + """ + Whether this is a reference of a human subject (for character consistency) or an + object that appears in the output. + """ + + 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): model: Required[Literal["gemini_2.5_flash"]] @@ -367,4 +474,6 @@ class Gemini2_5FlashReferenceImage(TypedDict, total=False): """ -TextToImageCreateParams: TypeAlias = Union[Gen4ImageTurbo, Gen4Image, GptImage2, GeminiImage3Pro, Gemini2_5Flash] +TextToImageCreateParams: TypeAlias = Union[ + Gen4ImageTurbo, Gen4Image, GptImage2, GeminiImage3Pro, GeminiImage3_1Flash, Gemini2_5Flash +] diff --git a/src/runwayml/types/video_to_video_create_params.py b/src/runwayml/types/video_to_video_create_params.py index e251396..bc71145 100644 --- a/src/runwayml/types/video_to_video_create_params.py +++ b/src/runwayml/types/video_to_video_create_params.py @@ -2,15 +2,29 @@ from __future__ import annotations -from typing import Iterable -from typing_extensions import Literal, Required, Annotated, TypedDict +from typing import Union, Iterable +from typing_extensions import Literal, Required, Annotated, TypeAlias, TypedDict from .._utils import PropertyInfo -__all__ = ["VideoToVideoCreateParams", "ContentModeration", "Reference"] - - -class VideoToVideoCreateParams(TypedDict, total=False): +__all__ = [ + "VideoToVideoCreateParams", + "Gen4Aleph", + "Gen4AlephContentModeration", + "Gen4AlephReference", + "Aleph2", + "Aleph2ContentModeration", + "Aleph2Keyframe", + "Aleph2KeyframeUnionMember0", + "Aleph2KeyframeUnionMember1", + "Aleph2PromptImage", + "Aleph2PromptImagePosition", + "Aleph2PromptImagePositionTimestampPosition", + "Aleph2PromptImagePositionRelativePosition", +] + + +class Gen4Aleph(TypedDict, total=False): model: Required[Literal["gen4_aleph"]] prompt_text: Required[Annotated[str, PropertyInfo(alias="promptText")]] @@ -22,7 +36,7 @@ class VideoToVideoCreateParams(TypedDict, total=False): video_uri: Required[Annotated[str, PropertyInfo(alias="videoUri")]] """A HTTPS URL.""" - content_moderation: Annotated[ContentModeration, PropertyInfo(alias="contentModeration")] + content_moderation: Annotated[Gen4AlephContentModeration, PropertyInfo(alias="contentModeration")] """Settings that affect the behavior of the content moderation system.""" ratio: Literal["1280:720", "720:1280", "1104:832", "960:960", "832:1104", "1584:672", "848:480", "640:480"] @@ -32,7 +46,7 @@ class VideoToVideoCreateParams(TypedDict, total=False): input video. """ - references: Iterable[Reference] + references: Iterable[Gen4AlephReference] """An array of references. Currently up to one reference is supported. See @@ -48,7 +62,7 @@ class VideoToVideoCreateParams(TypedDict, total=False): """ -class ContentModeration(TypedDict, total=False): +class Gen4AlephContentModeration(TypedDict, total=False): """Settings that affect the behavior of the content moderation system.""" public_figure_threshold: Annotated[Literal["auto", "low"], PropertyInfo(alias="publicFigureThreshold")] @@ -58,7 +72,7 @@ class ContentModeration(TypedDict, total=False): """ -class Reference(TypedDict, total=False): +class Gen4AlephReference(TypedDict, total=False): """ Passing an image reference allows the model to emulate the style or content of the reference in the output. """ @@ -67,3 +81,108 @@ class Reference(TypedDict, total=False): uri: Required[str] """A HTTPS URL.""" + + +class Aleph2(TypedDict, total=False): + model: Required[Literal["aleph2"]] + + prompt_text: Required[Annotated[str, PropertyInfo(alias="promptText")]] + """ + A non-empty string up to 1000 characters describing what should appear in the + output. + """ + + video_uri: Required[Annotated[str, PropertyInfo(alias="videoUri")]] + """A HTTPS URL.""" + + content_moderation: Annotated[Aleph2ContentModeration, PropertyInfo(alias="contentModeration")] + """Settings that affect the behavior of the content moderation system.""" + + keyframes: Iterable[Aleph2Keyframe] + """Timed guidance images placed at specific points in the input video. + + Up to 5 keyframes. + """ + + prompt_image: Annotated[Iterable[Aleph2PromptImage], PropertyInfo(alias="promptImage")] + """ + A list of up to 5 image keyframes for guiding the edit at specific points in the + video. + """ + + seed: int + """If unspecified, a random number is chosen. + + Varying the seed integer is a way to get different results for the same other + request parameters. Using the same seed integer for an identical request will + produce similar results. + """ + + +class Aleph2ContentModeration(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 Aleph2KeyframeUnionMember0(TypedDict, total=False): + seconds: Required[float] + """ + Absolute timestamp in seconds from the start of the input video when this + guidance image should apply. + """ + + uri: Required[str] + """A HTTPS URL.""" + + +class Aleph2KeyframeUnionMember1(TypedDict, total=False): + at: Required[float] + """ + Position as a fraction [0.0, 1.0] of the input video duration when this guidance + image should apply. + """ + + uri: Required[str] + """A HTTPS URL.""" + + +Aleph2Keyframe: TypeAlias = Union[Aleph2KeyframeUnionMember0, Aleph2KeyframeUnionMember1] + + +class Aleph2PromptImagePositionTimestampPosition(TypedDict, total=False): + timestamp_seconds: Required[Annotated[float, PropertyInfo(alias="timestampSeconds")]] + """Absolute timestamp in seconds from the start of the output video.""" + + type: Required[Literal["timestamp"]] + + +class Aleph2PromptImagePositionRelativePosition(TypedDict, total=False): + position_percentage: Required[Annotated[float, PropertyInfo(alias="positionPercentage")]] + """Position as a fraction [0.0, 1.0] of the total video duration.""" + + type: Required[Literal["position"]] + + +Aleph2PromptImagePosition: TypeAlias = Union[ + Literal["first", "last"], Aleph2PromptImagePositionTimestampPosition, Aleph2PromptImagePositionRelativePosition +] + + +class Aleph2PromptImage(TypedDict, total=False): + position: Required[Aleph2PromptImagePosition] + """ + - `first` - Places the image at the start of the output video (timestamp 0). + - `last` - Places the image at the end of the output video (timestamp = + duration). + """ + + uri: Required[str] + """A HTTPS URL.""" + + +VideoToVideoCreateParams: TypeAlias = Union[Gen4Aleph, Aleph2] diff --git a/tests/api_resources/test_image_upscale.py b/tests/api_resources/test_image_upscale.py new file mode 100644 index 0000000..5ac1d19 --- /dev/null +++ b/tests/api_resources/test_image_upscale.py @@ -0,0 +1,118 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import os +from typing import Any, cast + +import pytest + +from runwayml import RunwayML, AsyncRunwayML +from tests.utils import assert_matches_type +from runwayml.types import ImageUpscaleCreateResponse + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestImageUpscale: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @parametrize + def test_method_create(self, client: RunwayML) -> None: + image_upscale = client.image_upscale.create( + image_uri="https://example.com/image.jpg", + model="magnific_precision_upscaler_v2", + ) + assert_matches_type(ImageUpscaleCreateResponse, image_upscale, path=["response"]) + + @parametrize + def test_method_create_with_all_params(self, client: RunwayML) -> None: + image_upscale = client.image_upscale.create( + image_uri="https://example.com/image.jpg", + model="magnific_precision_upscaler_v2", + flavor="sublime", + scale_factor=2, + sharpen=0, + smart_grain=0, + ultra_detail=0, + ) + assert_matches_type(ImageUpscaleCreateResponse, image_upscale, path=["response"]) + + @parametrize + def test_raw_response_create(self, client: RunwayML) -> None: + response = client.image_upscale.with_raw_response.create( + image_uri="https://example.com/image.jpg", + model="magnific_precision_upscaler_v2", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + image_upscale = response.parse() + assert_matches_type(ImageUpscaleCreateResponse, image_upscale, path=["response"]) + + @parametrize + def test_streaming_response_create(self, client: RunwayML) -> None: + with client.image_upscale.with_streaming_response.create( + image_uri="https://example.com/image.jpg", + model="magnific_precision_upscaler_v2", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + image_upscale = response.parse() + assert_matches_type(ImageUpscaleCreateResponse, image_upscale, path=["response"]) + + assert cast(Any, response.is_closed) is True + + +class TestAsyncImageUpscale: + 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_upscale = await async_client.image_upscale.create( + image_uri="https://example.com/image.jpg", + model="magnific_precision_upscaler_v2", + ) + assert_matches_type(ImageUpscaleCreateResponse, image_upscale, path=["response"]) + + @parametrize + async def test_method_create_with_all_params(self, async_client: AsyncRunwayML) -> None: + image_upscale = await async_client.image_upscale.create( + image_uri="https://example.com/image.jpg", + model="magnific_precision_upscaler_v2", + flavor="sublime", + scale_factor=2, + sharpen=0, + smart_grain=0, + ultra_detail=0, + ) + assert_matches_type(ImageUpscaleCreateResponse, image_upscale, path=["response"]) + + @parametrize + async def test_raw_response_create(self, async_client: AsyncRunwayML) -> None: + response = await async_client.image_upscale.with_raw_response.create( + image_uri="https://example.com/image.jpg", + model="magnific_precision_upscaler_v2", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + image_upscale = await response.parse() + assert_matches_type(ImageUpscaleCreateResponse, image_upscale, path=["response"]) + + @parametrize + async def test_streaming_response_create(self, async_client: AsyncRunwayML) -> None: + async with async_client.image_upscale.with_streaming_response.create( + image_uri="https://example.com/image.jpg", + model="magnific_precision_upscaler_v2", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + image_upscale = await response.parse() + assert_matches_type(ImageUpscaleCreateResponse, image_upscale, path=["response"]) + + assert cast(Any, response.is_closed) is True diff --git a/tests/api_resources/test_text_to_image.py b/tests/api_resources/test_text_to_image.py index e36d59f..db58b64 100644 --- a/tests/api_resources/test_text_to_image.py +++ b/tests/api_resources/test_text_to_image.py @@ -239,6 +239,60 @@ def test_streaming_response_create_overload_4(self, client: RunwayML) -> None: @parametrize def test_method_create_overload_5(self, client: RunwayML) -> None: + text_to_image = client.text_to_image.create( + model="gemini_image3.1_flash", + prompt_text="x", + ratio="512:512", + ) + assert_matches_type(TextToImageCreateResponse, text_to_image, path=["response"]) + + @parametrize + def test_method_create_with_all_params_overload_5(self, client: RunwayML) -> None: + text_to_image = client.text_to_image.create( + model="gemini_image3.1_flash", + prompt_text="x", + ratio="512:512", + output_count=1, + reference_images=[ + { + "uri": "https://example.com/file", + "subject": "object", + "tag": "tag", + } + ], + ) + assert_matches_type(TextToImageCreateResponse, text_to_image, path=["response"]) + + @parametrize + def test_raw_response_create_overload_5(self, client: RunwayML) -> None: + response = client.text_to_image.with_raw_response.create( + model="gemini_image3.1_flash", + prompt_text="x", + ratio="512:512", + ) + + 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_5(self, client: RunwayML) -> None: + with client.text_to_image.with_streaming_response.create( + model="gemini_image3.1_flash", + prompt_text="x", + ratio="512:512", + ) 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_6(self, client: RunwayML) -> None: text_to_image = client.text_to_image.create( model="gemini_2.5_flash", prompt_text="x", @@ -247,7 +301,7 @@ def test_method_create_overload_5(self, client: RunwayML) -> None: assert_matches_type(TextToImageCreateResponse, text_to_image, path=["response"]) @parametrize - def test_method_create_with_all_params_overload_5(self, client: RunwayML) -> None: + def test_method_create_with_all_params_overload_6(self, client: RunwayML) -> None: text_to_image = client.text_to_image.create( model="gemini_2.5_flash", prompt_text="x", @@ -262,7 +316,7 @@ def test_method_create_with_all_params_overload_5(self, client: RunwayML) -> Non assert_matches_type(TextToImageCreateResponse, text_to_image, path=["response"]) @parametrize - def test_raw_response_create_overload_5(self, client: RunwayML) -> None: + def test_raw_response_create_overload_6(self, client: RunwayML) -> None: response = client.text_to_image.with_raw_response.create( model="gemini_2.5_flash", prompt_text="x", @@ -275,7 +329,7 @@ def test_raw_response_create_overload_5(self, client: RunwayML) -> None: assert_matches_type(TextToImageCreateResponse, text_to_image, path=["response"]) @parametrize - def test_streaming_response_create_overload_5(self, client: RunwayML) -> None: + def test_streaming_response_create_overload_6(self, client: RunwayML) -> None: with client.text_to_image.with_streaming_response.create( model="gemini_2.5_flash", prompt_text="x", @@ -517,6 +571,60 @@ async def test_streaming_response_create_overload_4(self, async_client: AsyncRun @parametrize async def test_method_create_overload_5(self, async_client: AsyncRunwayML) -> None: + text_to_image = await async_client.text_to_image.create( + model="gemini_image3.1_flash", + prompt_text="x", + ratio="512:512", + ) + assert_matches_type(TextToImageCreateResponse, text_to_image, path=["response"]) + + @parametrize + async def test_method_create_with_all_params_overload_5(self, async_client: AsyncRunwayML) -> None: + text_to_image = await async_client.text_to_image.create( + model="gemini_image3.1_flash", + prompt_text="x", + ratio="512:512", + output_count=1, + reference_images=[ + { + "uri": "https://example.com/file", + "subject": "object", + "tag": "tag", + } + ], + ) + assert_matches_type(TextToImageCreateResponse, text_to_image, path=["response"]) + + @parametrize + async def test_raw_response_create_overload_5(self, async_client: AsyncRunwayML) -> None: + response = await async_client.text_to_image.with_raw_response.create( + model="gemini_image3.1_flash", + prompt_text="x", + ratio="512:512", + ) + + 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_5(self, async_client: AsyncRunwayML) -> None: + async with async_client.text_to_image.with_streaming_response.create( + model="gemini_image3.1_flash", + prompt_text="x", + ratio="512:512", + ) 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_6(self, async_client: AsyncRunwayML) -> None: text_to_image = await async_client.text_to_image.create( model="gemini_2.5_flash", prompt_text="x", @@ -525,7 +633,7 @@ async def test_method_create_overload_5(self, async_client: AsyncRunwayML) -> No assert_matches_type(TextToImageCreateResponse, text_to_image, path=["response"]) @parametrize - async def test_method_create_with_all_params_overload_5(self, async_client: AsyncRunwayML) -> None: + async def test_method_create_with_all_params_overload_6(self, async_client: AsyncRunwayML) -> None: text_to_image = await async_client.text_to_image.create( model="gemini_2.5_flash", prompt_text="x", @@ -540,7 +648,7 @@ async def test_method_create_with_all_params_overload_5(self, async_client: Asyn assert_matches_type(TextToImageCreateResponse, text_to_image, path=["response"]) @parametrize - async def test_raw_response_create_overload_5(self, async_client: AsyncRunwayML) -> None: + async def test_raw_response_create_overload_6(self, async_client: AsyncRunwayML) -> None: response = await async_client.text_to_image.with_raw_response.create( model="gemini_2.5_flash", prompt_text="x", @@ -553,7 +661,7 @@ async def test_raw_response_create_overload_5(self, async_client: AsyncRunwayML) assert_matches_type(TextToImageCreateResponse, text_to_image, path=["response"]) @parametrize - async def test_streaming_response_create_overload_5(self, async_client: AsyncRunwayML) -> None: + async def test_streaming_response_create_overload_6(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_video_to_video.py b/tests/api_resources/test_video_to_video.py index d66d911..d39b3d4 100644 --- a/tests/api_resources/test_video_to_video.py +++ b/tests/api_resources/test_video_to_video.py @@ -18,7 +18,7 @@ class TestVideoToVideo: parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) @parametrize - def test_method_create(self, client: RunwayML) -> None: + def test_method_create_overload_1(self, client: RunwayML) -> None: video_to_video = client.video_to_video.create( model="gen4_aleph", prompt_text="x", @@ -27,7 +27,7 @@ def test_method_create(self, client: RunwayML) -> None: assert_matches_type(VideoToVideoCreateResponse, video_to_video, path=["response"]) @parametrize - def test_method_create_with_all_params(self, client: RunwayML) -> None: + def test_method_create_with_all_params_overload_1(self, client: RunwayML) -> None: video_to_video = client.video_to_video.create( model="gen4_aleph", prompt_text="x", @@ -45,7 +45,7 @@ def test_method_create_with_all_params(self, client: RunwayML) -> None: assert_matches_type(VideoToVideoCreateResponse, video_to_video, path=["response"]) @parametrize - def test_raw_response_create(self, client: RunwayML) -> None: + def test_raw_response_create_overload_1(self, client: RunwayML) -> None: response = client.video_to_video.with_raw_response.create( model="gen4_aleph", prompt_text="x", @@ -58,7 +58,7 @@ def test_raw_response_create(self, client: RunwayML) -> None: assert_matches_type(VideoToVideoCreateResponse, video_to_video, path=["response"]) @parametrize - def test_streaming_response_create(self, client: RunwayML) -> None: + def test_streaming_response_create_overload_1(self, client: RunwayML) -> None: with client.video_to_video.with_streaming_response.create( model="gen4_aleph", prompt_text="x", @@ -72,6 +72,66 @@ def test_streaming_response_create(self, client: RunwayML) -> None: assert cast(Any, response.is_closed) is True + @parametrize + def test_method_create_overload_2(self, client: RunwayML) -> None: + video_to_video = client.video_to_video.create( + model="aleph2", + prompt_text="x", + video_uri="https://example.com/video.mp4", + ) + assert_matches_type(VideoToVideoCreateResponse, video_to_video, path=["response"]) + + @parametrize + def test_method_create_with_all_params_overload_2(self, client: RunwayML) -> None: + video_to_video = client.video_to_video.create( + model="aleph2", + prompt_text="x", + video_uri="https://example.com/video.mp4", + content_moderation={"public_figure_threshold": "auto"}, + keyframes=[ + { + "seconds": 0, + "uri": "https://example.com/file", + } + ], + prompt_image=[ + { + "position": "first", + "uri": "https://example.com/file", + } + ], + seed=0, + ) + assert_matches_type(VideoToVideoCreateResponse, video_to_video, path=["response"]) + + @parametrize + def test_raw_response_create_overload_2(self, client: RunwayML) -> None: + response = client.video_to_video.with_raw_response.create( + model="aleph2", + prompt_text="x", + video_uri="https://example.com/video.mp4", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + video_to_video = response.parse() + assert_matches_type(VideoToVideoCreateResponse, video_to_video, path=["response"]) + + @parametrize + def test_streaming_response_create_overload_2(self, client: RunwayML) -> None: + with client.video_to_video.with_streaming_response.create( + model="aleph2", + prompt_text="x", + video_uri="https://example.com/video.mp4", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + video_to_video = response.parse() + assert_matches_type(VideoToVideoCreateResponse, video_to_video, path=["response"]) + + assert cast(Any, response.is_closed) is True + class TestAsyncVideoToVideo: parametrize = pytest.mark.parametrize( @@ -79,7 +139,7 @@ class TestAsyncVideoToVideo: ) @parametrize - async def test_method_create(self, async_client: AsyncRunwayML) -> None: + async def test_method_create_overload_1(self, async_client: AsyncRunwayML) -> None: video_to_video = await async_client.video_to_video.create( model="gen4_aleph", prompt_text="x", @@ -88,7 +148,7 @@ async def test_method_create(self, async_client: AsyncRunwayML) -> None: assert_matches_type(VideoToVideoCreateResponse, video_to_video, path=["response"]) @parametrize - async def test_method_create_with_all_params(self, async_client: AsyncRunwayML) -> None: + async def test_method_create_with_all_params_overload_1(self, async_client: AsyncRunwayML) -> None: video_to_video = await async_client.video_to_video.create( model="gen4_aleph", prompt_text="x", @@ -106,7 +166,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncRunwayML) assert_matches_type(VideoToVideoCreateResponse, video_to_video, path=["response"]) @parametrize - async def test_raw_response_create(self, async_client: AsyncRunwayML) -> None: + async def test_raw_response_create_overload_1(self, async_client: AsyncRunwayML) -> None: response = await async_client.video_to_video.with_raw_response.create( model="gen4_aleph", prompt_text="x", @@ -119,7 +179,7 @@ async def test_raw_response_create(self, async_client: AsyncRunwayML) -> None: assert_matches_type(VideoToVideoCreateResponse, video_to_video, path=["response"]) @parametrize - async def test_streaming_response_create(self, async_client: AsyncRunwayML) -> None: + async def test_streaming_response_create_overload_1(self, async_client: AsyncRunwayML) -> None: async with async_client.video_to_video.with_streaming_response.create( model="gen4_aleph", prompt_text="x", @@ -132,3 +192,63 @@ async def test_streaming_response_create(self, async_client: AsyncRunwayML) -> N assert_matches_type(VideoToVideoCreateResponse, video_to_video, path=["response"]) assert cast(Any, response.is_closed) is True + + @parametrize + async def test_method_create_overload_2(self, async_client: AsyncRunwayML) -> None: + video_to_video = await async_client.video_to_video.create( + model="aleph2", + prompt_text="x", + video_uri="https://example.com/video.mp4", + ) + assert_matches_type(VideoToVideoCreateResponse, video_to_video, path=["response"]) + + @parametrize + async def test_method_create_with_all_params_overload_2(self, async_client: AsyncRunwayML) -> None: + video_to_video = await async_client.video_to_video.create( + model="aleph2", + prompt_text="x", + video_uri="https://example.com/video.mp4", + content_moderation={"public_figure_threshold": "auto"}, + keyframes=[ + { + "seconds": 0, + "uri": "https://example.com/file", + } + ], + prompt_image=[ + { + "position": "first", + "uri": "https://example.com/file", + } + ], + seed=0, + ) + assert_matches_type(VideoToVideoCreateResponse, video_to_video, path=["response"]) + + @parametrize + async def test_raw_response_create_overload_2(self, async_client: AsyncRunwayML) -> None: + response = await async_client.video_to_video.with_raw_response.create( + model="aleph2", + prompt_text="x", + video_uri="https://example.com/video.mp4", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + video_to_video = await response.parse() + assert_matches_type(VideoToVideoCreateResponse, video_to_video, path=["response"]) + + @parametrize + async def test_streaming_response_create_overload_2(self, async_client: AsyncRunwayML) -> None: + async with async_client.video_to_video.with_streaming_response.create( + model="aleph2", + prompt_text="x", + video_uri="https://example.com/video.mp4", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + video_to_video = await response.parse() + assert_matches_type(VideoToVideoCreateResponse, video_to_video, path=["response"]) + + assert cast(Any, response.is_closed) is True