Module supertokens_python.recipe.accountlinking.types
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 typing import TYPE_CHECKING, Any, Awaitable, Callable, Dict, List, Optional, Union
from typing_extensions import Literal
from supertokens_python.recipe.accountlinking.interfaces import (
RecipeInterface,
)
from supertokens_python.recipe.session import SessionContainer
from supertokens_python.types import (
AccountInfo,
LoginMethod,
RecipeUserId,
User,
)
from supertokens_python.types.config import (
BaseConfigWithoutAPIOverride,
BaseNormalisedConfigWithoutAPIOverride,
BaseNormalisedOverrideConfigWithoutAPI,
BaseOverrideableConfig,
BaseOverrideConfigWithoutAPI,
)
if TYPE_CHECKING:
from supertokens_python.recipe.thirdparty.types import ThirdPartyInfo
from supertokens_python.recipe.webauthn.types.base import WebauthnInfo
AccountLinkingOverrideConfig = BaseOverrideConfigWithoutAPI[RecipeInterface]
NormalisedAccountLinkingOverrideConfig = BaseNormalisedOverrideConfigWithoutAPI[
RecipeInterface
]
InputOverrideConfig = AccountLinkingOverrideConfig
"""Deprecated, use `AccountLinkingOverrideConfig` instead."""
class AccountInfoWithRecipeId(AccountInfo):
def __init__(
self,
recipe_id: Literal["emailpassword", "thirdparty", "passwordless", "webauthn"],
email: Optional[str] = None,
phone_number: Optional[str] = None,
third_party: Optional[ThirdPartyInfo] = None,
webauthn: Optional[WebauthnInfo] = None,
):
super().__init__(email, phone_number, third_party, webauthn=webauthn)
self.recipe_id: Literal[
"emailpassword", "thirdparty", "passwordless", "webauthn"
] = recipe_id
def to_json(self) -> Dict[str, Any]:
return {
**super().to_json(),
"recipeId": self.recipe_id,
}
class RecipeLevelUser(AccountInfoWithRecipeId):
def __init__(
self,
tenant_ids: List[str],
time_joined: int,
recipe_id: Literal["emailpassword", "thirdparty", "passwordless", "webauthn"],
email: Optional[str] = None,
phone_number: Optional[str] = None,
third_party: Optional[ThirdPartyInfo] = None,
webauthn: Optional[WebauthnInfo] = None,
):
super().__init__(recipe_id, email, phone_number, third_party, webauthn=webauthn)
self.tenant_ids = tenant_ids
self.time_joined = time_joined
self.recipe_id: Literal[
"emailpassword", "thirdparty", "passwordless", "webauthn"
] = recipe_id
@staticmethod
def from_login_method(
login_method: LoginMethod,
) -> RecipeLevelUser:
return RecipeLevelUser(
tenant_ids=login_method.tenant_ids,
time_joined=login_method.time_joined,
recipe_id=login_method.recipe_id,
email=login_method.email,
phone_number=login_method.phone_number,
third_party=login_method.third_party,
webauthn=login_method.webauthn,
)
class AccountInfoWithRecipeIdAndUserId(AccountInfoWithRecipeId):
def __init__(
self,
recipe_user_id: Optional[RecipeUserId],
recipe_id: Literal["emailpassword", "thirdparty", "passwordless", "webauthn"],
email: Optional[str] = None,
phone_number: Optional[str] = None,
third_party: Optional[ThirdPartyInfo] = None,
webauthn: Optional[WebauthnInfo] = None,
):
super().__init__(recipe_id, email, phone_number, third_party, webauthn=webauthn)
self.recipe_user_id = recipe_user_id
@staticmethod
def from_account_info_or_login_method(
account_info: Union[AccountInfoWithRecipeId, LoginMethod],
) -> AccountInfoWithRecipeIdAndUserId:
from supertokens_python.types import (
LoginMethod as LM,
)
return AccountInfoWithRecipeIdAndUserId(
recipe_id=account_info.recipe_id,
email=account_info.email,
phone_number=account_info.phone_number,
third_party=account_info.third_party,
webauthn=account_info.webauthn,
recipe_user_id=(
account_info.recipe_user_id if isinstance(account_info, LM) else None
),
)
class ShouldNotAutomaticallyLink:
def __init__(self):
pass
class ShouldAutomaticallyLink:
def __init__(self, should_require_verification: bool):
self.should_require_verification = should_require_verification
class AccountLinkingOverrideableConfig(BaseOverrideableConfig):
"""Input config properties overrideable using the plugin config overrides"""
on_account_linked: Optional[
Callable[[User, RecipeLevelUser, Dict[str, Any]], Awaitable[None]]
] = None
should_do_automatic_account_linking: Optional[
Callable[
[
AccountInfoWithRecipeIdAndUserId,
Optional[User],
Optional[SessionContainer],
str,
Dict[str, Any],
],
Awaitable[Union[ShouldNotAutomaticallyLink, ShouldAutomaticallyLink]],
]
] = None
class AccountLinkingConfig(
AccountLinkingOverrideableConfig,
BaseConfigWithoutAPIOverride[RecipeInterface, AccountLinkingOverrideableConfig],
):
def to_overrideable_config(self) -> AccountLinkingOverrideableConfig:
"""Create a `AccountLinkingOverrideableConfig` from the current config."""
return AccountLinkingOverrideableConfig(**self.model_dump())
def from_overrideable_config(
self,
overrideable_config: AccountLinkingOverrideableConfig,
) -> "AccountLinkingConfig":
"""
Create a `AccountLinkingConfig` from a `AccountLinkingOverrideableConfig`.
Not a classmethod since it needs to be used in a dynamic context within plugins.
"""
return AccountLinkingConfig(
**overrideable_config.model_dump(),
override=self.override,
)
class NormalisedAccountLinkingConfig(
BaseNormalisedConfigWithoutAPIOverride[RecipeInterface]
):
on_account_linked: Callable[
[User, RecipeLevelUser, Dict[str, Any]], Awaitable[None]
]
should_do_automatic_account_linking: Callable[
[
AccountInfoWithRecipeIdAndUserId,
Optional[User],
Optional[SessionContainer],
str,
Dict[str, Any],
],
Awaitable[Union[ShouldNotAutomaticallyLink, ShouldAutomaticallyLink]],
]
Classes
class AccountInfoWithRecipeId (recipe_id: "Literal['emailpassword', 'thirdparty', 'passwordless', 'webauthn']", email: Optional[str] = None, phone_number: Optional[str] = None, third_party: Optional[ThirdPartyInfo] = None, webauthn: Optional[WebauthnInfo] = None)-
Expand source code
class AccountInfoWithRecipeId(AccountInfo): def __init__( self, recipe_id: Literal["emailpassword", "thirdparty", "passwordless", "webauthn"], email: Optional[str] = None, phone_number: Optional[str] = None, third_party: Optional[ThirdPartyInfo] = None, webauthn: Optional[WebauthnInfo] = None, ): super().__init__(email, phone_number, third_party, webauthn=webauthn) self.recipe_id: Literal[ "emailpassword", "thirdparty", "passwordless", "webauthn" ] = recipe_id def to_json(self) -> Dict[str, Any]: return { **super().to_json(), "recipeId": self.recipe_id, }Ancestors
Subclasses
Methods
def to_json(self) ‑> Dict[str, Any]
class AccountInfoWithRecipeIdAndUserId (recipe_user_id: Optional[RecipeUserId], recipe_id: "Literal['emailpassword', 'thirdparty', 'passwordless', 'webauthn']", email: Optional[str] = None, phone_number: Optional[str] = None, third_party: Optional[ThirdPartyInfo] = None, webauthn: Optional[WebauthnInfo] = None)-
Expand source code
class AccountInfoWithRecipeIdAndUserId(AccountInfoWithRecipeId): def __init__( self, recipe_user_id: Optional[RecipeUserId], recipe_id: Literal["emailpassword", "thirdparty", "passwordless", "webauthn"], email: Optional[str] = None, phone_number: Optional[str] = None, third_party: Optional[ThirdPartyInfo] = None, webauthn: Optional[WebauthnInfo] = None, ): super().__init__(recipe_id, email, phone_number, third_party, webauthn=webauthn) self.recipe_user_id = recipe_user_id @staticmethod def from_account_info_or_login_method( account_info: Union[AccountInfoWithRecipeId, LoginMethod], ) -> AccountInfoWithRecipeIdAndUserId: from supertokens_python.types import ( LoginMethod as LM, ) return AccountInfoWithRecipeIdAndUserId( recipe_id=account_info.recipe_id, email=account_info.email, phone_number=account_info.phone_number, third_party=account_info.third_party, webauthn=account_info.webauthn, recipe_user_id=( account_info.recipe_user_id if isinstance(account_info, LM) else None ), )Ancestors
Static methods
def from_account_info_or_login_method(account_info: Union[AccountInfoWithRecipeId, LoginMethod]) ‑> AccountInfoWithRecipeIdAndUserId
class AccountLinkingConfig (**data: Any)-
Input config properties overrideable using the plugin config overrides
Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Expand source code
class AccountLinkingConfig( AccountLinkingOverrideableConfig, BaseConfigWithoutAPIOverride[RecipeInterface, AccountLinkingOverrideableConfig], ): def to_overrideable_config(self) -> AccountLinkingOverrideableConfig: """Create a `AccountLinkingOverrideableConfig` from the current config.""" return AccountLinkingOverrideableConfig(**self.model_dump()) def from_overrideable_config( self, overrideable_config: AccountLinkingOverrideableConfig, ) -> "AccountLinkingConfig": """ Create a `AccountLinkingConfig` from a `AccountLinkingOverrideableConfig`. Not a classmethod since it needs to be used in a dynamic context within plugins. """ return AccountLinkingConfig( **overrideable_config.model_dump(), override=self.override, )Ancestors
- AccountLinkingOverrideableConfig
- BaseOverrideableConfig
- supertokens_python.types.config.BaseConfigWithoutAPIOverride[RecipeInterface, AccountLinkingOverrideableConfig]
- BaseConfigWithoutAPIOverride
- CamelCaseBaseModel
- APIResponse
- abc.ABC
- pydantic.main.BaseModel
- typing.Generic
Methods
def from_overrideable_config(self, overrideable_config: AccountLinkingOverrideableConfig) ‑> AccountLinkingConfig-
Create a
AccountLinkingConfigfrom aAccountLinkingOverrideableConfig. Not a classmethod since it needs to be used in a dynamic context within plugins. def to_overrideable_config(self) ‑> AccountLinkingOverrideableConfig-
Create a
AccountLinkingOverrideableConfigfrom the current config.
Inherited members
class AccountLinkingOverrideableConfig (**data: Any)-
Input config properties overrideable using the plugin config overrides
Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Expand source code
class AccountLinkingOverrideableConfig(BaseOverrideableConfig): """Input config properties overrideable using the plugin config overrides""" on_account_linked: Optional[ Callable[[User, RecipeLevelUser, Dict[str, Any]], Awaitable[None]] ] = None should_do_automatic_account_linking: Optional[ Callable[ [ AccountInfoWithRecipeIdAndUserId, Optional[User], Optional[SessionContainer], str, Dict[str, Any], ], Awaitable[Union[ShouldNotAutomaticallyLink, ShouldAutomaticallyLink]], ] ] = NoneAncestors
- BaseOverrideableConfig
- CamelCaseBaseModel
- APIResponse
- abc.ABC
- pydantic.main.BaseModel
Subclasses
Class variables
var on_account_linked : Optional[Callable[[User, RecipeLevelUser, Dict[str, Any]], Awaitable[None]]]-
The type of the None singleton.
var should_do_automatic_account_linking : Optional[Callable[[AccountInfoWithRecipeIdAndUserId, Optional[User], Optional[SessionContainer], str, Dict[str, Any]], Awaitable[Union[ShouldNotAutomaticallyLink, ShouldAutomaticallyLink]]]]-
The type of the None singleton.
Inherited members
class InputOverrideConfig (**data: Any)-
Base class for input override config without API overrides.
Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- BaseOverrideConfigWithoutAPI
- CamelCaseBaseModel
- APIResponse
- abc.ABC
- pydantic.main.BaseModel
- typing.Generic
Inherited members
class NormalisedAccountLinkingConfig (**data: Any)-
Base class for normalized config of a Recipe without API overrides.
Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Expand source code
class NormalisedAccountLinkingConfig( BaseNormalisedConfigWithoutAPIOverride[RecipeInterface] ): on_account_linked: Callable[ [User, RecipeLevelUser, Dict[str, Any]], Awaitable[None] ] should_do_automatic_account_linking: Callable[ [ AccountInfoWithRecipeIdAndUserId, Optional[User], Optional[SessionContainer], str, Dict[str, Any], ], Awaitable[Union[ShouldNotAutomaticallyLink, ShouldAutomaticallyLink]], ]Ancestors
- supertokens_python.types.config.BaseNormalisedConfigWithoutAPIOverride[RecipeInterface]
- BaseNormalisedConfigWithoutAPIOverride
- CamelCaseBaseModel
- APIResponse
- abc.ABC
- pydantic.main.BaseModel
- typing.Generic
Class variables
var on_account_linked : Callable[[User, RecipeLevelUser, Dict[str, Any]], Awaitable[None]]-
The type of the None singleton.
var should_do_automatic_account_linking : Callable[[AccountInfoWithRecipeIdAndUserId, Optional[User], Optional[SessionContainer], str, Dict[str, Any]], Awaitable[Union[ShouldNotAutomaticallyLink, ShouldAutomaticallyLink]]]-
The type of the None singleton.
Inherited members
class RecipeLevelUser (tenant_ids: List[str], time_joined: int, recipe_id: "Literal['emailpassword', 'thirdparty', 'passwordless', 'webauthn']", email: Optional[str] = None, phone_number: Optional[str] = None, third_party: Optional[ThirdPartyInfo] = None, webauthn: Optional[WebauthnInfo] = None)-
Expand source code
class RecipeLevelUser(AccountInfoWithRecipeId): def __init__( self, tenant_ids: List[str], time_joined: int, recipe_id: Literal["emailpassword", "thirdparty", "passwordless", "webauthn"], email: Optional[str] = None, phone_number: Optional[str] = None, third_party: Optional[ThirdPartyInfo] = None, webauthn: Optional[WebauthnInfo] = None, ): super().__init__(recipe_id, email, phone_number, third_party, webauthn=webauthn) self.tenant_ids = tenant_ids self.time_joined = time_joined self.recipe_id: Literal[ "emailpassword", "thirdparty", "passwordless", "webauthn" ] = recipe_id @staticmethod def from_login_method( login_method: LoginMethod, ) -> RecipeLevelUser: return RecipeLevelUser( tenant_ids=login_method.tenant_ids, time_joined=login_method.time_joined, recipe_id=login_method.recipe_id, email=login_method.email, phone_number=login_method.phone_number, third_party=login_method.third_party, webauthn=login_method.webauthn, )Ancestors
Static methods
def from_login_method(login_method: LoginMethod) ‑> RecipeLevelUser
class ShouldAutomaticallyLink (should_require_verification: bool)-
Expand source code
class ShouldAutomaticallyLink: def __init__(self, should_require_verification: bool): self.should_require_verification = should_require_verification class ShouldNotAutomaticallyLink-
Expand source code
class ShouldNotAutomaticallyLink: def __init__(self): pass