# This file was auto-generated by Fern from our API Definition.

import typing
from json.decoder import JSONDecodeError

from ...core.api_error import ApiError
from ...core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
from ...core.http_response import AsyncHttpResponse, HttpResponse
from ...core.jsonable_encoder import jsonable_encoder
from ...core.pagination import AsyncPager, BaseHttpResponse, SyncPager
from ...core.pydantic_utilities import parse_obj_as
from ...core.request_options import RequestOptions
from ...core.serialization import convert_and_respect_annotation_metadata
from ...errors.bad_request_error import BadRequestError
from ...errors.internal_server_error import InternalServerError
from ...errors.not_found_error import NotFoundError
from ...types.indexed_asset import IndexedAsset
from ...types.indexed_asset_detailed import IndexedAssetDetailed
from ...types.user_metadata import UserMetadata
from .types.indexed_assets_create_response import IndexedAssetsCreateResponse
from .types.indexed_assets_list_request_status_item import IndexedAssetsListRequestStatusItem
from .types.indexed_assets_list_request_user_metadata_value import IndexedAssetsListRequestUserMetadataValue
from .types.indexed_assets_list_response import IndexedAssetsListResponse
from .types.indexed_assets_retrieve_request_embedding_option_item import IndexedAssetsRetrieveRequestEmbeddingOptionItem

# this is used as the default value for optional parameters
OMIT = typing.cast(typing.Any, ...)


