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

from __future__ import annotations

import os
import typing

import httpx
from .core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
from .core.logging import LogConfig, Logger
from .environment import ElevenLabsEnvironment

if typing.TYPE_CHECKING:
    from .audio_isolation.client import AsyncAudioIsolationClient, AudioIsolationClient
    from .audio_native.client import AsyncAudioNativeClient, AudioNativeClient
    from .conversational_ai.client import AsyncConversationalAiClient, ConversationalAiClient
    from .dubbing.client import AsyncDubbingClient, DubbingClient
    from .environment_variables.client import AsyncEnvironmentVariablesClient, EnvironmentVariablesClient
    from .forced_alignment.client import AsyncForcedAlignmentClient, ForcedAlignmentClient
    from .history.client import AsyncHistoryClient, HistoryClient
    from .models.client import AsyncModelsClient, ModelsClient
    from .music.client import AsyncMusicClient, MusicClient
    from .productions.client import AsyncProductionsClient, ProductionsClient
    from .pronunciation_dictionaries.client import AsyncPronunciationDictionariesClient, PronunciationDictionariesClient
    from .samples.client import AsyncSamplesClient, SamplesClient
    from .service_accounts.client import AsyncServiceAccountsClient, ServiceAccountsClient
    from .speech_engine.client import AsyncSpeechEngineClient, SpeechEngineClient
    from .speech_to_speech.client import AsyncSpeechToSpeechClient, SpeechToSpeechClient
    from .speech_to_text.client import AsyncSpeechToTextClient, SpeechToTextClient
    from .studio.client import AsyncStudioClient, StudioClient
    from .text_to_dialogue.client import AsyncTextToDialogueClient, TextToDialogueClient
    from .text_to_sound_effects.client import AsyncTextToSoundEffectsClient, TextToSoundEffectsClient
    from .text_to_speech.client import AsyncTextToSpeechClient, TextToSpeechClient
    from .text_to_voice.client import AsyncTextToVoiceClient, TextToVoiceClient
    from .tokens.client import AsyncTokensClient, TokensClient
    from .usage.client import AsyncUsageClient, UsageClient
    from .user.client import AsyncUserClient, UserClient
    from .voices.client import AsyncVoicesClient, VoicesClient
    from .webhooks.client import AsyncWebhooksClient, WebhooksClient
    from .workspace.client import AsyncWorkspaceClient, WorkspaceClient
    from .workspaces.client import AsyncWorkspacesClient, WorkspacesClient


