diff --git a/.release-please-manifest.json b/.release-please-manifest.json
index 4101074..5f7bf25 100644
--- a/.release-please-manifest.json
+++ b/.release-please-manifest.json
@@ -1,3 +1,3 @@
{
- ".": "5.3.0"
+ ".": "5.4.0"
}
\ No newline at end of file
diff --git a/.stats.yml b/.stats.yml
index 9fff147..aae4eec 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
-configured_endpoints: 49
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/runwayml/runwayml-a71b15907f45c6c7b3cf9a277bfc7483817c1596130abd497e95b761bb14bd42.yml
-openapi_spec_hash: dd22cae2258805fbe0b4ddf9632f9ffb
-config_hash: 702846e1d30f519e56e425ca5455febe
+configured_endpoints: 50
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/runwayml/runwayml-656482624bcaf91bbc524b761d1b3d9a97f84ea561a5b9f84db4122f38f342d0.yml
+openapi_spec_hash: a6f0749dba9a9e3a46e75216b4d14467
+config_hash: 955a0e451964a44778c5c0f54ca1c994
diff --git a/CHANGELOG.md b/CHANGELOG.md
index e1447cf..26909b0 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,14 @@
# Changelog
+## 5.4.0 (2026-06-26)
+
+Full Changelog: [v5.3.0...v5.4.0](https://github.com/runwayml/sdk-python/compare/v5.3.0...v5.4.0)
+
+### Features
+
+* **api:** add magnific video upscale model ([8cbd5e8](https://github.com/runwayml/sdk-python/commit/8cbd5e8feef194595fb9d2decaec0b0cb935e764))
+* **client:** make video upscale waitable ([9c0c6ac](https://github.com/runwayml/sdk-python/commit/9c0c6ac9bba3cd3890c67d51e662b6fc952d5820))
+
## 5.3.0 (2026-06-25)
Full Changelog: [v5.2.0...v5.3.0](https://github.com/runwayml/sdk-python/compare/v5.2.0...v5.3.0)
diff --git a/api.md b/api.md
index c4eaded..857cab3 100644
--- a/api.md
+++ b/api.md
@@ -143,6 +143,18 @@ Methods:
- client.image_upscale.create(\*\*params) -> ImageUpscaleCreateResponse
+# VideoUpscale
+
+Types:
+
+```python
+from runwayml.types import VideoUpscaleCreateResponse
+```
+
+Methods:
+
+- client.video_upscale.create(\*\*params) -> VideoUpscaleCreateResponse
+
# Organization
Types:
diff --git a/pyproject.toml b/pyproject.toml
index 493d691..263dc41 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,6 +1,6 @@
[project]
name = "runwayml"
-version = "5.3.0"
+version = "5.4.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 b134578..f5df830 100644
--- a/src/runwayml/_client.py
+++ b/src/runwayml/_client.py
@@ -49,6 +49,7 @@
image_upscale,
text_to_image,
text_to_video,
+ video_upscale,
voice_dubbing,
image_to_video,
text_to_speech,
@@ -73,6 +74,7 @@
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.video_upscale import VideoUpscaleResource, AsyncVideoUpscaleResource
from .resources.voice_dubbing import VoiceDubbingResource, AsyncVoiceDubbingResource
from .resources.image_to_video import ImageToVideoResource, AsyncImageToVideoResource
from .resources.text_to_speech import TextToSpeechResource, AsyncTextToSpeechResource
@@ -256,6 +258,13 @@ def image_upscale(self) -> ImageUpscaleResource:
return ImageUpscaleResource(self)
+ @cached_property
+ def video_upscale(self) -> VideoUpscaleResource:
+ """These endpoints all kick off tasks to create generations."""
+ from .resources.video_upscale import VideoUpscaleResource
+
+ return VideoUpscaleResource(self)
+
@cached_property
def organization(self) -> OrganizationResource:
from .resources.organization import OrganizationResource
@@ -592,6 +601,13 @@ def image_upscale(self) -> AsyncImageUpscaleResource:
return AsyncImageUpscaleResource(self)
+ @cached_property
+ def video_upscale(self) -> AsyncVideoUpscaleResource:
+ """These endpoints all kick off tasks to create generations."""
+ from .resources.video_upscale import AsyncVideoUpscaleResource
+
+ return AsyncVideoUpscaleResource(self)
+
@cached_property
def organization(self) -> AsyncOrganizationResource:
from .resources.organization import AsyncOrganizationResource
@@ -864,6 +880,13 @@ def image_upscale(self) -> image_upscale.ImageUpscaleResourceWithRawResponse:
return ImageUpscaleResourceWithRawResponse(self._client.image_upscale)
+ @cached_property
+ def video_upscale(self) -> video_upscale.VideoUpscaleResourceWithRawResponse:
+ """These endpoints all kick off tasks to create generations."""
+ from .resources.video_upscale import VideoUpscaleResourceWithRawResponse
+
+ return VideoUpscaleResourceWithRawResponse(self._client.video_upscale)
+
@cached_property
def organization(self) -> organization.OrganizationResourceWithRawResponse:
from .resources.organization import OrganizationResourceWithRawResponse
@@ -1021,6 +1044,13 @@ def image_upscale(self) -> image_upscale.AsyncImageUpscaleResourceWithRawRespons
return AsyncImageUpscaleResourceWithRawResponse(self._client.image_upscale)
+ @cached_property
+ def video_upscale(self) -> video_upscale.AsyncVideoUpscaleResourceWithRawResponse:
+ """These endpoints all kick off tasks to create generations."""
+ from .resources.video_upscale import AsyncVideoUpscaleResourceWithRawResponse
+
+ return AsyncVideoUpscaleResourceWithRawResponse(self._client.video_upscale)
+
@cached_property
def organization(self) -> organization.AsyncOrganizationResourceWithRawResponse:
from .resources.organization import AsyncOrganizationResourceWithRawResponse
@@ -1178,6 +1208,13 @@ def image_upscale(self) -> image_upscale.ImageUpscaleResourceWithStreamingRespon
return ImageUpscaleResourceWithStreamingResponse(self._client.image_upscale)
+ @cached_property
+ def video_upscale(self) -> video_upscale.VideoUpscaleResourceWithStreamingResponse:
+ """These endpoints all kick off tasks to create generations."""
+ from .resources.video_upscale import VideoUpscaleResourceWithStreamingResponse
+
+ return VideoUpscaleResourceWithStreamingResponse(self._client.video_upscale)
+
@cached_property
def organization(self) -> organization.OrganizationResourceWithStreamingResponse:
from .resources.organization import OrganizationResourceWithStreamingResponse
@@ -1335,6 +1372,13 @@ def image_upscale(self) -> image_upscale.AsyncImageUpscaleResourceWithStreamingR
return AsyncImageUpscaleResourceWithStreamingResponse(self._client.image_upscale)
+ @cached_property
+ def video_upscale(self) -> video_upscale.AsyncVideoUpscaleResourceWithStreamingResponse:
+ """These endpoints all kick off tasks to create generations."""
+ from .resources.video_upscale import AsyncVideoUpscaleResourceWithStreamingResponse
+
+ return AsyncVideoUpscaleResourceWithStreamingResponse(self._client.video_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 9caaa23..df39732 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.3.0" # x-release-please-version
+__version__ = "5.4.0" # x-release-please-version
diff --git a/src/runwayml/resources/__init__.py b/src/runwayml/resources/__init__.py
index 01606f2..336dc03 100644
--- a/src/runwayml/resources/__init__.py
+++ b/src/runwayml/resources/__init__.py
@@ -104,6 +104,14 @@
TextToVideoResourceWithStreamingResponse,
AsyncTextToVideoResourceWithStreamingResponse,
)
+from .video_upscale import (
+ VideoUpscaleResource,
+ AsyncVideoUpscaleResource,
+ VideoUpscaleResourceWithRawResponse,
+ AsyncVideoUpscaleResourceWithRawResponse,
+ VideoUpscaleResourceWithStreamingResponse,
+ AsyncVideoUpscaleResourceWithStreamingResponse,
+)
from .voice_dubbing import (
VoiceDubbingResource,
AsyncVoiceDubbingResource,
@@ -258,6 +266,12 @@
"AsyncImageUpscaleResourceWithRawResponse",
"ImageUpscaleResourceWithStreamingResponse",
"AsyncImageUpscaleResourceWithStreamingResponse",
+ "VideoUpscaleResource",
+ "AsyncVideoUpscaleResource",
+ "VideoUpscaleResourceWithRawResponse",
+ "AsyncVideoUpscaleResourceWithRawResponse",
+ "VideoUpscaleResourceWithStreamingResponse",
+ "AsyncVideoUpscaleResourceWithStreamingResponse",
"OrganizationResource",
"AsyncOrganizationResource",
"OrganizationResourceWithRawResponse",
diff --git a/src/runwayml/resources/video_to_video.py b/src/runwayml/resources/video_to_video.py
index e30a2e6..1c8a4dd 100644
--- a/src/runwayml/resources/video_to_video.py
+++ b/src/runwayml/resources/video_to_video.py
@@ -82,8 +82,7 @@ def create(
keyframes: Timed guidance images placed at specific points in the input video. Up to 5
keyframes.
- prompt_text: An optional string up to 1000 characters describing what should appear in the
- output.
+ prompt_text: A non-empty and optional string describing what should appear in the output.
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
@@ -405,8 +404,7 @@ async def create(
keyframes: Timed guidance images placed at specific points in the input video. Up to 5
keyframes.
- prompt_text: An optional string up to 1000 characters describing what should appear in the
- output.
+ prompt_text: A non-empty and optional string describing what should appear in the output.
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
diff --git a/src/runwayml/resources/video_upscale.py b/src/runwayml/resources/video_upscale.py
new file mode 100644
index 0000000..f364fed
--- /dev/null
+++ b/src/runwayml/resources/video_upscale.py
@@ -0,0 +1,248 @@
+# 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 video_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.video_upscale_create_response import VideoUpscaleCreateResponse
+
+__all__ = ["VideoUpscaleResource", "AsyncVideoUpscaleResource"]
+
+
+class VideoUpscaleResource(SyncAPIResource):
+ """These endpoints all kick off tasks to create generations."""
+
+ @cached_property
+ def with_raw_response(self) -> VideoUpscaleResourceWithRawResponse:
+ """
+ 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 VideoUpscaleResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> VideoUpscaleResourceWithStreamingResponse:
+ """
+ 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 VideoUpscaleResourceWithStreamingResponse(self)
+
+ def create(
+ self,
+ *,
+ model: Literal["magnific_video_upscaler_creative"],
+ video_uri: str,
+ creativity: int | Omit = omit,
+ flavor: Literal["vivid", "natural"] | Omit = omit,
+ fps_boost: bool | Omit = omit,
+ resolution: Literal["720p", "1k", "2k", "4k"] | Omit = omit,
+ sharpen: int | Omit = omit,
+ smart_grain: 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 starts a task to upscale a video.
+
+ Set `model` to choose the
+ upscaler.
+
+ Args:
+ video_uri: A HTTPS URL.
+
+ creativity: How much AI-generated detail to add during upscaling, from 0 (faithful) to 100.
+
+ flavor: Processing style: `vivid` for enhanced color and detail, `natural` for faithful
+ reproduction.
+
+ fps_boost: Whether to increase the output frame rate.
+
+ resolution: Target output resolution from 720p to 4k. Defaults to `2k`.
+
+ sharpen: Sharpness intensity from 0 (none) to 100.
+
+ smart_grain: Grain and texture 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/video_upscale",
+ body=maybe_transform(
+ {
+ "model": model,
+ "video_uri": video_uri,
+ "creativity": creativity,
+ "flavor": flavor,
+ "fps_boost": fps_boost,
+ "resolution": resolution,
+ "sharpen": sharpen,
+ "smart_grain": smart_grain,
+ },
+ video_upscale_create_params.VideoUpscaleCreateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=create_waitable_resource(VideoUpscaleCreateResponse, self._client),
+ )
+
+
+class AsyncVideoUpscaleResource(AsyncAPIResource):
+ """These endpoints all kick off tasks to create generations."""
+
+ @cached_property
+ def with_raw_response(self) -> AsyncVideoUpscaleResourceWithRawResponse:
+ """
+ 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 AsyncVideoUpscaleResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncVideoUpscaleResourceWithStreamingResponse:
+ """
+ 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 AsyncVideoUpscaleResourceWithStreamingResponse(self)
+
+ async def create(
+ self,
+ *,
+ model: Literal["magnific_video_upscaler_creative"],
+ video_uri: str,
+ creativity: int | Omit = omit,
+ flavor: Literal["vivid", "natural"] | Omit = omit,
+ fps_boost: bool | Omit = omit,
+ resolution: Literal["720p", "1k", "2k", "4k"] | Omit = omit,
+ sharpen: int | Omit = omit,
+ smart_grain: 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 starts a task to upscale a video.
+
+ Set `model` to choose the
+ upscaler.
+
+ Args:
+ video_uri: A HTTPS URL.
+
+ creativity: How much AI-generated detail to add during upscaling, from 0 (faithful) to 100.
+
+ flavor: Processing style: `vivid` for enhanced color and detail, `natural` for faithful
+ reproduction.
+
+ fps_boost: Whether to increase the output frame rate.
+
+ resolution: Target output resolution from 720p to 4k. Defaults to `2k`.
+
+ sharpen: Sharpness intensity from 0 (none) to 100.
+
+ smart_grain: Grain and texture 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/video_upscale",
+ body=await async_maybe_transform(
+ {
+ "model": model,
+ "video_uri": video_uri,
+ "creativity": creativity,
+ "flavor": flavor,
+ "fps_boost": fps_boost,
+ "resolution": resolution,
+ "sharpen": sharpen,
+ "smart_grain": smart_grain,
+ },
+ video_upscale_create_params.VideoUpscaleCreateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=create_async_waitable_resource(VideoUpscaleCreateResponse, self._client),
+ )
+
+
+class VideoUpscaleResourceWithRawResponse:
+ def __init__(self, video_upscale: VideoUpscaleResource) -> None:
+ self._video_upscale = video_upscale
+
+ self.create = to_raw_response_wrapper(
+ video_upscale.create,
+ )
+
+
+class AsyncVideoUpscaleResourceWithRawResponse:
+ def __init__(self, video_upscale: AsyncVideoUpscaleResource) -> None:
+ self._video_upscale = video_upscale
+
+ self.create = async_to_raw_response_wrapper(
+ video_upscale.create,
+ )
+
+
+class VideoUpscaleResourceWithStreamingResponse:
+ def __init__(self, video_upscale: VideoUpscaleResource) -> None:
+ self._video_upscale = video_upscale
+
+ self.create = to_streamed_response_wrapper(
+ video_upscale.create,
+ )
+
+
+class AsyncVideoUpscaleResourceWithStreamingResponse:
+ def __init__(self, video_upscale: AsyncVideoUpscaleResource) -> None:
+ self._video_upscale = video_upscale
+
+ self.create = async_to_streamed_response_wrapper(
+ video_upscale.create,
+ )
diff --git a/src/runwayml/types/__init__.py b/src/runwayml/types/__init__.py
index f51f5af..fbb5637 100644
--- a/src/runwayml/types/__init__.py
+++ b/src/runwayml/types/__init__.py
@@ -41,6 +41,7 @@
from .recipe_product_ugc_response import RecipeProductUgcResponse as RecipeProductUgcResponse
from .text_to_image_create_params import TextToImageCreateParams as TextToImageCreateParams
from .text_to_video_create_params import TextToVideoCreateParams as TextToVideoCreateParams
+from .video_upscale_create_params import VideoUpscaleCreateParams as VideoUpscaleCreateParams
from .voice_dubbing_create_params import VoiceDubbingCreateParams as VoiceDubbingCreateParams
from .avatar_video_create_response import AvatarVideoCreateResponse as AvatarVideoCreateResponse
from .image_to_video_create_params import ImageToVideoCreateParams as ImageToVideoCreateParams
@@ -51,6 +52,7 @@
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 .video_upscale_create_response import VideoUpscaleCreateResponse as VideoUpscaleCreateResponse
from .voice_dubbing_create_response import VoiceDubbingCreateResponse as VoiceDubbingCreateResponse
from .voice_isolation_create_params import VoiceIsolationCreateParams as VoiceIsolationCreateParams
from .image_to_video_create_response import ImageToVideoCreateResponse as ImageToVideoCreateResponse
diff --git a/src/runwayml/types/organization_retrieve_usage_response.py b/src/runwayml/types/organization_retrieve_usage_response.py
index e077547..84b1eee 100644
--- a/src/runwayml/types/organization_retrieve_usage_response.py
+++ b/src/runwayml/types/organization_retrieve_usage_response.py
@@ -47,6 +47,7 @@ class ResultUsedCredit(BaseModel):
"seedance2",
"seedance2_fast",
"magnific_precision_upscaler_v2",
+ "magnific_video_upscaler_creative",
"kling2.5_turbo_pro",
"kling3.0_pro",
"kling3.0_4k",
@@ -62,6 +63,7 @@ class ResultUsedCredit(BaseModel):
"product_ugc",
"marketing_stock_image",
"product_campaign_image",
+ "ad_localization",
]
"""The model that credits were spent on."""
@@ -108,6 +110,7 @@ class OrganizationRetrieveUsageResponse(BaseModel):
"seedance2",
"seedance2_fast",
"magnific_precision_upscaler_v2",
+ "magnific_video_upscaler_creative",
"kling2.5_turbo_pro",
"kling3.0_pro",
"kling3.0_4k",
@@ -123,6 +126,7 @@ class OrganizationRetrieveUsageResponse(BaseModel):
"product_ugc",
"marketing_stock_image",
"product_campaign_image",
+ "ad_localization",
]
]
"""The list of models with usage during the queried time range."""
diff --git a/src/runwayml/types/video_to_video_create_params.py b/src/runwayml/types/video_to_video_create_params.py
index 45b50c0..c345785 100644
--- a/src/runwayml/types/video_to_video_create_params.py
+++ b/src/runwayml/types/video_to_video_create_params.py
@@ -41,10 +41,7 @@ class Variant0(TypedDict, total=False):
"""
prompt_text: Annotated[str, PropertyInfo(alias="promptText")]
- """
- An optional string up to 1000 characters describing what should appear in the
- output.
- """
+ """A non-empty and optional string describing what should appear in the output."""
ratio: str
diff --git a/src/runwayml/types/video_upscale_create_params.py b/src/runwayml/types/video_upscale_create_params.py
new file mode 100644
index 0000000..c063d47
--- /dev/null
+++ b/src/runwayml/types/video_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__ = ["VideoUpscaleCreateParams"]
+
+
+class VideoUpscaleCreateParams(TypedDict, total=False):
+ model: Required[Literal["magnific_video_upscaler_creative"]]
+
+ video_uri: Required[Annotated[str, PropertyInfo(alias="videoUri")]]
+ """A HTTPS URL."""
+
+ creativity: int
+ """How much AI-generated detail to add during upscaling, from 0 (faithful) to 100."""
+
+ flavor: Literal["vivid", "natural"]
+ """
+ Processing style: `vivid` for enhanced color and detail, `natural` for faithful
+ reproduction.
+ """
+
+ fps_boost: Annotated[bool, PropertyInfo(alias="fpsBoost")]
+ """Whether to increase the output frame rate."""
+
+ resolution: Literal["720p", "1k", "2k", "4k"]
+ """Target output resolution from 720p to 4k. Defaults to `2k`."""
+
+ sharpen: int
+ """Sharpness intensity from 0 (none) to 100."""
+
+ smart_grain: Annotated[int, PropertyInfo(alias="smartGrain")]
+ """Grain and texture enhancement from 0 to 100."""
diff --git a/src/runwayml/types/video_upscale_create_response.py b/src/runwayml/types/video_upscale_create_response.py
new file mode 100644
index 0000000..0cf0a9e
--- /dev/null
+++ b/src/runwayml/types/video_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__ = ["VideoUpscaleCreateResponse"]
+
+
+class VideoUpscaleCreateResponse(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_video_upscale.py b/tests/api_resources/test_video_upscale.py
new file mode 100644
index 0000000..d67ad5a
--- /dev/null
+++ b/tests/api_resources/test_video_upscale.py
@@ -0,0 +1,120 @@
+# 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 VideoUpscaleCreateResponse
+
+base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
+
+
+class TestVideoUpscale:
+ parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
+
+ @parametrize
+ def test_method_create(self, client: RunwayML) -> None:
+ video_upscale = client.video_upscale.create(
+ model="magnific_video_upscaler_creative",
+ video_uri="https://example.com/video.mp4",
+ )
+ assert_matches_type(VideoUpscaleCreateResponse, video_upscale, path=["response"])
+
+ @parametrize
+ def test_method_create_with_all_params(self, client: RunwayML) -> None:
+ video_upscale = client.video_upscale.create(
+ model="magnific_video_upscaler_creative",
+ video_uri="https://example.com/video.mp4",
+ creativity=0,
+ flavor="vivid",
+ fps_boost=True,
+ resolution="720p",
+ sharpen=0,
+ smart_grain=0,
+ )
+ assert_matches_type(VideoUpscaleCreateResponse, video_upscale, path=["response"])
+
+ @parametrize
+ def test_raw_response_create(self, client: RunwayML) -> None:
+ response = client.video_upscale.with_raw_response.create(
+ model="magnific_video_upscaler_creative",
+ video_uri="https://example.com/video.mp4",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ video_upscale = response.parse()
+ assert_matches_type(VideoUpscaleCreateResponse, video_upscale, path=["response"])
+
+ @parametrize
+ def test_streaming_response_create(self, client: RunwayML) -> None:
+ with client.video_upscale.with_streaming_response.create(
+ model="magnific_video_upscaler_creative",
+ 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_upscale = response.parse()
+ assert_matches_type(VideoUpscaleCreateResponse, video_upscale, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+
+class TestAsyncVideoUpscale:
+ 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:
+ video_upscale = await async_client.video_upscale.create(
+ model="magnific_video_upscaler_creative",
+ video_uri="https://example.com/video.mp4",
+ )
+ assert_matches_type(VideoUpscaleCreateResponse, video_upscale, path=["response"])
+
+ @parametrize
+ async def test_method_create_with_all_params(self, async_client: AsyncRunwayML) -> None:
+ video_upscale = await async_client.video_upscale.create(
+ model="magnific_video_upscaler_creative",
+ video_uri="https://example.com/video.mp4",
+ creativity=0,
+ flavor="vivid",
+ fps_boost=True,
+ resolution="720p",
+ sharpen=0,
+ smart_grain=0,
+ )
+ assert_matches_type(VideoUpscaleCreateResponse, video_upscale, path=["response"])
+
+ @parametrize
+ async def test_raw_response_create(self, async_client: AsyncRunwayML) -> None:
+ response = await async_client.video_upscale.with_raw_response.create(
+ model="magnific_video_upscaler_creative",
+ video_uri="https://example.com/video.mp4",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ video_upscale = await response.parse()
+ assert_matches_type(VideoUpscaleCreateResponse, video_upscale, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_create(self, async_client: AsyncRunwayML) -> None:
+ async with async_client.video_upscale.with_streaming_response.create(
+ model="magnific_video_upscaler_creative",
+ 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_upscale = await response.parse()
+ assert_matches_type(VideoUpscaleCreateResponse, video_upscale, path=["response"])
+
+ assert cast(Any, response.is_closed) is True