From 0e13593e38bbf7d0120182d390727593ecefb189 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 6 Jul 2026 20:01:39 +0000 Subject: [PATCH 1/2] feat(api): add ad_localization recipe Add POST /v1/recipes/ad_localization for localizing ad images by target language (referenceImage + targetLanguage). --- .stats.yml | 8 +- api.md | 2 + src/runwayml/resources/recipes.py | 162 ++++++++++++++++++ src/runwayml/types/__init__.py | 2 + .../types/recipe_ad_localization_params.py | 68 ++++++++ .../types/recipe_ad_localization_response.py | 10 ++ tests/api_resources/test_recipes.py | 75 ++++++++ 7 files changed, 323 insertions(+), 4 deletions(-) create mode 100644 src/runwayml/types/recipe_ad_localization_params.py create mode 100644 src/runwayml/types/recipe_ad_localization_response.py diff --git a/.stats.yml b/.stats.yml index f6fb8cf..b1f4800 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ -configured_endpoints: 50 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/runwayml/runwayml-caa255c8f1c6fd2b54d331eeacc13de517b8dbaba491ef94745d107798b5eb7a.yml -openapi_spec_hash: d9f7b43604b06f389e2fc45376d0a519 -config_hash: 955a0e451964a44778c5c0f54ca1c994 +configured_endpoints: 51 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/runwayml/runwayml-d934e6804620f70a9a7d88bb3acf27146b57860ed56691e390e46027b3c04d4a.yml +openapi_spec_hash: 132fc1ce816bcfd680a239dc1ed58c8e +config_hash: 7caf94f26186e1ee432efcaa0b590bab diff --git a/api.md b/api.md index 857cab3..5b8a55f 100644 --- a/api.md +++ b/api.md @@ -253,6 +253,7 @@ Types: ```python from runwayml.types import ( + RecipeAdLocalizationResponse, RecipeMarketingStockImageResponse, RecipeMultiShotVideoResponse, RecipeProductAdResponse, @@ -264,6 +265,7 @@ from runwayml.types import ( Methods: +- client.recipes.ad_localization(\*\*params) -> RecipeAdLocalizationResponse - client.recipes.marketing_stock_image(\*\*params) -> RecipeMarketingStockImageResponse - client.recipes.multi_shot_video(\*\*params) -> RecipeMultiShotVideoResponse - client.recipes.product_ad(\*\*params) -> RecipeProductAdResponse diff --git a/src/runwayml/resources/recipes.py b/src/runwayml/resources/recipes.py index be41774..3e751d2 100644 --- a/src/runwayml/resources/recipes.py +++ b/src/runwayml/resources/recipes.py @@ -18,6 +18,7 @@ recipe_product_ad_params, recipe_product_ugc_params, recipe_product_swap_params, + recipe_ad_localization_params, recipe_multi_shot_video_params, recipe_marketing_stock_image_params, recipe_product_campaign_image_params, @@ -36,6 +37,7 @@ from ..types.recipe_product_ad_response import RecipeProductAdResponse from ..types.recipe_product_ugc_response import RecipeProductUgcResponse from ..types.recipe_product_swap_response import RecipeProductSwapResponse +from ..types.recipe_ad_localization_response import RecipeAdLocalizationResponse from ..types.recipe_multi_shot_video_response import RecipeMultiShotVideoResponse from ..types.recipe_marketing_stock_image_response import RecipeMarketingStockImageResponse from ..types.recipe_product_campaign_image_response import RecipeProductCampaignImageResponse @@ -63,6 +65,80 @@ def with_streaming_response(self) -> RecipesResourceWithStreamingResponse: """ return RecipesResourceWithStreamingResponse(self) + def ad_localization( + self, + *, + reference_image: recipe_ad_localization_params.ReferenceImage, + target_language: Literal[ + "ar", + "zh", + "zh-Hant", + "nl", + "en", + "fr", + "de", + "hi", + "id", + "it", + "ja", + "ko", + "pl", + "pt", + "ru", + "es", + "sv", + "th", + "tr", + "uk", + "vi", + "el", + ], + version: Literal["2026-06", "unsafe-latest"], + # 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: + """ + Localize an existing ad image for a target language, preserving visual creative + while adapting on-screen messaging. + + Args: + reference_image: Reference ad image to localize. See [our docs](/assets/inputs#images) on image + inputs. + + target_language: Target language for the localized ad. Use ISO-style codes (e.g. "ja" for + Japanese, "es" for Spanish). + + version: Workflow version. Use a dated version (e.g. "2026-06") to pin behavior, or + "unsafe-latest" to track the newest stable version (may break without notice). + + 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/recipes/ad_localization", + body=maybe_transform( + { + "reference_image": reference_image, + "target_language": target_language, + "version": version, + }, + recipe_ad_localization_params.RecipeAdLocalizationParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=create_waitable_resource(RecipeAdLocalizationResponse, self._client), + ) + def marketing_stock_image( self, *, @@ -564,6 +640,80 @@ def with_streaming_response(self) -> AsyncRecipesResourceWithStreamingResponse: """ return AsyncRecipesResourceWithStreamingResponse(self) + async def ad_localization( + self, + *, + reference_image: recipe_ad_localization_params.ReferenceImage, + target_language: Literal[ + "ar", + "zh", + "zh-Hant", + "nl", + "en", + "fr", + "de", + "hi", + "id", + "it", + "ja", + "ko", + "pl", + "pt", + "ru", + "es", + "sv", + "th", + "tr", + "uk", + "vi", + "el", + ], + version: Literal["2026-06", "unsafe-latest"], + # 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: + """ + Localize an existing ad image for a target language, preserving visual creative + while adapting on-screen messaging. + + Args: + reference_image: Reference ad image to localize. See [our docs](/assets/inputs#images) on image + inputs. + + target_language: Target language for the localized ad. Use ISO-style codes (e.g. "ja" for + Japanese, "es" for Spanish). + + version: Workflow version. Use a dated version (e.g. "2026-06") to pin behavior, or + "unsafe-latest" to track the newest stable version (may break without notice). + + 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/recipes/ad_localization", + body=await async_maybe_transform( + { + "reference_image": reference_image, + "target_language": target_language, + "version": version, + }, + recipe_ad_localization_params.RecipeAdLocalizationParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=create_async_waitable_resource(RecipeAdLocalizationResponse, self._client), + ) + async def marketing_stock_image( self, *, @@ -1049,6 +1199,9 @@ class RecipesResourceWithRawResponse: def __init__(self, recipes: RecipesResource) -> None: self._recipes = recipes + self.ad_localization = to_raw_response_wrapper( + recipes.ad_localization, + ) self.marketing_stock_image = to_raw_response_wrapper( recipes.marketing_stock_image, ) @@ -1073,6 +1226,9 @@ class AsyncRecipesResourceWithRawResponse: def __init__(self, recipes: AsyncRecipesResource) -> None: self._recipes = recipes + self.ad_localization = async_to_raw_response_wrapper( + recipes.ad_localization, + ) self.marketing_stock_image = async_to_raw_response_wrapper( recipes.marketing_stock_image, ) @@ -1097,6 +1253,9 @@ class RecipesResourceWithStreamingResponse: def __init__(self, recipes: RecipesResource) -> None: self._recipes = recipes + self.ad_localization = to_streamed_response_wrapper( + recipes.ad_localization, + ) self.marketing_stock_image = to_streamed_response_wrapper( recipes.marketing_stock_image, ) @@ -1121,6 +1280,9 @@ class AsyncRecipesResourceWithStreamingResponse: def __init__(self, recipes: AsyncRecipesResource) -> None: self._recipes = recipes + self.ad_localization = async_to_streamed_response_wrapper( + recipes.ad_localization, + ) self.marketing_stock_image = async_to_streamed_response_wrapper( recipes.marketing_stock_image, ) diff --git a/src/runwayml/types/__init__.py b/src/runwayml/types/__init__.py index fbb5637..05d793a 100644 --- a/src/runwayml/types/__init__.py +++ b/src/runwayml/types/__init__.py @@ -50,6 +50,7 @@ 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 .recipe_ad_localization_params import RecipeAdLocalizationParams as RecipeAdLocalizationParams from .text_to_image_create_response import TextToImageCreateResponse as TextToImageCreateResponse from .text_to_video_create_response import TextToVideoCreateResponse as TextToVideoCreateResponse from .video_upscale_create_response import VideoUpscaleCreateResponse as VideoUpscaleCreateResponse @@ -63,6 +64,7 @@ from .text_to_speech_create_response import TextToSpeechCreateResponse as TextToSpeechCreateResponse from .video_to_video_create_response import VideoToVideoCreateResponse as VideoToVideoCreateResponse from .avatar_conversation_list_params import AvatarConversationListParams as AvatarConversationListParams +from .recipe_ad_localization_response import RecipeAdLocalizationResponse as RecipeAdLocalizationResponse from .voice_isolation_create_response import VoiceIsolationCreateResponse as VoiceIsolationCreateResponse from .realtime_session_create_response import RealtimeSessionCreateResponse as RealtimeSessionCreateResponse from .recipe_multi_shot_video_response import RecipeMultiShotVideoResponse as RecipeMultiShotVideoResponse diff --git a/src/runwayml/types/recipe_ad_localization_params.py b/src/runwayml/types/recipe_ad_localization_params.py new file mode 100644 index 0000000..da31daa --- /dev/null +++ b/src/runwayml/types/recipe_ad_localization_params.py @@ -0,0 +1,68 @@ +# 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__ = ["RecipeAdLocalizationParams", "ReferenceImage"] + + +class RecipeAdLocalizationParams(TypedDict, total=False): + reference_image: Required[Annotated[ReferenceImage, PropertyInfo(alias="referenceImage")]] + """Reference ad image to localize. + + See [our docs](/assets/inputs#images) on image inputs. + """ + + target_language: Required[ + Annotated[ + Literal[ + "ar", + "zh", + "zh-Hant", + "nl", + "en", + "fr", + "de", + "hi", + "id", + "it", + "ja", + "ko", + "pl", + "pt", + "ru", + "es", + "sv", + "th", + "tr", + "uk", + "vi", + "el", + ], + PropertyInfo(alias="targetLanguage"), + ] + ] + """Target language for the localized ad. + + Use ISO-style codes (e.g. "ja" for Japanese, "es" for Spanish). + """ + + version: Required[Literal["2026-06", "unsafe-latest"]] + """Workflow version. + + Use a dated version (e.g. "2026-06") to pin behavior, or "unsafe-latest" to + track the newest stable version (may break without notice). + """ + + +class ReferenceImage(TypedDict, total=False): + """Reference ad image to localize. + + See [our docs](/assets/inputs#images) on image inputs. + """ + + uri: Required[str] + """A HTTPS URL.""" diff --git a/src/runwayml/types/recipe_ad_localization_response.py b/src/runwayml/types/recipe_ad_localization_response.py new file mode 100644 index 0000000..5a97589 --- /dev/null +++ b/src/runwayml/types/recipe_ad_localization_response.py @@ -0,0 +1,10 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from .._models import BaseModel + +__all__ = ["RecipeAdLocalizationResponse"] + + +class RecipeAdLocalizationResponse(BaseModel): + id: str + """The ID of the task that was created. Use this to retrieve the task later.""" diff --git a/tests/api_resources/test_recipes.py b/tests/api_resources/test_recipes.py index 4493307..07cbd7c 100644 --- a/tests/api_resources/test_recipes.py +++ b/tests/api_resources/test_recipes.py @@ -13,6 +13,7 @@ RecipeProductAdResponse, RecipeProductUgcResponse, RecipeProductSwapResponse, + RecipeAdLocalizationResponse, RecipeMultiShotVideoResponse, RecipeMarketingStockImageResponse, RecipeProductCampaignImageResponse, @@ -24,6 +25,43 @@ class TestRecipes: parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + @parametrize + def test_method_ad_localization(self, client: RunwayML) -> None: + recipe = client.recipes.ad_localization( + reference_image={"uri": "https://example.com/file"}, + target_language="ar", + version="2026-06", + ) + assert_matches_type(RecipeAdLocalizationResponse, recipe, path=["response"]) + + @parametrize + def test_raw_response_ad_localization(self, client: RunwayML) -> None: + response = client.recipes.with_raw_response.ad_localization( + reference_image={"uri": "https://example.com/file"}, + target_language="ar", + version="2026-06", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + recipe = response.parse() + assert_matches_type(RecipeAdLocalizationResponse, recipe, path=["response"]) + + @parametrize + def test_streaming_response_ad_localization(self, client: RunwayML) -> None: + with client.recipes.with_streaming_response.ad_localization( + reference_image={"uri": "https://example.com/file"}, + target_language="ar", + version="2026-06", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + recipe = response.parse() + assert_matches_type(RecipeAdLocalizationResponse, recipe, path=["response"]) + + assert cast(Any, response.is_closed) is True + @parametrize def test_method_marketing_stock_image(self, client: RunwayML) -> None: recipe = client.recipes.marketing_stock_image( @@ -421,6 +459,43 @@ class TestAsyncRecipes: "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] ) + @parametrize + async def test_method_ad_localization(self, async_client: AsyncRunwayML) -> None: + recipe = await async_client.recipes.ad_localization( + reference_image={"uri": "https://example.com/file"}, + target_language="ar", + version="2026-06", + ) + assert_matches_type(RecipeAdLocalizationResponse, recipe, path=["response"]) + + @parametrize + async def test_raw_response_ad_localization(self, async_client: AsyncRunwayML) -> None: + response = await async_client.recipes.with_raw_response.ad_localization( + reference_image={"uri": "https://example.com/file"}, + target_language="ar", + version="2026-06", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + recipe = await response.parse() + assert_matches_type(RecipeAdLocalizationResponse, recipe, path=["response"]) + + @parametrize + async def test_streaming_response_ad_localization(self, async_client: AsyncRunwayML) -> None: + async with async_client.recipes.with_streaming_response.ad_localization( + reference_image={"uri": "https://example.com/file"}, + target_language="ar", + version="2026-06", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + recipe = await response.parse() + assert_matches_type(RecipeAdLocalizationResponse, recipe, path=["response"]) + + assert cast(Any, response.is_closed) is True + @parametrize async def test_method_marketing_stock_image(self, async_client: AsyncRunwayML) -> None: recipe = await async_client.recipes.marketing_stock_image( From 51aec6ca6a4a02273e6296d78c24ac621a54d96e Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 6 Jul 2026 20:19:11 +0000 Subject: [PATCH 2/2] release: 5.9.0 --- .release-please-manifest.json | 2 +- CHANGELOG.md | 8 ++++++++ pyproject.toml | 2 +- src/runwayml/_version.py | 2 +- 4 files changed, 11 insertions(+), 3 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 8375aa0..8ed0bbc 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "5.8.0" + ".": "5.9.0" } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 9416654..0c3264c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## 5.9.0 (2026-07-06) + +Full Changelog: [v5.8.0...v5.9.0](https://github.com/runwayml/sdk-python/compare/v5.8.0...v5.9.0) + +### Features + +* **api:** add ad_localization recipe ([0e13593](https://github.com/runwayml/sdk-python/commit/0e13593e38bbf7d0120182d390727593ecefb189)) + ## 5.8.0 (2026-07-06) Full Changelog: [v5.7.0...v5.8.0](https://github.com/runwayml/sdk-python/compare/v5.7.0...v5.8.0) diff --git a/pyproject.toml b/pyproject.toml index 2d62054..05a4bc6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "runwayml" -version = "5.8.0" +version = "5.9.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 9b4ea71..0160beb 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.8.0" # x-release-please-version +__version__ = "5.9.0" # x-release-please-version