main
  1# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
  2
  3from __future__ import annotations
  4
  5from typing import TYPE_CHECKING, Mapping, cast
  6from typing_extensions import Literal, assert_never
  7
  8import httpx
  9
 10from .. import _legacy_response
 11from ..types import (
 12    VideoSize,
 13    VideoModel,
 14    VideoSeconds,
 15    video_list_params,
 16    video_remix_params,
 17    video_create_params,
 18    video_download_content_params,
 19)
 20from .._types import Body, Omit, Query, Headers, NotGiven, FileTypes, omit, not_given
 21from .._utils import extract_files, maybe_transform, deepcopy_minimal, async_maybe_transform
 22from .._compat import cached_property
 23from .._resource import SyncAPIResource, AsyncAPIResource
 24from .._response import (
 25    StreamedBinaryAPIResponse,
 26    AsyncStreamedBinaryAPIResponse,
 27    to_streamed_response_wrapper,
 28    async_to_streamed_response_wrapper,
 29    to_custom_streamed_response_wrapper,
 30    async_to_custom_streamed_response_wrapper,
 31)
 32from ..pagination import SyncConversationCursorPage, AsyncConversationCursorPage
 33from ..types.video import Video
 34from .._base_client import AsyncPaginator, make_request_options
 35from .._utils._utils import is_given
 36from ..types.video_size import VideoSize
 37from ..types.video_model import VideoModel
 38from ..types.video_seconds import VideoSeconds
 39from ..types.video_delete_response import VideoDeleteResponse
 40
 41__all__ = ["Videos", "AsyncVideos"]
 42
 43
 44class Videos(SyncAPIResource):
 45    @cached_property
 46    def with_raw_response(self) -> VideosWithRawResponse:
 47        """
 48        This property can be used as a prefix for any HTTP method call to return
 49        the raw response object instead of the parsed content.
 50
 51        For more information, see https://www.github.com/openai/openai-python#accessing-raw-response-data-eg-headers
 52        """
 53        return VideosWithRawResponse(self)
 54
 55    @cached_property
 56    def with_streaming_response(self) -> VideosWithStreamingResponse:
 57        """
 58        An alternative to `.with_raw_response` that doesn't eagerly read the response body.
 59
 60        For more information, see https://www.github.com/openai/openai-python#with_streaming_response
 61        """
 62        return VideosWithStreamingResponse(self)
 63
 64    def create(
 65        self,
 66        *,
 67        prompt: str,
 68        input_reference: FileTypes | Omit = omit,
 69        model: VideoModel | Omit = omit,
 70        seconds: VideoSeconds | Omit = omit,
 71        size: VideoSize | Omit = omit,
 72        # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
 73        # The extra values given here take precedence over values defined on the client or passed to this method.
 74        extra_headers: Headers | None = None,
 75        extra_query: Query | None = None,
 76        extra_body: Body | None = None,
 77        timeout: float | httpx.Timeout | None | NotGiven = not_given,
 78    ) -> Video:
 79        """
 80        Create a video
 81
 82        Args:
 83          prompt: Text prompt that describes the video to generate.
 84
 85          input_reference: Optional image reference that guides generation.
 86
 87          model: The video generation model to use (allowed values: sora-2, sora-2-pro). Defaults
 88              to `sora-2`.
 89
 90          seconds: Clip duration in seconds (allowed values: 4, 8, 12). Defaults to 4 seconds.
 91
 92          size: Output resolution formatted as width x height (allowed values: 720x1280,
 93              1280x720, 1024x1792, 1792x1024). Defaults to 720x1280.
 94
 95          extra_headers: Send extra headers
 96
 97          extra_query: Add additional query parameters to the request
 98
 99          extra_body: Add additional JSON properties to the request
100
101          timeout: Override the client-level default timeout for this request, in seconds
102        """
103        body = deepcopy_minimal(
104            {
105                "prompt": prompt,
106                "input_reference": input_reference,
107                "model": model,
108                "seconds": seconds,
109                "size": size,
110            }
111        )
112        files = extract_files(cast(Mapping[str, object], body), paths=[["input_reference"]])
113        if files:
114            # It should be noted that the actual Content-Type header that will be
115            # sent to the server will contain a `boundary` parameter, e.g.
116            # multipart/form-data; boundary=---abc--
117            extra_headers = {"Content-Type": "multipart/form-data", **(extra_headers or {})}
118        return self._post(
119            "/videos",
120            body=maybe_transform(body, video_create_params.VideoCreateParams),
121            files=files,
122            options=make_request_options(
123                extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
124            ),
125            cast_to=Video,
126        )
127
128    def create_and_poll(
129        self,
130        *,
131        prompt: str,
132        input_reference: FileTypes | Omit = omit,
133        model: VideoModel | Omit = omit,
134        seconds: VideoSeconds | Omit = omit,
135        size: VideoSize | Omit = omit,
136        poll_interval_ms: int | Omit = omit,
137        # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
138        # The extra values given here take precedence over values defined on the client or passed to this method.
139        extra_headers: Headers | None = None,
140        extra_query: Query | None = None,
141        extra_body: Body | None = None,
142        timeout: float | httpx.Timeout | None | NotGiven = not_given,
143    ) -> Video:
144        """Create a video and wait for it to be processed."""
145        video = self.create(
146            model=model,
147            prompt=prompt,
148            input_reference=input_reference,
149            seconds=seconds,
150            size=size,
151            extra_headers=extra_headers,
152            extra_query=extra_query,
153            extra_body=extra_body,
154            timeout=timeout,
155        )
156
157        return self.poll(
158            video.id,
159            poll_interval_ms=poll_interval_ms,
160        )
161
162    def poll(
163        self,
164        video_id: str,
165        *,
166        poll_interval_ms: int | Omit = omit,
167    ) -> Video:
168        """Wait for the vector store file to finish processing.
169
170        Note: this will return even if the file failed to process, you need to check
171        file.last_error and file.status to handle these cases
172        """
173        headers: dict[str, str] = {"X-Stainless-Poll-Helper": "true"}
174        if is_given(poll_interval_ms):
175            headers["X-Stainless-Custom-Poll-Interval"] = str(poll_interval_ms)
176
177        while True:
178            response = self.with_raw_response.retrieve(
179                video_id,
180                extra_headers=headers,
181            )
182
183            video = response.parse()
184            if video.status == "in_progress" or video.status == "queued":
185                if not is_given(poll_interval_ms):
186                    from_header = response.headers.get("openai-poll-after-ms")
187                    if from_header is not None:
188                        poll_interval_ms = int(from_header)
189                    else:
190                        poll_interval_ms = 1000
191
192                self._sleep(poll_interval_ms / 1000)
193            elif video.status == "completed" or video.status == "failed":
194                return video
195            else:
196                if TYPE_CHECKING:  # type: ignore[unreachable]
197                    assert_never(video.status)
198                else:
199                    return video
200
201    def retrieve(
202        self,
203        video_id: str,
204        *,
205        # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
206        # The extra values given here take precedence over values defined on the client or passed to this method.
207        extra_headers: Headers | None = None,
208        extra_query: Query | None = None,
209        extra_body: Body | None = None,
210        timeout: float | httpx.Timeout | None | NotGiven = not_given,
211    ) -> Video:
212        """
213        Retrieve a video
214
215        Args:
216          extra_headers: Send extra headers
217
218          extra_query: Add additional query parameters to the request
219
220          extra_body: Add additional JSON properties to the request
221
222          timeout: Override the client-level default timeout for this request, in seconds
223        """
224        if not video_id:
225            raise ValueError(f"Expected a non-empty value for `video_id` but received {video_id!r}")
226        return self._get(
227            f"/videos/{video_id}",
228            options=make_request_options(
229                extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
230            ),
231            cast_to=Video,
232        )
233
234    def list(
235        self,
236        *,
237        after: str | Omit = omit,
238        limit: int | Omit = omit,
239        order: Literal["asc", "desc"] | Omit = omit,
240        # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
241        # The extra values given here take precedence over values defined on the client or passed to this method.
242        extra_headers: Headers | None = None,
243        extra_query: Query | None = None,
244        extra_body: Body | None = None,
245        timeout: float | httpx.Timeout | None | NotGiven = not_given,
246    ) -> SyncConversationCursorPage[Video]:
247        """
248        List videos
249
250        Args:
251          after: Identifier for the last item from the previous pagination request
252
253          limit: Number of items to retrieve
254
255          order: Sort order of results by timestamp. Use `asc` for ascending order or `desc` for
256              descending order.
257
258          extra_headers: Send extra headers
259
260          extra_query: Add additional query parameters to the request
261
262          extra_body: Add additional JSON properties to the request
263
264          timeout: Override the client-level default timeout for this request, in seconds
265        """
266        return self._get_api_list(
267            "/videos",
268            page=SyncConversationCursorPage[Video],
269            options=make_request_options(
270                extra_headers=extra_headers,
271                extra_query=extra_query,
272                extra_body=extra_body,
273                timeout=timeout,
274                query=maybe_transform(
275                    {
276                        "after": after,
277                        "limit": limit,
278                        "order": order,
279                    },
280                    video_list_params.VideoListParams,
281                ),
282            ),
283            model=Video,
284        )
285
286    def delete(
287        self,
288        video_id: str,
289        *,
290        # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
291        # The extra values given here take precedence over values defined on the client or passed to this method.
292        extra_headers: Headers | None = None,
293        extra_query: Query | None = None,
294        extra_body: Body | None = None,
295        timeout: float | httpx.Timeout | None | NotGiven = not_given,
296    ) -> VideoDeleteResponse:
297        """
298        Delete a video
299
300        Args:
301          extra_headers: Send extra headers
302
303          extra_query: Add additional query parameters to the request
304
305          extra_body: Add additional JSON properties to the request
306
307          timeout: Override the client-level default timeout for this request, in seconds
308        """
309        if not video_id:
310            raise ValueError(f"Expected a non-empty value for `video_id` but received {video_id!r}")
311        return self._delete(
312            f"/videos/{video_id}",
313            options=make_request_options(
314                extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
315            ),
316            cast_to=VideoDeleteResponse,
317        )
318
319    def download_content(
320        self,
321        video_id: str,
322        *,
323        variant: Literal["video", "thumbnail", "spritesheet"] | Omit = omit,
324        # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
325        # The extra values given here take precedence over values defined on the client or passed to this method.
326        extra_headers: Headers | None = None,
327        extra_query: Query | None = None,
328        extra_body: Body | None = None,
329        timeout: float | httpx.Timeout | None | NotGiven = not_given,
330    ) -> _legacy_response.HttpxBinaryResponseContent:
331        """Download video content
332
333        Args:
334          variant: Which downloadable asset to return.
335
336        Defaults to the MP4 video.
337
338          extra_headers: Send extra headers
339
340          extra_query: Add additional query parameters to the request
341
342          extra_body: Add additional JSON properties to the request
343
344          timeout: Override the client-level default timeout for this request, in seconds
345        """
346        if not video_id:
347            raise ValueError(f"Expected a non-empty value for `video_id` but received {video_id!r}")
348        extra_headers = {"Accept": "application/binary", **(extra_headers or {})}
349        return self._get(
350            f"/videos/{video_id}/content",
351            options=make_request_options(
352                extra_headers=extra_headers,
353                extra_query=extra_query,
354                extra_body=extra_body,
355                timeout=timeout,
356                query=maybe_transform({"variant": variant}, video_download_content_params.VideoDownloadContentParams),
357            ),
358            cast_to=_legacy_response.HttpxBinaryResponseContent,
359        )
360
361    def remix(
362        self,
363        video_id: str,
364        *,
365        prompt: str,
366        # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
367        # The extra values given here take precedence over values defined on the client or passed to this method.
368        extra_headers: Headers | None = None,
369        extra_query: Query | None = None,
370        extra_body: Body | None = None,
371        timeout: float | httpx.Timeout | None | NotGiven = not_given,
372    ) -> Video:
373        """
374        Create a video remix
375
376        Args:
377          prompt: Updated text prompt that directs the remix generation.
378
379          extra_headers: Send extra headers
380
381          extra_query: Add additional query parameters to the request
382
383          extra_body: Add additional JSON properties to the request
384
385          timeout: Override the client-level default timeout for this request, in seconds
386        """
387        if not video_id:
388            raise ValueError(f"Expected a non-empty value for `video_id` but received {video_id!r}")
389        return self._post(
390            f"/videos/{video_id}/remix",
391            body=maybe_transform({"prompt": prompt}, video_remix_params.VideoRemixParams),
392            options=make_request_options(
393                extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
394            ),
395            cast_to=Video,
396        )
397
398
399class AsyncVideos(AsyncAPIResource):
400    @cached_property
401    def with_raw_response(self) -> AsyncVideosWithRawResponse:
402        """
403        This property can be used as a prefix for any HTTP method call to return
404        the raw response object instead of the parsed content.
405
406        For more information, see https://www.github.com/openai/openai-python#accessing-raw-response-data-eg-headers
407        """
408        return AsyncVideosWithRawResponse(self)
409
410    @cached_property
411    def with_streaming_response(self) -> AsyncVideosWithStreamingResponse:
412        """
413        An alternative to `.with_raw_response` that doesn't eagerly read the response body.
414
415        For more information, see https://www.github.com/openai/openai-python#with_streaming_response
416        """
417        return AsyncVideosWithStreamingResponse(self)
418
419    async def create(
420        self,
421        *,
422        prompt: str,
423        input_reference: FileTypes | Omit = omit,
424        model: VideoModel | Omit = omit,
425        seconds: VideoSeconds | Omit = omit,
426        size: VideoSize | Omit = omit,
427        # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
428        # The extra values given here take precedence over values defined on the client or passed to this method.
429        extra_headers: Headers | None = None,
430        extra_query: Query | None = None,
431        extra_body: Body | None = None,
432        timeout: float | httpx.Timeout | None | NotGiven = not_given,
433    ) -> Video:
434        """
435        Create a video
436
437        Args:
438          prompt: Text prompt that describes the video to generate.
439
440          input_reference: Optional image reference that guides generation.
441
442          model: The video generation model to use (allowed values: sora-2, sora-2-pro). Defaults
443              to `sora-2`.
444
445          seconds: Clip duration in seconds (allowed values: 4, 8, 12). Defaults to 4 seconds.
446
447          size: Output resolution formatted as width x height (allowed values: 720x1280,
448              1280x720, 1024x1792, 1792x1024). Defaults to 720x1280.
449
450          extra_headers: Send extra headers
451
452          extra_query: Add additional query parameters to the request
453
454          extra_body: Add additional JSON properties to the request
455
456          timeout: Override the client-level default timeout for this request, in seconds
457        """
458        body = deepcopy_minimal(
459            {
460                "prompt": prompt,
461                "input_reference": input_reference,
462                "model": model,
463                "seconds": seconds,
464                "size": size,
465            }
466        )
467        files = extract_files(cast(Mapping[str, object], body), paths=[["input_reference"]])
468        if files:
469            # It should be noted that the actual Content-Type header that will be
470            # sent to the server will contain a `boundary` parameter, e.g.
471            # multipart/form-data; boundary=---abc--
472            extra_headers = {"Content-Type": "multipart/form-data", **(extra_headers or {})}
473        return await self._post(
474            "/videos",
475            body=await async_maybe_transform(body, video_create_params.VideoCreateParams),
476            files=files,
477            options=make_request_options(
478                extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
479            ),
480            cast_to=Video,
481        )
482
483    async def create_and_poll(
484        self,
485        *,
486        prompt: str,
487        input_reference: FileTypes | Omit = omit,
488        model: VideoModel | Omit = omit,
489        seconds: VideoSeconds | Omit = omit,
490        size: VideoSize | Omit = omit,
491        poll_interval_ms: int | Omit = omit,
492        # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
493        # The extra values given here take precedence over values defined on the client or passed to this method.
494        extra_headers: Headers | None = None,
495        extra_query: Query | None = None,
496        extra_body: Body | None = None,
497        timeout: float | httpx.Timeout | None | NotGiven = not_given,
498    ) -> Video:
499        """Create a video and wait for it to be processed."""
500        video = await self.create(
501            model=model,
502            prompt=prompt,
503            input_reference=input_reference,
504            seconds=seconds,
505            size=size,
506            extra_headers=extra_headers,
507            extra_query=extra_query,
508            extra_body=extra_body,
509            timeout=timeout,
510        )
511
512        return await self.poll(
513            video.id,
514            poll_interval_ms=poll_interval_ms,
515        )
516
517    async def poll(
518        self,
519        video_id: str,
520        *,
521        poll_interval_ms: int | Omit = omit,
522    ) -> Video:
523        """Wait for the vector store file to finish processing.
524
525        Note: this will return even if the file failed to process, you need to check
526        file.last_error and file.status to handle these cases
527        """
528        headers: dict[str, str] = {"X-Stainless-Poll-Helper": "true"}
529        if is_given(poll_interval_ms):
530            headers["X-Stainless-Custom-Poll-Interval"] = str(poll_interval_ms)
531
532        while True:
533            response = await self.with_raw_response.retrieve(
534                video_id,
535                extra_headers=headers,
536            )
537
538            video = response.parse()
539            if video.status == "in_progress" or video.status == "queued":
540                if not is_given(poll_interval_ms):
541                    from_header = response.headers.get("openai-poll-after-ms")
542                    if from_header is not None:
543                        poll_interval_ms = int(from_header)
544                    else:
545                        poll_interval_ms = 1000
546
547                await self._sleep(poll_interval_ms / 1000)
548            elif video.status == "completed" or video.status == "failed":
549                return video
550            else:
551                if TYPE_CHECKING:  # type: ignore[unreachable]
552                    assert_never(video.status)
553                else:
554                    return video
555
556    async def retrieve(
557        self,
558        video_id: str,
559        *,
560        # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
561        # The extra values given here take precedence over values defined on the client or passed to this method.
562        extra_headers: Headers | None = None,
563        extra_query: Query | None = None,
564        extra_body: Body | None = None,
565        timeout: float | httpx.Timeout | None | NotGiven = not_given,
566    ) -> Video:
567        """
568        Retrieve a video
569
570        Args:
571          extra_headers: Send extra headers
572
573          extra_query: Add additional query parameters to the request
574
575          extra_body: Add additional JSON properties to the request
576
577          timeout: Override the client-level default timeout for this request, in seconds
578        """
579        if not video_id:
580            raise ValueError(f"Expected a non-empty value for `video_id` but received {video_id!r}")
581        return await self._get(
582            f"/videos/{video_id}",
583            options=make_request_options(
584                extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
585            ),
586            cast_to=Video,
587        )
588
589    def list(
590        self,
591        *,
592        after: str | Omit = omit,
593        limit: int | Omit = omit,
594        order: Literal["asc", "desc"] | Omit = omit,
595        # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
596        # The extra values given here take precedence over values defined on the client or passed to this method.
597        extra_headers: Headers | None = None,
598        extra_query: Query | None = None,
599        extra_body: Body | None = None,
600        timeout: float | httpx.Timeout | None | NotGiven = not_given,
601    ) -> AsyncPaginator[Video, AsyncConversationCursorPage[Video]]:
602        """
603        List videos
604
605        Args:
606          after: Identifier for the last item from the previous pagination request
607
608          limit: Number of items to retrieve
609
610          order: Sort order of results by timestamp. Use `asc` for ascending order or `desc` for
611              descending order.
612
613          extra_headers: Send extra headers
614
615          extra_query: Add additional query parameters to the request
616
617          extra_body: Add additional JSON properties to the request
618
619          timeout: Override the client-level default timeout for this request, in seconds
620        """
621        return self._get_api_list(
622            "/videos",
623            page=AsyncConversationCursorPage[Video],
624            options=make_request_options(
625                extra_headers=extra_headers,
626                extra_query=extra_query,
627                extra_body=extra_body,
628                timeout=timeout,
629                query=maybe_transform(
630                    {
631                        "after": after,
632                        "limit": limit,
633                        "order": order,
634                    },
635                    video_list_params.VideoListParams,
636                ),
637            ),
638            model=Video,
639        )
640
641    async def delete(
642        self,
643        video_id: str,
644        *,
645        # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
646        # The extra values given here take precedence over values defined on the client or passed to this method.
647        extra_headers: Headers | None = None,
648        extra_query: Query | None = None,
649        extra_body: Body | None = None,
650        timeout: float | httpx.Timeout | None | NotGiven = not_given,
651    ) -> VideoDeleteResponse:
652        """
653        Delete a video
654
655        Args:
656          extra_headers: Send extra headers
657
658          extra_query: Add additional query parameters to the request
659
660          extra_body: Add additional JSON properties to the request
661
662          timeout: Override the client-level default timeout for this request, in seconds
663        """
664        if not video_id:
665            raise ValueError(f"Expected a non-empty value for `video_id` but received {video_id!r}")
666        return await self._delete(
667            f"/videos/{video_id}",
668            options=make_request_options(
669                extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
670            ),
671            cast_to=VideoDeleteResponse,
672        )
673
674    async def download_content(
675        self,
676        video_id: str,
677        *,
678        variant: Literal["video", "thumbnail", "spritesheet"] | Omit = omit,
679        # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
680        # The extra values given here take precedence over values defined on the client or passed to this method.
681        extra_headers: Headers | None = None,
682        extra_query: Query | None = None,
683        extra_body: Body | None = None,
684        timeout: float | httpx.Timeout | None | NotGiven = not_given,
685    ) -> _legacy_response.HttpxBinaryResponseContent:
686        """Download video content
687
688        Args:
689          variant: Which downloadable asset to return.
690
691        Defaults to the MP4 video.
692
693          extra_headers: Send extra headers
694
695          extra_query: Add additional query parameters to the request
696
697          extra_body: Add additional JSON properties to the request
698
699          timeout: Override the client-level default timeout for this request, in seconds
700        """
701        if not video_id:
702            raise ValueError(f"Expected a non-empty value for `video_id` but received {video_id!r}")
703        extra_headers = {"Accept": "application/binary", **(extra_headers or {})}
704        return await self._get(
705            f"/videos/{video_id}/content",
706            options=make_request_options(
707                extra_headers=extra_headers,
708                extra_query=extra_query,
709                extra_body=extra_body,
710                timeout=timeout,
711                query=await async_maybe_transform(
712                    {"variant": variant}, video_download_content_params.VideoDownloadContentParams
713                ),
714            ),
715            cast_to=_legacy_response.HttpxBinaryResponseContent,
716        )
717
718    async def remix(
719        self,
720        video_id: str,
721        *,
722        prompt: str,
723        # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
724        # The extra values given here take precedence over values defined on the client or passed to this method.
725        extra_headers: Headers | None = None,
726        extra_query: Query | None = None,
727        extra_body: Body | None = None,
728        timeout: float | httpx.Timeout | None | NotGiven = not_given,
729    ) -> Video:
730        """
731        Create a video remix
732
733        Args:
734          prompt: Updated text prompt that directs the remix generation.
735
736          extra_headers: Send extra headers
737
738          extra_query: Add additional query parameters to the request
739
740          extra_body: Add additional JSON properties to the request
741
742          timeout: Override the client-level default timeout for this request, in seconds
743        """
744        if not video_id:
745            raise ValueError(f"Expected a non-empty value for `video_id` but received {video_id!r}")
746        return await self._post(
747            f"/videos/{video_id}/remix",
748            body=await async_maybe_transform({"prompt": prompt}, video_remix_params.VideoRemixParams),
749            options=make_request_options(
750                extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
751            ),
752            cast_to=Video,
753        )
754
755
756class VideosWithRawResponse:
757    def __init__(self, videos: Videos) -> None:
758        self._videos = videos
759
760        self.create = _legacy_response.to_raw_response_wrapper(
761            videos.create,
762        )
763        self.retrieve = _legacy_response.to_raw_response_wrapper(
764            videos.retrieve,
765        )
766        self.list = _legacy_response.to_raw_response_wrapper(
767            videos.list,
768        )
769        self.delete = _legacy_response.to_raw_response_wrapper(
770            videos.delete,
771        )
772        self.download_content = _legacy_response.to_raw_response_wrapper(
773            videos.download_content,
774        )
775        self.remix = _legacy_response.to_raw_response_wrapper(
776            videos.remix,
777        )
778
779
780class AsyncVideosWithRawResponse:
781    def __init__(self, videos: AsyncVideos) -> None:
782        self._videos = videos
783
784        self.create = _legacy_response.async_to_raw_response_wrapper(
785            videos.create,
786        )
787        self.retrieve = _legacy_response.async_to_raw_response_wrapper(
788            videos.retrieve,
789        )
790        self.list = _legacy_response.async_to_raw_response_wrapper(
791            videos.list,
792        )
793        self.delete = _legacy_response.async_to_raw_response_wrapper(
794            videos.delete,
795        )
796        self.download_content = _legacy_response.async_to_raw_response_wrapper(
797            videos.download_content,
798        )
799        self.remix = _legacy_response.async_to_raw_response_wrapper(
800            videos.remix,
801        )
802
803
804class VideosWithStreamingResponse:
805    def __init__(self, videos: Videos) -> None:
806        self._videos = videos
807
808        self.create = to_streamed_response_wrapper(
809            videos.create,
810        )
811        self.retrieve = to_streamed_response_wrapper(
812            videos.retrieve,
813        )
814        self.list = to_streamed_response_wrapper(
815            videos.list,
816        )
817        self.delete = to_streamed_response_wrapper(
818            videos.delete,
819        )
820        self.download_content = to_custom_streamed_response_wrapper(
821            videos.download_content,
822            StreamedBinaryAPIResponse,
823        )
824        self.remix = to_streamed_response_wrapper(
825            videos.remix,
826        )
827
828
829class AsyncVideosWithStreamingResponse:
830    def __init__(self, videos: AsyncVideos) -> None:
831        self._videos = videos
832
833        self.create = async_to_streamed_response_wrapper(
834            videos.create,
835        )
836        self.retrieve = async_to_streamed_response_wrapper(
837            videos.retrieve,
838        )
839        self.list = async_to_streamed_response_wrapper(
840            videos.list,
841        )
842        self.delete = async_to_streamed_response_wrapper(
843            videos.delete,
844        )
845        self.download_content = async_to_custom_streamed_response_wrapper(
846            videos.download_content,
847            AsyncStreamedBinaryAPIResponse,
848        )
849        self.remix = async_to_streamed_response_wrapper(
850            videos.remix,
851        )