Module supertokens_python.recipe.accountlinking.interfaces

Expand source code
# Copyright (c) 2024, VRAI Labs and/or its affiliates. All rights reserved.
#
# This software is licensed under the Apache License, Version 2.0 (the
# "License") as published by the Apache Software Foundation.
#
# You may not use this file except in compliance with the License. You may
# obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from __future__ import annotations

from abc import ABC, abstractmethod
from typing import TYPE_CHECKING, Any, Dict, List, Union, Optional
from typing_extensions import Literal

if TYPE_CHECKING:
    from supertokens_python.types import (
        User,
        RecipeUserId,
        AccountInfo,
    )


class RecipeInterface(ABC):
    @abstractmethod
    async def get_users(
        self,
        tenant_id: str,
        time_joined_order: Literal["ASC", "DESC"],
        limit: Optional[int],
        pagination_token: Optional[str],
        include_recipe_ids: Optional[List[str]],
        query: Optional[Dict[str, str]],
        user_context: Dict[str, Any],
    ) -> GetUsersResult:
        pass

    @abstractmethod
    async def can_create_primary_user(
        self, recipe_user_id: RecipeUserId, user_context: Dict[str, Any]
    ) -> Union[
        CanCreatePrimaryUserOkResult,
        CanCreatePrimaryUserRecipeUserIdAlreadyLinkedError,
        CanCreatePrimaryUserAccountInfoAlreadyAssociatedError,
    ]:
        pass

    @abstractmethod
    async def create_primary_user(
        self, recipe_user_id: RecipeUserId, user_context: Dict[str, Any]
    ) -> Union[
        CreatePrimaryUserOkResult,
        CreatePrimaryUserRecipeUserIdAlreadyLinkedError,
        CreatePrimaryUserAccountInfoAlreadyAssociatedError,
    ]:
        pass

    @abstractmethod
    async def can_link_accounts(
        self,
        recipe_user_id: RecipeUserId,
        primary_user_id: str,
        user_context: Dict[str, Any],
    ) -> Union[
        CanLinkAccountsOkResult,
        CanLinkAccountsRecipeUserIdAlreadyLinkedError,
        CanLinkAccountsAccountInfoAlreadyAssociatedError,
        CanLinkAccountsInputUserNotPrimaryError,
    ]:
        pass

    @abstractmethod
    async def link_accounts(
        self,
        recipe_user_id: RecipeUserId,
        primary_user_id: str,
        user_context: Dict[str, Any],
    ) -> Union[
        LinkAccountsOkResult,
        LinkAccountsRecipeUserIdAlreadyLinkedError,
        LinkAccountsAccountInfoAlreadyAssociatedError,
        LinkAccountsInputUserNotPrimaryError,
    ]:
        pass

    @abstractmethod
    async def unlink_account(
        self, recipe_user_id: RecipeUserId, user_context: Dict[str, Any]
    ) -> UnlinkAccountOkResult:
        pass

    @abstractmethod
    async def get_user(
        self, user_id: str, user_context: Dict[str, Any]
    ) -> Optional[User]:
        pass

    @abstractmethod
    async def list_users_by_account_info(
        self,
        tenant_id: str,
        account_info: AccountInfo,
        do_union_of_account_info: bool,
        user_context: Dict[str, Any],
    ) -> List[User]:
        pass

    @abstractmethod
    async def delete_user(
        self,
        user_id: str,
        remove_all_linked_accounts: bool,
        user_context: Dict[str, Any],
    ) -> None:
        pass


class GetUsersResult:
    def __init__(self, users: List[User], next_pagination_token: Optional[str]):
        self.users = users
        self.next_pagination_token = next_pagination_token


class CanCreatePrimaryUserOkResult:
    def __init__(self, was_already_a_primary_user: bool):
        self.status: Literal["OK"] = "OK"
        self.was_already_a_primary_user = was_already_a_primary_user


class CanCreatePrimaryUserRecipeUserIdAlreadyLinkedError:
    def __init__(self, primary_user_id: str, description: str):
        self.status: Literal[
            "RECIPE_USER_ID_ALREADY_LINKED_WITH_PRIMARY_USER_ID_ERROR"
        ] = "RECIPE_USER_ID_ALREADY_LINKED_WITH_PRIMARY_USER_ID_ERROR"
        self.primary_user_id = primary_user_id
        self.description = description


