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