class BaseElevenLabs:
    """
    Use this class to access the different functions within the SDK. You can instantiate any number of clients with different configuration that will propagate to these functions.

    Parameters
    ----------
    base_url : typing.Optional[str]
        The base url to use for requests from the client.

    environment : ElevenLabsEnvironment
        The environment to use for requests from the client. from .environment import ElevenLabsEnvironment



        Defaults to ElevenLabsEnvironment.PRODUCTION



    api_key : typing.Optional[str]
    headers : typing.Optional[typing.Dict[str, str]]
        Additional headers to send with every request.

    timeout : typing.Optional[float]
        The timeout to be used, in seconds, for requests. By default the timeout is 240 seconds, unless a custom httpx client is used, in which case this default is not enforced.

    follow_redirects : typing.Optional[bool]
        Whether the default httpx client follows redirects or not, this is irrelevant if a custom httpx client is passed in.

    httpx_client : typing.Optional[httpx.Client]
        The httpx client to use for making requests, a preconfigured client is used by default, however this is useful should you want to pass in any custom httpx configuration.

    logging : typing.Optional[typing.Union[LogConfig, Logger]]
        Configure logging for the SDK. Accepts a LogConfig dict with 'level' (debug/info/warn/error), 'logger' (custom logger implementation), and 'silent' (boolean, defaults to True) fields. You can also pass a pre-configured Logger instance.

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

    client = ElevenLabs(
        api_key="YOUR_API_KEY",
    )
    """

    def __init__(
        self,
        *,
        base_url: typing.Optional[str] = None,
        environment: ElevenLabsEnvironment = ElevenLabsEnvironment.PRODUCTION,
        api_key: typing.Optional[str] = os.getenv("ELEVENLABS_API_KEY"),
        headers: typing.Optional[typing.Dict[str, str]] = None,
        timeout: typing.Optional[float] = None,
        follow_redirects: typing.Optional[bool] = True,
        httpx_client: typing.Optional[httpx.Client] = None,
        logging: typing.Optional[typing.Union[LogConfig, Logger]] = None,
    ):
        _defaulted_timeout = (
            timeout if timeout is not None else 240 if httpx_client is None else httpx_client.timeout.read
        )
        self._client_wrapper = SyncClientWrapper(
            base_url=_get_base_url(base_url=base_url, environment=environment),
            api_key=api_key,
            headers=headers,
            httpx_client=httpx_client
            if httpx_client is not None
            else httpx.Client(timeout=_defaulted_timeout, follow_redirects=follow_redirects)
            if follow_redirects is not None
            else httpx.Client(timeout=_defaulted_timeout),
            timeout=_defaulted_timeout,
            logging=logging,
        )
        self._history: typing.Optional[HistoryClient] = None
        self._text_to_sound_effects: typing.Optional[TextToSoundEffectsClient] = None
        self._audio_isolation: typing.Optional[AudioIsolationClient] = None
        self._samples: typing.Optional[SamplesClient] = None
        self._text_to_speech: typing.Optional[TextToSpeechClient] = None
        self._text_to_dialogue: typing.Optional[TextToDialogueClient] = None
        self._speech_to_speech: typing.Optional[SpeechToSpeechClient] = None
        self._text_to_voice: typing.Optional[TextToVoiceClient] = None
        self._user: typing.Optional[UserClient] = None
        self._voices: typing.Optional[VoicesClient] = None
        self._studio: typing.Optional[StudioClient] = None
        self._dubbing: typing.Optional[DubbingClient] = None
        self._models: typing.Optional[ModelsClient] = None
        self._audio_native: typing.Optional[AudioNativeClient] = None
        self._usage: typing.Optional[UsageClient] = None
        self._pronunciation_dictionaries: typing.Optional[PronunciationDictionariesClient] = None
        self._workspace: typing.Optional[WorkspaceClient] = None
        self._service_accounts: typing.Optional[ServiceAccountsClient] = None
        self._webhooks: typing.Optional[WebhooksClient] = None
        self._music: typing.Optional[MusicClient] = None
        self._speech_to_text: typing.Optional[SpeechToTextClient] = None
        self._forced_alignment: typing.Optional[ForcedAlignmentClient] = None
        self._conversational_ai: typing.Optional[ConversationalAiClient] = None
        self._speech_engine: typing.Optional[SpeechEngineClient] = None
        self._environment_variables: typing.Optional[EnvironmentVariablesClient] = None
        self._productions: typing.Optional[ProductionsClient] = None
        self._tokens: typing.Optional[TokensClient] = None
        self._workspaces: typing.Optional[WorkspacesClient] = None

    @property
    def history(self):
        if self._history is None:
            from .history.client import HistoryClient  # noqa: E402

            self._history = HistoryClient(client_wrapper=self._client_wrapper)
        return self._history

    @property
    def text_to_sound_effects(self):
        if self._text_to_sound_effects is None:
            from .text_to_sound_effects.client import TextToSoundEffectsClient  # noqa: E402

            self._text_to_sound_effects = TextToSoundEffectsClient(client_wrapper=self._client_wrapper)
        return self._text_to_sound_effects

    @property
    def audio_isolation(self):
        if self._audio_isolation is None:
            from .audio_isolation.client import AudioIsolationClient  # noqa: E402

            self._audio_isolation = AudioIsolationClient(client_wrapper=self._client_wrapper)
        return self._audio_isolation

    @property
    def samples(self):
        if self._samples is None:
            from .samples.client import SamplesClient  # noqa: E402

            self._samples = SamplesClient(client_wrapper=self._client_wrapper)
        return self._samples

    @property
    def text_to_speech(self):
        if self._text_to_speech is None:
            from .text_to_speech.client import TextToSpeechClient  # noqa: E402

            self._text_to_speech = TextToSpeechClient(client_wrapper=self._client_wrapper)
        return self._text_to_speech

    @property
    def text_to_dialogue(self):
        if self._text_to_dialogue is None:
            from .text_to_dialogue.client import TextToDialogueClient  # noqa: E402

            self._text_to_dialogue = TextToDialogueClient(client_wrapper=self._client_wrapper)
        return self._text_to_dialogue

    @property
    def speech_to_speech(self):
        if self._speech_to_speech is None:
            from .speech_to_speech.client import SpeechToSpeechClient  # noqa: E402

            self._speech_to_speech = SpeechToSpeechClient(client_wrapper=self._client_wrapper)
        return self._speech_to_speech

    @property
    def text_to_voice(self):
        if self._text_to_voice is None:
            from .text_to_voice.client import TextToVoiceClient  # noqa: E402

            self._text_to_voice = TextToVoiceClient(client_wrapper=self._client_wrapper)
        return self._text_to_voice

    @property
    def user(self):
        if self._user is None:
            from .user.client import UserClient  # noqa: E402

            self._user = UserClient(client_wrapper=self._client_wrapper)
        return self._user

    @property
    def voices(self):
        if self._voices is None:
            from .voices.client import VoicesClient  # noqa: E402

            self._voices = VoicesClient(client_wrapper=self._client_wrapper)
        return self._voices

    @property
    def studio(self):
        if self._studio is None:
            from .studio.client import StudioClient  # noqa: E402

            self._studio = StudioClient(client_wrapper=self._client_wrapper)
        return self._studio

    @property
    def dubbing(self):
        if self._dubbing is None:
            from .dubbing.client import DubbingClient  # noqa: E402

            self._dubbing = DubbingClient(client_wrapper=self._client_wrapper)
        return self._dubbing

    @property
    def models(self):
        if self._models is None:
            from .models.client import ModelsClient  # noqa: E402

            self._models = ModelsClient(client_wrapper=self._client_wrapper)
        return self._models

    @property
    def audio_native(self):
        if self._audio_native is None:
            from .audio_native.client import AudioNativeClient  # noqa: E402

            self._audio_native = AudioNativeClient(client_wrapper=self._client_wrapper)
        return self._audio_native

    @property
    def usage(self):
        if self._usage is None:
            from .usage.client import UsageClient  # noqa: E402

            self._usage = UsageClient(client_wrapper=self._client_wrapper)
        return self._usage

    @property
    def pronunciation_dictionaries(self):
        if self._pronunciation_dictionaries is None:
            from .pronunciation_dictionaries.client import PronunciationDictionariesClient  # noqa: E402

            self._pronunciation_dictionaries = PronunciationDictionariesClient(client_wrapper=self._client_wrapper)
        return self._pronunciation_dictionaries

    @property
    def workspace(self):
        if self._workspace is None:
            from .workspace.client import WorkspaceClient  # noqa: E402

            self._workspace = WorkspaceClient(client_wrapper=self._client_wrapper)
        return self._workspace

    @property
    def service_accounts(self):
        if self._service_accounts is None:
            from .service_accounts.client import ServiceAccountsClient  # noqa: E402

            self._service_accounts = ServiceAccountsClient(client_wrapper=self._client_wrapper)
        return self._service_accounts

    @property
    def webhooks(self):
        if self._webhooks is None:
            from .webhooks.client import WebhooksClient  # noqa: E402

            self._webhooks = WebhooksClient(client_wrapper=self._client_wrapper)
        return self._webhooks

    @property
    def music(self):
        if self._music is None:
            from .music.client import MusicClient  # noqa: E402

            self._music = MusicClient(client_wrapper=self._client_wrapper)
        return self._music

    @property
    def speech_to_text(self):
        if self._speech_to_text is None:
            from .speech_to_text.client import SpeechToTextClient  # noqa: E402

            self._speech_to_text = SpeechToTextClient(client_wrapper=self._client_wrapper)
        return self._speech_to_text

    @property
    def forced_alignment(self):
        if self._forced_alignment is None:
            from .forced_alignment.client import ForcedAlignmentClient  # noqa: E402

            self._forced_alignment = ForcedAlignmentClient(client_wrapper=self._client_wrapper)
        return self._forced_alignment

    @property
    def conversational_ai(self):
        if self._conversational_ai is None:
            from .conversational_ai.client import ConversationalAiClient  # noqa: E402

            self._conversational_ai = ConversationalAiClient(client_wrapper=self._client_wrapper)
        return self._conversational_ai

    @property
    def speech_engine(self):
        if self._speech_engine is None:
            from .speech_engine.client import SpeechEngineClient  # noqa: E402

            self._speech_engine = SpeechEngineClient(client_wrapper=self._client_wrapper)
        return self._speech_engine

    @property
    def environment_variables(self):
        if self._environment_variables is None:
            from .environment_variables.client import EnvironmentVariablesClient  # noqa: E402

            self._environment_variables = EnvironmentVariablesClient(client_wrapper=self._client_wrapper)
        return self._environment_variables

    @property
    def productions(self):
        if self._productions is None:
            from .productions.client import ProductionsClient  # noqa: E402

            self._productions = ProductionsClient(client_wrapper=self._client_wrapper)
        return self._productions

    @property
    def tokens(self):
        if self._tokens is None:
            from .tokens.client import TokensClient  # noqa: E402

            self._tokens = TokensClient(client_wrapper=self._client_wrapper)
        return self._tokens

    @property
    def workspaces(self):
        if self._workspaces is None:
            from .workspaces.client import WorkspacesClient  # noqa: E402

            self._workspaces = WorkspacesClient(client_wrapper=self._client_wrapper)
        return self._workspaces


