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

import typing
from ..core.client_wrapper import SyncClientWrapper
from .pvc.client import PvcClient
from ..core.request_options import RequestOptions
from ..types.get_voices_response import GetVoicesResponse
from ..core.unchecked_base_model import construct_type
from ..errors.unprocessable_entity_error import UnprocessableEntityError
from ..types.http_validation_error import HttpValidationError
from json.decoder import JSONDecodeError
from ..core.api_error import ApiError
from ..types.get_voices_v_2_response import GetVoicesV2Response
from ..types.voice_settings import VoiceSettings
from ..core.jsonable_encoder import jsonable_encoder
from ..types.voice import Voice
from ..types.delete_voice_response_model import DeleteVoiceResponseModel
from ..types.edit_voice_settings_response_model import EditVoiceSettingsResponseModel
from ..core.serialization import convert_and_respect_annotation_metadata
from .. import core
from ..types.add_voice_ivc_response_model import AddVoiceIvcResponseModel
from ..types.edit_voice_response_model import EditVoiceResponseModel
from ..types.add_voice_response_model import AddVoiceResponseModel
from .types.voices_get_shared_request_category import VoicesGetSharedRequestCategory
from ..types.get_library_voices_response import GetLibraryVoicesResponse
from ..core.client_wrapper import AsyncClientWrapper
from .pvc.client import AsyncPvcClient

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


