# 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.pydantic_utilities import parse_obj_as
from ...core.request_options import RequestOptions
from ...errors.bad_request_error import BadRequestError
from .types.transfers_create_response import TransfersCreateResponse
from .types.transfers_get_logs_response import TransfersGetLogsResponse
from .types.transfers_get_status_response import TransfersGetStatusResponse

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


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

    def create(
        self,
        integration_id: str,
        *,
        index_id: str,
        incremental_import: typing.Optional[bool] = OMIT,
        retry_failed: typing.Optional[bool] = OMIT,
        user_metadata: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[TransfersCreateResponse]:
        """
        An import represents the process of uploading and indexing all videos from the specified integration.

        This method initiates an asynchronous import and returns two lists:
        - Videos that will be imported.
        - Videos that will not be imported, typically because they do not meet the prerequisites of all enabled video understanding models for your index. Note that the most restrictive prerequisites among the enabled models will apply.

        The actual uploading and indexing of videos occur asynchronously after you invoke this method. To monitor the status of each upload after invoking this method, use the [Retrieve import status](/v1.3/api-reference/tasks/cloud-to-cloud-integrations/get-status) method.

        <Accordion title="Video requirements">
          The videos you wish to upload must meet the following requirements:
          - **Video resolution**: Must be at least 360x360 and must not exceed 3840x2160.
          - **Aspect ratio**: Must be one of 1:1, 4:3, 4:5, 5:4, 16:9, 9:16, or 17:9.
          - **Video and audio formats**: Your video files must be encoded in the video and audio formats listed on the [FFmpeg Formats Documentation](https://ffmpeg.org/ffmpeg-formats.html) page. For videos in other formats, contact us at support@twelvelabs.io.
          - **Duration**: For Marengo, it must be between 4 seconds and 2 hours (7,200s). For Pegasus, it must be between 4 seconds and 60 minutes (3600s). In a future release, the maximum duration for Pegasus will be 2 hours (7,200 seconds).
          - **File size**: Must not exceed 2 GB.
            If you require different options, contact us at support@twelvelabs.io.

          If both Marengo and Pegasus are enabled for your index, the most restrictive prerequisites will apply.
        </Accordion>

        <Note title="Notes">
        - Before importing videos, you must set up an integration. For details, see the [Set up an integration](/v1.3/docs/advanced/cloud-to-cloud-integrations#set-up-an-integration) section.
        - By default, the platform checks for duplicate files using hashes within the target index and will not upload the same video to the same index twice. However, the same video can exist in multiple indexes. To bypass duplicate checking entirely and import duplicate videos into the same index, set the value of the `incremental_import` parameter to `false`.
        - Only one import job can run at a time. To start a new import, wait for the current job to complete. Use the [`GET`](/v1.3/api-reference/tasks/cloud-to-cloud-integrations/get-status) method of the `/tasks/transfers/import/{integration-id}/logs` endpoint to retrieve a list of your import jobs, including their creation time, completion time, and processing status for each video file.
        </Note>

        Parameters
        ----------
        integration_id : str
            The unique identifier of the integration for which you want to import videos. You can retrieve it from the [Integrations](https://playground.twelvelabs.io/dashboard/integrations) page.

        index_id : str
            The unique identifier of the index to which the videos are being uploaded.

        incremental_import : typing.Optional[bool]
            Specifies whether or not incremental sync is enabled. If set to `false`, the platform will synchronize all the files in the bucket.

            **Default**: `true`.

        retry_failed : typing.Optional[bool]
            Determines whether the platform retries failed uploads. When set to `true`, the platform attempts to re-upload files that failed during the initial upload process.

            **Default**: `false`.

        user_metadata : typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]]
            Metadata that helps you categorize your videos. You can specify a list of keys and values. Keys must be of type `string`, and values can be of the following types: `string`, `integer`, `float` or `boolean`.

            <Note title="Notes">
            - The metadata you specify when calling this method applies to all videos imported in this request.
            -  If you want to store other types of data such as objects or arrays, you must convert your data into string values.
            - You cannot override any of the predefined metadata (example: duration, width, length, etc) associated with a video.
            </Note>

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

        Returns
        -------
        HttpResponse[TransfersCreateResponse]
            An import has successfully been initiated.
        """
        _response = self._client_wrapper.httpx_client.request(
            f"tasks/transfers/import/{jsonable_encoder(integration_id)}",
            method="POST",
            json={
                "index_id": index_id,
                "incremental_import": incremental_import,
                "retry_failed": retry_failed,
                "user_metadata": user_metadata,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    TransfersCreateResponse,
                    parse_obj_as(
                        type_=TransfersCreateResponse,  # 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(),
                        ),
                    ),
                )
            _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 get_status(
        self, integration_id: str, *, index_id: str, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[TransfersGetStatusResponse]:
        """
        This method retrieves the current status for each video from a specified integration and index. It returns an object containing lists of videos grouped by status. See the [Task object](/v1.3/api-reference/tasks/the-task-object) page for details on each status.

        Parameters
        ----------
        integration_id : str
            The unique identifier of the integration for which you want to retrieve the status of your imported videos. You can retrieve it from the [Integrations](https://playground.twelvelabs.io/dashboard/integrations) page.

        index_id : str
            The unique identifier of the index for which you want to retrieve the status of your imported videos.

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

        Returns
        -------
        HttpResponse[TransfersGetStatusResponse]
            The status for each video from the specified integration and index has successfully been retrieved
        """
        _response = self._client_wrapper.httpx_client.request(
            f"tasks/transfers/import/{jsonable_encoder(integration_id)}/status",
            method="GET",
            params={
                "index_id": index_id,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    TransfersGetStatusResponse,
                    parse_obj_as(
                        type_=TransfersGetStatusResponse,  # 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(),
                        ),
                    ),
                )
            _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 get_logs(
        self, integration_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[TransfersGetLogsResponse]:
        """
        This endpoint returns a chronological list of import operations for the specified integration. The list is sorted by creation date, with the oldest imports first. Each item in the list contains:
        - The number of videos in each status
        - Detailed error information for failed uploads, including filenames and error messages.

        Use this endpoint to track import progress and troubleshoot potential issues across multiple operations.

        Parameters
        ----------
        integration_id : str
            The unique identifier of the integration for which you want to retrieve the import logs. You can retrieve it from the [Integrations](https://playground.twelvelabs.io/dashboard/integrations) page.

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

        Returns
        -------
        HttpResponse[TransfersGetLogsResponse]
            The import logs have successfully been retrieved.
        """
        _response = self._client_wrapper.httpx_client.request(
            f"tasks/transfers/import/{jsonable_encoder(integration_id)}/logs",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    TransfersGetLogsResponse,
                    parse_obj_as(
                        type_=TransfersGetLogsResponse,  # 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(),
                        ),
                    ),
                )
            _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 AsyncRawTransfersClient:
    def __init__(self, *, client_wrapper: AsyncClientWrapper):
        self._client_wrapper = client_wrapper

    async def create(
        self,
        integration_id: str,
        *,
        index_id: str,
        incremental_import: typing.Optional[bool] = OMIT,
        retry_failed: typing.Optional[bool] = OMIT,
        user_metadata: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[TransfersCreateResponse]:
        """
        An import represents the process of uploading and indexing all videos from the specified integration.

        This method initiates an asynchronous import and returns two lists:
        - Videos that will be imported.
        - Videos that will not be imported, typically because they do not meet the prerequisites of all enabled video understanding models for your index. Note that the most restrictive prerequisites among the enabled models will apply.

        The actual uploading and indexing of videos occur asynchronously after you invoke this method. To monitor the status of each upload after invoking this method, use the [Retrieve import status](/v1.3/api-reference/tasks/cloud-to-cloud-integrations/get-status) method.

        <Accordion title="Video requirements">
          The videos you wish to upload must meet the following requirements:
          - **Video resolution**: Must be at least 360x360 and must not exceed 3840x2160.
          - **Aspect ratio**: Must be one of 1:1, 4:3, 4:5, 5:4, 16:9, 9:16, or 17:9.
          - **Video and audio formats**: Your video files must be encoded in the video and audio formats listed on the [FFmpeg Formats Documentation](https://ffmpeg.org/ffmpeg-formats.html) page. For videos in other formats, contact us at support@twelvelabs.io.
          - **Duration**: For Marengo, it must be between 4 seconds and 2 hours (7,200s). For Pegasus, it must be between 4 seconds and 60 minutes (3600s). In a future release, the maximum duration for Pegasus will be 2 hours (7,200 seconds).
          - **File size**: Must not exceed 2 GB.
            If you require different options, contact us at support@twelvelabs.io.

          If both Marengo and Pegasus are enabled for your index, the most restrictive prerequisites will apply.
        </Accordion>

        <Note title="Notes">
        - Before importing videos, you must set up an integration. For details, see the [Set up an integration](/v1.3/docs/advanced/cloud-to-cloud-integrations#set-up-an-integration) section.
        - By default, the platform checks for duplicate files using hashes within the target index and will not upload the same video to the same index twice. However, the same video can exist in multiple indexes. To bypass duplicate checking entirely and import duplicate videos into the same index, set the value of the `incremental_import` parameter to `false`.
        - Only one import job can run at a time. To start a new import, wait for the current job to complete. Use the [`GET`](/v1.3/api-reference/tasks/cloud-to-cloud-integrations/get-status) method of the `/tasks/transfers/import/{integration-id}/logs` endpoint to retrieve a list of your import jobs, including their creation time, completion time, and processing status for each video file.
        </Note>

        Parameters
        ----------
        integration_id : str
            The unique identifier of the integration for which you want to import videos. You can retrieve it from the [Integrations](https://playground.twelvelabs.io/dashboard/integrations) page.

        index_id : str
            The unique identifier of the index to which the videos are being uploaded.

        incremental_import : typing.Optional[bool]
            Specifies whether or not incremental sync is enabled. If set to `false`, the platform will synchronize all the files in the bucket.

            **Default**: `true`.

        retry_failed : typing.Optional[bool]
            Determines whether the platform retries failed uploads. When set to `true`, the platform attempts to re-upload files that failed during the initial upload process.

            **Default**: `false`.

        user_metadata : typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]]
            Metadata that helps you categorize your videos. You can specify a list of keys and values. Keys must be of type `string`, and values can be of the following types: `string`, `integer`, `float` or `boolean`.

            <Note title="Notes">
            - The metadata you specify when calling this method applies to all videos imported in this request.
            -  If you want to store other types of data such as objects or arrays, you must convert your data into string values.
            - You cannot override any of the predefined metadata (example: duration, width, length, etc) associated with a video.
            </Note>

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

        Returns
        -------
        AsyncHttpResponse[TransfersCreateResponse]
            An import has successfully been initiated.
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"tasks/transfers/import/{jsonable_encoder(integration_id)}",
            method="POST",
            json={
                "index_id": index_id,
                "incremental_import": incremental_import,
                "retry_failed": retry_failed,
                "user_metadata": user_metadata,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    TransfersCreateResponse,
                    parse_obj_as(
                        type_=TransfersCreateResponse,  # 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(),
                        ),
                    ),
                )
            _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 get_status(
        self, integration_id: str, *, index_id: str, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[TransfersGetStatusResponse]:
        """
        This method retrieves the current status for each video from a specified integration and index. It returns an object containing lists of videos grouped by status. See the [Task object](/v1.3/api-reference/tasks/the-task-object) page for details on each status.

        Parameters
        ----------
        integration_id : str
            The unique identifier of the integration for which you want to retrieve the status of your imported videos. You can retrieve it from the [Integrations](https://playground.twelvelabs.io/dashboard/integrations) page.

        index_id : str
            The unique identifier of the index for which you want to retrieve the status of your imported videos.

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

        Returns
        -------
        AsyncHttpResponse[TransfersGetStatusResponse]
            The status for each video from the specified integration and index has successfully been retrieved
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"tasks/transfers/import/{jsonable_encoder(integration_id)}/status",
            method="GET",
            params={
                "index_id": index_id,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    TransfersGetStatusResponse,
                    parse_obj_as(
                        type_=TransfersGetStatusResponse,  # 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(),
                        ),
                    ),
                )
            _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 get_logs(
        self, integration_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[TransfersGetLogsResponse]:
        """
        This endpoint returns a chronological list of import operations for the specified integration. The list is sorted by creation date, with the oldest imports first. Each item in the list contains:
        - The number of videos in each status
        - Detailed error information for failed uploads, including filenames and error messages.

        Use this endpoint to track import progress and troubleshoot potential issues across multiple operations.

        Parameters
        ----------
        integration_id : str
            The unique identifier of the integration for which you want to retrieve the import logs. You can retrieve it from the [Integrations](https://playground.twelvelabs.io/dashboard/integrations) page.

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

        Returns
        -------
        AsyncHttpResponse[TransfersGetLogsResponse]
            The import logs have successfully been retrieved.
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"tasks/transfers/import/{jsonable_encoder(integration_id)}/logs",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    TransfersGetLogsResponse,
                    parse_obj_as(
                        type_=TransfersGetLogsResponse,  # 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(),
                        ),
                    ),
                )
            _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)