class CanCreatePrimaryUserAccountInfoAlreadyAssociatedError:
    def __init__(self, primary_user_id: str, description: str):
        self.status: Literal[
            "ACCOUNT_INFO_ALREADY_ASSOCIATED_WITH_ANOTHER_PRIMARY_USER_ID_ERROR"
        ] = "ACCOUNT_INFO_ALREADY_ASSOCIATED_WITH_ANOTHER_PRIMARY_USER_ID_ERROR"
        self.primary_user_id = primary_user_id
        self.description = description


class CreatePrimaryUserOkResult:
    def __init__(self, user: User, was_already_a_primary_user: bool):
        self.status: Literal["OK"] = "OK"
        self.user = user
        self.was_already_a_primary_user = was_already_a_primary_user

    def to_json(self) -> Dict[str, Any]:
        return {
            "status": self.status,
            "user": self.user.to_json(),
            "wasAlreadyAPrimaryUser": self.was_already_a_primary_user,
        }


class CreatePrimaryUserRecipeUserIdAlreadyLinkedError:
    def __init__(self, primary_user_id: str, description: Optional[str] = None):
        self.status: Literal[
            "RECIPE_USER_ID_ALREADY_LINKED_WITH_PRIMARY_USER_ID_ERROR"
        ] = "RECIPE_USER_ID_ALREADY_LINKED_WITH_PRIMARY_USER_ID_ERROR"
        self.primary_user_id = primary_user_id
        self.description = description


class CreatePrimaryUserAccountInfoAlreadyAssociatedError:
    def __init__(self, primary_user_id: str, description: Optional[str] = None):
        self.status: Literal[
            "ACCOUNT_INFO_ALREADY_ASSOCIATED_WITH_ANOTHER_PRIMARY_USER_ID_ERROR"
        ] = "ACCOUNT_INFO_ALREADY_ASSOCIATED_WITH_ANOTHER_PRIMARY_USER_ID_ERROR"
        self.primary_user_id = primary_user_id
        self.description = description


class CanLinkAccountsOkResult:
    def __init__(self, accounts_already_linked: bool):
        self.status: Literal["OK"] = "OK"
        self.accounts_already_linked = accounts_already_linked


class CanLinkAccountsRecipeUserIdAlreadyLinkedError:
    def __init__(
        self, primary_user_id: Optional[str] = None, description: Optional[str] = None
    ):
        self.status: Literal[
            "RECIPE_USER_ID_ALREADY_LINKED_WITH_ANOTHER_PRIMARY_USER_ID_ERROR"
        ] = "RECIPE_USER_ID_ALREADY_LINKED_WITH_ANOTHER_PRIMARY_USER_ID_ERROR"
        self.primary_user_id = primary_user_id
        self.description = description


class CanLinkAccountsAccountInfoAlreadyAssociatedError:
    def __init__(
        self, primary_user_id: Optional[str] = None, description: Optional[str] = None
    ):
        self.status: Literal[
            "ACCOUNT_INFO_ALREADY_ASSOCIATED_WITH_ANOTHER_PRIMARY_USER_ID_ERROR"
        ] = "ACCOUNT_INFO_ALREADY_ASSOCIATED_WITH_ANOTHER_PRIMARY_USER_ID_ERROR"
        self.primary_user_id = primary_user_id
        self.description = description


class CanLinkAccountsInputUserNotPrimaryError:
    def __init__(self, description: Optional[str] = None):
        self.status: Literal["INPUT_USER_IS_NOT_A_PRIMARY_USER"] = (
            "INPUT_USER_IS_NOT_A_PRIMARY_USER"
        )
        self.description = description


class LinkAccountsOkResult:
    def __init__(self, accounts_already_linked: bool, user: User):
        self.status: Literal["OK"] = "OK"
        self.accounts_already_linked = accounts_already_linked
        self.user = user

    def to_json(self) -> Dict[str, Any]:
        return {
            "status": self.status,
            "accountsAlreadyLinked": self.accounts_already_linked,
            "user": self.user.to_json(),
        }


class LinkAccountsRecipeUserIdAlreadyLinkedError:
    def __init__(
        self,
        primary_user_id: str,
        user: User,
        description: str,
    ):
        self.status: Literal[
            "RECIPE_USER_ID_ALREADY_LINKED_WITH_ANOTHER_PRIMARY_USER_ID_ERROR"
        ] = "RECIPE_USER_ID_ALREADY_LINKED_WITH_ANOTHER_PRIMARY_USER_ID_ERROR"
        self.primary_user_id = primary_user_id
        self.user = user
        self.description = description


