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

import typing
from ..core.client_wrapper import SyncClientWrapper
from ..core.request_options import RequestOptions
from ..types.get_projects_response import GetProjectsResponse
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 .. import core
from ..types.add_project_response_model import AddProjectResponseModel
from ..types.project_extended_response_model import ProjectExtendedResponseModel
from ..core.jsonable_encoder import jsonable_encoder
from ..types.edit_project_response_model import EditProjectResponseModel
from ..types.project_snapshots_response import ProjectSnapshotsResponse
from ..types.pronunciation_dictionary_version_locator import PronunciationDictionaryVersionLocator
from ..core.serialization import convert_and_respect_annotation_metadata
from ..core.client_wrapper import AsyncClientWrapper

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


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

    def get_all(self, *, request_options: typing.Optional[RequestOptions] = None) -> GetProjectsResponse:
        """
        Returns a list of your projects together and its metadata.

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

        Returns
        -------
        GetProjectsResponse
            Successful Response

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

        client = ElevenLabs(
            api_key="YOUR_API_KEY",
        )
        client.projects.get_all()
        """
        _response = self._client_wrapper.httpx_client.request(
            "v1/projects",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    GetProjectsResponse,
                    construct_type(
                        type_=GetProjectsResponse,  # 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,
        default_title_voice_id: str,
        default_paragraph_voice_id: str,
        default_model_id: str,
        from_url: typing.Optional[str] = OMIT,
        from_document: typing.Optional[core.File] = OMIT,
        quality_preset: typing.Optional[str] = OMIT,
        title: typing.Optional[str] = OMIT,
        author: typing.Optional[str] = OMIT,
        isbn_number: typing.Optional[str] = OMIT,
        acx_volume_normalization: typing.Optional[bool] = OMIT,
        volume_normalization: typing.Optional[bool] = OMIT,
        pronunciation_dictionary_locators: typing.Optional[typing.List[str]] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AddProjectResponseModel:
        """
        Creates a new project, it can be either initialized as blank, from a document or from a URL.

        Parameters
        ----------
        name : str
            The name of the project, used for identification only.

        default_title_voice_id : str
            The voice_id that corresponds to the default voice used for new titles.

        default_paragraph_voice_id : str
            The voice_id that corresponds to the default voice used for new paragraphs.

        default_model_id : str
            The model_id of the model to be used for this project, you can query GET https://api.elevenlabs.io/v1/models to list all available models.

        from_url : typing.Optional[str]
            An optional URL from which we will extract content to initialize the project. If this is set, 'from_url' must be null. If neither 'from_url' or 'from_document' are provided we will initialize the project as blank.

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

        quality_preset : typing.Optional[str]
            Output quality of the generated audio. Must be one of:
            standard - standard output format, 128kbps with 44.1kHz sample rate.
            high - high quality output format, 192kbps with 44.1kHz sample rate and major improvements on our side. Using this setting increases the character cost by 20%.
            ultra - ultra quality output format, 192kbps with 44.1kHz sample rate and highest improvements on our side. Using this setting increases the character cost by 50%.
            ultra lossless - ultra quality output format, 705.6kbps with 44.1kHz sample rate and highest improvements on our side in a fully lossless format. Using this setting increases the character cost by 100%.


        title : typing.Optional[str]
            An optional name of the author of the project, this will be added as metadata to the mp3 file on project / chapter download.

        author : typing.Optional[str]
            An optional name of the author of the project, this will be added as metadata to the mp3 file on project / chapter download.

        isbn_number : typing.Optional[str]
            An optional ISBN number of the project you want to create, this will be added as metadata to the mp3 file on project / chapter download.

        acx_volume_normalization : typing.Optional[bool]
            [Deprecated] When the project is downloaded, should the returned audio have postprocessing in order to make it compliant with audiobook normalized volume requirements

        volume_normalization : typing.Optional[bool]
            When the project is downloaded, should the returned audio have postprocessing in order to make it compliant with audiobook normalized volume requirements

        pronunciation_dictionary_locators : typing.Optional[typing.List[str]]
            A list of pronunciation dictionary locators (pronunciation_dictionary_id, version_id) encoded as a list of JSON strings for pronunciation dictionaries to be applied to the text.  A list of json encoded strings is required as adding projects may occur through formData as opposed to jsonBody. To specify multiple dictionaries use multiple --form lines in your curl, such as --form 'pronunciation_dictionary_locators="{\"pronunciation_dictionary_id\":\"Vmd4Zor6fplcA7WrINey\",\"version_id\":\"hRPaxjlTdR7wFMhV4w0b\"}"' --form 'pronunciation_dictionary_locators="{\"pronunciation_dictionary_id\":\"JzWtcGQMJ6bnlWwyMo7e\",\"version_id\":\"lbmwxiLu4q6txYxgdZqn\"}"'. Note that multiple dictionaries are not currently supported by our UI which will only show the first.

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

        Returns
        -------
        AddProjectResponseModel
            Successful Response

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

        client = ElevenLabs(
            api_key="YOUR_API_KEY",
        )
        client.projects.add(
            name="name",
            default_title_voice_id="default_title_voice_id",
            default_paragraph_voice_id="default_paragraph_voice_id",
            default_model_id="default_model_id",
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            "v1/projects/add",
            method="POST",
            data={
                "name": name,
                "default_title_voice_id": default_title_voice_id,
                "default_paragraph_voice_id": default_paragraph_voice_id,
                "default_model_id": default_model_id,
                "from_url": from_url,
                "quality_preset": quality_preset,
                "title": title,
                "author": author,
                "isbn_number": isbn_number,
                "acx_volume_normalization": acx_volume_normalization,
                "volume_normalization": volume_normalization,
                "pronunciation_dictionary_locators": pronunciation_dictionary_locators,
            },
            files={
                "from_document": from_document,
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    AddProjectResponseModel,
                    construct_type(
                        type_=AddProjectResponseModel,  # 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, project_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> ProjectExtendedResponseModel:
        """
        Returns information about a specific project. This endpoint returns more detailed information about a project than GET api.elevenlabs.io/v1/projects.

        Parameters
        ----------
        project_id : str
            The project_id of the project, you can query GET https://api.elevenlabs.io/v1/projects to list all available projects.

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

        Returns
        -------
        ProjectExtendedResponseModel
            Successful Response

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

        client = ElevenLabs(
            api_key="YOUR_API_KEY",
        )
        client.projects.get(
            project_id="21m00Tcm4TlvDq8ikWAM",
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v1/projects/{jsonable_encoder(project_id)}",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    ProjectExtendedResponseModel,
                    construct_type(
                        type_=ProjectExtendedResponseModel,  # 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_basic_project_info(
        self,
        project_id: str,
        *,
        name: str,
        default_title_voice_id: str,
        default_paragraph_voice_id: str,
        title: typing.Optional[str] = OMIT,
        author: typing.Optional[str] = OMIT,
        isbn_number: typing.Optional[str] = OMIT,
        volume_normalization: typing.Optional[bool] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> EditProjectResponseModel:
        """
        Edits basic project info.

        Parameters
        ----------
        project_id : str
            The project_id of the project, you can query GET https://api.elevenlabs.io/v1/projects to list all available projects.

        name : str
            The name of the project, used for identification only.

        default_title_voice_id : str
            The voice_id that corresponds to the default voice used for new titles.

        default_paragraph_voice_id : str
            The voice_id that corresponds to the default voice used for new paragraphs.

        title : typing.Optional[str]
            An optional name of the author of the project, this will be added as metadata to the mp3 file on project / chapter download.

        author : typing.Optional[str]
            An optional name of the author of the project, this will be added as metadata to the mp3 file on project / chapter download.

        isbn_number : typing.Optional[str]
            An optional ISBN number of the project you want to create, this will be added as metadata to the mp3 file on project / chapter download.

        volume_normalization : typing.Optional[bool]
            When the project is downloaded, should the returned audio have postprocessing in order to make it compliant with audiobook normalized volume requirements

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

        Returns
        -------
        EditProjectResponseModel
            Successful Response

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

        client = ElevenLabs(
            api_key="YOUR_API_KEY",
        )
        client.projects.edit_basic_project_info(
            project_id="21m00Tcm4TlvDq8ikWAM",
            name="name",
            default_title_voice_id="default_title_voice_id",
            default_paragraph_voice_id="default_paragraph_voice_id",
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v1/projects/{jsonable_encoder(project_id)}",
            method="POST",
            json={
                "name": name,
                "default_title_voice_id": default_title_voice_id,
                "default_paragraph_voice_id": default_paragraph_voice_id,
                "title": title,
                "author": author,
                "isbn_number": isbn_number,
                "volume_normalization": volume_normalization,
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    EditProjectResponseModel,
                    construct_type(
                        type_=EditProjectResponseModel,  # 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, project_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> typing.Optional[typing.Any]:
        """
        Delete a project by its project_id.

        Parameters
        ----------
        project_id : str
            The project_id of the project, you can query GET https://api.elevenlabs.io/v1/projects to list all available projects.

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

        Returns
        -------
        typing.Optional[typing.Any]
            Successful Response

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

        client = ElevenLabs(
            api_key="YOUR_API_KEY",
        )
        client.projects.delete(
            project_id="21m00Tcm4TlvDq8ikWAM",
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v1/projects/{jsonable_encoder(project_id)}",
            method="DELETE",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    typing.Optional[typing.Any],
                    construct_type(
                        type_=typing.Optional[typing.Any],  # 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 convert(
        self, project_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> typing.Optional[typing.Any]:
        """
        Starts conversion of a project and all of its chapters.

        Parameters
        ----------
        project_id : str
            The project_id of the project, you can query GET https://api.elevenlabs.io/v1/projects to list all available projects.

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

        Returns
        -------
        typing.Optional[typing.Any]
            Successful Response

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

        client = ElevenLabs(
            api_key="YOUR_API_KEY",
        )
        client.projects.convert(
            project_id="21m00Tcm4TlvDq8ikWAM",
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v1/projects/{jsonable_encoder(project_id)}/convert",
            method="POST",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    typing.Optional[typing.Any],
                    construct_type(
                        type_=typing.Optional[typing.Any],  # 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_snapshots(
        self, project_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> ProjectSnapshotsResponse:
        """
        Gets the snapshots of a project.

        Parameters
        ----------
        project_id : str
            The project_id of the project, you can query GET https://api.elevenlabs.io/v1/projects to list all available projects.

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

        Returns
        -------
        ProjectSnapshotsResponse
            Successful Response

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

        client = ElevenLabs(
            api_key="YOUR_API_KEY",
        )
        client.projects.get_snapshots(
            project_id="21m00Tcm4TlvDq8ikWAM",
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v1/projects/{jsonable_encoder(project_id)}/snapshots",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    ProjectSnapshotsResponse,
                    construct_type(
                        type_=ProjectSnapshotsResponse,  # 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 stream_audio(
        self,
        project_id: str,
        project_snapshot_id: str,
        *,
        convert_to_mpeg: typing.Optional[bool] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> typing.Iterator[bytes]:
        """
        Stream the audio from a project snapshot.

        Parameters
        ----------
        project_id : str
            The project_id of the project, you can query GET https://api.elevenlabs.io/v1/projects to list all available projects.

        project_snapshot_id : str
            The project_snapshot_id of the project snapshot. You can query GET /v1/projects/{project_id}/snapshots to list all available snapshots for a project.

        convert_to_mpeg : typing.Optional[bool]
            Whether to convert the audio to mpeg format.

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

        Yields
        ------
        typing.Iterator[bytes]
            Successful Response

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

        client = ElevenLabs(
            api_key="YOUR_API_KEY",
        )
        client.projects.stream_audio(
            project_id="string",
            project_snapshot_id="string",
            convert_to_mpeg=True,
        )
        """
        with self._client_wrapper.httpx_client.stream(
            f"v1/projects/{jsonable_encoder(project_id)}/snapshots/{jsonable_encoder(project_snapshot_id)}/stream",
            method="POST",
            json={
                "convert_to_mpeg": convert_to_mpeg,
            },
            request_options=request_options,
            omit=OMIT,
        ) as _response:
            try:
                if 200 <= _response.status_code < 300:
                    for _chunk in _response.iter_bytes():
                        yield _chunk
                    return
                _response.read()
                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 stream_archive(
        self, project_id: str, project_snapshot_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> None:
        """
        Streams archive with project audio.

        Parameters
        ----------
        project_id : str
            The project_id of the project, you can query GET https://api.elevenlabs.io/v1/projects to list all available projects.

        project_snapshot_id : str
            The project_snapshot_id of the project snapshot. You can query GET /v1/projects/{project_id}/snapshots to list all available snapshots for a project.

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

        Returns
        -------
        None

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

        client = ElevenLabs(
            api_key="YOUR_API_KEY",
        )
        client.projects.stream_archive(
            project_id="21m00Tcm4TlvDq8ikWAM",
            project_snapshot_id="21m00Tcm4TlvDq8ikWAM",
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v1/projects/{jsonable_encoder(project_id)}/snapshots/{jsonable_encoder(project_snapshot_id)}/archive",
            method="POST",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return
            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 update_pronunciation_dictionaries(
        self,
        project_id: str,
        *,
        pronunciation_dictionary_locators: typing.Sequence[PronunciationDictionaryVersionLocator],
        request_options: typing.Optional[RequestOptions] = None,
    ) -> typing.Optional[typing.Any]:
        """
        Updates the set of pronunciation dictionaries acting on a project. This will automatically mark text within this project as requiring reconverting where the new dictionary would apply or the old one no longer does.

        Parameters
        ----------
        project_id : str
            The project_id of the project, you can query GET https://api.elevenlabs.io/v1/projects to list all available projects.

        pronunciation_dictionary_locators : typing.Sequence[PronunciationDictionaryVersionLocator]
            A list of pronunciation dictionary locators (pronunciation_dictionary_id, version_id) encoded as a list of JSON strings for pronunciation dictionaries to be applied to the text.  A list of json encoded strings is required as adding projects may occur through formData as opposed to jsonBody. To specify multiple dictionaries use multiple --form lines in your curl, such as --form 'pronunciation_dictionary_locators="{\"pronunciation_dictionary_id\":\"Vmd4Zor6fplcA7WrINey\",\"version_id\":\"hRPaxjlTdR7wFMhV4w0b\"}"' --form 'pronunciation_dictionary_locators="{\"pronunciation_dictionary_id\":\"JzWtcGQMJ6bnlWwyMo7e\",\"version_id\":\"lbmwxiLu4q6txYxgdZqn\"}"'. Note that multiple dictionaries are not currently supported by our UI which will only show the first.

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

        Returns
        -------
        typing.Optional[typing.Any]
            Successful Response

        Examples
        --------
        from elevenlabs import ElevenLabs, PronunciationDictionaryVersionLocator

        client = ElevenLabs(
            api_key="YOUR_API_KEY",
        )
        client.projects.update_pronunciation_dictionaries(
            project_id="21m00Tcm4TlvDq8ikWAM",
            pronunciation_dictionary_locators=[
                PronunciationDictionaryVersionLocator(
                    pronunciation_dictionary_id="pronunciation_dictionary_id",
                    version_id="version_id",
                )
            ],
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v1/projects/{jsonable_encoder(project_id)}/update-pronunciation-dictionaries",
            method="POST",
            json={
                "pronunciation_dictionary_locators": convert_and_respect_annotation_metadata(
                    object_=pronunciation_dictionary_locators,
                    annotation=typing.Sequence[PronunciationDictionaryVersionLocator],
                    direction="write",
                ),
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    typing.Optional[typing.Any],
                    construct_type(
                        type_=typing.Optional[typing.Any],  # 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 AsyncProjectsClient:
    def __init__(self, *, client_wrapper: AsyncClientWrapper):
        self._client_wrapper = client_wrapper

    async def get_all(self, *, request_options: typing.Optional[RequestOptions] = None) -> GetProjectsResponse:
        """
        Returns a list of your projects together and its metadata.

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

        Returns
        -------
        GetProjectsResponse
            Successful Response

        Examples
        --------
        import asyncio

        from elevenlabs import AsyncElevenLabs

        client = AsyncElevenLabs(
            api_key="YOUR_API_KEY",
        )


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


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            "v1/projects",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    GetProjectsResponse,
                    construct_type(
                        type_=GetProjectsResponse,  # 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,
        default_title_voice_id: str,
        default_paragraph_voice_id: str,
        default_model_id: str,
        from_url: typing.Optional[str] = OMIT,
        from_document: typing.Optional[core.File] = OMIT,
        quality_preset: typing.Optional[str] = OMIT,
        title: typing.Optional[str] = OMIT,
        author: typing.Optional[str] = OMIT,
        isbn_number: typing.Optional[str] = OMIT,
        acx_volume_normalization: typing.Optional[bool] = OMIT,
        volume_normalization: typing.Optional[bool] = OMIT,
        pronunciation_dictionary_locators: typing.Optional[typing.List[str]] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AddProjectResponseModel:
        """
        Creates a new project, it can be either initialized as blank, from a document or from a URL.

        Parameters
        ----------
        name : str
            The name of the project, used for identification only.

        default_title_voice_id : str
            The voice_id that corresponds to the default voice used for new titles.

        default_paragraph_voice_id : str
            The voice_id that corresponds to the default voice used for new paragraphs.

        default_model_id : str
            The model_id of the model to be used for this project, you can query GET https://api.elevenlabs.io/v1/models to list all available models.

        from_url : typing.Optional[str]
            An optional URL from which we will extract content to initialize the project. If this is set, 'from_url' must be null. If neither 'from_url' or 'from_document' are provided we will initialize the project as blank.

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

        quality_preset : typing.Optional[str]
            Output quality of the generated audio. Must be one of:
            standard - standard output format, 128kbps with 44.1kHz sample rate.
            high - high quality output format, 192kbps with 44.1kHz sample rate and major improvements on our side. Using this setting increases the character cost by 20%.
            ultra - ultra quality output format, 192kbps with 44.1kHz sample rate and highest improvements on our side. Using this setting increases the character cost by 50%.
            ultra lossless - ultra quality output format, 705.6kbps with 44.1kHz sample rate and highest improvements on our side in a fully lossless format. Using this setting increases the character cost by 100%.


        title : typing.Optional[str]
            An optional name of the author of the project, this will be added as metadata to the mp3 file on project / chapter download.

        author : typing.Optional[str]
            An optional name of the author of the project, this will be added as metadata to the mp3 file on project / chapter download.

        isbn_number : typing.Optional[str]
            An optional ISBN number of the project you want to create, this will be added as metadata to the mp3 file on project / chapter download.

        acx_volume_normalization : typing.Optional[bool]
            [Deprecated] When the project is downloaded, should the returned audio have postprocessing in order to make it compliant with audiobook normalized volume requirements

        volume_normalization : typing.Optional[bool]
            When the project is downloaded, should the returned audio have postprocessing in order to make it compliant with audiobook normalized volume requirements

        pronunciation_dictionary_locators : typing.Optional[typing.List[str]]
            A list of pronunciation dictionary locators (pronunciation_dictionary_id, version_id) encoded as a list of JSON strings for pronunciation dictionaries to be applied to the text.  A list of json encoded strings is required as adding projects may occur through formData as opposed to jsonBody. To specify multiple dictionaries use multiple --form lines in your curl, such as --form 'pronunciation_dictionary_locators="{\"pronunciation_dictionary_id\":\"Vmd4Zor6fplcA7WrINey\",\"version_id\":\"hRPaxjlTdR7wFMhV4w0b\"}"' --form 'pronunciation_dictionary_locators="{\"pronunciation_dictionary_id\":\"JzWtcGQMJ6bnlWwyMo7e\",\"version_id\":\"lbmwxiLu4q6txYxgdZqn\"}"'. Note that multiple dictionaries are not currently supported by our UI which will only show the first.

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

        Returns
        -------
        AddProjectResponseModel
            Successful Response

        Examples
        --------
        import asyncio

        from elevenlabs import AsyncElevenLabs

        client = AsyncElevenLabs(
            api_key="YOUR_API_KEY",
        )


        async def main() -> None:
            await client.projects.add(
                name="name",
                default_title_voice_id="default_title_voice_id",
                default_paragraph_voice_id="default_paragraph_voice_id",
                default_model_id="default_model_id",
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            "v1/projects/add",
            method="POST",
            data={
                "name": name,
                "default_title_voice_id": default_title_voice_id,
                "default_paragraph_voice_id": default_paragraph_voice_id,
                "default_model_id": default_model_id,
                "from_url": from_url,
                "quality_preset": quality_preset,
                "title": title,
                "author": author,
                "isbn_number": isbn_number,
                "acx_volume_normalization": acx_volume_normalization,
                "volume_normalization": volume_normalization,
                "pronunciation_dictionary_locators": pronunciation_dictionary_locators,
            },
            files={
                "from_document": from_document,
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    AddProjectResponseModel,
                    construct_type(
                        type_=AddProjectResponseModel,  # 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, project_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> ProjectExtendedResponseModel:
        """
        Returns information about a specific project. This endpoint returns more detailed information about a project than GET api.elevenlabs.io/v1/projects.

        Parameters
        ----------
        project_id : str
            The project_id of the project, you can query GET https://api.elevenlabs.io/v1/projects to list all available projects.

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

        Returns
        -------
        ProjectExtendedResponseModel
            Successful Response

        Examples
        --------
        import asyncio

        from elevenlabs import AsyncElevenLabs

        client = AsyncElevenLabs(
            api_key="YOUR_API_KEY",
        )


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


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v1/projects/{jsonable_encoder(project_id)}",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    ProjectExtendedResponseModel,
                    construct_type(
                        type_=ProjectExtendedResponseModel,  # 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_basic_project_info(
        self,
        project_id: str,
        *,
        name: str,
        default_title_voice_id: str,
        default_paragraph_voice_id: str,
        title: typing.Optional[str] = OMIT,
        author: typing.Optional[str] = OMIT,
        isbn_number: typing.Optional[str] = OMIT,
        volume_normalization: typing.Optional[bool] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> EditProjectResponseModel:
        """
        Edits basic project info.

        Parameters
        ----------
        project_id : str
            The project_id of the project, you can query GET https://api.elevenlabs.io/v1/projects to list all available projects.

        name : str
            The name of the project, used for identification only.

        default_title_voice_id : str
            The voice_id that corresponds to the default voice used for new titles.

        default_paragraph_voice_id : str
            The voice_id that corresponds to the default voice used for new paragraphs.

        title : typing.Optional[str]
            An optional name of the author of the project, this will be added as metadata to the mp3 file on project / chapter download.

        author : typing.Optional[str]
            An optional name of the author of the project, this will be added as metadata to the mp3 file on project / chapter download.

        isbn_number : typing.Optional[str]
            An optional ISBN number of the project you want to create, this will be added as metadata to the mp3 file on project / chapter download.

        volume_normalization : typing.Optional[bool]
            When the project is downloaded, should the returned audio have postprocessing in order to make it compliant with audiobook normalized volume requirements

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

        Returns
        -------
        EditProjectResponseModel
            Successful Response

        Examples
        --------
        import asyncio

        from elevenlabs import AsyncElevenLabs

        client = AsyncElevenLabs(
            api_key="YOUR_API_KEY",
        )


        async def main() -> None:
            await client.projects.edit_basic_project_info(
                project_id="21m00Tcm4TlvDq8ikWAM",
                name="name",
                default_title_voice_id="default_title_voice_id",
                default_paragraph_voice_id="default_paragraph_voice_id",
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v1/projects/{jsonable_encoder(project_id)}",
            method="POST",
            json={
                "name": name,
                "default_title_voice_id": default_title_voice_id,
                "default_paragraph_voice_id": default_paragraph_voice_id,
                "title": title,
                "author": author,
                "isbn_number": isbn_number,
                "volume_normalization": volume_normalization,
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    EditProjectResponseModel,
                    construct_type(
                        type_=EditProjectResponseModel,  # 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, project_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> typing.Optional[typing.Any]:
        """
        Delete a project by its project_id.

        Parameters
        ----------
        project_id : str
            The project_id of the project, you can query GET https://api.elevenlabs.io/v1/projects to list all available projects.

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

        Returns
        -------
        typing.Optional[typing.Any]
            Successful Response

        Examples
        --------
        import asyncio

        from elevenlabs import AsyncElevenLabs

        client = AsyncElevenLabs(
            api_key="YOUR_API_KEY",
        )


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


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v1/projects/{jsonable_encoder(project_id)}",
            method="DELETE",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    typing.Optional[typing.Any],
                    construct_type(
                        type_=typing.Optional[typing.Any],  # 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 convert(
        self, project_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> typing.Optional[typing.Any]:
        """
        Starts conversion of a project and all of its chapters.

        Parameters
        ----------
        project_id : str
            The project_id of the project, you can query GET https://api.elevenlabs.io/v1/projects to list all available projects.

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

        Returns
        -------
        typing.Optional[typing.Any]
            Successful Response

        Examples
        --------
        import asyncio

        from elevenlabs import AsyncElevenLabs

        client = AsyncElevenLabs(
            api_key="YOUR_API_KEY",
        )


        async def main() -> None:
            await client.projects.convert(
                project_id="21m00Tcm4TlvDq8ikWAM",
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v1/projects/{jsonable_encoder(project_id)}/convert",
            method="POST",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    typing.Optional[typing.Any],
                    construct_type(
                        type_=typing.Optional[typing.Any],  # 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_snapshots(
        self, project_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> ProjectSnapshotsResponse:
        """
        Gets the snapshots of a project.

        Parameters
        ----------
        project_id : str
            The project_id of the project, you can query GET https://api.elevenlabs.io/v1/projects to list all available projects.

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

        Returns
        -------
        ProjectSnapshotsResponse
            Successful Response

        Examples
        --------
        import asyncio

        from elevenlabs import AsyncElevenLabs

        client = AsyncElevenLabs(
            api_key="YOUR_API_KEY",
        )


        async def main() -> None:
            await client.projects.get_snapshots(
                project_id="21m00Tcm4TlvDq8ikWAM",
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v1/projects/{jsonable_encoder(project_id)}/snapshots",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    ProjectSnapshotsResponse,
                    construct_type(
                        type_=ProjectSnapshotsResponse,  # 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 stream_audio(
        self,
        project_id: str,
        project_snapshot_id: str,
        *,
        convert_to_mpeg: typing.Optional[bool] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> typing.AsyncIterator[bytes]:
        """
        Stream the audio from a project snapshot.

        Parameters
        ----------
        project_id : str
            The project_id of the project, you can query GET https://api.elevenlabs.io/v1/projects to list all available projects.

        project_snapshot_id : str
            The project_snapshot_id of the project snapshot. You can query GET /v1/projects/{project_id}/snapshots to list all available snapshots for a project.

        convert_to_mpeg : typing.Optional[bool]
            Whether to convert the audio to mpeg format.

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

        Yields
        ------
        typing.AsyncIterator[bytes]
            Successful Response

        Examples
        --------
        import asyncio

        from elevenlabs import AsyncElevenLabs

        client = AsyncElevenLabs(
            api_key="YOUR_API_KEY",
        )


        async def main() -> None:
            await client.projects.stream_audio(
                project_id="string",
                project_snapshot_id="string",
                convert_to_mpeg=True,
            )


        asyncio.run(main())
        """
        async with self._client_wrapper.httpx_client.stream(
            f"v1/projects/{jsonable_encoder(project_id)}/snapshots/{jsonable_encoder(project_snapshot_id)}/stream",
            method="POST",
            json={
                "convert_to_mpeg": convert_to_mpeg,
            },
            request_options=request_options,
            omit=OMIT,
        ) as _response:
            try:
                if 200 <= _response.status_code < 300:
                    async for _chunk in _response.aiter_bytes():
                        yield _chunk
                    return
                await _response.aread()
                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 stream_archive(
        self, project_id: str, project_snapshot_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> None:
        """
        Streams archive with project audio.

        Parameters
        ----------
        project_id : str
            The project_id of the project, you can query GET https://api.elevenlabs.io/v1/projects to list all available projects.

        project_snapshot_id : str
            The project_snapshot_id of the project snapshot. You can query GET /v1/projects/{project_id}/snapshots to list all available snapshots for a project.

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

        Returns
        -------
        None

        Examples
        --------
        import asyncio

        from elevenlabs import AsyncElevenLabs

        client = AsyncElevenLabs(
            api_key="YOUR_API_KEY",
        )


        async def main() -> None:
            await client.projects.stream_archive(
                project_id="21m00Tcm4TlvDq8ikWAM",
                project_snapshot_id="21m00Tcm4TlvDq8ikWAM",
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v1/projects/{jsonable_encoder(project_id)}/snapshots/{jsonable_encoder(project_snapshot_id)}/archive",
            method="POST",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return
            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 update_pronunciation_dictionaries(
        self,
        project_id: str,
        *,
        pronunciation_dictionary_locators: typing.Sequence[PronunciationDictionaryVersionLocator],
        request_options: typing.Optional[RequestOptions] = None,
    ) -> typing.Optional[typing.Any]:
        """
        Updates the set of pronunciation dictionaries acting on a project. This will automatically mark text within this project as requiring reconverting where the new dictionary would apply or the old one no longer does.

        Parameters
        ----------
        project_id : str
            The project_id of the project, you can query GET https://api.elevenlabs.io/v1/projects to list all available projects.

        pronunciation_dictionary_locators : typing.Sequence[PronunciationDictionaryVersionLocator]
            A list of pronunciation dictionary locators (pronunciation_dictionary_id, version_id) encoded as a list of JSON strings for pronunciation dictionaries to be applied to the text.  A list of json encoded strings is required as adding projects may occur through formData as opposed to jsonBody. To specify multiple dictionaries use multiple --form lines in your curl, such as --form 'pronunciation_dictionary_locators="{\"pronunciation_dictionary_id\":\"Vmd4Zor6fplcA7WrINey\",\"version_id\":\"hRPaxjlTdR7wFMhV4w0b\"}"' --form 'pronunciation_dictionary_locators="{\"pronunciation_dictionary_id\":\"JzWtcGQMJ6bnlWwyMo7e\",\"version_id\":\"lbmwxiLu4q6txYxgdZqn\"}"'. Note that multiple dictionaries are not currently supported by our UI which will only show the first.

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

        Returns
        -------
        typing.Optional[typing.Any]
            Successful Response

        Examples
        --------
        import asyncio

        from elevenlabs import AsyncElevenLabs, PronunciationDictionaryVersionLocator

        client = AsyncElevenLabs(
            api_key="YOUR_API_KEY",
        )


        async def main() -> None:
            await client.projects.update_pronunciation_dictionaries(
                project_id="21m00Tcm4TlvDq8ikWAM",
                pronunciation_dictionary_locators=[
                    PronunciationDictionaryVersionLocator(
                        pronunciation_dictionary_id="pronunciation_dictionary_id",
                        version_id="version_id",
                    )
                ],
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v1/projects/{jsonable_encoder(project_id)}/update-pronunciation-dictionaries",
            method="POST",
            json={
                "pronunciation_dictionary_locators": convert_and_respect_annotation_metadata(
                    object_=pronunciation_dictionary_locators,
                    annotation=typing.Sequence[PronunciationDictionaryVersionLocator],
                    direction="write",
                ),
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    typing.Optional[typing.Any],
                    construct_type(
                        type_=typing.Optional[typing.Any],  # 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)
