# 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 .errors.authentication_error import AuthenticationError
from .errors.rate_limit_error import RateLimitError
from .errors.transcription_not_found import TranscriptionNotFound
from .types.transcription import Transcription
from .types.transcription_id import TranscriptionId
from .types.transcription_info import TranscriptionInfo
from .types.transcription_request_info import TranscriptionRequestInfo
from .types.transcription_summary import TranscriptionSummary

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


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

    def create_transcription(
        self,
        *,
        info: TranscriptionRequestInfo,
        audio_url: typing.Optional[str] = OMIT,
        audio_file: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[TranscriptionId]:
        """
        Create a new transcription

        Parameters
        ----------
        info : TranscriptionRequestInfo
            Transcription parameters

        audio_url : typing.Optional[str]
            URL to a downloadable audio file. Must be a direct link to the file (not a streaming or preview link). If the URL is not directly downloadable, consider using our Link API to extract a downloadable link from supported sites. Either audio_url or audio_file must be provided, but not both.

        audio_file : typing.Optional[str]
            Base64 encoded audio file content. Either audio_url or audio_file must be provided, but not both.

            ## Base64 Encoding Example

            **Python:**
            ```python
            import base64
            from soferai import SoferAI

            # Initialize client
            client = SoferAI(api_key="your_api_key_here")

            # Read and encode audio file
            with open("audio.mp3", "rb") as f:
                base64_audio = base64.b64encode(f.read()).decode("utf-8")

            # Create transcription request
            response = client.transcribe.create_transcription(
                audio_file=base64_audio,
                info={
                    "model": "v1",
                    "primary_language": "en",
                    "hebrew_word_format": ["he"],
                    "title": "My Shiur Transcription",
                },
            )

            print(f"Transcription ID: {response}")
            ```

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

        Returns
        -------
        HttpResponse[TranscriptionId]
            The unique identifier for the newly created transcription.
            Use this ID to check the status of the transcription or to retrieve the transcription result.
        """
        _response = self._client_wrapper.httpx_client.request(
            "v1/transcriptions/",
            method="POST",
            json={
                "audio_url": audio_url,
                "audio_file": audio_file,
                "info": convert_and_respect_annotation_metadata(
                    object_=info, annotation=TranscriptionRequestInfo, direction="write"
                ),
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    TranscriptionId,
                    parse_obj_as(
                        type_=TranscriptionId,  # 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_transcription_status(
        self, transcription_id: uuid.UUID, *, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[TranscriptionInfo]:
        """
        Get transcription status

        Parameters
        ----------
        transcription_id : uuid.UUID
            ID of the transcription. Use the ID returned from the Create Transcription endpoint.

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

        Returns
        -------
        HttpResponse[TranscriptionInfo]
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v1/transcriptions/{jsonable_encoder(transcription_id)}/status",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    TranscriptionInfo,
                    parse_obj_as(
                        type_=TranscriptionInfo,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 404:
                raise TranscriptionNotFound(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_transcription(
        self,
        transcription_id: uuid.UUID,
        *,
        filter_hebrew_word_format: typing.Optional[str] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[Transcription]:
        """
        Get transcription

        Parameters
        ----------
        transcription_id : uuid.UUID
            ID of the transcription. Use the ID returned from the Create Transcription endpoint.

        filter_hebrew_word_format : typing.Optional[str]
            Optionally filter the response to a single Hebrew word format. If set to 'en', the response text will have Hebrew characters removed and timestamps will exclude words tagged with 'he'. If set to 'he', italicized transliterations are removed from the text and timestamps will exclude words tagged only with 'en'. If set to 'hybrid', the response includes both transliteration and Hebrew characters for each word.

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

        Returns
        -------
        HttpResponse[Transcription]
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v1/transcriptions/{jsonable_encoder(transcription_id)}",
            method="GET",
            params={
                "filter_hebrew_word_format": filter_hebrew_word_format,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    Transcription,
                    parse_obj_as(
                        type_=Transcription,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 404:
                raise TranscriptionNotFound(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 list_transcriptions(
        self, *, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[typing.List[TranscriptionSummary]]:
        """
        Get all transcriptions for the authenticated user

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

        Returns
        -------
        HttpResponse[typing.List[TranscriptionSummary]]
        """
        _response = self._client_wrapper.httpx_client.request(
            "v1/transcriptions/",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    typing.List[TranscriptionSummary],
                    parse_obj_as(
                        type_=typing.List[TranscriptionSummary],  # 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)


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

    async def create_transcription(
        self,
        *,
        info: TranscriptionRequestInfo,
        audio_url: typing.Optional[str] = OMIT,
        audio_file: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[TranscriptionId]:
        """
        Create a new transcription

        Parameters
        ----------
        info : TranscriptionRequestInfo
            Transcription parameters

        audio_url : typing.Optional[str]
            URL to a downloadable audio file. Must be a direct link to the file (not a streaming or preview link). If the URL is not directly downloadable, consider using our Link API to extract a downloadable link from supported sites. Either audio_url or audio_file must be provided, but not both.

        audio_file : typing.Optional[str]
            Base64 encoded audio file content. Either audio_url or audio_file must be provided, but not both.

            ## Base64 Encoding Example

            **Python:**
            ```python
            import base64
            from soferai import SoferAI

            # Initialize client
            client = SoferAI(api_key="your_api_key_here")

            # Read and encode audio file
            with open("audio.mp3", "rb") as f:
                base64_audio = base64.b64encode(f.read()).decode("utf-8")

            # Create transcription request
            response = client.transcribe.create_transcription(
                audio_file=base64_audio,
                info={
                    "model": "v1",
                    "primary_language": "en",
                    "hebrew_word_format": ["he"],
                    "title": "My Shiur Transcription",
                },
            )

            print(f"Transcription ID: {response}")
            ```

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

        Returns
        -------
        AsyncHttpResponse[TranscriptionId]
            The unique identifier for the newly created transcription.
            Use this ID to check the status of the transcription or to retrieve the transcription result.
        """
        _response = await self._client_wrapper.httpx_client.request(
            "v1/transcriptions/",
            method="POST",
            json={
                "audio_url": audio_url,
                "audio_file": audio_file,
                "info": convert_and_respect_annotation_metadata(
                    object_=info, annotation=TranscriptionRequestInfo, direction="write"
                ),
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    TranscriptionId,
                    parse_obj_as(
                        type_=TranscriptionId,  # 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_transcription_status(
        self, transcription_id: uuid.UUID, *, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[TranscriptionInfo]:
        """
        Get transcription status

        Parameters
        ----------
        transcription_id : uuid.UUID
            ID of the transcription. Use the ID returned from the Create Transcription endpoint.

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

        Returns
        -------
        AsyncHttpResponse[TranscriptionInfo]
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v1/transcriptions/{jsonable_encoder(transcription_id)}/status",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    TranscriptionInfo,
                    parse_obj_as(
                        type_=TranscriptionInfo,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 404:
                raise TranscriptionNotFound(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_transcription(
        self,
        transcription_id: uuid.UUID,
        *,
        filter_hebrew_word_format: typing.Optional[str] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[Transcription]:
        """
        Get transcription

        Parameters
        ----------
        transcription_id : uuid.UUID
            ID of the transcription. Use the ID returned from the Create Transcription endpoint.

        filter_hebrew_word_format : typing.Optional[str]
            Optionally filter the response to a single Hebrew word format. If set to 'en', the response text will have Hebrew characters removed and timestamps will exclude words tagged with 'he'. If set to 'he', italicized transliterations are removed from the text and timestamps will exclude words tagged only with 'en'. If set to 'hybrid', the response includes both transliteration and Hebrew characters for each word.

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

        Returns
        -------
        AsyncHttpResponse[Transcription]
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v1/transcriptions/{jsonable_encoder(transcription_id)}",
            method="GET",
            params={
                "filter_hebrew_word_format": filter_hebrew_word_format,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    Transcription,
                    parse_obj_as(
                        type_=Transcription,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 404:
                raise TranscriptionNotFound(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 list_transcriptions(
        self, *, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[typing.List[TranscriptionSummary]]:
        """
        Get all transcriptions for the authenticated user

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

        Returns
        -------
        AsyncHttpResponse[typing.List[TranscriptionSummary]]
        """
        _response = await self._client_wrapper.httpx_client.request(
            "v1/transcriptions/",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    typing.List[TranscriptionSummary],
                    parse_obj_as(
                        type_=typing.List[TranscriptionSummary],  # 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)