class LinkAccountsAccountInfoAlreadyAssociatedError:
    def __init__(
        self,
        primary_user_id: Optional[str] = None,
        description: Optional[str] = None,
    ):
        self.status: Literal[
            "ACCOUNT_INFO_ALREADY_ASSOCIATED_WITH_ANOTHER_PRIMARY_USER_ID_ERROR"
        ] = "ACCOUNT_INFO_ALREADY_ASSOCIATED_WITH_ANOTHER_PRIMARY_USER_ID_ERROR"
        self.primary_user_id = primary_user_id
        self.description = description


class LinkAccountsInputUserNotPrimaryError:
    def __init__(self):
        self.status: Literal["INPUT_USER_IS_NOT_A_PRIMARY_USER"] = (
            "INPUT_USER_IS_NOT_A_PRIMARY_USER"
        )


class UnlinkAccountOkResult:
    def __init__(self, was_recipe_user_deleted: bool, was_linked: bool):
        self.status: Literal["OK"] = "OK"
        self.was_recipe_user_deleted = was_recipe_user_deleted
        self.was_linked = was_linked

Classes

class CanCreatePrimaryUserAccountInfoAlreadyAssociatedError (primary_user_id: str, description: str)
Expand source code
class CanCreatePrimaryUserAccountInfoAlreadyAssociatedError:
    def __init__(self, primary_user_id: str, description: str):
        self.status: Literal[
            "ACCOUNT_INFO_ALREADY_ASSOCIATED_WITH_ANOTHER_PRIMARY_USER_ID_ERROR"
        ] = "ACCOUNT_INFO_ALREADY_ASSOCIATED_WITH_ANOTHER_PRIMARY_USER_ID_ERROR"
        self.primary_user_id = primary_user_id
        self.description = description
class CanCreatePrimaryUserOkResult (was_already_a_primary_user: bool)
Expand source code
class CanCreatePrimaryUserOkResult:
    def __init__(self, was_already_a_primary_user: bool):
        self.status: Literal["OK"] = "OK"
        self.was_already_a_primary_user = was_already_a_primary_user
class CanCreatePrimaryUserRecipeUserIdAlreadyLinkedError (primary_user_id: str, description: str)
Expand source code
class CanCreatePrimaryUserRecipeUserIdAlreadyLinkedError:
    def __init__(self, primary_user_id: str, description: str):
        self.status: Literal[
            "RECIPE_USER_ID_ALREADY_LINKED_WITH_PRIMARY_USER_ID_ERROR"
        ] = "RECIPE_USER_ID_ALREADY_LINKED_WITH_PRIMARY_USER_ID_ERROR"
        self.primary_user_id = primary_user_id
        self.description = description
class CanLinkAccountsAccountInfoAlreadyAssociatedError (primary_user_id: Optional[str] = None, description: Optional[str] = None)
Expand source code
class CanLinkAccountsAccountInfoAlreadyAssociatedError:
    def __init__(
        self, primary_user_id: Optional[str] = None, description: Optional[str] = None
    ):
        self.status: Literal[
            "ACCOUNT_INFO_ALREADY_ASSOCIATED_WITH_ANOTHER_PRIMARY_USER_ID_ERROR"
        ] = "ACCOUNT_INFO_ALREADY_ASSOCIATED_WITH_ANOTHER_PRIMARY_USER_ID_ERROR"
        self.primary_user_id = primary_user_id
        self.description = description
class CanLinkAccountsInputUserNotPrimaryError (description: Optional[str] = None)
Expand source code
class CanLinkAccountsInputUserNotPrimaryError:
    def __init__(self, description: Optional[str] = None):
        self.status: Literal["INPUT_USER_IS_NOT_A_PRIMARY_USER"] = (
            "INPUT_USER_IS_NOT_A_PRIMARY_USER"
        )
        self.description = description
class CanLinkAccountsOkResult (accounts_already_linked: bool)
Expand source code
class CanLinkAccountsOkResult:
    def __init__(self, accounts_already_linked: bool):
        self.status: Literal["OK"] = "OK"
        self.accounts_already_linked = accounts_already_linked
class CanLinkAccountsRecipeUserIdAlreadyLinkedError (primary_user_id: Optional[str] = None, description: Optional[str] = None)
Expand source code
class CanLinkAccountsRecipeUserIdAlreadyLinkedError:
    def __init__(
        self, primary_user_id: Optional[str] = None, description: Optional[str] = None
    ):
        self.status: Literal[
            "RECIPE_USER_ID_ALREADY_LINKED_WITH_ANOTHER_PRIMARY_USER_ID_ERROR"
        ] = "RECIPE_USER_ID_ALREADY_LINKED_WITH_ANOTHER_PRIMARY_USER_ID_ERROR"
        self.primary_user_id = primary_user_id
        self.description = description