class VoicesClient:
    def __init__(self, *, client_wrapper: SyncClientWrapper):
        self._client_wrapper = client_wrapper
        self.pvc = PvcClient(client_wrapper=self._client_wrapper)

    def get_all(
        self,
        *,
        show_legacy: typing.Optional[bool] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> GetVoicesResponse:
        """
        Returns a list of all available voices for a user.

        Parameters
        ----------
        show_legacy : typing.Optional[bool]
            If set to true, legacy premade voices will be included in responses from /v1/voices

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

        Returns
        -------
        GetVoicesResponse
            Successful Response

        Examples
        --------
        from elevenlabs import ElevenLabs

        client = ElevenLabs(
            api_key="YOUR_API_KEY",
        )
        client.voices.get_all()
        """
        _response = self._client_wrapper.httpx_client.request(
            "v1/voices",
            base_url=self._client_wrapper.get_environment().base,
            method="GET",
            params={
                "show_legacy": show_legacy,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    GetVoicesResponse,
                    construct_type(
                        type_=GetVoicesResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        construct_type(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def search(
        self,
        *,
        next_page_token: typing.Optional[str] = None,
        page_size: typing.Optional[int] = None,
        search: typing.Optional[str] = None,
        sort: typing.Optional[str] = None,
        sort_direction: typing.Optional[str] = None,
        voice_type: typing.Optional[str] = None,
        category: typing.Optional[str] = None,
        fine_tuning_state: typing.Optional[str] = None,
        collection_id: typing.Optional[str] = None,
        include_total_count: typing.Optional[bool] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> GetVoicesV2Response:
        """
        Gets a list of all available voices for a user with search, filtering and pagination.

        Parameters
        ----------
        next_page_token : typing.Optional[str]
            The next page token to use for pagination. Returned from the previous request.

        page_size : typing.Optional[int]
            How many voices to return at maximum. Can not exceed 100, defaults to 10. Page 0 may include more voices due to default voices being included.

        search : typing.Optional[str]
            Search term to filter voices by. Searches in name, description, labels, category.

        sort : typing.Optional[str]
            Which field to sort by, one of 'created_at_unix' or 'name'. 'created_at_unix' may not be available for older voices.

        sort_direction : typing.Optional[str]
            Which direction to sort the voices in. 'asc' or 'desc'.

        voice_type : typing.Optional[str]
            Type of the voice to filter by. One of 'personal', 'community', 'default', 'workspace', 'non-default'. 'non-default' is equal to 'personal' plus 'community'.

        category : typing.Optional[str]
            Category of the voice to filter by. One of 'premade', 'cloned', 'generated', 'professional'

        fine_tuning_state : typing.Optional[str]
            State of the voice's fine tuning to filter by. Applicable only to professional voices clones. One of 'draft', 'not_verified', 'not_started', 'queued', 'fine_tuning', 'fine_tuned', 'failed', 'delayed'

        collection_id : typing.Optional[str]
            Collection ID to filter voices by.

        include_total_count : typing.Optional[bool]
            Whether to include the total count of voices found in the response. Incurs a performance cost.

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

        Returns
        -------
        GetVoicesV2Response
            Successful Response

        Examples
        --------
        from elevenlabs import ElevenLabs

        client = ElevenLabs(
            api_key="YOUR_API_KEY",
        )
        client.voices.search(
            include_total_count=True,
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            "v2/voices",
            base_url=self._client_wrapper.get_environment().base,
            method="GET",
            params={
                "next_page_token": next_page_token,
                "page_size": page_size,
                "search": search,
                "sort": sort,
                "sort_direction": sort_direction,
                "voice_type": voice_type,
                "category": category,
                "fine_tuning_state": fine_tuning_state,
                "collection_id": collection_id,
                "include_total_count": include_total_count,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    GetVoicesV2Response,
                    construct_type(
                        type_=GetVoicesV2Response,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        construct_type(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def get_default_settings(self, *, request_options: typing.Optional[RequestOptions] = None) -> VoiceSettings:
        """
        Gets the default settings for voices. "similarity_boost" corresponds to"Clarity + Similarity Enhancement" in the web app and "stability" corresponds to "Stability" slider in the web app.

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

        Returns
        -------
        VoiceSettings
            Successful Response

        Examples
        --------
        from elevenlabs import ElevenLabs

        client = ElevenLabs(
            api_key="YOUR_API_KEY",
        )
        client.voices.get_default_settings()
        """
        _response = self._client_wrapper.httpx_client.request(
            "v1/voices/settings/default",
            base_url=self._client_wrapper.get_environment().base,
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    VoiceSettings,
                    construct_type(
                        type_=VoiceSettings,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def get_settings(self, voice_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> VoiceSettings:
        """
        Returns the settings for a specific voice. "similarity_boost" corresponds to"Clarity + Similarity Enhancement" in the web app and "stability" corresponds to "Stability" slider in the web app.

        Parameters
        ----------
        voice_id : str
            Voice ID to be used, you can use https://api.elevenlabs.io/v1/voices to list all the available voices.

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

        Returns
        -------
        VoiceSettings
            Successful Response

        Examples
        --------
        from elevenlabs import ElevenLabs

        client = ElevenLabs(
            api_key="YOUR_API_KEY",
        )
        client.voices.get_settings(
            voice_id="21m00Tcm4TlvDq8ikWAM",
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v1/voices/{jsonable_encoder(voice_id)}/settings",
            base_url=self._client_wrapper.get_environment().base,
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    VoiceSettings,
                    construct_type(
                        type_=VoiceSettings,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        construct_type(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def get(
        self,
        voice_id: str,
        *,
        with_settings: typing.Optional[bool] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> Voice:
        """
        Returns metadata about a specific voice.

        Parameters
        ----------
        voice_id : str
            ID of the voice to be used. You can use the [Get voices](/docs/api-reference/voices/search) endpoint list all the available voices.

        with_settings : typing.Optional[bool]
            This parameter is now deprecated. It is ignored and will be removed in a future version.

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

        Returns
        -------
        Voice
            Successful Response

        Examples
        --------
        from elevenlabs import ElevenLabs

        client = ElevenLabs(
            api_key="YOUR_API_KEY",
        )
        client.voices.get(
            voice_id="21m00Tcm4TlvDq8ikWAM",
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v1/voices/{jsonable_encoder(voice_id)}",
            base_url=self._client_wrapper.get_environment().base,
            method="GET",
            params={
                "with_settings": with_settings,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    Voice,
                    construct_type(
                        type_=Voice,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        construct_type(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def delete(
        self, voice_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> DeleteVoiceResponseModel:
        """
        Deletes a voice by its ID.

        Parameters
        ----------
        voice_id : str
            ID of the voice to be used. You can use the [Get voices](/docs/api-reference/voices/search) endpoint list all the available voices.

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

        Returns
        -------
        DeleteVoiceResponseModel
            Successful Response

        Examples
        --------
        from elevenlabs import ElevenLabs

        client = ElevenLabs(
            api_key="YOUR_API_KEY",
        )
        client.voices.delete(
            voice_id="21m00Tcm4TlvDq8ikWAM",
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v1/voices/{jsonable_encoder(voice_id)}",
            base_url=self._client_wrapper.get_environment().base,
            method="DELETE",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    DeleteVoiceResponseModel,
                    construct_type(
                        type_=DeleteVoiceResponseModel,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        construct_type(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def edit_settings(
        self,
        voice_id: str,
        *,
        request: VoiceSettings,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> EditVoiceSettingsResponseModel:
        """
        Edit your settings for a specific voice. "similarity_boost" corresponds to "Clarity + Similarity Enhancement" in the web app and "stability" corresponds to "Stability" slider in the web app.

        Parameters
        ----------
        voice_id : str
            ID of the voice to be used. You can use the [Get voices](/docs/api-reference/voices/search) endpoint list all the available voices.

        request : VoiceSettings

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

        Returns
        -------
        EditVoiceSettingsResponseModel
            Successful Response

        Examples
        --------
        from elevenlabs import ElevenLabs, VoiceSettings

        client = ElevenLabs(
            api_key="YOUR_API_KEY",
        )
        client.voices.edit_settings(
            voice_id="21m00Tcm4TlvDq8ikWAM",
            request=VoiceSettings(
                stability=1.0,
                similarity_boost=1.0,
                style=0.0,
                use_speaker_boost=True,
                speed=1.0,
            ),
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v1/voices/{jsonable_encoder(voice_id)}/settings/edit",
            base_url=self._client_wrapper.get_environment().base,
            method="POST",
            json=convert_and_respect_annotation_metadata(object_=request, annotation=VoiceSettings, direction="write"),
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    EditVoiceSettingsResponseModel,
                    construct_type(
                        type_=EditVoiceSettingsResponseModel,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        construct_type(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def add(
        self,
        *,
        name: str,
        files: typing.List[core.File],
        remove_background_noise: typing.Optional[bool] = OMIT,
        description: typing.Optional[str] = OMIT,
        labels: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AddVoiceIvcResponseModel:
        """
        Create a voice clone and add it to your Voices

        Parameters
        ----------
        name : str
            The name that identifies this voice. This will be displayed in the dropdown of the website.

        files : typing.List[core.File]
            See core.File for more documentation

        remove_background_noise : typing.Optional[bool]
            If set will remove background noise for voice samples using our audio isolation model. If the samples do not include background noise, it can make the quality worse.

        description : typing.Optional[str]
            A description of the voice.

        labels : typing.Optional[str]
            Serialized labels dictionary for the voice.

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

        Returns
        -------
        AddVoiceIvcResponseModel
            Successful Response

        Examples
        --------
        from elevenlabs import ElevenLabs

        client = ElevenLabs(
            api_key="YOUR_API_KEY",
        )
        client.voices.add(
            name="name",
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            "v1/voices/add",
            base_url=self._client_wrapper.get_environment().base,
            method="POST",
            data={
                "name": name,
                "remove_background_noise": remove_background_noise,
                "description": description,
                "labels": labels,
            },
            files={
                "files": files,
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    AddVoiceIvcResponseModel,
                    construct_type(
                        type_=AddVoiceIvcResponseModel,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        construct_type(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def edit(
        self,
        voice_id: str,
        *,
        name: str,
        files: typing.Optional[typing.List[core.File]] = OMIT,
        remove_background_noise: typing.Optional[bool] = OMIT,
        description: typing.Optional[str] = OMIT,
        labels: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> EditVoiceResponseModel:
        """
        Edit a voice created by you.

        Parameters
        ----------
        voice_id : str
            ID of the voice to be used. You can use the [Get voices](/docs/api-reference/voices/search) endpoint list all the available voices.

        name : str
            The name that identifies this voice. This will be displayed in the dropdown of the website.

        files : typing.Optional[typing.List[core.File]]
            See core.File for more documentation

        remove_background_noise : typing.Optional[bool]
            If set will remove background noise for voice samples using our audio isolation model. If the samples do not include background noise, it can make the quality worse.

        description : typing.Optional[str]
            A description of the voice.

        labels : typing.Optional[str]
            Serialized labels dictionary for the voice.

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

        Returns
        -------
        EditVoiceResponseModel
            Successful Response

        Examples
        --------
        from elevenlabs import ElevenLabs

        client = ElevenLabs(
            api_key="YOUR_API_KEY",
        )
        client.voices.edit(
            voice_id="21m00Tcm4TlvDq8ikWAM",
            name="name",
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v1/voices/{jsonable_encoder(voice_id)}/edit",
            base_url=self._client_wrapper.get_environment().base,
            method="POST",
            data={
                "name": name,
                "remove_background_noise": remove_background_noise,
                "description": description,
                "labels": labels,
            },
            files={
                "files": files,
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    EditVoiceResponseModel,
                    construct_type(
                        type_=EditVoiceResponseModel,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        construct_type(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def add_sharing_voice(
        self,
        public_user_id: str,
        voice_id: str,
        *,
        new_name: str,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AddVoiceResponseModel:
        """
        Add a shared voice to your collection of Voices

        Parameters
        ----------
        public_user_id : str
            Public user ID used to publicly identify ElevenLabs users.

        voice_id : str
            ID of the voice to be used. You can use the [Get voices](/docs/api-reference/voices/search) endpoint list all the available voices.

        new_name : str
            The name that identifies this voice. This will be displayed in the dropdown of the website.

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

        Returns
        -------
        AddVoiceResponseModel
            Successful Response

        Examples
        --------
        from elevenlabs import ElevenLabs

        client = ElevenLabs(
            api_key="YOUR_API_KEY",
        )
        client.voices.add_sharing_voice(
            public_user_id="63e06b7e7cafdc46be4d2e0b3f045940231ae058d508589653d74d1265a574ca",
            voice_id="21m00Tcm4TlvDq8ikWAM",
            new_name="John Smith",
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v1/voices/add/{jsonable_encoder(public_user_id)}/{jsonable_encoder(voice_id)}",
            base_url=self._client_wrapper.get_environment().base,
            method="POST",
            json={
                "new_name": new_name,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    AddVoiceResponseModel,
                    construct_type(
                        type_=AddVoiceResponseModel,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        construct_type(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def get_shared(
        self,
        *,
        page_size: typing.Optional[int] = None,
        category: typing.Optional[VoicesGetSharedRequestCategory] = None,
        gender: typing.Optional[str] = None,
        age: typing.Optional[str] = None,
        accent: typing.Optional[str] = None,
        language: typing.Optional[str] = None,
        locale: typing.Optional[str] = None,
        search: typing.Optional[str] = None,
        use_cases: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
        descriptives: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
        featured: typing.Optional[bool] = None,
        min_notice_period_days: typing.Optional[int] = None,
        include_custom_rates: typing.Optional[bool] = None,
        reader_app_enabled: typing.Optional[bool] = None,
        owner_id: typing.Optional[str] = None,
        sort: typing.Optional[str] = None,
        page: typing.Optional[int] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> GetLibraryVoicesResponse:
        """
        Retrieves a list of shared voices.

        Parameters
        ----------
        page_size : typing.Optional[int]
            How many shared voices to return at maximum. Can not exceed 100, defaults to 30.

        category : typing.Optional[VoicesGetSharedRequestCategory]
            Voice category used for filtering

        gender : typing.Optional[str]
            Gender used for filtering

        age : typing.Optional[str]
            Age used for filtering

        accent : typing.Optional[str]
            Accent used for filtering

        language : typing.Optional[str]
            Language used for filtering

        locale : typing.Optional[str]
            Locale used for filtering

        search : typing.Optional[str]
            Search term used for filtering

        use_cases : typing.Optional[typing.Union[str, typing.Sequence[str]]]
            Use-case used for filtering

        descriptives : typing.Optional[typing.Union[str, typing.Sequence[str]]]
            Search term used for filtering

        featured : typing.Optional[bool]
            Filter featured voices

        min_notice_period_days : typing.Optional[int]
            Filter voices with a minimum notice period of the given number of days.

        include_custom_rates : typing.Optional[bool]
            Include/exclude voices with custom rates

        reader_app_enabled : typing.Optional[bool]
            Filter voices that are enabled for the reader app

        owner_id : typing.Optional[str]
            Filter voices by public owner ID

        sort : typing.Optional[str]
            Sort criteria

        page : typing.Optional[int]

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

        Returns
        -------
        GetLibraryVoicesResponse
            Successful Response

        Examples
        --------
        from elevenlabs import ElevenLabs

        client = ElevenLabs(
            api_key="YOUR_API_KEY",
        )
        client.voices.get_shared(
            featured=True,
            reader_app_enabled=True,
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            "v1/shared-voices",
            base_url=self._client_wrapper.get_environment().base,
            method="GET",
            params={
                "page_size": page_size,
                "category": category,
                "gender": gender,
                "age": age,
                "accent": accent,
                "language": language,
                "locale": locale,
                "search": search,
                "use_cases": use_cases,
                "descriptives": descriptives,
                "featured": featured,
                "min_notice_period_days": min_notice_period_days,
                "include_custom_rates": include_custom_rates,
                "reader_app_enabled": reader_app_enabled,
                "owner_id": owner_id,
                "sort": sort,
                "page": page,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    GetLibraryVoicesResponse,
                    construct_type(
                        type_=GetLibraryVoicesResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        construct_type(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def get_similar_library_voices(
        self,
        *,
        audio_file: typing.Optional[core.File] = OMIT,
        similarity_threshold: typing.Optional[float] = OMIT,
        top_k: typing.Optional[int] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> GetLibraryVoicesResponse:
        """
        Returns a list of shared voices similar to the provided audio sample. If neither similarity_threshold nor top_k is provided, we will apply default values.

        Parameters
        ----------
        audio_file : typing.Optional[core.File]
            See core.File for more documentation

        similarity_threshold : typing.Optional[float]
            Threshold for voice similarity between provided sample and library voices. Values range from 0 to 2. The smaller the value the more similar voices will be returned.

        top_k : typing.Optional[int]
            Number of most similar voices to return. If similarity_threshold is provided, less than this number of voices may be returned. Values range from 1 to 100.

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

        Returns
        -------
        GetLibraryVoicesResponse
            Successful Response

        Examples
        --------
        from elevenlabs import ElevenLabs

        client = ElevenLabs(
            api_key="YOUR_API_KEY",
        )
        client.voices.get_similar_library_voices()
        """
        _response = self._client_wrapper.httpx_client.request(
            "v1/similar-voices",
            base_url=self._client_wrapper.get_environment().base,
            method="POST",
            data={
                "similarity_threshold": similarity_threshold,
                "top_k": top_k,
            },
            files={
                "audio_file": audio_file,
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    GetLibraryVoicesResponse,
                    construct_type(
                        type_=GetLibraryVoicesResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        construct_type(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)


class AsyncVoicesClient:
    def __init__(self, *, client_wrapper: AsyncClientWrapper):
        self._client_wrapper = client_wrapper
        self.pvc = AsyncPvcClient(client_wrapper=self._client_wrapper)

    async def get_all(
        self,
        *,
        show_legacy: typing.Optional[bool] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> GetVoicesResponse:
        """
        Returns a list of all available voices for a user.

        Parameters
        ----------
        show_legacy : typing.Optional[bool]
            If set to true, legacy premade voices will be included in responses from /v1/voices

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

        Returns
        -------
        GetVoicesResponse
            Successful Response

        Examples
        --------
        import asyncio

        from elevenlabs import AsyncElevenLabs

        client = AsyncElevenLabs(
            api_key="YOUR_API_KEY",
        )


        async def main() -> None:
            await client.voices.get_all()


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            "v1/voices",
            base_url=self._client_wrapper.get_environment().base,
            method="GET",
            params={
                "show_legacy": show_legacy,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    GetVoicesResponse,
                    construct_type(
                        type_=GetVoicesResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        construct_type(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def search(
        self,
        *,
        next_page_token: typing.Optional[str] = None,
        page_size: typing.Optional[int] = None,
        search: typing.Optional[str] = None,
        sort: typing.Optional[str] = None,
        sort_direction: typing.Optional[str] = None,
        voice_type: typing.Optional[str] = None,
        category: typing.Optional[str] = None,
        fine_tuning_state: typing.Optional[str] = None,
        collection_id: typing.Optional[str] = None,
        include_total_count: typing.Optional[bool] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> GetVoicesV2Response:
        """
        Gets a list of all available voices for a user with search, filtering and pagination.

        Parameters
        ----------
        next_page_token : typing.Optional[str]
            The next page token to use for pagination. Returned from the previous request.

        page_size : typing.Optional[int]
            How many voices to return at maximum. Can not exceed 100, defaults to 10. Page 0 may include more voices due to default voices being included.

        search : typing.Optional[str]
            Search term to filter voices by. Searches in name, description, labels, category.

        sort : typing.Optional[str]
            Which field to sort by, one of 'created_at_unix' or 'name'. 'created_at_unix' may not be available for older voices.

        sort_direction : typing.Optional[str]
            Which direction to sort the voices in. 'asc' or 'desc'.

        voice_type : typing.Optional[str]
            Type of the voice to filter by. One of 'personal', 'community', 'default', 'workspace', 'non-default'. 'non-default' is equal to 'personal' plus 'community'.

        category : typing.Optional[str]
            Category of the voice to filter by. One of 'premade', 'cloned', 'generated', 'professional'

        fine_tuning_state : typing.Optional[str]
            State of the voice's fine tuning to filter by. Applicable only to professional voices clones. One of 'draft', 'not_verified', 'not_started', 'queued', 'fine_tuning', 'fine_tuned', 'failed', 'delayed'

        collection_id : typing.Optional[str]
            Collection ID to filter voices by.

        include_total_count : typing.Optional[bool]
            Whether to include the total count of voices found in the response. Incurs a performance cost.

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

        Returns
        -------
        GetVoicesV2Response
            Successful Response

        Examples
        --------
        import asyncio

        from elevenlabs import AsyncElevenLabs

        client = AsyncElevenLabs(
            api_key="YOUR_API_KEY",
        )


        async def main() -> None:
            await client.voices.search(
                include_total_count=True,
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            "v2/voices",
            base_url=self._client_wrapper.get_environment().base,
            method="GET",
            params={
                "next_page_token": next_page_token,
                "page_size": page_size,
                "search": search,
                "sort": sort,
                "sort_direction": sort_direction,
                "voice_type": voice_type,
                "category": category,
                "fine_tuning_state": fine_tuning_state,
                "collection_id": collection_id,
                "include_total_count": include_total_count,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    GetVoicesV2Response,
                    construct_type(
                        type_=GetVoicesV2Response,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        construct_type(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def get_default_settings(self, *, request_options: typing.Optional[RequestOptions] = None) -> VoiceSettings:
        """
        Gets the default settings for voices. "similarity_boost" corresponds to"Clarity + Similarity Enhancement" in the web app and "stability" corresponds to "Stability" slider in the web app.

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

        Returns
        -------
        VoiceSettings
            Successful Response

        Examples
        --------
        import asyncio

        from elevenlabs import AsyncElevenLabs

        client = AsyncElevenLabs(
            api_key="YOUR_API_KEY",
        )


        async def main() -> None:
            await client.voices.get_default_settings()


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            "v1/voices/settings/default",
            base_url=self._client_wrapper.get_environment().base,
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    VoiceSettings,
                    construct_type(
                        type_=VoiceSettings,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def get_settings(
        self, voice_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> VoiceSettings:
        """
        Returns the settings for a specific voice. "similarity_boost" corresponds to"Clarity + Similarity Enhancement" in the web app and "stability" corresponds to "Stability" slider in the web app.

        Parameters
        ----------
        voice_id : str
            Voice ID to be used, you can use https://api.elevenlabs.io/v1/voices to list all the available voices.

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

        Returns
        -------
        VoiceSettings
            Successful Response

        Examples
        --------
        import asyncio

        from elevenlabs import AsyncElevenLabs

        client = AsyncElevenLabs(
            api_key="YOUR_API_KEY",
        )


        async def main() -> None:
            await client.voices.get_settings(
                voice_id="21m00Tcm4TlvDq8ikWAM",
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v1/voices/{jsonable_encoder(voice_id)}/settings",
            base_url=self._client_wrapper.get_environment().base,
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    VoiceSettings,
                    construct_type(
                        type_=VoiceSettings,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        construct_type(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def get(
        self,
        voice_id: str,
        *,
        with_settings: typing.Optional[bool] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> Voice:
        """
        Returns metadata about a specific voice.

        Parameters
        ----------
        voice_id : str
            ID of the voice to be used. You can use the [Get voices](/docs/api-reference/voices/search) endpoint list all the available voices.

        with_settings : typing.Optional[bool]
            This parameter is now deprecated. It is ignored and will be removed in a future version.

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

        Returns
        -------
        Voice
            Successful Response

        Examples
        --------
        import asyncio

        from elevenlabs import AsyncElevenLabs

        client = AsyncElevenLabs(
            api_key="YOUR_API_KEY",
        )


        async def main() -> None:
            await client.voices.get(
                voice_id="21m00Tcm4TlvDq8ikWAM",
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v1/voices/{jsonable_encoder(voice_id)}",
            base_url=self._client_wrapper.get_environment().base,
            method="GET",
            params={
                "with_settings": with_settings,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    Voice,
                    construct_type(
                        type_=Voice,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        construct_type(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def delete(
        self, voice_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> DeleteVoiceResponseModel:
        """
        Deletes a voice by its ID.

        Parameters
        ----------
        voice_id : str
            ID of the voice to be used. You can use the [Get voices](/docs/api-reference/voices/search) endpoint list all the available voices.

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

        Returns
        -------
        DeleteVoiceResponseModel
            Successful Response

        Examples
        --------
        import asyncio

        from elevenlabs import AsyncElevenLabs

        client = AsyncElevenLabs(
            api_key="YOUR_API_KEY",
        )


        async def main() -> None:
            await client.voices.delete(
                voice_id="21m00Tcm4TlvDq8ikWAM",
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v1/voices/{jsonable_encoder(voice_id)}",
            base_url=self._client_wrapper.get_environment().base,
            method="DELETE",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    DeleteVoiceResponseModel,
                    construct_type(
                        type_=DeleteVoiceResponseModel,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        construct_type(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def edit_settings(
        self,
        voice_id: str,
        *,
        request: VoiceSettings,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> EditVoiceSettingsResponseModel:
        """
        Edit your settings for a specific voice. "similarity_boost" corresponds to "Clarity + Similarity Enhancement" in the web app and "stability" corresponds to "Stability" slider in the web app.

        Parameters
        ----------
        voice_id : str
            ID of the voice to be used. You can use the [Get voices](/docs/api-reference/voices/search) endpoint list all the available voices.

        request : VoiceSettings

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

        Returns
        -------
        EditVoiceSettingsResponseModel
            Successful Response

        Examples
        --------
        import asyncio

        from elevenlabs import AsyncElevenLabs, VoiceSettings

        client = AsyncElevenLabs(
            api_key="YOUR_API_KEY",
        )


        async def main() -> None:
            await client.voices.edit_settings(
                voice_id="21m00Tcm4TlvDq8ikWAM",
                request=VoiceSettings(
                    stability=1.0,
                    similarity_boost=1.0,
                    style=0.0,
                    use_speaker_boost=True,
                    speed=1.0,
                ),
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v1/voices/{jsonable_encoder(voice_id)}/settings/edit",
            base_url=self._client_wrapper.get_environment().base,
            method="POST",
            json=convert_and_respect_annotation_metadata(object_=request, annotation=VoiceSettings, direction="write"),
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    EditVoiceSettingsResponseModel,
                    construct_type(
                        type_=EditVoiceSettingsResponseModel,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        construct_type(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def add(
        self,
        *,
        name: str,
        files: typing.List[core.File],
        remove_background_noise: typing.Optional[bool] = OMIT,
        description: typing.Optional[str] = OMIT,
        labels: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AddVoiceIvcResponseModel:
        """
        Create a voice clone and add it to your Voices

        Parameters
        ----------
        name : str
            The name that identifies this voice. This will be displayed in the dropdown of the website.

        files : typing.List[core.File]
            See core.File for more documentation

        remove_background_noise : typing.Optional[bool]
            If set will remove background noise for voice samples using our audio isolation model. If the samples do not include background noise, it can make the quality worse.

        description : typing.Optional[str]
            A description of the voice.

        labels : typing.Optional[str]
            Serialized labels dictionary for the voice.

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

        Returns
        -------
        AddVoiceIvcResponseModel
            Successful Response

        Examples
        --------
        import asyncio

        from elevenlabs import AsyncElevenLabs

        client = AsyncElevenLabs(
            api_key="YOUR_API_KEY",
        )


        async def main() -> None:
            await client.voices.add(
                name="name",
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            "v1/voices/add",
            base_url=self._client_wrapper.get_environment().base,
            method="POST",
            data={
                "name": name,
                "remove_background_noise": remove_background_noise,
                "description": description,
                "labels": labels,
            },
            files={
                "files": files,
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    AddVoiceIvcResponseModel,
                    construct_type(
                        type_=AddVoiceIvcResponseModel,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        construct_type(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def edit(
        self,
        voice_id: str,
        *,
        name: str,
        files: typing.Optional[typing.List[core.File]] = OMIT,
        remove_background_noise: typing.Optional[bool] = OMIT,
        description: typing.Optional[str] = OMIT,
        labels: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> EditVoiceResponseModel:
        """
        Edit a voice created by you.

        Parameters
        ----------
        voice_id : str
            ID of the voice to be used. You can use the [Get voices](/docs/api-reference/voices/search) endpoint list all the available voices.

        name : str
            The name that identifies this voice. This will be displayed in the dropdown of the website.

        files : typing.Optional[typing.List[core.File]]
            See core.File for more documentation

        remove_background_noise : typing.Optional[bool]
            If set will remove background noise for voice samples using our audio isolation model. If the samples do not include background noise, it can make the quality worse.

        description : typing.Optional[str]
            A description of the voice.

        labels : typing.Optional[str]
            Serialized labels dictionary for the voice.

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

        Returns
        -------
        EditVoiceResponseModel
            Successful Response

        Examples
        --------
        import asyncio

        from elevenlabs import AsyncElevenLabs

        client = AsyncElevenLabs(
            api_key="YOUR_API_KEY",
        )


        async def main() -> None:
            await client.voices.edit(
                voice_id="21m00Tcm4TlvDq8ikWAM",
                name="name",
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v1/voices/{jsonable_encoder(voice_id)}/edit",
            base_url=self._client_wrapper.get_environment().base,
            method="POST",
            data={
                "name": name,
                "remove_background_noise": remove_background_noise,
                "description": description,
                "labels": labels,
            },
            files={
                "files": files,
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    EditVoiceResponseModel,
                    construct_type(
                        type_=EditVoiceResponseModel,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        construct_type(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def add_sharing_voice(
        self,
        public_user_id: str,
        voice_id: str,
        *,
        new_name: str,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AddVoiceResponseModel:
        """
        Add a shared voice to your collection of Voices

        Parameters
        ----------
        public_user_id : str
            Public user ID used to publicly identify ElevenLabs users.

        voice_id : str
            ID of the voice to be used. You can use the [Get voices](/docs/api-reference/voices/search) endpoint list all the available voices.

        new_name : str
            The name that identifies this voice. This will be displayed in the dropdown of the website.

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

        Returns
        -------
        AddVoiceResponseModel
            Successful Response

        Examples
        --------
        import asyncio

        from elevenlabs import AsyncElevenLabs

        client = AsyncElevenLabs(
            api_key="YOUR_API_KEY",
        )


        async def main() -> None:
            await client.voices.add_sharing_voice(
                public_user_id="63e06b7e7cafdc46be4d2e0b3f045940231ae058d508589653d74d1265a574ca",
                voice_id="21m00Tcm4TlvDq8ikWAM",
                new_name="John Smith",
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v1/voices/add/{jsonable_encoder(public_user_id)}/{jsonable_encoder(voice_id)}",
            base_url=self._client_wrapper.get_environment().base,
            method="POST",
            json={
                "new_name": new_name,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    AddVoiceResponseModel,
                    construct_type(
                        type_=AddVoiceResponseModel,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        construct_type(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def get_shared(
        self,
        *,
        page_size: typing.Optional[int] = None,
        category: typing.Optional[VoicesGetSharedRequestCategory] = None,
        gender: typing.Optional[str] = None,
        age: typing.Optional[str] = None,
        accent: typing.Optional[str] = None,
        language: typing.Optional[str] = None,
        locale: typing.Optional[str] = None,
        search: typing.Optional[str] = None,
        use_cases: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
        descriptives: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
        featured: typing.Optional[bool] = None,
        min_notice_period_days: typing.Optional[int] = None,
        include_custom_rates: typing.Optional[bool] = None,
        reader_app_enabled: typing.Optional[bool] = None,
        owner_id: typing.Optional[str] = None,
        sort: typing.Optional[str] = None,
        page: typing.Optional[int] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> GetLibraryVoicesResponse:
        """
        Retrieves a list of shared voices.

        Parameters
        ----------
        page_size : typing.Optional[int]
            How many shared voices to return at maximum. Can not exceed 100, defaults to 30.

        category : typing.Optional[VoicesGetSharedRequestCategory]
            Voice category used for filtering

        gender : typing.Optional[str]
            Gender used for filtering

        age : typing.Optional[str]
            Age used for filtering

        accent : typing.Optional[str]
            Accent used for filtering

        language : typing.Optional[str]
            Language used for filtering

        locale : typing.Optional[str]
            Locale used for filtering

        search : typing.Optional[str]
            Search term used for filtering

        use_cases : typing.Optional[typing.Union[str, typing.Sequence[str]]]
            Use-case used for filtering

        descriptives : typing.Optional[typing.Union[str, typing.Sequence[str]]]
            Search term used for filtering

        featured : typing.Optional[bool]
            Filter featured voices

        min_notice_period_days : typing.Optional[int]
            Filter voices with a minimum notice period of the given number of days.

        include_custom_rates : typing.Optional[bool]
            Include/exclude voices with custom rates

        reader_app_enabled : typing.Optional[bool]
            Filter voices that are enabled for the reader app

        owner_id : typing.Optional[str]
            Filter voices by public owner ID

        sort : typing.Optional[str]
            Sort criteria

        page : typing.Optional[int]

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

        Returns
        -------
        GetLibraryVoicesResponse
            Successful Response

        Examples
        --------
        import asyncio

        from elevenlabs import AsyncElevenLabs

        client = AsyncElevenLabs(
            api_key="YOUR_API_KEY",
        )


        async def main() -> None:
            await client.voices.get_shared(
                featured=True,
                reader_app_enabled=True,
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            "v1/shared-voices",
            base_url=self._client_wrapper.get_environment().base,
            method="GET",
            params={
                "page_size": page_size,
                "category": category,
                "gender": gender,
                "age": age,
                "accent": accent,
                "language": language,
                "locale": locale,
                "search": search,
                "use_cases": use_cases,
                "descriptives": descriptives,
                "featured": featured,
                "min_notice_period_days": min_notice_period_days,
                "include_custom_rates": include_custom_rates,
                "reader_app_enabled": reader_app_enabled,
                "owner_id": owner_id,
                "sort": sort,
                "page": page,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    GetLibraryVoicesResponse,
                    construct_type(
                        type_=GetLibraryVoicesResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        construct_type(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def get_similar_library_voices(
        self,
        *,
        audio_file: typing.Optional[core.File] = OMIT,
        similarity_threshold: typing.Optional[float] = OMIT,
        top_k: typing.Optional[int] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> GetLibraryVoicesResponse:
        """
        Returns a list of shared voices similar to the provided audio sample. If neither similarity_threshold nor top_k is provided, we will apply default values.

        Parameters
        ----------
        audio_file : typing.Optional[core.File]
            See core.File for more documentation

        similarity_threshold : typing.Optional[float]
            Threshold for voice similarity between provided sample and library voices. Values range from 0 to 2. The smaller the value the more similar voices will be returned.

        top_k : typing.Optional[int]
            Number of most similar voices to return. If similarity_threshold is provided, less than this number of voices may be returned. Values range from 1 to 100.

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

        Returns
        -------
        GetLibraryVoicesResponse
            Successful Response

        Examples
        --------
        import asyncio

        from elevenlabs import AsyncElevenLabs

        client = AsyncElevenLabs(
            api_key="YOUR_API_KEY",
        )


        async def main() -> None:
            await client.voices.get_similar_library_voices()


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            "v1/similar-voices",
            base_url=self._client_wrapper.get_environment().base,
            method="POST",
            data={
                "similarity_threshold": similarity_threshold,
                "top_k": top_k,
            },
            files={
                "audio_file": audio_file,
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    GetLibraryVoicesResponse,
                    construct_type(
                        type_=GetLibraryVoicesResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        construct_type(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)
