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

import typing
import uuid
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 ..core.serialization import convert_and_respect_annotation_metadata
from ..transcribe.errors.authentication_error import AuthenticationError
from ..transcribe.errors.batch_not_found import BatchNotFound
from ..transcribe.errors.rate_limit_error import RateLimitError
from ..transcribe.types.batch_audio_source import BatchAudioSource
from ..transcribe.types.batch_file_content_type import BatchFileContentType
from ..transcribe.types.batch_file_detail import BatchFileDetail
from ..transcribe.types.batch_file_metadata import BatchFileMetadata
from ..transcribe.types.batch_file_upload_response import BatchFileUploadResponse
from ..transcribe.types.batch_manifest_audio_source import BatchManifestAudioSource
from ..transcribe.types.batch_status_response import BatchStatusResponse
from ..transcribe.types.batch_transcription_response import BatchTranscriptionResponse
from ..transcribe.types.list_batch_files_response import ListBatchFilesResponse
from ..transcribe.types.processing_mode import ProcessingMode
from ..transcribe.types.transcription_request_info import TranscriptionRequestInfo

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


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

    def create_batch_transcription(
        self,
        *,
        info: TranscriptionRequestInfo,
        processing_mode: typing.Optional[ProcessingMode] = OMIT,
        batch_file_id: typing.Optional[uuid.UUID] = OMIT,
        audio_sources: typing.Optional[typing.Sequence[BatchAudioSource]] = OMIT,
        batch_title: typing.Optional[str] = OMIT,
        batch_id: typing.Optional[uuid.UUID] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[BatchTranscriptionResponse]:
        """
        Create multiple transcriptions in a single batch request.

        **Choose a processing mode:**

        - **Express mode**: Transcriptions start immediately. Max 10 files. Higher cost. Pass `audio_sources` directly in the request. Pricing for v1 is $1.20/hour.
        - **Standard mode**: Transcriptions processed within 24 hours. Max 500 files. Lower cost. First upload a manifest via [Upload Batch Manifest File](/api-reference/batch-transcribe/upload-batch-file), then pass the `batch_file_id` here. Pricing for v1 batch standard is $0.90/hour.

        All files in the batch share the same transcription settings (model, language, etc.) defined in `info`.

        Parameters
        ----------
        info : TranscriptionRequestInfo
            Transcription settings applied to all files in the batch (model, language, etc.)

        processing_mode : typing.Optional[ProcessingMode]
            Choose how the batch is processed:
            - `standard` (default): Lower cost, processed within 24 hours. Max 500 files. Use with `batch_file_id`. Pricing for v1 batch standard is $0.90/hour.
            - `express`: Higher cost, starts immediately. Max 10 files. Use with `audio_sources`. Pricing for v1 is $1.20/hour.

        batch_file_id : typing.Optional[uuid.UUID]
            **For standard mode only.** ID of a previously uploaded batch manifest.

            Get this by calling [Upload Batch Manifest File](/api-reference/batch-transcribe/upload-batch-file) first.

        audio_sources : typing.Optional[typing.Sequence[BatchAudioSource]]
            **For express mode only.** List of audio URLs to transcribe (max 10).

            Each item needs an `audio_url` and can optionally include a `title`.

        batch_title : typing.Optional[str]
            Default title prefix for transcriptions. Individual items can override this. Items without titles become "{batch_title} - Item 1", "{batch_title} - Item 2", etc.

        batch_id : typing.Optional[uuid.UUID]
            Custom UUID for this batch. Auto-generated if not provided.

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

        Returns
        -------
        HttpResponse[BatchTranscriptionResponse]
            Returns the batch ID and individual transcription IDs. Use [Get Batch Status](/api-reference/batch-transcribe/get-batch-status) to track progress.
        """
        _response = self._client_wrapper.httpx_client.request(
            "v1/transcriptions/batch",
            method="POST",
            json={
                "processing_mode": processing_mode,
                "batch_file_id": batch_file_id,
                "audio_sources": convert_and_respect_annotation_metadata(
                    object_=audio_sources, annotation=typing.Sequence[BatchAudioSource], direction="write"
                ),
                "info": convert_and_respect_annotation_metadata(
                    object_=info, annotation=TranscriptionRequestInfo, direction="write"
                ),
                "batch_title": batch_title,
                "batch_id": batch_id,
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    BatchTranscriptionResponse,
                    parse_obj_as(
                        type_=BatchTranscriptionResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 401:
                raise AuthenticationError(headers=dict(_response.headers))
            if _response.status_code == 429:
                raise RateLimitError(headers=dict(_response.headers))
            _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 upload_batch_file(
        self,
        *,
        content_type: BatchFileContentType,
        json_items: typing.Optional[typing.Sequence[BatchManifestAudioSource]] = OMIT,
        jsonl: typing.Optional[str] = OMIT,
        metadata: typing.Optional[BatchFileMetadata] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[BatchFileUploadResponse]:
        """
        Upload a batch manifest containing audio URLs for standard mode batch processing.

        **Workflow:**
        1. Upload your manifest here to get a `batch_file_id`
        2. Use that ID in [Create Batch Transcription](/api-reference/batch-transcribe/create-batch-transcription) with `processing_mode: "standard"`

        The manifest is a list of audio sources (max 500), each with a URL and optional title. You can provide it as a JSON array or JSONL format.

        Parameters
        ----------
        content_type : BatchFileContentType
            Format of your manifest data

        json_items : typing.Optional[typing.Sequence[BatchManifestAudioSource]]
            **For JSON format.** Array of audio sources to transcribe (max 500).

        jsonl : typing.Optional[str]
            **For JSONL format.** One audio source per line as JSON, separated by newlines (max 500 lines).

            Example: `{"audio_url": "https://..."}\n{"audio_url": "https://..."}`

        metadata : typing.Optional[BatchFileMetadata]
            Optional title and description for this manifest

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

        Returns
        -------
        HttpResponse[BatchFileUploadResponse]
        """
        _response = self._client_wrapper.httpx_client.request(
            "v1/transcriptions/batch-files",
            method="POST",
            json={
                "content_type": content_type,
                "json_items": convert_and_respect_annotation_metadata(
                    object_=json_items, annotation=typing.Sequence[BatchManifestAudioSource], direction="write"
                ),
                "jsonl": jsonl,
                "metadata": convert_and_respect_annotation_metadata(
                    object_=metadata, annotation=BatchFileMetadata, direction="write"
                ),
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    BatchFileUploadResponse,
                    parse_obj_as(
                        type_=BatchFileUploadResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 401:
                raise AuthenticationError(headers=dict(_response.headers))
            if _response.status_code == 429:
                raise RateLimitError(headers=dict(_response.headers))
            _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 list_batch_files(
        self, *, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[ListBatchFilesResponse]:
        """
        List all batch file manifests you've uploaded. Use this to find a `batch_file_id` for starting a standard mode batch.

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

        Returns
        -------
        HttpResponse[ListBatchFilesResponse]
        """
        _response = self._client_wrapper.httpx_client.request(
            "v1/transcriptions/batch-files",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    ListBatchFilesResponse,
                    parse_obj_as(
                        type_=ListBatchFilesResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 401:
                raise AuthenticationError(headers=dict(_response.headers))
            if _response.status_code == 429:
                raise RateLimitError(headers=dict(_response.headers))
            _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_batch_file(
        self, batch_file_id: uuid.UUID, *, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[BatchFileDetail]:
        """
        Get details about a specific batch file manifest, including its validation status. Check this after uploading to ensure your manifest is valid before starting a batch.

        Parameters
        ----------
        batch_file_id : uuid.UUID
            The batch file ID returned from [Upload Batch File](/api-reference/batch-transcribe/upload-batch-file)

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

        Returns
        -------
        HttpResponse[BatchFileDetail]
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v1/transcriptions/batch-files/{jsonable_encoder(batch_file_id)}",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    BatchFileDetail,
                    parse_obj_as(
                        type_=BatchFileDetail,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 404:
                raise BatchNotFound(headers=dict(_response.headers))
            if _response.status_code == 401:
                raise AuthenticationError(headers=dict(_response.headers))
            if _response.status_code == 429:
                raise RateLimitError(headers=dict(_response.headers))
            _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_batch_status(
        self, batch_id: uuid.UUID, *, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[BatchStatusResponse]:
        """
        Check the progress of a batch transcription. Returns counts of completed, failed, and pending transcriptions, plus details for each individual transcription.

        Parameters
        ----------
        batch_id : uuid.UUID
            The batch ID returned from [Create Batch Transcription](/api-reference/batch-transcribe/create-batch-transcription)

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

        Returns
        -------
        HttpResponse[BatchStatusResponse]
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v1/transcriptions/batch/{jsonable_encoder(batch_id)}/status",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    BatchStatusResponse,
                    parse_obj_as(
                        type_=BatchStatusResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 404:
                raise BatchNotFound(headers=dict(_response.headers))
            if _response.status_code == 401:
                raise AuthenticationError(headers=dict(_response.headers))
            if _response.status_code == 429:
                raise RateLimitError(headers=dict(_response.headers))
            _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 AsyncRawBatchTranscribeClient:
    def __init__(self, *, client_wrapper: AsyncClientWrapper):
        self._client_wrapper = client_wrapper

    async def create_batch_transcription(
        self,
        *,
        info: TranscriptionRequestInfo,
        processing_mode: typing.Optional[ProcessingMode] = OMIT,
        batch_file_id: typing.Optional[uuid.UUID] = OMIT,
        audio_sources: typing.Optional[typing.Sequence[BatchAudioSource]] = OMIT,
        batch_title: typing.Optional[str] = OMIT,
        batch_id: typing.Optional[uuid.UUID] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[BatchTranscriptionResponse]:
        """
        Create multiple transcriptions in a single batch request.

        **Choose a processing mode:**

        - **Express mode**: Transcriptions start immediately. Max 10 files. Higher cost. Pass `audio_sources` directly in the request. Pricing for v1 is $1.20/hour.
        - **Standard mode**: Transcriptions processed within 24 hours. Max 500 files. Lower cost. First upload a manifest via [Upload Batch Manifest File](/api-reference/batch-transcribe/upload-batch-file), then pass the `batch_file_id` here. Pricing for v1 batch standard is $0.90/hour.

        All files in the batch share the same transcription settings (model, language, etc.) defined in `info`.

        Parameters
        ----------
        info : TranscriptionRequestInfo
            Transcription settings applied to all files in the batch (model, language, etc.)

        processing_mode : typing.Optional[ProcessingMode]
            Choose how the batch is processed:
            - `standard` (default): Lower cost, processed within 24 hours. Max 500 files. Use with `batch_file_id`. Pricing for v1 batch standard is $0.90/hour.
            - `express`: Higher cost, starts immediately. Max 10 files. Use with `audio_sources`. Pricing for v1 is $1.20/hour.

        batch_file_id : typing.Optional[uuid.UUID]
            **For standard mode only.** ID of a previously uploaded batch manifest.

            Get this by calling [Upload Batch Manifest File](/api-reference/batch-transcribe/upload-batch-file) first.

        audio_sources : typing.Optional[typing.Sequence[BatchAudioSource]]
            **For express mode only.** List of audio URLs to transcribe (max 10).

            Each item needs an `audio_url` and can optionally include a `title`.

        batch_title : typing.Optional[str]
            Default title prefix for transcriptions. Individual items can override this. Items without titles become "{batch_title} - Item 1", "{batch_title} - Item 2", etc.

        batch_id : typing.Optional[uuid.UUID]
            Custom UUID for this batch. Auto-generated if not provided.

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

        Returns
        -------
        AsyncHttpResponse[BatchTranscriptionResponse]
            Returns the batch ID and individual transcription IDs. Use [Get Batch Status](/api-reference/batch-transcribe/get-batch-status) to track progress.
        """
        _response = await self._client_wrapper.httpx_client.request(
            "v1/transcriptions/batch",
            method="POST",
            json={
                "processing_mode": processing_mode,
                "batch_file_id": batch_file_id,
                "audio_sources": convert_and_respect_annotation_metadata(
                    object_=audio_sources, annotation=typing.Sequence[BatchAudioSource], direction="write"
                ),
                "info": convert_and_respect_annotation_metadata(
                    object_=info, annotation=TranscriptionRequestInfo, direction="write"
                ),
                "batch_title": batch_title,
                "batch_id": batch_id,
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    BatchTranscriptionResponse,
                    parse_obj_as(
                        type_=BatchTranscriptionResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 401:
                raise AuthenticationError(headers=dict(_response.headers))
            if _response.status_code == 429:
                raise RateLimitError(headers=dict(_response.headers))
            _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 upload_batch_file(
        self,
        *,
        content_type: BatchFileContentType,
        json_items: typing.Optional[typing.Sequence[BatchManifestAudioSource]] = OMIT,
        jsonl: typing.Optional[str] = OMIT,
        metadata: typing.Optional[BatchFileMetadata] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[BatchFileUploadResponse]:
        """
        Upload a batch manifest containing audio URLs for standard mode batch processing.

        **Workflow:**
        1. Upload your manifest here to get a `batch_file_id`
        2. Use that ID in [Create Batch Transcription](/api-reference/batch-transcribe/create-batch-transcription) with `processing_mode: "standard"`

        The manifest is a list of audio sources (max 500), each with a URL and optional title. You can provide it as a JSON array or JSONL format.

        Parameters
        ----------
        content_type : BatchFileContentType
            Format of your manifest data

        json_items : typing.Optional[typing.Sequence[BatchManifestAudioSource]]
            **For JSON format.** Array of audio sources to transcribe (max 500).

        jsonl : typing.Optional[str]
            **For JSONL format.** One audio source per line as JSON, separated by newlines (max 500 lines).

            Example: `{"audio_url": "https://..."}\n{"audio_url": "https://..."}`

        metadata : typing.Optional[BatchFileMetadata]
            Optional title and description for this manifest

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

        Returns
        -------
        AsyncHttpResponse[BatchFileUploadResponse]
        """
        _response = await self._client_wrapper.httpx_client.request(
            "v1/transcriptions/batch-files",
            method="POST",
            json={
                "content_type": content_type,
                "json_items": convert_and_respect_annotation_metadata(
                    object_=json_items, annotation=typing.Sequence[BatchManifestAudioSource], direction="write"
                ),
                "jsonl": jsonl,
                "metadata": convert_and_respect_annotation_metadata(
                    object_=metadata, annotation=BatchFileMetadata, direction="write"
                ),
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    BatchFileUploadResponse,
                    parse_obj_as(
                        type_=BatchFileUploadResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 401:
                raise AuthenticationError(headers=dict(_response.headers))
            if _response.status_code == 429:
                raise RateLimitError(headers=dict(_response.headers))
            _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 list_batch_files(
        self, *, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[ListBatchFilesResponse]:
        """
        List all batch file manifests you've uploaded. Use this to find a `batch_file_id` for starting a standard mode batch.

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

        Returns
        -------
        AsyncHttpResponse[ListBatchFilesResponse]
        """
        _response = await self._client_wrapper.httpx_client.request(
            "v1/transcriptions/batch-files",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    ListBatchFilesResponse,
                    parse_obj_as(
                        type_=ListBatchFilesResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 401:
                raise AuthenticationError(headers=dict(_response.headers))
            if _response.status_code == 429:
                raise RateLimitError(headers=dict(_response.headers))
            _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_batch_file(
        self, batch_file_id: uuid.UUID, *, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[BatchFileDetail]:
        """
        Get details about a specific batch file manifest, including its validation status. Check this after uploading to ensure your manifest is valid before starting a batch.

        Parameters
        ----------
        batch_file_id : uuid.UUID
            The batch file ID returned from [Upload Batch File](/api-reference/batch-transcribe/upload-batch-file)

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

        Returns
        -------
        AsyncHttpResponse[BatchFileDetail]
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v1/transcriptions/batch-files/{jsonable_encoder(batch_file_id)}",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    BatchFileDetail,
                    parse_obj_as(
                        type_=BatchFileDetail,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 404:
                raise BatchNotFound(headers=dict(_response.headers))
            if _response.status_code == 401:
                raise AuthenticationError(headers=dict(_response.headers))
            if _response.status_code == 429:
                raise RateLimitError(headers=dict(_response.headers))
            _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_batch_status(
        self, batch_id: uuid.UUID, *, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[BatchStatusResponse]:
        """
        Check the progress of a batch transcription. Returns counts of completed, failed, and pending transcriptions, plus details for each individual transcription.

        Parameters
        ----------
        batch_id : uuid.UUID
            The batch ID returned from [Create Batch Transcription](/api-reference/batch-transcribe/create-batch-transcription)

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

        Returns
        -------
        AsyncHttpResponse[BatchStatusResponse]
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v1/transcriptions/batch/{jsonable_encoder(batch_id)}/status",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    BatchStatusResponse,
                    parse_obj_as(
                        type_=BatchStatusResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 404:
                raise BatchNotFound(headers=dict(_response.headers))
            if _response.status_code == 401:
                raise AuthenticationError(headers=dict(_response.headers))
            if _response.status_code == 429:
                raise RateLimitError(headers=dict(_response.headers))
            _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)