class CreatePrimaryUserAccountInfoAlreadyAssociatedError (primary_user_id: str, description: Optional[str] = None)
Expand source code
class CreatePrimaryUserAccountInfoAlreadyAssociatedError:
    def __init__(self, primary_user_id: str, description: Optional[str] = None):
        self.status: Literal[
            "ACCOUNT_INFO_ALREADY_ASSOCIATED_WITH_ANOTHER_PRIMARY_USER_ID_ERROR"
        ] = "ACCOUNT_INFO_ALREADY_ASSOCIATED_WITH_ANOTHER_PRIMARY_USER_ID_ERROR"
        self.primary_user_id = primary_user_id
        self.description = description
class CreatePrimaryUserOkResult (user: User, was_already_a_primary_user: bool)
Expand source code
class CreatePrimaryUserOkResult:
    def __init__(self, user: User, was_already_a_primary_user: bool):
        self.status: Literal["OK"] = "OK"
        self.user = user
        self.was_already_a_primary_user = was_already_a_primary_user

    def to_json(self) -> Dict[str, Any]:
        return {
            "status": self.status,
            "user": self.user.to_json(),
            "wasAlreadyAPrimaryUser": self.was_already_a_primary_user,
        }

Methods

def to_json(self) ‑> Dict[str, Any]
class CreatePrimaryUserRecipeUserIdAlreadyLinkedError (primary_user_id: str, description: Optional[str] = None)
Expand source code
class CreatePrimaryUserRecipeUserIdAlreadyLinkedError:
    def __init__(self, primary_user_id: str, description: Optional[str] = None):
        self.status: Literal[
            "RECIPE_USER_ID_ALREADY_LINKED_WITH_PRIMARY_USER_ID_ERROR"
        ] = "RECIPE_USER_ID_ALREADY_LINKED_WITH_PRIMARY_USER_ID_ERROR"
        self.primary_user_id = primary_user_id
        self.description = description
class GetUsersResult (users: List[User], next_pagination_token: Optional[str])
Expand source code
class GetUsersResult:
    def __init__(self, users: List[User], next_pagination_token: Optional[str]):
        self.users = users
        self.next_pagination_token = next_pagination_token
class LinkAccountsAccountInfoAlreadyAssociatedError (primary_user_id: Optional[str] = None, description: Optional[str] = None)
Expand source code
class LinkAccountsAccountInfoAlreadyAssociatedError:
    def __init__(
        self,
        primary_user_id: Optional[str] = None,
        description: Optional[str] = None,
    ):
        self.status: Literal[
            "ACCOUNT_INFO_ALREADY_ASSOCIATED_WITH_ANOTHER_PRIMARY_USER_ID_ERROR"
        ] = "ACCOUNT_INFO_ALREADY_ASSOCIATED_WITH_ANOTHER_PRIMARY_USER_ID_ERROR"
        self.primary_user_id = primary_user_id
        self.description = description
class LinkAccountsInputUserNotPrimaryError
Expand source code
class LinkAccountsInputUserNotPrimaryError:
    def __init__(self):
        self.status: Literal["INPUT_USER_IS_NOT_A_PRIMARY_USER"] = (
            "INPUT_USER_IS_NOT_A_PRIMARY_USER"
        )
class LinkAccountsOkResult (accounts_already_linked: bool, user: User)
Expand source code
class LinkAccountsOkResult:
    def __init__(self, accounts_already_linked: bool, user: User):
        self.status: Literal["OK"] = "OK"
        self.accounts_already_linked = accounts_already_linked
        self.user = user

    def to_json(self) -> Dict[str, Any]:
        return {
            "status": self.status,
            "accountsAlreadyLinked": self.accounts_already_linked,
            "user": self.user.to_json(),
        }

Methods

def to_json(self) ‑> Dict[str, Any]
class LinkAccountsRecipeUserIdAlreadyLinkedError (primary_user_id: str, user: User, description: str)
Expand source code
class LinkAccountsRecipeUserIdAlreadyLinkedError:
    def __init__(
        self,
        primary_user_id: str,
        user: User,
        description: str,
    ):
        self.status: Literal[
            "RECIPE_USER_ID_ALREADY_LINKED_WITH_ANOTHER_PRIMARY_USER_ID_ERROR"
        ] = "RECIPE_USER_ID_ALREADY_LINKED_WITH_ANOTHER_PRIMARY_USER_ID_ERROR"
        self.primary_user_id = primary_user_id
        self.user = user
        self.description = description
