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

import typing
from ..core.client_wrapper import SyncClientWrapper
from ..types.o_auth_providers import OAuthProviders
from ..types.connection_recipe import ConnectionRecipe
from ..core.request_options import RequestOptions
from ..types.bulk_import_connections_response import BulkImportConnectionsResponse
from ..core.pydantic_utilities import parse_obj_as
from ..errors.unprocessable_entity_error import UnprocessableEntityError
from ..types.http_validation_error import HttpValidationError
from json.decoder import JSONDecodeError
from ..core.api_error import ApiError
from ..types.bulk_export_connections_response import BulkExportConnectionsResponse
from ..types.providers import Providers
from ..types.link_token_exchange_response import LinkTokenExchangeResponse
import datetime as dt
from ..types.vital_token_created_response import VitalTokenCreatedResponse
from ..core.datetime_utils import serialize_datetime
from ..types.auth_type import AuthType
from ..types.region import Region
from ..types.source import Source
from ..core.jsonable_encoder import jsonable_encoder
from ..types.password_providers import PasswordProviders
from ..types.provider_link_response import ProviderLinkResponse
from ..types.source_link import SourceLink
from ..types.manual_providers import ManualProviders
from ..types.demo_providers import DemoProviders
from ..types.demo_connection_status import DemoConnectionStatus
from ..core.client_wrapper import AsyncClientWrapper

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


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

    def bulk_import(
        self,
        *,
        provider: OAuthProviders,
        connections: typing.Sequence[ConnectionRecipe],
        request_options: typing.Optional[RequestOptions] = None,
    ) -> BulkImportConnectionsResponse:
        """
        Parameters
        ----------
        provider : OAuthProviders

        connections : typing.Sequence[ConnectionRecipe]

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

        Returns
        -------
        BulkImportConnectionsResponse
            Successful Response

        Examples
        --------
        from vital import ConnectionRecipe, OAuthProviders, Vital

        client = Vital(
            api_key="YOUR_API_KEY",
        )
        client.link.bulk_import(
            provider=OAuthProviders.OURA,
            connections=[
                ConnectionRecipe(
                    user_id="user_id",
                    access_token="access_token",
                    refresh_token="refresh_token",
                    provider_id="provider_id",
                    expires_at=1,
                )
            ],
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            "v2/link/bulk_import",
            method="POST",
            json={
                "provider": provider,
                "connections": connections,
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    BulkImportConnectionsResponse,
                    parse_obj_as(
                        type_=BulkImportConnectionsResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            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 bulk_trigger_historical_pull(
        self,
        *,
        user_ids: typing.Sequence[str],
        provider: OAuthProviders,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> typing.Optional[typing.Any]:
        """
        Parameters
        ----------
        user_ids : typing.Sequence[str]

        provider : OAuthProviders

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

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

        Examples
        --------
        from vital import OAuthProviders, Vital

        client = Vital(
            api_key="YOUR_API_KEY",
        )
        client.link.bulk_trigger_historical_pull(
            user_ids=["user_ids"],
            provider=OAuthProviders.OURA,
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            "v2/link/bulk_trigger_historical_pull",
            method="POST",
            json={
                "user_ids": user_ids,
                "provider": provider,
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    typing.Optional[typing.Any],
                    parse_obj_as(
                        type_=typing.Optional[typing.Any],  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            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 bulk_export(
        self,
        *,
        provider: OAuthProviders,
        user_ids: typing.Optional[typing.Sequence[str]] = OMIT,
        next_token: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> BulkExportConnectionsResponse:
        """
        Parameters
        ----------
        provider : OAuthProviders

        user_ids : typing.Optional[typing.Sequence[str]]

        next_token : typing.Optional[str]

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

        Returns
        -------
        BulkExportConnectionsResponse
            Successful Response

        Examples
        --------
        from vital import OAuthProviders, Vital

        client = Vital(
            api_key="YOUR_API_KEY",
        )
        client.link.bulk_export(
            provider=OAuthProviders.OURA,
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            "v2/link/bulk_export",
            method="POST",
            json={
                "user_ids": user_ids,
                "provider": provider,
                "next_token": next_token,
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    BulkExportConnectionsResponse,
                    parse_obj_as(
                        type_=BulkExportConnectionsResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            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 bulk_pause(
        self,
        *,
        user_ids: typing.Sequence[str],
        provider: OAuthProviders,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> typing.Optional[typing.Any]:
        """
        Parameters
        ----------
        user_ids : typing.Sequence[str]

        provider : OAuthProviders

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

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

        Examples
        --------
        from vital import OAuthProviders, Vital

        client = Vital(
            api_key="YOUR_API_KEY",
        )
        client.link.bulk_pause(
            user_ids=["user_ids"],
            provider=OAuthProviders.OURA,
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            "v2/link/bulk_pause",
            method="POST",
            json={
                "user_ids": user_ids,
                "provider": provider,
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    typing.Optional[typing.Any],
                    parse_obj_as(
                        type_=typing.Optional[typing.Any],  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            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 token(
        self,
        *,
        user_id: str,
        provider: typing.Optional[Providers] = OMIT,
        redirect_url: typing.Optional[str] = OMIT,
        filter_on_providers: typing.Optional[typing.Sequence[Providers]] = OMIT,
        on_error: typing.Optional[typing.Literal["redirect"]] = OMIT,
        on_close: typing.Optional[typing.Literal["redirect"]] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> LinkTokenExchangeResponse:
        """
        Endpoint to generate a user link token, to be used throughout the vital
        link process. The vital link token is a one time use token, that
        expires after 10 minutes. If you would like vital-link widget to launch
        with a specific provider, pass in a provider in the body. If you would
        like to redirect to a custom url after successful or error connection,
        pass in your own custom redirect_url parameter.

        Parameters
        ----------
        user_id : str
            User id returned by vital create user request. This id should be stored in your database against the user and used for all interactions with the vital api.

        provider : typing.Optional[Providers]

        redirect_url : typing.Optional[str]

        filter_on_providers : typing.Optional[typing.Sequence[Providers]]

        on_error : typing.Optional[typing.Literal["redirect"]]

        on_close : typing.Optional[typing.Literal["redirect"]]

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

        Returns
        -------
        LinkTokenExchangeResponse
            Successful Response

        Examples
        --------
        from vital import Vital

        client = Vital(
            api_key="YOUR_API_KEY",
        )
        client.link.token(
            user_id="user_id",
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            "v2/link/token",
            method="POST",
            json={
                "user_id": user_id,
                "provider": provider,
                "redirect_url": redirect_url,
                "filter_on_providers": filter_on_providers,
                "on_error": on_error,
                "on_close": on_close,
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    LinkTokenExchangeResponse,
                    parse_obj_as(
                        type_=LinkTokenExchangeResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            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 is_token_valid(
        self, *, token: str, request_options: typing.Optional[RequestOptions] = None
    ) -> typing.Dict[str, typing.Optional[typing.Any]]:
        """
        Parameters
        ----------
        token : str

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

        Returns
        -------
        typing.Dict[str, typing.Optional[typing.Any]]
            Successful Response

        Examples
        --------
        from vital import Vital

        client = Vital(
            api_key="YOUR_API_KEY",
        )
        client.link.is_token_valid(
            token="token",
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            "v2/link/token/isValid",
            method="POST",
            json={
                "token": token,
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    typing.Dict[str, typing.Optional[typing.Any]],
                    parse_obj_as(
                        type_=typing.Dict[str, typing.Optional[typing.Any]],  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            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 code_create(
        self,
        *,
        user_id: str,
        expires_at: typing.Optional[dt.datetime] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> VitalTokenCreatedResponse:
        """
        Generate a token to invite a user of Vital mobile app to your team

        Parameters
        ----------
        user_id : str

        expires_at : typing.Optional[dt.datetime]
            When the link code should expire. Defaults to server time plus 1 hour.

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

        Returns
        -------
        VitalTokenCreatedResponse
            Successful Response

        Examples
        --------
        from vital import Vital

        client = Vital(
            api_key="YOUR_API_KEY",
        )
        client.link.code_create(
            user_id="user_id",
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            "v2/link/code/create",
            method="POST",
            params={
                "user_id": user_id,
                "expires_at": serialize_datetime(expires_at) if expires_at is not None else None,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    VitalTokenCreatedResponse,
                    parse_obj_as(
                        type_=VitalTokenCreatedResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            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 start_connect(
        self, *, link_token: str, provider: Providers, request_options: typing.Optional[RequestOptions] = None
    ) -> typing.Dict[str, typing.Optional[typing.Any]]:
        """
        REQUEST_SOURCE: VITAL-LINK
        Start link token process

        Parameters
        ----------
        link_token : str

        provider : Providers

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

        Returns
        -------
        typing.Dict[str, typing.Optional[typing.Any]]
            Successful Response

        Examples
        --------
        from vital import Providers, Vital

        client = Vital(
            api_key="YOUR_API_KEY",
        )
        client.link.start_connect(
            link_token="link_token",
            provider=Providers.OURA,
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            "v2/link/start",
            method="POST",
            json={
                "link_token": link_token,
                "provider": provider,
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    typing.Dict[str, typing.Optional[typing.Any]],
                    parse_obj_as(
                        type_=typing.Dict[str, typing.Optional[typing.Any]],  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            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 token_state(
        self, *, vital_link_token: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None
    ) -> typing.Dict[str, typing.Optional[typing.Any]]:
        """
        REQUEST_SOURCE: VITAL-LINK
        Check link token state - can be hit continuously used as heartbeat

        Parameters
        ----------
        vital_link_token : typing.Optional[str]

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

        Returns
        -------
        typing.Dict[str, typing.Optional[typing.Any]]
            Successful Response

        Examples
        --------
        from vital import Vital

        client = Vital(
            api_key="YOUR_API_KEY",
        )
        client.link.token_state()
        """
        _response = self._client_wrapper.httpx_client.request(
            "v2/link/state",
            method="GET",
            headers={
                "x-vital-link-token": str(vital_link_token) if vital_link_token is not None else None,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    typing.Dict[str, typing.Optional[typing.Any]],
                    parse_obj_as(
                        type_=typing.Dict[str, typing.Optional[typing.Any]],  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            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 email_auth(
        self,
        *,
        email: str,
        provider: Providers,
        auth_type: AuthType,
        vital_link_token: typing.Optional[str] = None,
        region: typing.Optional[Region] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> typing.Optional[typing.Any]:
        """
        Deprecated. Use `POST /v2/link/provider/email/{provider}` instead.

        Parameters
        ----------
        email : str

        provider : Providers

        auth_type : AuthType

        vital_link_token : typing.Optional[str]

        region : typing.Optional[Region]

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

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

        Examples
        --------
        from vital import AuthType, Providers, Vital

        client = Vital(
            api_key="YOUR_API_KEY",
        )
        client.link.email_auth(
            email="email",
            provider=Providers.OURA,
            auth_type=AuthType.PASSWORD,
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            "v2/link/auth/email",
            method="POST",
            json={
                "email": email,
                "provider": provider,
                "auth_type": auth_type,
                "region": region,
            },
            headers={
                "x-vital-link-token": str(vital_link_token) if vital_link_token is not None else None,
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    typing.Optional[typing.Any],
                    parse_obj_as(
                        type_=typing.Optional[typing.Any],  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            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 password_auth(
        self,
        *,
        username: str,
        password: str,
        provider: Providers,
        auth_type: AuthType,
        vital_link_token: typing.Optional[str] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> typing.Optional[typing.Any]:
        """
        Deprecated. Use `POST /v2/link/provider/password/{provider}` instead.

        Parameters
        ----------
        username : str

        password : str

        provider : Providers

        auth_type : AuthType

        vital_link_token : typing.Optional[str]

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

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

        Examples
        --------
        from vital import AuthType, Providers, Vital

        client = Vital(
            api_key="YOUR_API_KEY",
        )
        client.link.password_auth(
            username="username",
            password="password",
            provider=Providers.OURA,
            auth_type=AuthType.PASSWORD,
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            "v2/link/auth",
            method="POST",
            json={
                "username": username,
                "password": password,
                "provider": provider,
                "auth_type": auth_type,
            },
            headers={
                "x-vital-link-token": str(vital_link_token) if vital_link_token is not None else None,
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    typing.Optional[typing.Any],
                    parse_obj_as(
                        type_=typing.Optional[typing.Any],  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            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 generate_oauth_link(
        self,
        oauth_provider: OAuthProviders,
        *,
        vital_link_token: typing.Optional[str] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> Source:
        """
        This endpoint generates an OAuth link for oauth provider

        Parameters
        ----------
        oauth_provider : OAuthProviders

        vital_link_token : typing.Optional[str]

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

        Returns
        -------
        Source
            Successful Response

        Examples
        --------
        from vital import OAuthProviders, Vital

        client = Vital(
            api_key="YOUR_API_KEY",
        )
        client.link.generate_oauth_link(
            oauth_provider=OAuthProviders.OURA,
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v2/link/provider/oauth/{jsonable_encoder(oauth_provider)}",
            method="GET",
            headers={
                "x-vital-link-token": str(vital_link_token) if vital_link_token is not None else None,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    Source,
                    parse_obj_as(
                        type_=Source,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            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 connect_password_provider(
        self,
        provider: PasswordProviders,
        *,
        username: str,
        password: str,
        vital_link_token: typing.Optional[str] = None,
        region: typing.Optional[Region] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> ProviderLinkResponse:
        """
        This connects auth providers that are password based.

        Parameters
        ----------
        provider : PasswordProviders

        username : str
            Username for provider

        password : str
            Password for provider

        vital_link_token : typing.Optional[str]

        region : typing.Optional[Region]

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

        Returns
        -------
        ProviderLinkResponse
            Successful Response

        Examples
        --------
        from vital import PasswordProviders, Vital

        client = Vital(
            api_key="YOUR_API_KEY",
        )
        client.link.connect_password_provider(
            provider=PasswordProviders.WHOOP,
            username="username",
            password="password",
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v2/link/provider/password/{jsonable_encoder(provider)}",
            method="POST",
            json={
                "username": username,
                "password": password,
                "region": region,
            },
            headers={
                "x-vital-link-token": str(vital_link_token) if vital_link_token is not None else None,
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    ProviderLinkResponse,
                    parse_obj_as(
                        type_=ProviderLinkResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            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 complete_password_provider_mfa(
        self,
        provider: PasswordProviders,
        *,
        mfa_code: str,
        vital_link_token: typing.Optional[str] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> ProviderLinkResponse:
        """
        This connects auth providers that are password based.

        Parameters
        ----------
        provider : PasswordProviders

        mfa_code : str

        vital_link_token : typing.Optional[str]

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

        Returns
        -------
        ProviderLinkResponse
            Successful Response

        Examples
        --------
        from vital import PasswordProviders, Vital

        client = Vital(
            api_key="YOUR_API_KEY",
        )
        client.link.complete_password_provider_mfa(
            provider=PasswordProviders.WHOOP,
            mfa_code="mfa_code",
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v2/link/provider/password/{jsonable_encoder(provider)}/complete_mfa",
            method="POST",
            json={
                "mfa_code": mfa_code,
            },
            headers={
                "x-vital-link-token": str(vital_link_token) if vital_link_token is not None else None,
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    ProviderLinkResponse,
                    parse_obj_as(
                        type_=ProviderLinkResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            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 connect_email_auth_provider(
        self,
        *,
        email: str,
        vital_link_token: typing.Optional[str] = None,
        email_provider_auth_link_provider: typing.Optional[Providers] = OMIT,
        region: typing.Optional[Region] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> typing.Optional[typing.Any]:
        """
        This connects auth providers that are email based.

        Parameters
        ----------
        email : str

        vital_link_token : typing.Optional[str]

        email_provider_auth_link_provider : typing.Optional[Providers]

        region : typing.Optional[Region]

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

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

        Examples
        --------
        from vital import Vital

        client = Vital(
            api_key="YOUR_API_KEY",
        )
        client.link.connect_email_auth_provider(
            email="email",
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v2/link/provider/email/freestyle_libre",
            method="POST",
            json={
                "email": email,
                "provider": email_provider_auth_link_provider,
                "region": region,
            },
            headers={
                "x-vital-link-token": str(vital_link_token) if vital_link_token is not None else None,
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    typing.Optional[typing.Any],
                    parse_obj_as(
                        type_=typing.Optional[typing.Any],  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            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_all_providers(
        self, *, vital_link_token: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None
    ) -> typing.List[SourceLink]:
        """
        GET List of all available providers given the generated link token.

        Parameters
        ----------
        vital_link_token : typing.Optional[str]

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

        Returns
        -------
        typing.List[SourceLink]
            Successful Response

        Examples
        --------
        from vital import Vital

        client = Vital(
            api_key="YOUR_API_KEY",
        )
        client.link.get_all_providers()
        """
        _response = self._client_wrapper.httpx_client.request(
            "v2/link/providers",
            method="GET",
            headers={
                "x-vital-link-token": str(vital_link_token) if vital_link_token is not None else None,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    typing.List[SourceLink],
                    parse_obj_as(
                        type_=typing.List[SourceLink],  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            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 connect_manual_provider(
        self,
        provider: ManualProviders,
        *,
        user_id: str,
        provider_id: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> typing.Dict[str, bool]:
        """
        Parameters
        ----------
        provider : ManualProviders

        user_id : str

        provider_id : typing.Optional[str]

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

        Returns
        -------
        typing.Dict[str, bool]
            Successful Response

        Examples
        --------
        from vital import ManualProviders, Vital

        client = Vital(
            api_key="YOUR_API_KEY",
        )
        client.link.connect_manual_provider(
            provider=ManualProviders.BEURER_BLE,
            user_id="user_id",
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v2/link/provider/manual/{jsonable_encoder(provider)}",
            method="POST",
            json={
                "user_id": user_id,
                "provider_id": provider_id,
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    typing.Dict[str, bool],
                    parse_obj_as(
                        type_=typing.Dict[str, bool],  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            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 connect_demo_provider(
        self, *, user_id: str, provider: DemoProviders, request_options: typing.Optional[RequestOptions] = None
    ) -> DemoConnectionStatus:
        """
        POST Connect the given Vital user to a demo provider.

        Parameters
        ----------
        user_id : str
            Vital user ID

        provider : DemoProviders
            Demo provider. For more information, please check out our docs (https://docs.tryvital.io/wearables/providers/test_data)

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

        Returns
        -------
        DemoConnectionStatus
            Successful Response

        Examples
        --------
        from vital import DemoProviders, Vital

        client = Vital(
            api_key="YOUR_API_KEY",
        )
        client.link.connect_demo_provider(
            user_id="user_id",
            provider=DemoProviders.APPLE_HEALTH_KIT,
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            "v2/link/connect/demo",
            method="POST",
            json={
                "user_id": user_id,
                "provider": provider,
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    DemoConnectionStatus,
                    parse_obj_as(
                        type_=DemoConnectionStatus,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            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 AsyncLinkClient:
    def __init__(self, *, client_wrapper: AsyncClientWrapper):
        self._client_wrapper = client_wrapper

    async def bulk_import(
        self,
        *,
        provider: OAuthProviders,
        connections: typing.Sequence[ConnectionRecipe],
        request_options: typing.Optional[RequestOptions] = None,
    ) -> BulkImportConnectionsResponse:
        """
        Parameters
        ----------
        provider : OAuthProviders

        connections : typing.Sequence[ConnectionRecipe]

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

        Returns
        -------
        BulkImportConnectionsResponse
            Successful Response

        Examples
        --------
        import asyncio

        from vital import AsyncVital, ConnectionRecipe, OAuthProviders

        client = AsyncVital(
            api_key="YOUR_API_KEY",
        )


        async def main() -> None:
            await client.link.bulk_import(
                provider=OAuthProviders.OURA,
                connections=[
                    ConnectionRecipe(
                        user_id="user_id",
                        access_token="access_token",
                        refresh_token="refresh_token",
                        provider_id="provider_id",
                        expires_at=1,
                    )
                ],
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            "v2/link/bulk_import",
            method="POST",
            json={
                "provider": provider,
                "connections": connections,
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    BulkImportConnectionsResponse,
                    parse_obj_as(
                        type_=BulkImportConnectionsResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            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 bulk_trigger_historical_pull(
        self,
        *,
        user_ids: typing.Sequence[str],
        provider: OAuthProviders,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> typing.Optional[typing.Any]:
        """
        Parameters
        ----------
        user_ids : typing.Sequence[str]

        provider : OAuthProviders

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

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

        Examples
        --------
        import asyncio

        from vital import AsyncVital, OAuthProviders

        client = AsyncVital(
            api_key="YOUR_API_KEY",
        )


        async def main() -> None:
            await client.link.bulk_trigger_historical_pull(
                user_ids=["user_ids"],
                provider=OAuthProviders.OURA,
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            "v2/link/bulk_trigger_historical_pull",
            method="POST",
            json={
                "user_ids": user_ids,
                "provider": provider,
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    typing.Optional[typing.Any],
                    parse_obj_as(
                        type_=typing.Optional[typing.Any],  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            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 bulk_export(
        self,
        *,
        provider: OAuthProviders,
        user_ids: typing.Optional[typing.Sequence[str]] = OMIT,
        next_token: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> BulkExportConnectionsResponse:
        """
        Parameters
        ----------
        provider : OAuthProviders

        user_ids : typing.Optional[typing.Sequence[str]]

        next_token : typing.Optional[str]

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

        Returns
        -------
        BulkExportConnectionsResponse
            Successful Response

        Examples
        --------
        import asyncio

        from vital import AsyncVital, OAuthProviders

        client = AsyncVital(
            api_key="YOUR_API_KEY",
        )


        async def main() -> None:
            await client.link.bulk_export(
                provider=OAuthProviders.OURA,
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            "v2/link/bulk_export",
            method="POST",
            json={
                "user_ids": user_ids,
                "provider": provider,
                "next_token": next_token,
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    BulkExportConnectionsResponse,
                    parse_obj_as(
                        type_=BulkExportConnectionsResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            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 bulk_pause(
        self,
        *,
        user_ids: typing.Sequence[str],
        provider: OAuthProviders,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> typing.Optional[typing.Any]:
        """
        Parameters
        ----------
        user_ids : typing.Sequence[str]

        provider : OAuthProviders

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

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

        Examples
        --------
        import asyncio

        from vital import AsyncVital, OAuthProviders

        client = AsyncVital(
            api_key="YOUR_API_KEY",
        )


        async def main() -> None:
            await client.link.bulk_pause(
                user_ids=["user_ids"],
                provider=OAuthProviders.OURA,
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            "v2/link/bulk_pause",
            method="POST",
            json={
                "user_ids": user_ids,
                "provider": provider,
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    typing.Optional[typing.Any],
                    parse_obj_as(
                        type_=typing.Optional[typing.Any],  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            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 token(
        self,
        *,
        user_id: str,
        provider: typing.Optional[Providers] = OMIT,
        redirect_url: typing.Optional[str] = OMIT,
        filter_on_providers: typing.Optional[typing.Sequence[Providers]] = OMIT,
        on_error: typing.Optional[typing.Literal["redirect"]] = OMIT,
        on_close: typing.Optional[typing.Literal["redirect"]] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> LinkTokenExchangeResponse:
        """
        Endpoint to generate a user link token, to be used throughout the vital
        link process. The vital link token is a one time use token, that
        expires after 10 minutes. If you would like vital-link widget to launch
        with a specific provider, pass in a provider in the body. If you would
        like to redirect to a custom url after successful or error connection,
        pass in your own custom redirect_url parameter.

        Parameters
        ----------
        user_id : str
            User id returned by vital create user request. This id should be stored in your database against the user and used for all interactions with the vital api.

        provider : typing.Optional[Providers]

        redirect_url : typing.Optional[str]

        filter_on_providers : typing.Optional[typing.Sequence[Providers]]

        on_error : typing.Optional[typing.Literal["redirect"]]

        on_close : typing.Optional[typing.Literal["redirect"]]

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

        Returns
        -------
        LinkTokenExchangeResponse
            Successful Response

        Examples
        --------
        import asyncio

        from vital import AsyncVital

        client = AsyncVital(
            api_key="YOUR_API_KEY",
        )


        async def main() -> None:
            await client.link.token(
                user_id="user_id",
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            "v2/link/token",
            method="POST",
            json={
                "user_id": user_id,
                "provider": provider,
                "redirect_url": redirect_url,
                "filter_on_providers": filter_on_providers,
                "on_error": on_error,
                "on_close": on_close,
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    LinkTokenExchangeResponse,
                    parse_obj_as(
                        type_=LinkTokenExchangeResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            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 is_token_valid(
        self, *, token: str, request_options: typing.Optional[RequestOptions] = None
    ) -> typing.Dict[str, typing.Optional[typing.Any]]:
        """
        Parameters
        ----------
        token : str

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

        Returns
        -------
        typing.Dict[str, typing.Optional[typing.Any]]
            Successful Response

        Examples
        --------
        import asyncio

        from vital import AsyncVital

        client = AsyncVital(
            api_key="YOUR_API_KEY",
        )


        async def main() -> None:
            await client.link.is_token_valid(
                token="token",
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            "v2/link/token/isValid",
            method="POST",
            json={
                "token": token,
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    typing.Dict[str, typing.Optional[typing.Any]],
                    parse_obj_as(
                        type_=typing.Dict[str, typing.Optional[typing.Any]],  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            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 code_create(
        self,
        *,
        user_id: str,
        expires_at: typing.Optional[dt.datetime] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> VitalTokenCreatedResponse:
        """
        Generate a token to invite a user of Vital mobile app to your team

        Parameters
        ----------
        user_id : str

        expires_at : typing.Optional[dt.datetime]
            When the link code should expire. Defaults to server time plus 1 hour.

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

        Returns
        -------
        VitalTokenCreatedResponse
            Successful Response

        Examples
        --------
        import asyncio

        from vital import AsyncVital

        client = AsyncVital(
            api_key="YOUR_API_KEY",
        )


        async def main() -> None:
            await client.link.code_create(
                user_id="user_id",
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            "v2/link/code/create",
            method="POST",
            params={
                "user_id": user_id,
                "expires_at": serialize_datetime(expires_at) if expires_at is not None else None,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    VitalTokenCreatedResponse,
                    parse_obj_as(
                        type_=VitalTokenCreatedResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            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 start_connect(
        self, *, link_token: str, provider: Providers, request_options: typing.Optional[RequestOptions] = None
    ) -> typing.Dict[str, typing.Optional[typing.Any]]:
        """
        REQUEST_SOURCE: VITAL-LINK
        Start link token process

        Parameters
        ----------
        link_token : str

        provider : Providers

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

        Returns
        -------
        typing.Dict[str, typing.Optional[typing.Any]]
            Successful Response

        Examples
        --------
        import asyncio

        from vital import AsyncVital, Providers

        client = AsyncVital(
            api_key="YOUR_API_KEY",
        )


        async def main() -> None:
            await client.link.start_connect(
                link_token="link_token",
                provider=Providers.OURA,
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            "v2/link/start",
            method="POST",
            json={
                "link_token": link_token,
                "provider": provider,
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    typing.Dict[str, typing.Optional[typing.Any]],
                    parse_obj_as(
                        type_=typing.Dict[str, typing.Optional[typing.Any]],  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            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 token_state(
        self, *, vital_link_token: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None
    ) -> typing.Dict[str, typing.Optional[typing.Any]]:
        """
        REQUEST_SOURCE: VITAL-LINK
        Check link token state - can be hit continuously used as heartbeat

        Parameters
        ----------
        vital_link_token : typing.Optional[str]

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

        Returns
        -------
        typing.Dict[str, typing.Optional[typing.Any]]
            Successful Response

        Examples
        --------
        import asyncio

        from vital import AsyncVital

        client = AsyncVital(
            api_key="YOUR_API_KEY",
        )


        async def main() -> None:
            await client.link.token_state()


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            "v2/link/state",
            method="GET",
            headers={
                "x-vital-link-token": str(vital_link_token) if vital_link_token is not None else None,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    typing.Dict[str, typing.Optional[typing.Any]],
                    parse_obj_as(
                        type_=typing.Dict[str, typing.Optional[typing.Any]],  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            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 email_auth(
        self,
        *,
        email: str,
        provider: Providers,
        auth_type: AuthType,
        vital_link_token: typing.Optional[str] = None,
        region: typing.Optional[Region] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> typing.Optional[typing.Any]:
        """
        Deprecated. Use `POST /v2/link/provider/email/{provider}` instead.

        Parameters
        ----------
        email : str

        provider : Providers

        auth_type : AuthType

        vital_link_token : typing.Optional[str]

        region : typing.Optional[Region]

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

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

        Examples
        --------
        import asyncio

        from vital import AsyncVital, AuthType, Providers

        client = AsyncVital(
            api_key="YOUR_API_KEY",
        )


        async def main() -> None:
            await client.link.email_auth(
                email="email",
                provider=Providers.OURA,
                auth_type=AuthType.PASSWORD,
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            "v2/link/auth/email",
            method="POST",
            json={
                "email": email,
                "provider": provider,
                "auth_type": auth_type,
                "region": region,
            },
            headers={
                "x-vital-link-token": str(vital_link_token) if vital_link_token is not None else None,
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    typing.Optional[typing.Any],
                    parse_obj_as(
                        type_=typing.Optional[typing.Any],  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            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 password_auth(
        self,
        *,
        username: str,
        password: str,
        provider: Providers,
        auth_type: AuthType,
        vital_link_token: typing.Optional[str] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> typing.Optional[typing.Any]:
        """
        Deprecated. Use `POST /v2/link/provider/password/{provider}` instead.

        Parameters
        ----------
        username : str

        password : str

        provider : Providers

        auth_type : AuthType

        vital_link_token : typing.Optional[str]

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

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

        Examples
        --------
        import asyncio

        from vital import AsyncVital, AuthType, Providers

        client = AsyncVital(
            api_key="YOUR_API_KEY",
        )


        async def main() -> None:
            await client.link.password_auth(
                username="username",
                password="password",
                provider=Providers.OURA,
                auth_type=AuthType.PASSWORD,
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            "v2/link/auth",
            method="POST",
            json={
                "username": username,
                "password": password,
                "provider": provider,
                "auth_type": auth_type,
            },
            headers={
                "x-vital-link-token": str(vital_link_token) if vital_link_token is not None else None,
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    typing.Optional[typing.Any],
                    parse_obj_as(
                        type_=typing.Optional[typing.Any],  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            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 generate_oauth_link(
        self,
        oauth_provider: OAuthProviders,
        *,
        vital_link_token: typing.Optional[str] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> Source:
        """
        This endpoint generates an OAuth link for oauth provider

        Parameters
        ----------
        oauth_provider : OAuthProviders

        vital_link_token : typing.Optional[str]

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

        Returns
        -------
        Source
            Successful Response

        Examples
        --------
        import asyncio

        from vital import AsyncVital, OAuthProviders

        client = AsyncVital(
            api_key="YOUR_API_KEY",
        )


        async def main() -> None:
            await client.link.generate_oauth_link(
                oauth_provider=OAuthProviders.OURA,
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v2/link/provider/oauth/{jsonable_encoder(oauth_provider)}",
            method="GET",
            headers={
                "x-vital-link-token": str(vital_link_token) if vital_link_token is not None else None,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    Source,
                    parse_obj_as(
                        type_=Source,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            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 connect_password_provider(
        self,
        provider: PasswordProviders,
        *,
        username: str,
        password: str,
        vital_link_token: typing.Optional[str] = None,
        region: typing.Optional[Region] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> ProviderLinkResponse:
        """
        This connects auth providers that are password based.

        Parameters
        ----------
        provider : PasswordProviders

        username : str
            Username for provider

        password : str
            Password for provider

        vital_link_token : typing.Optional[str]

        region : typing.Optional[Region]

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

        Returns
        -------
        ProviderLinkResponse
            Successful Response

        Examples
        --------
        import asyncio

        from vital import AsyncVital, PasswordProviders

        client = AsyncVital(
            api_key="YOUR_API_KEY",
        )


        async def main() -> None:
            await client.link.connect_password_provider(
                provider=PasswordProviders.WHOOP,
                username="username",
                password="password",
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v2/link/provider/password/{jsonable_encoder(provider)}",
            method="POST",
            json={
                "username": username,
                "password": password,
                "region": region,
            },
            headers={
                "x-vital-link-token": str(vital_link_token) if vital_link_token is not None else None,
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    ProviderLinkResponse,
                    parse_obj_as(
                        type_=ProviderLinkResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            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 complete_password_provider_mfa(
        self,
        provider: PasswordProviders,
        *,
        mfa_code: str,
        vital_link_token: typing.Optional[str] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> ProviderLinkResponse:
        """
        This connects auth providers that are password based.

        Parameters
        ----------
        provider : PasswordProviders

        mfa_code : str

        vital_link_token : typing.Optional[str]

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

        Returns
        -------
        ProviderLinkResponse
            Successful Response

        Examples
        --------
        import asyncio

        from vital import AsyncVital, PasswordProviders

        client = AsyncVital(
            api_key="YOUR_API_KEY",
        )


        async def main() -> None:
            await client.link.complete_password_provider_mfa(
                provider=PasswordProviders.WHOOP,
                mfa_code="mfa_code",
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v2/link/provider/password/{jsonable_encoder(provider)}/complete_mfa",
            method="POST",
            json={
                "mfa_code": mfa_code,
            },
            headers={
                "x-vital-link-token": str(vital_link_token) if vital_link_token is not None else None,
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    ProviderLinkResponse,
                    parse_obj_as(
                        type_=ProviderLinkResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            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 connect_email_auth_provider(
        self,
        *,
        email: str,
        vital_link_token: typing.Optional[str] = None,
        email_provider_auth_link_provider: typing.Optional[Providers] = OMIT,
        region: typing.Optional[Region] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> typing.Optional[typing.Any]:
        """
        This connects auth providers that are email based.

        Parameters
        ----------
        email : str

        vital_link_token : typing.Optional[str]

        email_provider_auth_link_provider : typing.Optional[Providers]

        region : typing.Optional[Region]

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

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

        Examples
        --------
        import asyncio

        from vital import AsyncVital

        client = AsyncVital(
            api_key="YOUR_API_KEY",
        )


        async def main() -> None:
            await client.link.connect_email_auth_provider(
                email="email",
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v2/link/provider/email/freestyle_libre",
            method="POST",
            json={
                "email": email,
                "provider": email_provider_auth_link_provider,
                "region": region,
            },
            headers={
                "x-vital-link-token": str(vital_link_token) if vital_link_token is not None else None,
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    typing.Optional[typing.Any],
                    parse_obj_as(
                        type_=typing.Optional[typing.Any],  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            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_all_providers(
        self, *, vital_link_token: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None
    ) -> typing.List[SourceLink]:
        """
        GET List of all available providers given the generated link token.

        Parameters
        ----------
        vital_link_token : typing.Optional[str]

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

        Returns
        -------
        typing.List[SourceLink]
            Successful Response

        Examples
        --------
        import asyncio

        from vital import AsyncVital

        client = AsyncVital(
            api_key="YOUR_API_KEY",
        )


        async def main() -> None:
            await client.link.get_all_providers()


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            "v2/link/providers",
            method="GET",
            headers={
                "x-vital-link-token": str(vital_link_token) if vital_link_token is not None else None,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    typing.List[SourceLink],
                    parse_obj_as(
                        type_=typing.List[SourceLink],  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            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 connect_manual_provider(
        self,
        provider: ManualProviders,
        *,
        user_id: str,
        provider_id: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> typing.Dict[str, bool]:
        """
        Parameters
        ----------
        provider : ManualProviders

        user_id : str

        provider_id : typing.Optional[str]

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

        Returns
        -------
        typing.Dict[str, bool]
            Successful Response

        Examples
        --------
        import asyncio

        from vital import AsyncVital, ManualProviders

        client = AsyncVital(
            api_key="YOUR_API_KEY",
        )


        async def main() -> None:
            await client.link.connect_manual_provider(
                provider=ManualProviders.BEURER_BLE,
                user_id="user_id",
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v2/link/provider/manual/{jsonable_encoder(provider)}",
            method="POST",
            json={
                "user_id": user_id,
                "provider_id": provider_id,
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    typing.Dict[str, bool],
                    parse_obj_as(
                        type_=typing.Dict[str, bool],  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            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 connect_demo_provider(
        self, *, user_id: str, provider: DemoProviders, request_options: typing.Optional[RequestOptions] = None
    ) -> DemoConnectionStatus:
        """
        POST Connect the given Vital user to a demo provider.

        Parameters
        ----------
        user_id : str
            Vital user ID

        provider : DemoProviders
            Demo provider. For more information, please check out our docs (https://docs.tryvital.io/wearables/providers/test_data)

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

        Returns
        -------
        DemoConnectionStatus
            Successful Response

        Examples
        --------
        import asyncio

        from vital import AsyncVital, DemoProviders

        client = AsyncVital(
            api_key="YOUR_API_KEY",
        )


        async def main() -> None:
            await client.link.connect_demo_provider(
                user_id="user_id",
                provider=DemoProviders.APPLE_HEALTH_KIT,
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            "v2/link/connect/demo",
            method="POST",
            json={
                "user_id": user_id,
                "provider": provider,
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    DemoConnectionStatus,
                    parse_obj_as(
                        type_=DemoConnectionStatus,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            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)
