# 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 .environment import SoferAIEnvironment

if typing.TYPE_CHECKING:
    from .balance.client import AsyncBalanceClient, BalanceClient
    from .categories.client import AsyncCategoriesClient, CategoriesClient
    from .health.client import AsyncHealthClient, HealthClient
    from .link.client import AsyncLinkClient, LinkClient
    from .maishiv.client import AsyncMaishivClient, MaishivClient
    from .ocr.client import AsyncOcrClient, OcrClient
    from .timestamps.client import AsyncTimestampsClient, TimestampsClient
    from .transcribe.client import AsyncTranscribeClient, TranscribeClient
    from .transformations.client import AsyncTransformationsClient, TransformationsClient
    from .utils.client import AsyncUtilsClient, UtilsClient


class SoferAI:
    """
    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 : SoferAIEnvironment
        The environment to use for requests from the client. from .environment import SoferAIEnvironment



        Defaults to SoferAIEnvironment.PRODUCTION



    api_key : typing.Optional[typing.Union[str, typing.Callable[[], 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 60 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.

    Examples
    --------
    from soferai import SoferAI

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

    def __init__(
        self,
        *,
        base_url: typing.Optional[str] = None,
        environment: SoferAIEnvironment = SoferAIEnvironment.PRODUCTION,
        api_key: typing.Optional[typing.Union[str, typing.Callable[[], str]]] = os.getenv("SOFERAI_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,
    ):
        _defaulted_timeout = (
            timeout if timeout is not None else 60 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,
        )
        self._balance: typing.Optional[BalanceClient] = None
        self._categories: typing.Optional[CategoriesClient] = None
        self._health: typing.Optional[HealthClient] = None
        self._link: typing.Optional[LinkClient] = None
        self._maishiv: typing.Optional[MaishivClient] = None
        self._ocr: typing.Optional[OcrClient] = None
        self._timestamps: typing.Optional[TimestampsClient] = None
        self._transcribe: typing.Optional[TranscribeClient] = None
        self._transformations: typing.Optional[TransformationsClient] = None
        self._utils: typing.Optional[UtilsClient] = None

    @property
    def balance(self):
        if self._balance is None:
            from .balance.client import BalanceClient

            self._balance = BalanceClient(client_wrapper=self._client_wrapper)
        return self._balance

    @property
    def categories(self):
        if self._categories is None:
            from .categories.client import CategoriesClient

            self._categories = CategoriesClient(client_wrapper=self._client_wrapper)
        return self._categories

    @property
    def health(self):
        if self._health is None:
            from .health.client import HealthClient

            self._health = HealthClient(client_wrapper=self._client_wrapper)
        return self._health

    @property
    def link(self):
        if self._link is None:
            from .link.client import LinkClient

            self._link = LinkClient(client_wrapper=self._client_wrapper)
        return self._link

    @property
    def maishiv(self):
        if self._maishiv is None:
            from .maishiv.client import MaishivClient

            self._maishiv = MaishivClient(client_wrapper=self._client_wrapper)
        return self._maishiv

    @property
    def ocr(self):
        if self._ocr is None:
            from .ocr.client import OcrClient

            self._ocr = OcrClient(client_wrapper=self._client_wrapper)
        return self._ocr

    @property
    def timestamps(self):
        if self._timestamps is None:
            from .timestamps.client import TimestampsClient

            self._timestamps = TimestampsClient(client_wrapper=self._client_wrapper)
        return self._timestamps

    @property
    def transcribe(self):
        if self._transcribe is None:
            from .transcribe.client import TranscribeClient

            self._transcribe = TranscribeClient(client_wrapper=self._client_wrapper)
        return self._transcribe

    @property
    def transformations(self):
        if self._transformations is None:
            from .transformations.client import TransformationsClient

            self._transformations = TransformationsClient(client_wrapper=self._client_wrapper)
        return self._transformations

    @property
    def utils(self):
        if self._utils is None:
            from .utils.client import UtilsClient

            self._utils = UtilsClient(client_wrapper=self._client_wrapper)
        return self._utils


class AsyncSoferAI:
    """
    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 : SoferAIEnvironment
        The environment to use for requests from the client. from .environment import SoferAIEnvironment



        Defaults to SoferAIEnvironment.PRODUCTION



    api_key : typing.Optional[typing.Union[str, typing.Callable[[], 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 60 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.

    Examples
    --------
    from soferai import AsyncSoferAI

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

    def __init__(
        self,
        *,
        base_url: typing.Optional[str] = None,
        environment: SoferAIEnvironment = SoferAIEnvironment.PRODUCTION,
        api_key: typing.Optional[typing.Union[str, typing.Callable[[], str]]] = os.getenv("SOFERAI_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,
    ):
        _defaulted_timeout = (
            timeout if timeout is not None else 60 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,
        )
        self._balance: typing.Optional[AsyncBalanceClient] = None
        self._categories: typing.Optional[AsyncCategoriesClient] = None
        self._health: typing.Optional[AsyncHealthClient] = None
        self._link: typing.Optional[AsyncLinkClient] = None
        self._maishiv: typing.Optional[AsyncMaishivClient] = None
        self._ocr: typing.Optional[AsyncOcrClient] = None
        self._timestamps: typing.Optional[AsyncTimestampsClient] = None
        self._transcribe: typing.Optional[AsyncTranscribeClient] = None
        self._transformations: typing.Optional[AsyncTransformationsClient] = None
        self._utils: typing.Optional[AsyncUtilsClient] = None

    @property
    def balance(self):
        if self._balance is None:
            from .balance.client import AsyncBalanceClient

            self._balance = AsyncBalanceClient(client_wrapper=self._client_wrapper)
        return self._balance

    @property
    def categories(self):
        if self._categories is None:
            from .categories.client import AsyncCategoriesClient

            self._categories = AsyncCategoriesClient(client_wrapper=self._client_wrapper)
        return self._categories

    @property
    def health(self):
        if self._health is None:
            from .health.client import AsyncHealthClient

            self._health = AsyncHealthClient(client_wrapper=self._client_wrapper)
        return self._health

    @property
    def link(self):
        if self._link is None:
            from .link.client import AsyncLinkClient

            self._link = AsyncLinkClient(client_wrapper=self._client_wrapper)
        return self._link

    @property
    def maishiv(self):
        if self._maishiv is None:
            from .maishiv.client import AsyncMaishivClient

            self._maishiv = AsyncMaishivClient(client_wrapper=self._client_wrapper)
        return self._maishiv

    @property
    def ocr(self):
        if self._ocr is None:
            from .ocr.client import AsyncOcrClient

            self._ocr = AsyncOcrClient(client_wrapper=self._client_wrapper)
        return self._ocr

    @property
    def timestamps(self):
        if self._timestamps is None:
            from .timestamps.client import AsyncTimestampsClient

            self._timestamps = AsyncTimestampsClient(client_wrapper=self._client_wrapper)
        return self._timestamps

    @property
    def transcribe(self):
        if self._transcribe is None:
            from .transcribe.client import AsyncTranscribeClient

            self._transcribe = AsyncTranscribeClient(client_wrapper=self._client_wrapper)
        return self._transcribe

    @property
    def transformations(self):
        if self._transformations is None:
            from .transformations.client import AsyncTransformationsClient

            self._transformations = AsyncTransformationsClient(client_wrapper=self._client_wrapper)
        return self._transformations

    @property
    def utils(self):
        if self._utils is None:
            from .utils.client import AsyncUtilsClient

            self._utils = AsyncUtilsClient(client_wrapper=self._client_wrapper)
        return self._utils


def _get_base_url(*, base_url: typing.Optional[str] = None, environment: SoferAIEnvironment) -> 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")