class RecipeInterface

Helper class that provides a standard way to create an ABC using inheritance.

Expand source code
class RecipeInterface(ABC):
    @abstractmethod
    async def get_users(
        self,
        tenant_id: str,
        time_joined_order: Literal["ASC", "DESC"],
        limit: Optional[int],
        pagination_token: Optional[str],
        include_recipe_ids: Optional[List[str]],
        query: Optional[Dict[str, str]],
        user_context: Dict[str, Any],
    ) -> GetUsersResult:
        pass

    @abstractmethod
    async def can_create_primary_user(
        self, recipe_user_id: RecipeUserId, user_context: Dict[str, Any]
    ) -> Union[
        CanCreatePrimaryUserOkResult,
        CanCreatePrimaryUserRecipeUserIdAlreadyLinkedError,
        CanCreatePrimaryUserAccountInfoAlreadyAssociatedError,
    ]:
        pass

    @abstractmethod
    async def create_primary_user(
        self, recipe_user_id: RecipeUserId, user_context: Dict[str, Any]
    ) -> Union[
        CreatePrimaryUserOkResult,
        CreatePrimaryUserRecipeUserIdAlreadyLinkedError,
        CreatePrimaryUserAccountInfoAlreadyAssociatedError,
    ]:
        pass

    @abstractmethod
    async def can_link_accounts(
        self,
        recipe_user_id: RecipeUserId,
        primary_user_id: str,
        user_context: Dict[str, Any],
    ) -> Union[
        CanLinkAccountsOkResult,
        CanLinkAccountsRecipeUserIdAlreadyLinkedError,
        CanLinkAccountsAccountInfoAlreadyAssociatedError,
        CanLinkAccountsInputUserNotPrimaryError,
    ]:
        pass

    @abstractmethod
    async def link_accounts(
        self,
        recipe_user_id: RecipeUserId,
        primary_user_id: str,
        user_context: Dict[str, Any],
    ) -> Union[
        LinkAccountsOkResult,
        LinkAccountsRecipeUserIdAlreadyLinkedError,
        LinkAccountsAccountInfoAlreadyAssociatedError,
        LinkAccountsInputUserNotPrimaryError,
    ]:
        pass

    @abstractmethod
    async def unlink_account(
        self, recipe_user_id: RecipeUserId, user_context: Dict[str, Any]
    ) -> UnlinkAccountOkResult:
        pass

    @abstractmethod
    async def get_user(
        self, user_id: str, user_context: Dict[str, Any]
    ) -> Optional[User]:
        pass

    @abstractmethod
    async def list_users_by_account_info(
        self,
        tenant_id: str,
        account_info: AccountInfo,
        do_union_of_account_info: bool,
        user_context: Dict[str, Any],
    ) -> List[User]:
        pass

    @abstractmethod
    async def delete_user(
        self,
        user_id: str,
        remove_all_linked_accounts: bool,
        user_context: Dict[str, Any],
    ) -> None:
        pass

Ancestors

  • abc.ABC

Subclasses

Methods

async def can_create_primary_user(self, recipe_user_id: RecipeUserId, user_context: Dict[str, Any])
async def create_primary_user(self, recipe_user_id: RecipeUserId, user_context: Dict[str, Any])
async def delete_user(self, user_id: str, remove_all_linked_accounts: bool, user_context: Dict[str, Any]) ‑> None
async def get_user(self, user_id: str, user_context: Dict[str, Any])
async def get_users(self, tenant_id: str, time_joined_order: "Literal[('ASC', 'DESC')]", limit: Optional[int], pagination_token: Optional[str], include_recipe_ids: Optional[List[str]], query: Optional[Dict[str, str]], user_context: Dict[str, Any]) ‑> GetUsersResult
async def list_users_by_account_info(self, tenant_id: str, account_info: AccountInfo, do_union_of_account_info: bool, user_context: Dict[str, Any])
class UnlinkAccountOkResult (was_recipe_user_deleted: bool, was_linked: bool)
Expand source code
class UnlinkAccountOkResult:
    def __init__(self, was_recipe_user_deleted: bool, was_linked: bool):
        self.status: Literal["OK"] = "OK"
        self.was_recipe_user_deleted = was_recipe_user_deleted
        self.was_linked = was_linked