class AsyncBaseElevenLabs:
    """
    Use this class to access the different functions within the SDK. You can instantiate any number of clients with different configuration that will propagate to these functions.

    Parameters
    ----------
    base_url : typing.Optional[str]
        The base url to use for requests from the client.

    environment : ElevenLabsEnvironment
        The environment to use for requests from the client. from .environment import ElevenLabsEnvironment



        Defaults to ElevenLabsEnvironment.PRODUCTION



    api_key : typing.Optional[str]
    headers : typing.Optional[typing.Dict[str, str]]
        Additional headers to send with every request.

    timeout : typing.Optional[float]
        The timeout to be used, in seconds, for requests. By default the timeout is 240 seconds, unless a custom httpx client is used, in which case this default is not enforced.

    follow_redirects : typing.Optional[bool]
        Whether the default httpx client follows redirects or not, this is irrelevant if a custom httpx client is passed in.

    httpx_client : typing.Optional[httpx.AsyncClient]
        The httpx client to use for making requests, a preconfigured client is used by default, however this is useful should you want to pass in any custom httpx configuration.

    logging : typing.Optional[typing.Union[LogConfig, Logger]]
        Configure logging for the SDK. Accepts a LogConfig dict with 'level' (debug/info/warn/error), 'logger' (custom logger implementation), and 'silent' (boolean, defaults to True) fields. You can also pass a pre-configured Logger instance.

    Examples
    --------
    from elevenlabs import AsyncElevenLabs

    client = AsyncElevenLabs(
        api_key="YOUR_API_KEY",
    )
    """

    def __init__(
        self,
        *,
        base_url: typing.Optional[str] = None,
        environment: ElevenLabsEnvironment = ElevenLabsEnvironment.PRODUCTION,
        api_key: typing.Optional[str] = os.getenv("ELEVENLABS_API_KEY"),
        headers: typing.Optional[typing.Dict[str, str]] = None,
        timeout: typing.Optional[float] = None,
        follow_redirects: typing.Optional[bool] = True,
        httpx_client: typing.Optional[httpx.AsyncClient] = None,
        logging: typing.Optional[typing.Union[LogConfig, Logger]] = None,
    ):
        _defaulted_timeout = (
            timeout if timeout is not None else 240 if httpx_client is None else httpx_client.timeout.read
        )
        self._client_wrapper = AsyncClientWrapper(
            base_url=_get_base_url(base_url=base_url, environment=environment),
            api_key=api_key,
            headers=headers,
            httpx_client=httpx_client
            if httpx_client is not None
            else httpx.AsyncClient(timeout=_defaulted_timeout, follow_redirects=follow_redirects)
            if follow_redirects is not None
            else httpx.AsyncClient(timeout=_defaulted_timeout),
            timeout=_defaulted_timeout,
            logging=logging,
        )
        self._history: typing.Optional[AsyncHistoryClient] = None
        self._text_to_sound_effects: typing.Optional[AsyncTextToSoundEffectsClient] = None
        self._audio_isolation: typing.Optional[AsyncAudioIsolationClient] = None
        self._samples: typing.Optional[AsyncSamplesClient] = None
        self._text_to_speech: typing.Optional[AsyncTextToSpeechClient] = None
        self._text_to_dialogue: typing.Optional[AsyncTextToDialogueClient] = None
        self._speech_to_speech: typing.Optional[AsyncSpeechToSpeechClient] = None
        self._text_to_voice: typing.Optional[AsyncTextToVoiceClient] = None
        self._user: typing.Optional[AsyncUserClient] = None
        self._voices: typing.Optional[AsyncVoicesClient] = None
        self._studio: typing.Optional[AsyncStudioClient] = None
        self._dubbing: typing.Optional[AsyncDubbingClient] = None
        self._models: typing.Optional[AsyncModelsClient] = None
        self._audio_native: typing.Optional[AsyncAudioNativeClient] = None
        self._usage: typing.Optional[AsyncUsageClient] = None
        self._pronunciation_dictionaries: typing.Optional[AsyncPronunciationDictionariesClient] = None
        self._workspace: typing.Optional[AsyncWorkspaceClient] = None
        self._service_accounts: typing.Optional[AsyncServiceAccountsClient] = None
        self._webhooks: typing.Optional[AsyncWebhooksClient] = None
        self._music: typing.Optional[AsyncMusicClient] = None
        self._speech_to_text: typing.Optional[AsyncSpeechToTextClient] = None
        self._forced_alignment: typing.Optional[AsyncForcedAlignmentClient] = None
        self._conversational_ai: typing.Optional[AsyncConversationalAiClient] = None
        self._speech_engine: typing.Optional[AsyncSpeechEngineClient] = None
        self._environment_variables: typing.Optional[AsyncEnvironmentVariablesClient] = None
        self._productions: typing.Optional[AsyncProductionsClient] = None
        self._tokens: typing.Optional[AsyncTokensClient] = None
        self._workspaces: typing.Optional[AsyncWorkspacesClient] = None

    @property
    def history(self):
        if self._history is None:
            from .history.client import AsyncHistoryClient  # noqa: E402

            self._history = AsyncHistoryClient(client_wrapper=self._client_wrapper)
        return self._history

    @property
    def text_to_sound_effects(self):
        if self._text_to_sound_effects is None:
            from .text_to_sound_effects.client import AsyncTextToSoundEffectsClient  # noqa: E402

            self._text_to_sound_effects = AsyncTextToSoundEffectsClient(client_wrapper=self._client_wrapper)
        return self._text_to_sound_effects

    @property
    def audio_isolation(self):
        if self._audio_isolation is None:
            from .audio_isolation.client import AsyncAudioIsolationClient  # noqa: E402

            self._audio_isolation = AsyncAudioIsolationClient(client_wrapper=self._client_wrapper)
        return self._audio_isolation

    @property
    def samples(self):
        if self._samples is None:
            from .samples.client import AsyncSamplesClient  # noqa: E402

            self._samples = AsyncSamplesClient(client_wrapper=self._client_wrapper)
        return self._samples

    @property
    def text_to_speech(self):
        if self._text_to_speech is None:
            from .text_to_speech.client import AsyncTextToSpeechClient  # noqa: E402

            self._text_to_speech = AsyncTextToSpeechClient(client_wrapper=self._client_wrapper)
        return self._text_to_speech

    @property
    def text_to_dialogue(self):
        if self._text_to_dialogue is None:
            from .text_to_dialogue.client import AsyncTextToDialogueClient  # noqa: E402

            self._text_to_dialogue = AsyncTextToDialogueClient(client_wrapper=self._client_wrapper)
        return self._text_to_dialogue

    @property
    def speech_to_speech(self):
        if self._speech_to_speech is None:
            from .speech_to_speech.client import AsyncSpeechToSpeechClient  # noqa: E402

            self._speech_to_speech = AsyncSpeechToSpeechClient(client_wrapper=self._client_wrapper)
        return self._speech_to_speech

    @property
    def text_to_voice(self):
        if self._text_to_voice is None:
            from .text_to_voice.client import AsyncTextToVoiceClient  # noqa: E402

            self._text_to_voice = AsyncTextToVoiceClient(client_wrapper=self._client_wrapper)
        return self._text_to_voice

    @property
    def user(self):
        if self._user is None:
            from .user.client import AsyncUserClient  # noqa: E402

            self._user = AsyncUserClient(client_wrapper=self._client_wrapper)
        return self._user

    @property
    def voices(self):
        if self._voices is None:
            from .voices.client import AsyncVoicesClient  # noqa: E402

            self._voices = AsyncVoicesClient(client_wrapper=self._client_wrapper)
        return self._voices

    @property
    def studio(self):
        if self._studio is None:
            from .studio.client import AsyncStudioClient  # noqa: E402

            self._studio = AsyncStudioClient(client_wrapper=self._client_wrapper)
        return self._studio

    @property
    def dubbing(self):
        if self._dubbing is None:
            from .dubbing.client import AsyncDubbingClient  # noqa: E402

            self._dubbing = AsyncDubbingClient(client_wrapper=self._client_wrapper)
        return self._dubbing

    @property
    def models(self):
        if self._models is None:
            from .models.client import AsyncModelsClient  # noqa: E402

            self._models = AsyncModelsClient(client_wrapper=self._client_wrapper)
        return self._models

    @property
    def audio_native(self):
        if self._audio_native is None:
            from .audio_native.client import AsyncAudioNativeClient  # noqa: E402

            self._audio_native = AsyncAudioNativeClient(client_wrapper=self._client_wrapper)
        return self._audio_native

    @property
    def usage(self):
        if self._usage is None:
            from .usage.client import AsyncUsageClient  # noqa: E402

            self._usage = AsyncUsageClient(client_wrapper=self._client_wrapper)
        return self._usage

    @property
    def pronunciation_dictionaries(self):
        if self._pronunciation_dictionaries is None:
            from .pronunciation_dictionaries.client import AsyncPronunciationDictionariesClient  # noqa: E402

            self._pronunciation_dictionaries = AsyncPronunciationDictionariesClient(client_wrapper=self._client_wrapper)
        return self._pronunciation_dictionaries

    @property
    def workspace(self):
        if self._workspace is None:
            from .workspace.client import AsyncWorkspaceClient  # noqa: E402

            self._workspace = AsyncWorkspaceClient(client_wrapper=self._client_wrapper)
        return self._workspace

    @property
    def service_accounts(self):
        if self._service_accounts is None:
            from .service_accounts.client import AsyncServiceAccountsClient  # noqa: E402

            self._service_accounts = AsyncServiceAccountsClient(client_wrapper=self._client_wrapper)
        return self._service_accounts

    @property
    def webhooks(self):
        if self._webhooks is None:
            from .webhooks.client import AsyncWebhooksClient  # noqa: E402

            self._webhooks = AsyncWebhooksClient(client_wrapper=self._client_wrapper)
        return self._webhooks

    @property
    def music(self):
        if self._music is None:
            from .music.client import AsyncMusicClient  # noqa: E402

            self._music = AsyncMusicClient(client_wrapper=self._client_wrapper)
        return self._music

    @property
    def speech_to_text(self):
        if self._speech_to_text is None:
            from .speech_to_text.client import AsyncSpeechToTextClient  # noqa: E402

            self._speech_to_text = AsyncSpeechToTextClient(client_wrapper=self._client_wrapper)
        return self._speech_to_text

    @property
    def forced_alignment(self):
        if self._forced_alignment is None:
            from .forced_alignment.client import AsyncForcedAlignmentClient  # noqa: E402

            self._forced_alignment = AsyncForcedAlignmentClient(client_wrapper=self._client_wrapper)
        return self._forced_alignment

    @property
    def conversational_ai(self):
        if self._conversational_ai is None:
            from .conversational_ai.client import AsyncConversationalAiClient  # noqa: E402

            self._conversational_ai = AsyncConversationalAiClient(client_wrapper=self._client_wrapper)
        return self._conversational_ai

    @property
    def speech_engine(self):
        if self._speech_engine is None:
            from .speech_engine.client import AsyncSpeechEngineClient  # noqa: E402

            self._speech_engine = AsyncSpeechEngineClient(client_wrapper=self._client_wrapper)
        return self._speech_engine

    @property
    def environment_variables(self):
        if self._environment_variables is None:
            from .environment_variables.client import AsyncEnvironmentVariablesClient  # noqa: E402

            self._environment_variables = AsyncEnvironmentVariablesClient(client_wrapper=self._client_wrapper)
        return self._environment_variables

    @property
    def productions(self):
        if self._productions is None:
            from .productions.client import AsyncProductionsClient  # noqa: E402

            self._productions = AsyncProductionsClient(client_wrapper=self._client_wrapper)
        return self._productions

    @property
    def tokens(self):
        if self._tokens is None:
            from .tokens.client import AsyncTokensClient  # noqa: E402

            self._tokens = AsyncTokensClient(client_wrapper=self._client_wrapper)
        return self._tokens

    @property
    def workspaces(self):
        if self._workspaces is None:
            from .workspaces.client import AsyncWorkspacesClient  # noqa: E402

            self._workspaces = AsyncWorkspacesClient(client_wrapper=self._client_wrapper)
        return self._workspaces


def _get_base_url(*, base_url: typing.Optional[str] = None, environment: ElevenLabsEnvironment) -> str:
    if base_url is not None:
        return base_url
    elif environment is not None:
        return environment.value
    else:
        raise Exception("Please pass in either base_url or environment to construct the client")