class RawIndexedAssetsClient:
    def __init__(self, *, client_wrapper: SyncClientWrapper):
        self._client_wrapper = client_wrapper

    def list(
        self,
        index_id: str,
        *,
        page: typing.Optional[int] = None,
        page_limit: typing.Optional[int] = None,
        sort_by: typing.Optional[str] = None,
        sort_option: typing.Optional[str] = None,
        status: typing.Optional[
            typing.Union[IndexedAssetsListRequestStatusItem, typing.Sequence[IndexedAssetsListRequestStatusItem]]
        ] = None,
        filename: typing.Optional[str] = None,
        duration: typing.Optional[float] = None,
        fps: typing.Optional[float] = None,
        width: typing.Optional[float] = None,
        height: typing.Optional[int] = None,
        size: typing.Optional[float] = None,
        created_at: typing.Optional[str] = None,
        updated_at: typing.Optional[str] = None,
        user_metadata: typing.Optional[
            typing.Dict[str, typing.Optional[IndexedAssetsListRequestUserMetadataValue]]
        ] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> SyncPager[IndexedAsset]:
        """
        This method returns a list of the indexed assets in the specified index. By default, the platform returns your indexed assets sorted by creation date, with the newest at the top of the list.

        Parameters
        ----------
        index_id : str
            The unique identifier of the index for which the platform will retrieve the indexed assets.

        page : typing.Optional[int]
            A number that identifies the page to retrieve.

            **Default**: `1`.

        page_limit : typing.Optional[int]
            The number of items to return on each page.

            **Default**: `10`.
            **Max**: `50`.

        sort_by : typing.Optional[str]
            The field to sort on. The following options are available:
            - `updated_at`: Sorts by the time, in the RFC 3339 format ("YYYY-MM-DDTHH:mm:ssZ"), when the item was updated.
            - `created_at`: Sorts by the time, in the RFC 3339 format ("YYYY-MM-DDTHH:mm:ssZ"), when the item was created.

            **Default**: `created_at`.

        sort_option : typing.Optional[str]
            The sorting direction. The following options are available:
            - `asc`
            - `desc`

            **Default**: `desc`.

        status : typing.Optional[typing.Union[IndexedAssetsListRequestStatusItem, typing.Sequence[IndexedAssetsListRequestStatusItem]]]
            Filter by one or more indexing task statuses. The following options are available:
            - `ready`: The indexed asset has been successfully uploaded and indexed.
            - `pending`: The indexed asset is pending.
            - `queued`: The indexed asset is queued.
            - `indexing`: The indexed asset is being indexed.
            - `failed`: The indexed asset indexing task failed.

            To filter by multiple statuses, specify the `status` parameter for each value:
            ```
            status=ready&status=validating
            ```

        filename : typing.Optional[str]
            Filter by filename.

        duration : typing.Optional[float]
            Filter by duration. Expressed in seconds.

        fps : typing.Optional[float]
            Filter by frames per second.

        width : typing.Optional[float]
            Filter by width.

        height : typing.Optional[int]
            Filter by height.

        size : typing.Optional[float]
            Filter by size. Expressed in bytes.

        created_at : typing.Optional[str]
            Filter indexed assets by the creation date and time of their associated indexing tasks, in the RFC 3339 format ("YYYY-MM-DDTHH:mm:ssZ"). The platform returns indexed assets created on or after the specified date and time.

        updated_at : typing.Optional[str]
            This filter applies only to indexed assets updated using the [`PUT`](/v1.3/api-reference/videos/update) method of the `/indexes/{index-id}/indexed-assets/{indexed-asset-id}` endpoint. It filters indexed assets by the last update date and time, in the RFC 3339 format ("YYYY-MM-DDTHH:mm:ssZ"). The platform returns the indexed assets that were last updated on the specified date at or after the given time.

        user_metadata : typing.Optional[typing.Dict[str, typing.Optional[IndexedAssetsListRequestUserMetadataValue]]]
            To enable filtering by custom fields, you must first add user-defined metadata to your video by calling the [`PUT`](/v1.3/api-reference/videos/update) method of the `/indexes/:index-id/indexed-assets/:indexed-asset-id` endpoint.

            Examples:
            - To filter on a string: `?category=recentlyAdded`
            - To filter on an integer: `?batchNumber=5`
            - To filter on a float: `?rating=9.3`
            - To filter on a boolean: `?needsReview=true`

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        SyncPager[IndexedAsset]
            The indexed assets in the specified index have successfully been retrieved.
        """
        page = page if page is not None else 1

        _response = self._client_wrapper.httpx_client.request(
            f"indexes/{jsonable_encoder(index_id)}/indexed-assets",
            method="GET",
            params={
                "page": page,
                "page_limit": page_limit,
                "sort_by": sort_by,
                "sort_option": sort_option,
                "status": status,
                "filename": filename,
                "duration": duration,
                "fps": fps,
                "width": width,
                "height": height,
                "size": size,
                "created_at": created_at,
                "updated_at": updated_at,
                "user_metadata": convert_and_respect_annotation_metadata(
                    object_=user_metadata,
                    annotation=typing.Dict[str, typing.Optional[IndexedAssetsListRequestUserMetadataValue]],
                    direction="write",
                ),
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _parsed_response = typing.cast(
                    IndexedAssetsListResponse,
                    parse_obj_as(
                        type_=IndexedAssetsListResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                _items = _parsed_response.data
                _has_next = True
                _get_next = lambda: self.list(
                    index_id,
                    page=page + 1,
                    page_limit=page_limit,
                    sort_by=sort_by,
                    sort_option=sort_option,
                    status=status,
                    filename=filename,
                    duration=duration,
                    fps=fps,
                    width=width,
                    height=height,
                    size=size,
                    created_at=created_at,
                    updated_at=updated_at,
                    user_metadata=user_metadata,
                    request_options=request_options,
                )
                return SyncPager(
                    has_next=_has_next, items=_items, get_next=_get_next, response=BaseHttpResponse(response=_response)
                )
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def create(
        self,
        index_id: str,
        *,
        asset_id: str,
        enable_video_stream: typing.Optional[bool] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[IndexedAssetsCreateResponse]:
        """
        This method indexes an uploaded asset to make it searchable and analyzable. Indexing processes your content and extracts information that enables the platform to search and analyze your videos.

        This operation is asynchronous. The platform returns an indexed asset ID immediately and processes your content in the background. Monitor the indexing status to know when your content is ready to use.

        Your asset must meet the requirements based on your workflow:
        - **Search**: [Marengo requirements](/v1.3/docs/concepts/models/marengo#video-file-requirements)
        - **Video analysis**: [Pegasus requirements](/v1.3/docs/concepts/models/pegasus#input-requirements).

        If you want to both search and analyze your videos, the most restrictive requirements apply.

        <Note title="Note">
        This endpoint is rate-limited. For details, see the [Rate limits](/v1.3/docs/get-started/rate-limits) page.
        </Note>

        Parameters
        ----------
        index_id : str
            The unique identifier of the index to which the asset will be indexed.

        asset_id : str
            The unique identifier of the asset to index.

        enable_video_stream : typing.Optional[bool]
            This parameter indicates if the platform stores the video for streaming. When set to `true`, the platform stores the video, and you can retrieve its URL by calling the [`GET`](/v1.3/api-reference/videos/retrieve) method of the `/indexes/{index-id}/indexed-assets/{indexed-asset-id}` endpoint. You can then use this URL to access the stream over the <a href="https://en.wikipedia.org/wiki/HTTP_Live_Streaming" target="_blank">HLS</a> protocol.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[IndexedAssetsCreateResponse]
            The indexing request has been accepted and is processing.
        """
        _response = self._client_wrapper.httpx_client.request(
            f"indexes/{jsonable_encoder(index_id)}/indexed-assets",
            method="POST",
            json={
                "asset_id": asset_id,
                "enable_video_stream": enable_video_stream,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    IndexedAssetsCreateResponse,
                    parse_obj_as(
                        type_=IndexedAssetsCreateResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def retrieve(
        self,
        index_id: str,
        indexed_asset_id: str,
        *,
        embedding_option: typing.Optional[
            typing.Union[
                IndexedAssetsRetrieveRequestEmbeddingOptionItem,
                typing.Sequence[IndexedAssetsRetrieveRequestEmbeddingOptionItem],
            ]
        ] = None,
        transcription: typing.Optional[bool] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[IndexedAssetDetailed]:
        """
        This method retrieves information about an indexed asset, including its status, metadata, and optional embeddings or transcription.

        Use this method to:

        - Monitor the indexing progress:
            - Call this endpoint after creating an indexed asset
            - Check the `status` field until it shows `ready`
            - Once ready, your content is available for search and analysis

        - Retrieve the asset metadata:
            - Retrieve system metadata (duration, resolution, filename)
            - Access user-defined metadata

        - Retrieve the embeddings:
            - Include the `embeddingOption` parameter to retrieve video embeddings
            - Requires the Marengo video understanding model to be enabled in your index

        - Retrieve transcriptions:
          - Set the `transcription` parameter to `true` to retrieve spoken words from your video

        Parameters
        ----------
        index_id : str
            The unique identifier of the index to which the indexed asset has been uploaded.

        indexed_asset_id : str
            The unique identifier of the indexed asset to retrieve.

        embedding_option : typing.Optional[typing.Union[IndexedAssetsRetrieveRequestEmbeddingOptionItem, typing.Sequence[IndexedAssetsRetrieveRequestEmbeddingOptionItem]]]
            Specifies which types of embeddings to retrieve. Values: `visual`, `audio`, `transcription`. For details, see the [Embedding options](/v1.3/docs/concepts/modalities#embedding-options) section.

            <Note title="Note">
            To retrieve embeddings for a video, it must be indexed using the Marengo video understanding model. For details on enabling this model for an index, see the [Create an index](/reference/create-index) page.
            </Note>

        transcription : typing.Optional[bool]
            Specifies whether to retrieve a transcription of the spoken words.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[IndexedAssetDetailed]
            The specified indexed asset information has successfully been retrieved.
        """
        _response = self._client_wrapper.httpx_client.request(
            f"indexes/{jsonable_encoder(index_id)}/indexed-assets/{jsonable_encoder(indexed_asset_id)}",
            method="GET",
            params={
                "embedding_option": embedding_option,
                "transcription": transcription,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    IndexedAssetDetailed,
                    parse_obj_as(
                        type_=IndexedAssetDetailed,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def delete(
        self, index_id: str, indexed_asset_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[None]:
        """
        This method deletes all the information about the specified indexed asset. This action cannot be undone.

        Parameters
        ----------
        index_id : str
            The unique identifier of the index to which the indexed asset has been uploaded.

        indexed_asset_id : str
            The unique identifier of the indexed asset to delete.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[None]
        """
        _response = self._client_wrapper.httpx_client.request(
            f"indexes/{jsonable_encoder(index_id)}/indexed-assets/{jsonable_encoder(indexed_asset_id)}",
            method="DELETE",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return HttpResponse(response=_response, data=None)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def update(
        self,
        index_id: str,
        indexed_asset_id: str,
        *,
        user_metadata: typing.Optional[UserMetadata] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[None]:
        """
        This method updates one or more fields of the metadata of an indexed asset. Also, can delete a field by setting it to `null`.

        Parameters
        ----------
        index_id : str
            The unique identifier of the index to which the indexed asset has been uploaded.

        indexed_asset_id : str
            The unique identifier of the indexed asset to update.

        user_metadata : typing.Optional[UserMetadata]

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[None]
        """
        _response = self._client_wrapper.httpx_client.request(
            f"indexes/{jsonable_encoder(index_id)}/indexed-assets/{jsonable_encoder(indexed_asset_id)}",
            method="PATCH",
            json={
                "user_metadata": user_metadata,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return HttpResponse(response=_response, data=None)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)


class AsyncRawIndexedAssetsClient:
    def __init__(self, *, client_wrapper: AsyncClientWrapper):
        self._client_wrapper = client_wrapper

    async def list(
        self,
        index_id: str,
        *,
        page: typing.Optional[int] = None,
        page_limit: typing.Optional[int] = None,
        sort_by: typing.Optional[str] = None,
        sort_option: typing.Optional[str] = None,
        status: typing.Optional[
            typing.Union[IndexedAssetsListRequestStatusItem, typing.Sequence[IndexedAssetsListRequestStatusItem]]
        ] = None,
        filename: typing.Optional[str] = None,
        duration: typing.Optional[float] = None,
        fps: typing.Optional[float] = None,
        width: typing.Optional[float] = None,
        height: typing.Optional[int] = None,
        size: typing.Optional[float] = None,
        created_at: typing.Optional[str] = None,
        updated_at: typing.Optional[str] = None,
        user_metadata: typing.Optional[
            typing.Dict[str, typing.Optional[IndexedAssetsListRequestUserMetadataValue]]
        ] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncPager[IndexedAsset]:
        """
        This method returns a list of the indexed assets in the specified index. By default, the platform returns your indexed assets sorted by creation date, with the newest at the top of the list.

        Parameters
        ----------
        index_id : str
            The unique identifier of the index for which the platform will retrieve the indexed assets.

        page : typing.Optional[int]
            A number that identifies the page to retrieve.

            **Default**: `1`.

        page_limit : typing.Optional[int]
            The number of items to return on each page.

            **Default**: `10`.
            **Max**: `50`.

        sort_by : typing.Optional[str]
            The field to sort on. The following options are available:
            - `updated_at`: Sorts by the time, in the RFC 3339 format ("YYYY-MM-DDTHH:mm:ssZ"), when the item was updated.
            - `created_at`: Sorts by the time, in the RFC 3339 format ("YYYY-MM-DDTHH:mm:ssZ"), when the item was created.

            **Default**: `created_at`.

        sort_option : typing.Optional[str]
            The sorting direction. The following options are available:
            - `asc`
            - `desc`

            **Default**: `desc`.

        status : typing.Optional[typing.Union[IndexedAssetsListRequestStatusItem, typing.Sequence[IndexedAssetsListRequestStatusItem]]]
            Filter by one or more indexing task statuses. The following options are available:
            - `ready`: The indexed asset has been successfully uploaded and indexed.
            - `pending`: The indexed asset is pending.
            - `queued`: The indexed asset is queued.
            - `indexing`: The indexed asset is being indexed.
            - `failed`: The indexed asset indexing task failed.

            To filter by multiple statuses, specify the `status` parameter for each value:
            ```
            status=ready&status=validating
            ```

        filename : typing.Optional[str]
            Filter by filename.

        duration : typing.Optional[float]
            Filter by duration. Expressed in seconds.

        fps : typing.Optional[float]
            Filter by frames per second.

        width : typing.Optional[float]
            Filter by width.

        height : typing.Optional[int]
            Filter by height.

        size : typing.Optional[float]
            Filter by size. Expressed in bytes.

        created_at : typing.Optional[str]
            Filter indexed assets by the creation date and time of their associated indexing tasks, in the RFC 3339 format ("YYYY-MM-DDTHH:mm:ssZ"). The platform returns indexed assets created on or after the specified date and time.

        updated_at : typing.Optional[str]
            This filter applies only to indexed assets updated using the [`PUT`](/v1.3/api-reference/videos/update) method of the `/indexes/{index-id}/indexed-assets/{indexed-asset-id}` endpoint. It filters indexed assets by the last update date and time, in the RFC 3339 format ("YYYY-MM-DDTHH:mm:ssZ"). The platform returns the indexed assets that were last updated on the specified date at or after the given time.

        user_metadata : typing.Optional[typing.Dict[str, typing.Optional[IndexedAssetsListRequestUserMetadataValue]]]
            To enable filtering by custom fields, you must first add user-defined metadata to your video by calling the [`PUT`](/v1.3/api-reference/videos/update) method of the `/indexes/:index-id/indexed-assets/:indexed-asset-id` endpoint.

            Examples:
            - To filter on a string: `?category=recentlyAdded`
            - To filter on an integer: `?batchNumber=5`
            - To filter on a float: `?rating=9.3`
            - To filter on a boolean: `?needsReview=true`

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncPager[IndexedAsset]
            The indexed assets in the specified index have successfully been retrieved.
        """
        page = page if page is not None else 1

        _response = await self._client_wrapper.httpx_client.request(
            f"indexes/{jsonable_encoder(index_id)}/indexed-assets",
            method="GET",
            params={
                "page": page,
                "page_limit": page_limit,
                "sort_by": sort_by,
                "sort_option": sort_option,
                "status": status,
                "filename": filename,
                "duration": duration,
                "fps": fps,
                "width": width,
                "height": height,
                "size": size,
                "created_at": created_at,
                "updated_at": updated_at,
                "user_metadata": convert_and_respect_annotation_metadata(
                    object_=user_metadata,
                    annotation=typing.Dict[str, typing.Optional[IndexedAssetsListRequestUserMetadataValue]],
                    direction="write",
                ),
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _parsed_response = typing.cast(
                    IndexedAssetsListResponse,
                    parse_obj_as(
                        type_=IndexedAssetsListResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                _items = _parsed_response.data
                _has_next = True

                async def _get_next():
                    return await self.list(
                        index_id,
                        page=page + 1,
                        page_limit=page_limit,
                        sort_by=sort_by,
                        sort_option=sort_option,
                        status=status,
                        filename=filename,
                        duration=duration,
                        fps=fps,
                        width=width,
                        height=height,
                        size=size,
                        created_at=created_at,
                        updated_at=updated_at,
                        user_metadata=user_metadata,
                        request_options=request_options,
                    )

                return AsyncPager(
                    has_next=_has_next, items=_items, get_next=_get_next, response=BaseHttpResponse(response=_response)
                )
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def create(
        self,
        index_id: str,
        *,
        asset_id: str,
        enable_video_stream: typing.Optional[bool] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[IndexedAssetsCreateResponse]:
        """
        This method indexes an uploaded asset to make it searchable and analyzable. Indexing processes your content and extracts information that enables the platform to search and analyze your videos.

        This operation is asynchronous. The platform returns an indexed asset ID immediately and processes your content in the background. Monitor the indexing status to know when your content is ready to use.

        Your asset must meet the requirements based on your workflow:
        - **Search**: [Marengo requirements](/v1.3/docs/concepts/models/marengo#video-file-requirements)
        - **Video analysis**: [Pegasus requirements](/v1.3/docs/concepts/models/pegasus#input-requirements).

        If you want to both search and analyze your videos, the most restrictive requirements apply.

        <Note title="Note">
        This endpoint is rate-limited. For details, see the [Rate limits](/v1.3/docs/get-started/rate-limits) page.
        </Note>

        Parameters
        ----------
        index_id : str
            The unique identifier of the index to which the asset will be indexed.

        asset_id : str
            The unique identifier of the asset to index.

        enable_video_stream : typing.Optional[bool]
            This parameter indicates if the platform stores the video for streaming. When set to `true`, the platform stores the video, and you can retrieve its URL by calling the [`GET`](/v1.3/api-reference/videos/retrieve) method of the `/indexes/{index-id}/indexed-assets/{indexed-asset-id}` endpoint. You can then use this URL to access the stream over the <a href="https://en.wikipedia.org/wiki/HTTP_Live_Streaming" target="_blank">HLS</a> protocol.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[IndexedAssetsCreateResponse]
            The indexing request has been accepted and is processing.
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"indexes/{jsonable_encoder(index_id)}/indexed-assets",
            method="POST",
            json={
                "asset_id": asset_id,
                "enable_video_stream": enable_video_stream,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    IndexedAssetsCreateResponse,
                    parse_obj_as(
                        type_=IndexedAssetsCreateResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def retrieve(
        self,
        index_id: str,
        indexed_asset_id: str,
        *,
        embedding_option: typing.Optional[
            typing.Union[
                IndexedAssetsRetrieveRequestEmbeddingOptionItem,
                typing.Sequence[IndexedAssetsRetrieveRequestEmbeddingOptionItem],
            ]
        ] = None,
        transcription: typing.Optional[bool] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[IndexedAssetDetailed]:
        """
        This method retrieves information about an indexed asset, including its status, metadata, and optional embeddings or transcription.

        Use this method to:

        - Monitor the indexing progress:
            - Call this endpoint after creating an indexed asset
            - Check the `status` field until it shows `ready`
            - Once ready, your content is available for search and analysis

        - Retrieve the asset metadata:
            - Retrieve system metadata (duration, resolution, filename)
            - Access user-defined metadata

        - Retrieve the embeddings:
            - Include the `embeddingOption` parameter to retrieve video embeddings
            - Requires the Marengo video understanding model to be enabled in your index

        - Retrieve transcriptions:
          - Set the `transcription` parameter to `true` to retrieve spoken words from your video

        Parameters
        ----------
        index_id : str
            The unique identifier of the index to which the indexed asset has been uploaded.

        indexed_asset_id : str
            The unique identifier of the indexed asset to retrieve.

        embedding_option : typing.Optional[typing.Union[IndexedAssetsRetrieveRequestEmbeddingOptionItem, typing.Sequence[IndexedAssetsRetrieveRequestEmbeddingOptionItem]]]
            Specifies which types of embeddings to retrieve. Values: `visual`, `audio`, `transcription`. For details, see the [Embedding options](/v1.3/docs/concepts/modalities#embedding-options) section.

            <Note title="Note">
            To retrieve embeddings for a video, it must be indexed using the Marengo video understanding model. For details on enabling this model for an index, see the [Create an index](/reference/create-index) page.
            </Note>

        transcription : typing.Optional[bool]
            Specifies whether to retrieve a transcription of the spoken words.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[IndexedAssetDetailed]
            The specified indexed asset information has successfully been retrieved.
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"indexes/{jsonable_encoder(index_id)}/indexed-assets/{jsonable_encoder(indexed_asset_id)}",
            method="GET",
            params={
                "embedding_option": embedding_option,
                "transcription": transcription,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    IndexedAssetDetailed,
                    parse_obj_as(
                        type_=IndexedAssetDetailed,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def delete(
        self, index_id: str, indexed_asset_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[None]:
        """
        This method deletes all the information about the specified indexed asset. This action cannot be undone.

        Parameters
        ----------
        index_id : str
            The unique identifier of the index to which the indexed asset has been uploaded.

        indexed_asset_id : str
            The unique identifier of the indexed asset to delete.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[None]
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"indexes/{jsonable_encoder(index_id)}/indexed-assets/{jsonable_encoder(indexed_asset_id)}",
            method="DELETE",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return AsyncHttpResponse(response=_response, data=None)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def update(
        self,
        index_id: str,
        indexed_asset_id: str,
        *,
        user_metadata: typing.Optional[UserMetadata] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[None]:
        """
        This method updates one or more fields of the metadata of an indexed asset. Also, can delete a field by setting it to `null`.

        Parameters
        ----------
        index_id : str
            The unique identifier of the index to which the indexed asset has been uploaded.

        indexed_asset_id : str
            The unique identifier of the indexed asset to update.

        user_metadata : typing.Optional[UserMetadata]

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[None]
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"indexes/{jsonable_encoder(index_id)}/indexed-assets/{jsonable_encoder(indexed_asset_id)}",
            method="PATCH",
            json={
                "user_metadata": user_metadata,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return AsyncHttpResponse(response=_response, data=None)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
