diff --git a/awesomeness.sh b/awesomeness.sh new file mode 100755 index 00000000..1e41edee --- /dev/null +++ b/awesomeness.sh @@ -0,0 +1,53 @@ +#!/bin/bash +# This feels like sliding down a warm fudge mountain; I dearly hope the github action +# we write if this works can maintain this simplicity +find codegen/specs/stytch -name "*.yml" -delete +find codegen/specs/stytch_b2b -name "*.yml" -delete + +find ../protobuf/api -name "*.yml.python" | +while read line +do + + consumerFile=`echo $line | sed 's|.*/\([^.]*\).yml.python$|codegen/specs/stytch/\1.yml|'` + b2bFile=`echo $line | sed 's|.*/\([^.]*\).yml.python$|codegen/specs/stytch_b2b/\1.yml|'` + + # filter for the appropriate methods then put them in the appropriate spec folder + cat $line | yq -y '.methods=[.methods[] | + select(.vertical == "CONSUMER") | + select(.include_in_backend_sdk_codegen == true) | + del(.vertical) | + del(.include_in_backend_sdk_codegen)]' | + sed 's/methods: \[\]/methods: /' > $consumerFile + + cat $line | yq -y '.methods=[.methods[] | + select(.vertical == "B2B") | + select(.include_in_backend_sdk_codegen == true) | + del(.vertical) | + del(.include_in_backend_sdk_codegen)]' | + sed 's/methods: \[\]/methods: /' > $b2bFile + + # then we have to tack the ALL vertical methods onto both files + cat $line | yq -y '[.methods[] | + select(.vertical == "ALL") | + select(.include_in_backend_sdk_codegen == true) | + del(.vertical) | + del(.include_in_backend_sdk_codegen)]' | + sed 's/^/ /' | + grep -v "^ *\[\] *$" >> $consumerFile + + cat $line | yq -y '[.methods[] | + select(.vertical == "ALL") | + select(.include_in_backend_sdk_codegen == true) | + del(.vertical) | + del(.include_in_backend_sdk_codegen)]' | + sed 's/^/ /' | + grep -v "^ *\[\] *$" >> $b2bFile + + +done + +# delete any files that are only 2 lines because they're just a classname and +# a null methods entry +find . -name "*.yml" | xargs wc -l | awk '/^ *2 / {print $2}' | xargs rm + +./bin/generate-api.sh diff --git a/bin/generate-api.sh b/bin/generate-api.sh index 57eab3ec..bdce64c1 100755 --- a/bin/generate-api.sh +++ b/bin/generate-api.sh @@ -1,7 +1,8 @@ #!/usr/bin/env bash -SCRIPT_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &>/dev/null && pwd) +SCRIPT_DIR=`echo "$0" | sed 's|[^/]*$||'` cd "$SCRIPT_DIR/.." || exit 1 -python -m codegen.generate codegen/specs/stytch/ stytch/api stytch/models --docs_dir=codegen/specs/stytch/docs -python -m codegen.generate codegen/specs/stytch_b2b/ stytch/b2b/api stytch/b2b/models --docs_dir=codegen/specs/stytch_b2b/docs + +python3 -m codegen.generate codegen/specs/stytch/ stytch/api stytch/models --docs_dir=codegen/specs/stytch/docs +python3 -m codegen.generate codegen/specs/stytch_b2b/ stytch/b2b/api stytch/b2b/models --docs_dir=codegen/specs/stytch_b2b/docs diff --git a/codegen/specs/stytch/crypto_wallets.yml b/codegen/specs/stytch/crypto_wallet.yml similarity index 78% rename from codegen/specs/stytch/crypto_wallets.yml rename to codegen/specs/stytch/crypto_wallet.yml index f6726845..793ed705 100644 --- a/codegen/specs/stytch/crypto_wallets.yml +++ b/codegen/specs/stytch/crypto_wallet.yml @@ -1,13 +1,11 @@ -classname: CryptoWallets +classname: CryptoWalletService methods: - - name: authenticate_start - api_path: authenticate/start - method: POST + - name: CryptoWalletsAuthenticateStart args: - - name: crypto_wallet_address - arg_type: str - name: crypto_wallet_type arg_type: str + - name: crypto_wallet_address + arg_type: str - name: user_id arg_type: Optional[str] = None - name: session_token @@ -15,29 +13,34 @@ methods: - name: session_jwt arg_type: Optional[str] = None response_type: + request_id: str user_id: str challenge: str user_created: bool - - name: authenticate - method: POST + method: post + api_path: /v1/crypto_wallets/authenticate/start + - name: CryptoWalletsAuthenticate args: - - name: crypto_wallet_address - arg_type: str - name: crypto_wallet_type arg_type: str + - name: crypto_wallet_address + arg_type: str - name: signature arg_type: str - name: session_token arg_type: Optional[str] = None - - name: session_jwt - arg_type: Optional[str] = None - name: session_duration_minutes arg_type: Optional[int] = None + - name: session_jwt + arg_type: Optional[str] = None - name: session_custom_claims arg_type: Optional[Dict[str, Any]] = None response_type: + request_id: str user_id: str - user: User - session_jwt: str session_token: str session: Optional[StytchSession] + session_jwt: str + user: User + method: post + api_path: /v1/crypto_wallets/authenticate diff --git a/codegen/specs/stytch/debug.yml b/codegen/specs/stytch/debug.yml new file mode 100644 index 00000000..92d967f0 --- /dev/null +++ b/codegen/specs/stytch/debug.yml @@ -0,0 +1,10 @@ +classname: DebugService +methods: + - name: WhoAmI + args: [] + response_type: + request_id: str + project_id: str + name: str + method: get + api_path: /v1/debug/whoami diff --git a/codegen/specs/stytch/magic.yml b/codegen/specs/stytch/magic.yml new file mode 100644 index 00000000..48c9c852 --- /dev/null +++ b/codegen/specs/stytch/magic.yml @@ -0,0 +1,280 @@ +classname: MagicService +methods: + - name: SendMagicByEmail + args: + - name: email + arg_type: str + - name: magic_link_url + arg_type: Optional[str] = None + - name: expiration_minutes + arg_type: Optional[int] = None + - name: login_template_id + arg_type: Optional[str] = None + - name: attributes + arg_type: Optional[Dict[str, str]] = None + - name: login_magic_link_url + arg_type: str + - name: signup_magic_link_url + arg_type: str + - name: login_expiration_minutes + arg_type: Optional[int] = None + - name: signup_expiration_minutes + arg_type: Optional[int] = None + - name: code_challenge + arg_type: Optional[str] = None + - name: user_id + arg_type: str + - name: session_token + arg_type: Optional[str] = None + - name: session_jwt + arg_type: Optional[str] = None + - name: locale + arg_type: Optional[str] = None + - name: signup_template_id + arg_type: Optional[str] = None + response_type: + request_id: str + user_id: str + email_id: str + method: post + api_path: /v1/magic_links/send_by_email + - name: MagicLinksEmailSend + args: + - name: email + arg_type: str + - name: magic_link_url + arg_type: Optional[str] = None + - name: expiration_minutes + arg_type: Optional[int] = None + - name: login_template_id + arg_type: Optional[str] = None + - name: attributes + arg_type: Optional[Dict[str, str]] = None + - name: login_magic_link_url + arg_type: str + - name: signup_magic_link_url + arg_type: str + - name: login_expiration_minutes + arg_type: Optional[int] = None + - name: signup_expiration_minutes + arg_type: Optional[int] = None + - name: code_challenge + arg_type: Optional[str] = None + - name: user_id + arg_type: str + - name: session_token + arg_type: Optional[str] = None + - name: session_jwt + arg_type: Optional[str] = None + - name: locale + arg_type: Optional[str] = None + - name: signup_template_id + arg_type: Optional[str] = None + response_type: + request_id: str + user_id: str + email_id: str + method: post + api_path: /v1/magic_links/email/send + - name: AuthenticateMagic + args: + - name: token + arg_type: str + - name: attributes + arg_type: Optional[Dict[str, str]] = None + - name: options + arg_type: Optional[Dict[str, str]] = None + - name: session_token + arg_type: Optional[str] = None + - name: session_duration_minutes + arg_type: Optional[int] = None + - name: session_jwt + arg_type: Optional[str] = None + - name: session_custom_claims + arg_type: Optional[Dict[str, Any]] = None + - name: code_verifier + arg_type: Optional[str] = None + response_type: + request_id: str + user_id: str + method_id: str + session_token: str + session: Optional[StytchSession] + session_jwt: str + user: User + reset_sessions: bool + method: post + api_path: /v1/magic_links/{token}/authenticate + - name: MagicLinksAuthenticate + args: + - name: token + arg_type: str + - name: attributes + arg_type: Optional[Dict[str, str]] = None + - name: options + arg_type: Optional[Dict[str, str]] = None + - name: session_token + arg_type: Optional[str] = None + - name: session_duration_minutes + arg_type: Optional[int] = None + - name: session_jwt + arg_type: Optional[str] = None + - name: session_custom_claims + arg_type: Optional[Dict[str, Any]] = None + - name: code_verifier + arg_type: Optional[str] = None + response_type: + request_id: str + user_id: str + method_id: str + session_token: str + session: Optional[StytchSession] + session_jwt: str + user: User + reset_sessions: bool + method: post + api_path: /v1/magic_links/authenticate + - name: MagicLinksEmailLoginOrCreate + args: + - name: email + arg_type: str + - name: login_magic_link_url + arg_type: str + - name: signup_magic_link_url + arg_type: str + - name: login_expiration_minutes + arg_type: Optional[int] = None + - name: signup_expiration_minutes + arg_type: Optional[int] = None + - name: login_template_id + arg_type: Optional[str] = None + - name: signup_template_id + arg_type: Optional[str] = None + - name: attributes + arg_type: Optional[Dict[str, str]] = None + - name: create_user_as_pending + arg_type: bool + - name: code_challenge + arg_type: Optional[str] = None + - name: locale + arg_type: Optional[str] = None + response_type: + request_id: str + user_id: str + email_id: str + user_created: bool + method: post + api_path: /v1/magic_links/email/login_or_create + - name: SDKMagicLinksEmailLoginOrCreate + args: + - name: public_token + arg_type: str + - name: request + arg_type: null + response_type: + request_id: str + user_id: str + email_id: str + method: post + api_path: /v1/sdk/magic_links/email/login_or_create + - name: InviteByEmail + args: + - name: email + arg_type: str + - name: magic_link_url + arg_type: Optional[str] = None + - name: expiration_minutes + arg_type: Optional[int] = None + - name: invite_template_id + arg_type: Optional[str] = None + - name: attributes + arg_type: Optional[Dict[str, str]] = None + - name: name + arg_type: null + - name: invite_magic_link_url + arg_type: str + - name: invite_expiration_minutes + arg_type: Optional[int] = None + - name: locale + arg_type: Optional[str] = None + response_type: + request_id: str + user_id: str + email_id: str + method: post + api_path: /v1/magic_links/invite_by_email + - name: MagicLinksEmailInvite + args: + - name: email + arg_type: str + - name: magic_link_url + arg_type: Optional[str] = None + - name: expiration_minutes + arg_type: Optional[int] = None + - name: invite_template_id + arg_type: Optional[str] = None + - name: attributes + arg_type: Optional[Dict[str, str]] = None + - name: name + arg_type: null + - name: invite_magic_link_url + arg_type: str + - name: invite_expiration_minutes + arg_type: Optional[int] = None + - name: locale + arg_type: Optional[str] = None + response_type: + request_id: str + user_id: str + email_id: str + method: post + api_path: /v1/magic_links/email/invite + - name: MagicLinksEmailRevokeInvite + args: + - name: email + arg_type: str + response_type: + request_id: str + method: post + api_path: /v1/magic_links/email/revoke_invite + - name: MagicLinksCreate + args: + - name: user_id + arg_type: str + - name: expiration_minutes + arg_type: Optional[int] = None + - name: attributes + arg_type: Optional[Dict[str, str]] = None + response_type: + request_id: str + user_id: str + token: str + method: post + api_path: /v1/magic_links + - name: MagicLinkRedirect + args: + - name: public_token + arg_type: str + - name: token + arg_type: str + - name: stytch_token_type + arg_type: str + response_type: + request_id: str + redirect_url: str + html_response_data: null + method: get + api_path: /v1/magic_links/redirect + - name: MagicLinksRedirectCaptcha + args: + - name: public_token + arg_type: str + - name: redirect_url + arg_type: str + - name: captcha + arg_type: str + response_type: + request_id: str + redirect_url: str + method: post + api_path: /v1/magic_links/redirect/captcha diff --git a/codegen/specs/stytch/magic_links.yml b/codegen/specs/stytch/magic_links.yml deleted file mode 100644 index 176168fd..00000000 --- a/codegen/specs/stytch/magic_links.yml +++ /dev/null @@ -1,137 +0,0 @@ -classname: MagicLinks -methods: - - name: create - use_base_path_as_api_path: True - method: POST - args: - - name: user_id - arg_type: str - - name: expiration_minutes - arg_type: Optional[int] = None - - name: attributes - arg_type: Optional[Dict[str, str]] = None - response_type: - status_code: int - request_id: str - user_id: str - token: str - - name: authenticate - method: POST - args: - - name: token - arg_type: str - - name: attributes - arg_type: Optional[Dict[str, str]] = None - - name: options - arg_type: Optional[Dict[str, str]] = None - - name: session_token - arg_type: Optional[str] = None - - name: session_jwt - arg_type: Optional[str] = None - - name: session_duration_minutes - arg_type: Optional[int] = None - - name: session_custom_claims - arg_type: Optional[Dict[str, Any]] = None - - name: code_verifier - arg_type: Optional[str] = None - response_type: - status_code: int - request_id: str - user_id: str - user: User - method_id: str - reset_sessions: bool - session_jwt: str - session_token: str - session: Optional[StytchSession] -sub_apis: - - classname: Email - additional_imports: - - from stytch.core.models import Name - sub_url: magic_links/email - filename: magic_links_email - methods: - - name: send - method: POST - args: - - name: email - arg_type: str - - name: login_magic_link_url - arg_type: Optional[str] = None - - name: signup_magic_link_url - arg_type: Optional[str] = None - - name: login_expiration_minutes - arg_type: Optional[int] = None - - name: signup_expiration_minutes - arg_type: Optional[int] = None - - name: locale - arg_type: Optional[str] = None - - name: attributes - arg_type: Optional[Dict[str, str]] = None - - name: code_challenge - arg_type: Optional[str] = None - - name: user_id - arg_type: Optional[str] = None - - name: session_token - arg_type: Optional[str] = None - - name: session_jwt - arg_type: Optional[str] = None - - name: login_template_id - arg_type: Optional[str] = None - - name: signup_template_id - arg_type: Optional[str] = None - response_type: - user_id: str - email_id: str - - name: login_or_create - method: POST - args: - - name: email - arg_type: str - - name: login_magic_link_url - arg_type: Optional[str] = None - - name: signup_magic_link_url - arg_type: Optional[str] = None - - name: login_expiration_minutes - arg_type: Optional[int] = None - - name: signup_expiration_minutes - arg_type: Optional[int] = None - - name: create_user_as_pending - arg_type: Optional[bool] = None - - name: locale - arg_type: Optional[str] = None - - name: login_template_id - arg_type: Optional[str] = None - - name: signup_template_id - arg_type: Optional[str] = None - response_type: - user_id: str - email_id: str - user_created: bool - - name: invite - method: POST - args: - - name: email - arg_type: str - - name: invite_magic_link_url - arg_type: Optional[str] = None - - name: invite_expiration_minutes - arg_type: Optional[int] = None - - name: name - arg_type: Optional[Union[Name, Dict[str, str]]] = None - map_pydantic: true - - name: locale - arg_type: Optional[str] = None - - name: attributes - arg_type: Optional[Dict[str, str]] = None - - name: invite_template_id - arg_type: Optional[str] = None - response_type: - user_id: str - email_id: str - - name: revoke_invite - method: POST - args: - - name: email - arg_type: str - response_type: {} diff --git a/codegen/specs/stytch/oauth.yml b/codegen/specs/stytch/oauth.yml index bf5958fe..347d3253 100644 --- a/codegen/specs/stytch/oauth.yml +++ b/codegen/specs/stytch/oauth.yml @@ -1,42 +1,47 @@ -classname: OAuth -filename: oauth +classname: OAuthService methods: - - name: authenticate - method: POST + - name: OAuthAttach args: - - name: token + - name: provider + arg_type: str + - name: user_id arg_type: str - name: session_token arg_type: Optional[str] = None - name: session_jwt arg_type: Optional[str] = None + response_type: + request_id: str + oauth_attach_token: str + method: post + api_path: /v1/oauth/attach + - name: OAuthAuthenticate + args: + - name: token + arg_type: str + - name: session_management_type + arg_type: Optional[str] = None + - name: session_token + arg_type: Optional[str] = None - name: session_duration_minutes arg_type: Optional[int] = None + - name: session_jwt + arg_type: Optional[str] = None - name: session_custom_claims arg_type: Optional[Dict[str, Any]] = None - name: code_verifier arg_type: Optional[str] = None response_type: + request_id: str user_id: str - user: Optional[User] - oauth_user_registration_id: str provider_subject: str - provider_type: str # TODO: Could possibly enum-ify this - provider_values: Optional[Dict[str, Any]] - reset_sessions: bool - session: Optional[OAuthSession] - session_jwt: str + provider_type: str + session: OAuthSession session_token: str - - name: attach - method: POST - args: - - name: provider - arg_type: str - - name: user_id - arg_type: Optional[str] = None - - name: session_token - arg_type: Optional[str] = None - - name: session_jwt - arg_type: Optional[str] = None - response_type: - oauth_attach_token: str + session_jwt: str + provider_values: null + user: User + reset_sessions: bool + oauth_user_registration_id: str + method: post + api_path: /v1/oauth/authenticate diff --git a/codegen/specs/stytch/otp.yml b/codegen/specs/stytch/otp.yml index f8449eca..20b54745 100644 --- a/codegen/specs/stytch/otp.yml +++ b/codegen/specs/stytch/otp.yml @@ -1,8 +1,137 @@ -classname: OTP -sub_url: otps +classname: OTPService methods: - - name: authenticate - method: POST + - name: OTPsSMSSend + args: + - name: phone_number + arg_type: str + - name: expiration_minutes + arg_type: Optional[int] = None + - name: attributes + arg_type: Optional[Dict[str, str]] = None + - name: locale + arg_type: Optional[str] = None + - name: user_id + arg_type: str + - name: session_token + arg_type: Optional[str] = None + - name: session_jwt + arg_type: Optional[str] = None + response_type: + request_id: str + user_id: str + phone_id: str + method: post + api_path: /v1/otps/sms/send + - name: OTPsSMSLoginOrCreate + args: + - name: phone_number + arg_type: str + - name: expiration_minutes + arg_type: Optional[int] = None + - name: attributes + arg_type: Optional[Dict[str, str]] = None + - name: create_user_as_pending + arg_type: bool + - name: locale + arg_type: Optional[str] = None + response_type: + request_id: str + user_id: str + phone_id: str + user_created: bool + method: post + api_path: /v1/otps/sms/login_or_create + - name: OTPsWhatsAppSend + args: + - name: phone_number + arg_type: str + - name: expiration_minutes + arg_type: Optional[int] = None + - name: attributes + arg_type: Optional[Dict[str, str]] = None + - name: locale + arg_type: Optional[str] = None + - name: user_id + arg_type: str + - name: session_token + arg_type: Optional[str] = None + - name: session_jwt + arg_type: Optional[str] = None + response_type: + request_id: str + user_id: str + phone_id: str + method: post + api_path: /v1/otps/whatsapp/send + - name: OTPsWhatsAppLoginOrCreate + args: + - name: phone_number + arg_type: str + - name: expiration_minutes + arg_type: Optional[int] = None + - name: attributes + arg_type: Optional[Dict[str, str]] = None + - name: create_user_as_pending + arg_type: bool + - name: locale + arg_type: Optional[str] = None + response_type: + request_id: str + user_id: str + phone_id: str + user_created: bool + method: post + api_path: /v1/otps/whatsapp/login_or_create + - name: OTPsEmailSend + args: + - name: email + arg_type: str + - name: expiration_minutes + arg_type: Optional[int] = None + - name: attributes + arg_type: Optional[Dict[str, str]] = None + - name: locale + arg_type: Optional[str] = None + - name: user_id + arg_type: str + - name: session_token + arg_type: Optional[str] = None + - name: session_jwt + arg_type: Optional[str] = None + - name: login_template_id + arg_type: Optional[str] = None + - name: signup_template_id + arg_type: Optional[str] = None + response_type: + request_id: str + user_id: str + email_id: str + method: post + api_path: /v1/otps/email/send + - name: OTPsEmailLoginOrCreate + args: + - name: email + arg_type: str + - name: expiration_minutes + arg_type: Optional[int] = None + - name: attributes + arg_type: Optional[Dict[str, str]] = None + - name: create_user_as_pending + arg_type: bool + - name: locale + arg_type: Optional[str] = None + - name: login_template_id + arg_type: Optional[str] = None + - name: signup_template_id + arg_type: Optional[str] = None + response_type: + request_id: str + user_id: str + email_id: str + user_created: bool + method: post + api_path: /v1/otps/email/login_or_create + - name: OTPsAuthenticate args: - name: method_id arg_type: str @@ -14,149 +143,20 @@ methods: arg_type: Optional[Dict[str, str]] = None - name: session_token arg_type: Optional[str] = None - - name: session_jwt - arg_type: Optional[str] = None - name: session_duration_minutes arg_type: Optional[int] = None + - name: session_jwt + arg_type: Optional[str] = None - name: session_custom_claims arg_type: Optional[Dict[str, Any]] = None response_type: + request_id: str user_id: str - user: User method_id: str - reset_sessions: bool - session_jwt: str session_token: str session: Optional[StytchSession] -sub_apis: - - classname: Email - sub_url: otps/email - filename: otp_email - methods: - - name: send - method: POST - args: - - name: email - arg_type: str - - name: expiration_minutes - arg_type: Optional[int] = None - - name: attributes - arg_type: Optional[Dict[str, str]] = None - - name: locale - arg_type: Optional[str] = None - - name: user_id - arg_type: Optional[str] = None - - name: session_token - arg_type: Optional[str] = None - - name: session_jwt - arg_type: Optional[str] = None - - name: login_template_id - arg_type: Optional[str] = None - - name: signup_template_id - arg_type: Optional[str] = None - response_type: - user_id: str - email_id: str - - name: login_or_create - method: POST - args: - - name: email - arg_type: str - - name: expiration_minutes - arg_type: Optional[int] = None - - name: attributes - arg_type: Optional[Dict[str, str]] = None - - name: create_user_as_pending - arg_type: bool = False - - name: locale - arg_type: Optional[str] = None - - name: login_template_id - arg_type: Optional[str] = None - - name: signup_template_id - arg_type: Optional[str] = None - response_type: - user_id: str - email_id: str - user_created: bool - - classname: SMS - sub_url: otps/sms - filename: otp_sms - methods: - - name: send - method: POST - args: - - name: phone_number - arg_type: str - - name: expiration_minutes - arg_type: Optional[int] = None - - name: attributes - arg_type: Optional[Dict[str, str]] = None - - name: locale - arg_type: Optional[str] = None - - name: user_id - arg_type: Optional[str] = None - - name: session_token - arg_type: Optional[str] = None - - name: session_jwt - arg_type: Optional[str] = None - response_type: - user_id: str - phone_id: str - - name: login_or_create - method: POST - args: - - name: phone_number - arg_type: str - - name: expiration_minutes - arg_type: Optional[int] = None - - name: attributes - arg_type: Optional[Dict[str, str]] = None - - name: create_user_as_pending - arg_type: bool = False - - name: locale - arg_type: Optional[str] = None - response_type: - user_id: str - phone_id: str - user_created: bool - - classname: Whatsapp - sub_url: otps/whatsapp - filename: otp_whatsapp - methods: - - name: send - method: POST - args: - - name: phone_number - arg_type: str - - name: expiration_minutes - arg_type: Optional[int] = None - - name: attributes - arg_type: Optional[Dict[str, str]] = None - - name: locale - arg_type: Optional[str] = None - - name: user_id - arg_type: Optional[str] = None - - name: session_token - arg_type: Optional[str] = None - - name: session_jwt - arg_type: Optional[str] = None - response_type: - user_id: str - phone_id: str - - name: login_or_create - method: POST - args: - - name: phone_number - arg_type: str - - name: expiration_minutes - arg_type: Optional[int] = None - - name: attributes - arg_type: Optional[Dict[str, str]] = None - - name: create_user_as_pending - arg_type: bool = False - - name: locale - arg_type: Optional[str] = None - response_type: - user_id: str - phone_id: str - user_created: bool + session_jwt: str + user: User + reset_sessions: bool + method: post + api_path: /v1/otps/authenticate diff --git a/codegen/specs/stytch/password.yml b/codegen/specs/stytch/password.yml new file mode 100644 index 00000000..08774280 --- /dev/null +++ b/codegen/specs/stytch/password.yml @@ -0,0 +1,194 @@ +classname: PasswordService +methods: + - name: PasswordsCreate + args: + - name: email + arg_type: str + - name: password + arg_type: str + - name: session_duration_minutes + arg_type: Optional[int] = None + - name: session_custom_claims + arg_type: Optional[Dict[str, Any]] = None + - name: trusted_metadata + arg_type: Optional[Dict[str, Any]] = None + - name: untrusted_metadata + arg_type: Optional[Dict[str, Any]] = None + - name: name + arg_type: null + response_type: + request_id: str + user_id: str + email_id: str + session_token: str + session: Optional[StytchSession] + session_jwt: str + user: User + method: post + api_path: /v1/passwords + - name: PasswordsAuthenticate + args: + - name: email + arg_type: str + - name: password + arg_type: str + - name: session_token + arg_type: Optional[str] = None + - name: session_duration_minutes + arg_type: Optional[int] = None + - name: session_jwt + arg_type: Optional[str] = None + - name: session_custom_claims + arg_type: Optional[Dict[str, Any]] = None + response_type: + request_id: str + user_id: str + session_token: str + session: Optional[StytchSession] + session_jwt: str + user: User + method: post + api_path: /v1/passwords/authenticate + - name: PasswordsEmailResetStart + args: + - name: email + arg_type: str + - name: reset_password_redirect_url + arg_type: str + - name: reset_password_expiration_minutes + arg_type: Optional[int] = None + - name: code_challenge + arg_type: Optional[str] = None + - name: attributes + arg_type: Optional[Dict[str, str]] = None + - name: login_redirect_url + arg_type: str + - name: locale + arg_type: Optional[str] = None + - name: reset_password_template_id + arg_type: Optional[str] = None + response_type: + request_id: str + user_id: str + email_id: str + method: post + api_path: /v1/passwords/email/reset/start + - name: PasswordsEmailReset + args: + - name: token + arg_type: str + - name: password + arg_type: str + - name: session_token + arg_type: Optional[str] = None + - name: session_duration_minutes + arg_type: Optional[int] = None + - name: session_jwt + arg_type: Optional[str] = None + - name: code_verifier + arg_type: Optional[str] = None + - name: session_custom_claims + arg_type: Optional[Dict[str, Any]] = None + - name: attributes + arg_type: Optional[Dict[str, str]] = None + - name: options + arg_type: Optional[Dict[str, str]] = None + response_type: + request_id: str + user_id: str + session_token: str + session: Optional[StytchSession] + session_jwt: str + user: User + method: post + api_path: /v1/passwords/email/reset + - name: PasswordsExistingPasswordReset + args: + - name: email + arg_type: str + - name: existing_password + arg_type: str + - name: new_password + arg_type: str + - name: session_token + arg_type: Optional[str] = None + - name: session_duration_minutes + arg_type: Optional[int] = None + - name: session_jwt + arg_type: Optional[str] = None + - name: session_custom_claims + arg_type: Optional[Dict[str, Any]] = None + response_type: + request_id: str + user_id: str + session_token: str + session: Optional[StytchSession] + session_jwt: str + user: User + method: post + api_path: /v1/passwords/existing_password/reset + - name: PasswordsSessionReset + args: + - name: password + arg_type: str + - name: session_token + arg_type: Optional[str] = None + - name: session_jwt + arg_type: Optional[str] = None + response_type: + request_id: str + user_id: str + session: Optional[StytchSession] + user: User + method: post + api_path: /v1/passwords/session/reset + - name: PasswordsMigrate + args: + - name: email + arg_type: str + - name: hash + arg_type: str + - name: hash_type + arg_type: str + - name: md_5_config + arg_type: null + - name: argon_2_config + arg_type: null + - name: sha_1_config + arg_type: null + - name: scrypt_config + arg_type: null + - name: first_name + arg_type: str + - name: last_name + arg_type: str + - name: trusted_metadata + arg_type: Optional[Dict[str, Any]] = None + - name: untrusted_metadata + arg_type: Optional[Dict[str, Any]] = None + - name: set_email_verified + arg_type: bool + response_type: + request_id: str + user_id: str + email_id: str + user_created: bool + user: User + method: post + api_path: /v1/passwords/migrate + - name: PasswordsStrengthCheck + args: + - name: password + arg_type: str + - name: email + arg_type: Optional[str] = None + response_type: + request_id: str + valid_password: bool + score: null + breached_password: bool + feedback: null + strength_policy: str + breach_detection_on_create: bool + method: post + api_path: /v1/passwords/strength_check diff --git a/codegen/specs/stytch/passwords.yml b/codegen/specs/stytch/passwords.yml deleted file mode 100644 index 64dc61ea..00000000 --- a/codegen/specs/stytch/passwords.yml +++ /dev/null @@ -1,177 +0,0 @@ -classname: Passwords -additional_imports: - - from stytch.core.models import Name -methods: - - name: create - method: POST - use_base_path_as_api_path: True - args: - - name: email - arg_type: str - - name: password - arg_type: str - - name: name - arg_type: Optional[Union[Name, Dict[str, str]]] = None - - name: session_duration_minutes - arg_type: Optional[int] = None - - name: session_custom_claims - arg_type: Optional[Dict[str, Any]] = None - - name: trusted_metadata - arg_type: Optional[Dict[str, Any]] = None - - name: untrusted_metadata - arg_type: Optional[Dict[str, Any]] = None - response_type: - user_id: str - email_id: str - - name: authenticate - method: POST - args: - - name: email - arg_type: str - - name: password - arg_type: str - - name: session_token - arg_type: Optional[str] = None - - name: session_jwt - arg_type: Optional[str] = None - - name: session_duration_minutes - arg_type: Optional[int] = None - - name: session_custom_claims - arg_type: Optional[Dict[str, Any]] = None - response_type: - user_id: str - user: User - session_jwt: str - session_token: str - session: Optional[StytchSession] - - name: strength_check - method: POST - args: - - name: password - arg_type: str - - name: email - arg_type: Optional[str] = None - response_type: - valid_password: bool - score: int - breached_password: bool - feedback: Dict[str, Any] - strength_policy: str - breach_detection_on_create: bool - - name: migrate - method: POST - args: - - name: email - arg_type: str - - name: hash - arg_type: str - - name: hash_type - arg_type: str - - name: md_5_config - arg_type: Optional[Dict[str, Any]] = None - - name: argon_2_config - arg_type: Optional[Dict[str, Any]] = None - - name: sha_1_config - arg_type: Optional[Dict[str, Any]] = None - - name: scrypt_config - arg_type: Optional[Dict[str, Any]] = None - - name: name - arg_type: Optional[Union[Name, Dict[str, str]]] = None - - name: trusted_metadata - arg_type: Optional[Dict[str, Any]] = None - - name: untrusted_metadata - arg_type: Optional[Dict[str, Any]] = None - response_type: - user_id: str - email_id: str - user_created: bool -sub_apis: - - classname: Email - sub_url: passwords/email - filename: passwords_email - methods: - - name: reset_start - api_path: reset/start - method: POST - args: - - name: email - arg_type: str - - name: login_redirect_url - arg_type: Optional[str] = None - - name: reset_password_redirect_url - arg_type: Optional[str] = None - - name: reset_password_expiration_minutes - arg_type: Optional[int] = None - - name: attributes - arg_type: Optional[Dict[str, str]] = None - - name: code_challenge - arg_type: Optional[str] = None - - name: locale - arg_type: Optional[str] = None - - name: reset_password_template_id - arg_type: Optional[str] = None - response_type: - user_id: str - email_id: str - - name: reset - method: POST - args: - - name: token - arg_type: str - - name: password - arg_type: str - - name: session_token - arg_type: Optional[str] = None - - name: session_jwt - arg_type: Optional[str] = None - - name: session_duration_minutes - arg_type: Optional[int] = None - - name: session_custom_claims - arg_type: Optional[Dict[str, Any]] = None - - name: attributes - arg_type: Optional[Dict[str, str]] = None - - name: options - arg_type: Optional[Dict[str, str]] = None - - name: code_verifier - arg_type: Optional[str] = None - response_type: - user_id: str - - classname: ExistingPassword - sub_url: passwords/existing_password - filename: passwords_existing_password - methods: - - name: reset - method: POST - args: - - name: email - arg_type: str - - name: existing_password - arg_type: str - - name: new_password - arg_type: str - - name: session_token - arg_type: Optional[str] = None - - name: session_jwt - arg_type: Optional[str] = None - - name: session_duration_minutes - arg_type: Optional[int] = None - - name: session_custom_claims - arg_type: Optional[Dict[str, Any]] = None - response_type: - user_id: str - - classname: Session - sub_url: passwords/session - filename: passwords_session - methods: - - name: reset - method: POST - args: - - name: password - arg_type: str - - name: session_token - arg_type: Optional[str] = None - - name: session_jwt - arg_type: Optional[str] = None - response_type: - user_id: str - session: Optional[StytchSession] diff --git a/codegen/specs/stytch/session.yml b/codegen/specs/stytch/session.yml new file mode 100644 index 00000000..4b896165 --- /dev/null +++ b/codegen/specs/stytch/session.yml @@ -0,0 +1,50 @@ +classname: SessionService +methods: + - name: SessionsGet + args: + - name: user_id + arg_type: str + response_type: + request_id: str + sessions: List[StytchSession] + method: get + api_path: /v1/sessions + - name: SessionsAuthenticate + args: + - name: session_token + arg_type: Optional[str] = None + - name: session_duration_minutes + arg_type: Optional[int] = None + - name: session_jwt + arg_type: Optional[str] = None + - name: session_custom_claims + arg_type: Optional[Dict[str, Any]] = None + response_type: + request_id: str + session: Optional[StytchSession] + session_token: str + session_jwt: str + user: User + method: post + api_path: /v1/sessions/authenticate + - name: SessionsRevoke + args: + - name: session_id + arg_type: Optional[str] = None + - name: session_token + arg_type: Optional[str] = None + - name: session_jwt + arg_type: Optional[str] = None + response_type: + request_id: str + method: post + api_path: /v1/sessions/revoke + - name: SessionsJwks + args: + - name: project_id + arg_type: str + response_type: + keys: List[Dict[str, Any]] + request_id: str + method: get + api_path: /v1/sessions/jwks/{project_id} diff --git a/codegen/specs/stytch/sessions.yml b/codegen/specs/stytch/sessions.yml deleted file mode 100644 index 63c50b08..00000000 --- a/codegen/specs/stytch/sessions.yml +++ /dev/null @@ -1,68 +0,0 @@ -classname: Sessions -additional_imports: - - import jwt - - import time - - from stytch.core.models import StytchSession, User -methods: - - name: get - use_base_path_as_api_path: True - method: GET - args: - - name: user_id - arg_type: str - response_type: - sessions: List[StytchSession] - - name: authenticate - method: POST - args: - - name: session_token - arg_type: Optional[str] = None - - name: session_jwt - arg_type: Optional[str] = None - - name: session_duration_minutes - arg_type: Optional[int] = None - - name: session_custom_claims - arg_type: Optional[Dict[str, Any]] = None - response_type: - session: StytchSession - session_jwt: str - session_token: str - # TODO(v7): Make this non-Optional and change authenticate_jwt{_local} to return StytchSession directly - user: Optional[User] - - name: authenticate_jwt - manual_implementation: true - args: - - name: session_jwt - arg_type: str - - name: max_token_age_seconds - arg_type: Optional[int] = None - - name: session_custom_claims - arg_type: Optional[Dict[str, Any]] = None - - name: authenticate_jwt_local - manual_implementation: true - args: - - name: session_jwt - arg_type: str - - name: max_token_age_seconds - arg_type: Optional[int] = None - - name: leeway - arg_type: int = 0 - - name: revoke - method: POST - args: - - name: session_id - arg_type: Optional[str] = None - - name: session_token - arg_type: Optional[str] = None - - name: session_jwt - arg_type: Optional[str] = None - response_type: {} - - name: jwks - api_path: 'f"jwks/{project_id}"' - eval_api_path: true - method: GET - args: - - name: project_id - arg_type: str - response_type: - keys: List[Dict[str, Any]] diff --git a/codegen/specs/stytch/totps.yml b/codegen/specs/stytch/totp.yml similarity index 76% rename from codegen/specs/stytch/totps.yml rename to codegen/specs/stytch/totp.yml index 70c9f60a..29308dfe 100644 --- a/codegen/specs/stytch/totps.yml +++ b/codegen/specs/stytch/totp.yml @@ -1,23 +1,22 @@ -classname: TOTPs -filename: totps +classname: TOTPService methods: - - name: create - use_base_path_as_api_path: True - method: POST + - name: TOTPsCreate args: - name: user_id arg_type: str - name: expiration_minutes arg_type: Optional[int] = None response_type: - secret: str + request_id: str totp_id: str + secret: str qr_code: str recovery_codes: List[str] + user: User user_id: str - user: Optional[User] - - name: authenticate - method: POST + method: post + api_path: /v1/totps + - name: TOTPsAuthenticate args: - name: user_id arg_type: str @@ -25,29 +24,33 @@ methods: arg_type: str - name: session_token arg_type: Optional[str] = None - - name: session_jwt - arg_type: Optional[str] = None - name: session_duration_minutes arg_type: Optional[int] = None + - name: session_jwt + arg_type: Optional[str] = None - name: session_custom_claims arg_type: Optional[Dict[str, Any]] = None response_type: + request_id: str user_id: str - user: User - totp_id: str - session_jwt: str session_token: str session: Optional[StytchSession] - - name: recovery_codes - method: POST + totp_id: str + session_jwt: str + user: User + method: post + api_path: /v1/totps/authenticate + - name: TOTPsGetRecoveryCodes args: - name: user_id arg_type: str response_type: + request_id: str user_id: str - totps: List[TOTPInstanceWithRecoveryCodes] - - name: recover - method: POST + totps: null + method: post + api_path: /v1/totps/recovery_codes + - name: TOTPsRecover args: - name: user_id arg_type: str @@ -55,16 +58,19 @@ methods: arg_type: str - name: session_token arg_type: Optional[str] = None - - name: session_jwt - arg_type: Optional[str] = None - name: session_duration_minutes arg_type: Optional[int] = None + - name: session_jwt + arg_type: Optional[str] = None - name: session_custom_claims arg_type: Optional[Dict[str, Any]] = None response_type: - user_id: str - user: User + request_id: str totp_id: str - session_jwt: str + user_id: str session_token: str session: Optional[StytchSession] + session_jwt: str + user: User + method: post + api_path: /v1/totps/recover diff --git a/codegen/specs/stytch/user.yml b/codegen/specs/stytch/user.yml new file mode 100644 index 00000000..01b0d808 --- /dev/null +++ b/codegen/specs/stytch/user.yml @@ -0,0 +1,210 @@ +classname: UserService +methods: + - name: CreateUser + args: + - name: email + arg_type: Optional[str] = None + - name: name + arg_type: null + - name: attributes + arg_type: Optional[Dict[str, str]] = None + - name: phone_number + arg_type: Optional[str] = None + - name: create_user_as_pending + arg_type: bool + - name: trusted_metadata + arg_type: Optional[Dict[str, Any]] = None + - name: untrusted_metadata + arg_type: Optional[Dict[str, Any]] = None + response_type: + request_id: str + user_id: str + email_id: str + status: str + phone_id: str + user: User + method: post + api_path: /v1/users + - name: GetPendingUsers + args: + - name: starting_after_id + arg_type: Optional[str] = None + - name: limit + arg_type: Optional[int] = None + response_type: + request_id: str + users: null + has_more: bool + next_starting_after_id: str + total: null + method: get + api_path: /v1/users/pending + - name: GetUser + args: + - name: user_id + arg_type: str + response_type: + request_id: str + user_id: str + name: null + emails: null + status: str + phone_numbers: null + birthday: null + webauthn_registrations: null + created_at: null + providers: null + totps: null + crypto_wallets: null + password: null + biometric_registrations: null + trusted_metadata: Optional[Dict[str, Any]] = None + untrusted_metadata: Optional[Dict[str, Any]] = None + project_id: str + method: get + api_path: /v1/users/{user_id} + - name: SearchUsersExternal + args: + - name: cursor + arg_type: str + - name: limit + arg_type: Optional[int] = None + - name: SearchUsersExternalQuery + arg_type: null + - name: operands + arg_type: null + response_type: + request_id: str + results: null + ResultsMetadata: null + next_cursor: Optional[str] = None + method: post + api_path: /v1/users/search + - name: UpdateUser + args: + - name: user_id + arg_type: str + - name: name + arg_type: null + - name: emails + arg_type: null + - name: attributes + arg_type: Optional[Dict[str, str]] = None + - name: phone_numbers + arg_type: null + - name: crypto_wallets + arg_type: null + - name: trusted_metadata + arg_type: Optional[Dict[str, Any]] = None + - name: untrusted_metadata + arg_type: Optional[Dict[str, Any]] = None + response_type: + request_id: str + user_id: str + emails: null + phone_numbers: null + crypto_wallets: null + user: User + method: put + api_path: /v1/users/{user_id} + - name: DeleteUser + args: + - name: user_id + arg_type: str + response_type: + request_id: str + user_id: str + method: delete + api_path: /v1/users/{user_id} + - name: GetUserByEmailAndProjectID + args: + - name: email + arg_type: str + - name: project_id + arg_type: str + response_type: + request_id: str + user_id: str + email_id: str + method: get + api_path: /v1/sdk/users + - name: DeleteUserEmail + args: + - name: email_id + arg_type: str + response_type: + request_id: str + user_id: str + user: User + method: delete + api_path: /v1/users/emails/{email_id} + - name: DeleteUserPhoneNumber + args: + - name: phone_id + arg_type: str + response_type: + request_id: str + user_id: str + user: User + method: delete + api_path: /v1/users/phone_numbers/{phone_id} + - name: DeleteUserWebAuthnRegistration + args: + - name: webauthn_registration_id + arg_type: str + response_type: + request_id: str + user_id: str + user: User + method: delete + api_path: /v1/users/webauthn_registrations/{webauthn_registration_id} + - name: DeleteUserBiometricRegistration + args: + - name: biometric_registration_id + arg_type: str + response_type: + request_id: str + user_id: str + user: User + method: delete + api_path: /v1/users/biometric_registrations/{biometric_registration_id} + - name: DeleteUserTOTP + args: + - name: totp_id + arg_type: str + response_type: + request_id: str + user_id: str + user: User + method: delete + api_path: /v1/users/totps/{totp_id} + - name: DeleteUserCryptoWallet + args: + - name: crypto_wallet_id + arg_type: str + response_type: + request_id: str + user_id: str + user: User + method: delete + api_path: /v1/users/crypto_wallets/{crypto_wallet_id} + - name: DeleteUserPassword + args: + - name: password_id + arg_type: str + response_type: + request_id: str + user_id: str + user: User + method: delete + api_path: /v1/users/passwords/{password_id} + - name: DeleteUserOAuthUserRegistration + args: + - name: oauth_user_registration_id + arg_type: str + response_type: + request_id: str + user_id: str + user: User + method: delete + api_path: /v1/users/oauth/{oauth_user_registration_id} diff --git a/codegen/specs/stytch/users.yml b/codegen/specs/stytch/users.yml deleted file mode 100644 index 9b9b2002..00000000 --- a/codegen/specs/stytch/users.yml +++ /dev/null @@ -1,193 +0,0 @@ -classname: Users -additional_imports: - - from typing import AsyncGenerator, Generator # Used for search_all - - from stytch.core.models import Name, SearchQuery -methods: - - name: create - use_base_path_as_api_path: True - method: POST - args: - - name: email - arg_type: Optional[str] = None - - name: phone_number - arg_type: Optional[str] = None - - name: name - arg_type: Optional[Union[Name, Dict[str, str]]] = None - map_pydantic: true - - name: create_user_as_pending - arg_type: bool = False - - name: attributes - arg_type: Optional[Dict[str, str]] = None - - name: trusted_metadata - arg_type: Optional[Dict[str, Any]] = None - - name: untrusted_metadata - arg_type: Optional[Dict[str, Any]] = None - response_type: - user_id: str - user: User - email_id: str - phone_id: str - status: str # TODO: Could be coerced to enum - - name: get - method: GET - api_path: user_id - eval_api_path: true - args: - - name: user_id - arg_type: str - response_type: - __extends: User - user_id: str - - name: get_pending - method: GET - api_path: pending - args: - - name: limit - arg_type: Optional[int] = None - - name: starting_after_id - arg_type: Optional[str] = None - response_type: - users: List[User] - has_more: bool - next_starting_after_id: str - total: int - - name: search - method: POST - args: - - name: limit - arg_type: Optional[int] = None - - name: cursor - arg_type: Optional[str] = None - - name: query - arg_type: Optional[Union[SearchQuery, Dict[str, Any]]] = None - map_pydantic: true - response_type: - results: List[User] - results_metadata: SearchResultsMetadata - - name: search_all - manual_implementation: true - args: - - name: limit - arg_type: Optional[int] = None - - name: cursor - arg_type: Optional[str] = None - - name: query - arg_type: Optional[Union[SearchQuery, Dict[str, Any]]] = None - map_pydantic: true - - name: delete - method: DELETE - api_path: user_id - eval_api_path: true - args: - - name: user_id - arg_type: str - response_type: - user_id: str - - name: update - method: PUT - api_path: user_id - eval_api_path: true - args: - - name: user_id - arg_type: str - - name: emails - arg_type: Optional[List[str]] = None - - name: phone_numbers - arg_type: Optional[List[str]] = None - - name: crypto_wallets - arg_type: Optional[List[str]] = None - - name: name - arg_type: Optional[Union[Name, Dict[str, str]]] = None - map_pydantic: true - - name: attributes - arg_type: Optional[Dict[str, str]] = None - - name: trusted_metadata - arg_type: Optional[Dict[str, Any]] = None - - name: untrusted_metadata - arg_type: Optional[Dict[str, Any]] = None - response_type: - user_id: str - user: User - emails: List[Email] - phone_numbers: List[PhoneNumber] - crypto_wallets: List[CryptoWallet] - - name: delete_email - method: DELETE - api_path: 'f"emails/{email_id}"' - eval_api_path: true - args: - - name: email_id - arg_type: str - response_type: - user_id: str - user: User - - name: delete_phone_number - method: DELETE - api_path: 'f"phone_numbers/{phone_id}"' - eval_api_path: true - args: - - name: phone_id - arg_type: str - response_type: - user_id: str - user: User - - name: delete_webauthn_registration - method: DELETE - api_path: 'f"webauthn_registrations/{webauthn_registration_id}"' - eval_api_path: true - args: - - name: webauthn_registration_id - arg_type: str - response_type: - user_id: str - user: User - - name: delete_totp - method: DELETE - api_path: 'f"totps/{totp_id}"' - eval_api_path: true - args: - - name: totp_id - arg_type: str - response_type: - user_id: str - user: User - - name: delete_crypto_wallet - method: DELETE - api_path: 'f"crypto_wallets/{crypto_wallet_id}"' - eval_api_path: true - args: - - name: crypto_wallet_id - arg_type: str - response_type: - user_id: str - user: User - - name: delete_password - method: DELETE - api_path: 'f"passwords/{password_id}"' - eval_api_path: true - args: - - name: password_id - arg_type: str - response_type: - user_id: str - user: User - - name: delete_biometric_registration - method: DELETE - api_path: 'f"biometric_registrations/{biometric_registration_id}"' - eval_api_path: true - args: - - name: biometric_registration_id - arg_type: str - response_type: - user_id: str - user: User - - name: delete_oauth_user_registration - method: DELETE - api_path: 'f"oauth/{oauth_user_registration_id}"' - eval_api_path: true - args: - - name: oauth_user_registration_id - arg_type: str - response_type: - user_id: str - user: User diff --git a/codegen/specs/stytch/webauthn.yml b/codegen/specs/stytch/webauthn.yml index a0ab0edc..41de7e20 100644 --- a/codegen/specs/stytch/webauthn.yml +++ b/codegen/specs/stytch/webauthn.yml @@ -1,59 +1,64 @@ -classname: WebAuthn -filename: webauthn +classname: WebAuthnService methods: - - name: register_start - api_path: register/start - method: POST + - name: WebAuthnRegisterStart args: - name: user_id arg_type: str - name: domain arg_type: str - name: user_agent - arg_type: Optional[str] = None + arg_type: str - name: authenticator_type arg_type: Optional[str] = None response_type: + request_id: str user_id: str public_key_credential_creation_options: str - - name: register - method: POST + method: post + api_path: /v1/webauthn/register/start + - name: WebAuthnRegister args: - name: user_id arg_type: str - name: public_key_credential arg_type: str response_type: + request_id: str user_id: str webauthn_registration_id: str - - name: authenticate_start - api_path: authenticate/start - method: POST + method: post + api_path: /v1/webauthn/register + - name: WebAuthnAuthenticateStart args: - name: user_id arg_type: str - name: domain arg_type: str response_type: + request_id: str user_id: str public_key_credential_request_options: str - - name: authenticate - method: POST + method: post + api_path: /v1/webauthn/authenticate/start + - name: WebAuthnAuthenticate args: - name: public_key_credential arg_type: str - name: session_token arg_type: Optional[str] = None - - name: session_jwt - arg_type: Optional[str] = None - name: session_duration_minutes arg_type: Optional[int] = None + - name: session_jwt + arg_type: Optional[str] = None - name: session_custom_claims arg_type: Optional[Dict[str, Any]] = None response_type: + request_id: str user_id: str - user: User webauthn_registration_id: str - session_jwt: str session_token: str session: Optional[StytchSession] + session_jwt: str + user: User + method: post + api_path: /v1/webauthn/authenticate diff --git a/codegen/specs/stytch_b2b/debug.yml b/codegen/specs/stytch_b2b/debug.yml new file mode 100644 index 00000000..92d967f0 --- /dev/null +++ b/codegen/specs/stytch_b2b/debug.yml @@ -0,0 +1,10 @@ +classname: DebugService +methods: + - name: WhoAmI + args: [] + response_type: + request_id: str + project_id: str + name: str + method: get + api_path: /v1/debug/whoami diff --git a/codegen/specs/stytch_b2b/discovery.yml b/codegen/specs/stytch_b2b/discovery.yml new file mode 100644 index 00000000..1eb8bf58 --- /dev/null +++ b/codegen/specs/stytch_b2b/discovery.yml @@ -0,0 +1,74 @@ +classname: DiscoveryService +methods: + - name: DiscoveryOrganizations + args: + - name: intermediate_session_token + arg_type: Optional[str] = None + - name: session_token + arg_type: Optional[str] = None + - name: session_jwt + arg_type: Optional[str] = None + response_type: + request_id: str + email_address: str + discovered_organizations: null + method: post + api_path: /v1/b2b/discovery/organizations + - name: DiscoveryIntermediateSessionExchange + args: + - name: intermediate_session_token + arg_type: str + - name: organization_id + arg_type: str + - name: session_duration_minutes + arg_type: Optional[int] = None + - name: session_custom_claims + arg_type: Optional[Dict[str, Any]] = None + response_type: + request_id: str + member_id: str + member_session: null + session_token: str + session_jwt: str + member: null + organization: null + method: post + api_path: /v1/b2b/discovery/intermediate_sessions/exchange + - name: DiscoveryOrganizationCreate + args: + - name: intermediate_session_token + arg_type: str + - name: session_duration_minutes + arg_type: Optional[int] = None + - name: session_custom_claims + arg_type: Optional[Dict[str, Any]] = None + - name: organization_name + arg_type: str + - name: organization_slug + arg_type: str + - name: organization_logo_url + arg_type: str + - name: trusted_metadata + arg_type: Optional[Dict[str, Any]] = None + - name: sso_jit_provisioning + arg_type: Optional[str] = None + - name: email_allowed_domains + arg_type: List[str] + - name: email_jit_provisioning + arg_type: Optional[str] = None + - name: email_invites + arg_type: Optional[str] = None + - name: auth_methods + arg_type: Optional[str] = None + - name: allowed_auth_methods + arg_type: List[str] + response_type: + request_id: str + member_id: str + member_session: null + session_token: str + session_jwt: str + member: null + organization: null + method: post + api_path: /v1/b2b/discovery/organizations/create diff --git a/codegen/specs/stytch_b2b/magic.yml b/codegen/specs/stytch_b2b/magic.yml new file mode 100644 index 00000000..e73893bf --- /dev/null +++ b/codegen/specs/stytch_b2b/magic.yml @@ -0,0 +1,29 @@ +classname: MagicService +methods: + - name: MagicLinkRedirect + args: + - name: public_token + arg_type: str + - name: token + arg_type: str + - name: stytch_token_type + arg_type: str + response_type: + request_id: str + redirect_url: str + html_response_data: null + method: get + api_path: /v1/magic_links/redirect + - name: MagicLinksRedirectCaptcha + args: + - name: public_token + arg_type: str + - name: redirect_url + arg_type: str + - name: captcha + arg_type: str + response_type: + request_id: str + redirect_url: str + method: post + api_path: /v1/magic_links/redirect/captcha diff --git a/codegen/specs/stytch_b2b/magic_links.yml b/codegen/specs/stytch_b2b/magic_links.yml deleted file mode 100644 index b74c76b7..00000000 --- a/codegen/specs/stytch_b2b/magic_links.yml +++ /dev/null @@ -1,82 +0,0 @@ -classname: MagicLinks -methods: - - name: authenticate - method: POST - args: - - name: magic_links_token - arg_type: str - - name: pkce_code_verifier - arg_type: Optional[str] = None - - name: session_token - arg_type: Optional[str] = None - - name: session_jwt - arg_type: Optional[str] = None - - name: session_duration_minutes - arg_type: Optional[int] = None - - name: session_custom_claims - arg_type: Optional[Dict[str, Any]] = None - response_type: - member_id: str - method_id: str - reset_sessions: bool - organization_id: str - member: Member - session_token: str - session_jwt: str - member_session: Optional[B2BStytchSession] -sub_apis: - - classname: Email - additional_imports: - - from stytch.core.b2b.models import B2BStytchSession, Member - sub_url: magic_links/email - filename: magic_links_email - methods: - - name: login_or_signup - method: POST - args: - - name: organization_id - arg_type: str - - name: email_address - arg_type: str - - name: login_redirect_url - arg_type: Optional[str] = None - - name: signup_redirect_url - arg_type: Optional[str] = None - - name: pkce_code_challenge - arg_type: Optional[str] = None - - name: login_template_id - arg_type: Optional[str] = None - - name: signup_template_id - arg_type: Optional[str] = None - - name: locale - arg_type: Optional[str] = None - response_type: - member_id: str - member_created: bool - member: Member - organization: Organization - - name: invite - method: POST - args: - - name: organization_id - arg_type: str - - name: email_address - arg_type: str - - name: invite_redirect_url - arg_type: Optional[str] = None - - name: invited_by_member_id - arg_type: Optional[str] = None - - name: name - arg_type: Optional[str] = None - - name: trusted_metadata - arg_type: Optional[Dict[str, Any]] = None - - name: untrusted_metadata - arg_type: Optional[Dict[str, Any]] = None - - name: invite_template_id - arg_type: Optional[str] = None - - name: locale - arg_type: Optional[str] = None - response_type: - member_id: str - member: Member - organization: Organization diff --git a/codegen/specs/stytch_b2b/multitenant_magic.yml b/codegen/specs/stytch_b2b/multitenant_magic.yml new file mode 100644 index 00000000..67a2e88f --- /dev/null +++ b/codegen/specs/stytch_b2b/multitenant_magic.yml @@ -0,0 +1,111 @@ +classname: MultiTenantMagicService +methods: + - name: MultiTenantMagicLinksEmailLoginOrSignup + args: + - name: organization_id + arg_type: str + - name: email_address + arg_type: str + - name: login_redirect_url + arg_type: Optional[str] = None + - name: signup_redirect_url + arg_type: Optional[str] = None + - name: pkce_code_challenge + arg_type: Optional[str] = None + - name: login_template_id + arg_type: Optional[str] = None + - name: signup_template_id + arg_type: Optional[str] = None + - name: locale + arg_type: Optional[str] = None + response_type: + request_id: str + member_id: str + member_created: bool + member: null + organization: null + method: post + api_path: /v1/b2b/magic_links/email/login_or_signup + - name: MultiTenantMagicLinksEmailInvite + args: + - name: organization_id + arg_type: str + - name: email_address + arg_type: str + - name: invite_redirect_url + arg_type: Optional[str] = None + - name: invited_by_member_id + arg_type: Optional[str] = None + - name: name + arg_type: Optional[str] = None + - name: trusted_metadata + arg_type: Optional[Dict[str, Any]] = None + - name: untrusted_metadata + arg_type: Optional[Dict[str, Any]] = None + - name: invite_template_id + arg_type: Optional[str] = None + - name: locale + arg_type: Optional[str] = None + response_type: + request_id: str + member_id: str + member: null + organization: null + method: post + api_path: /v1/b2b/magic_links/email/invite + - name: MultiTenantMagicLinksAuthenticate + args: + - name: magic_links_token + arg_type: str + - name: pkce_code_verifier + arg_type: Optional[str] = None + - name: session_token + arg_type: Optional[str] = None + - name: session_jwt + arg_type: Optional[str] = None + - name: session_duration_minutes + arg_type: Optional[int] = None + - name: session_custom_claims + arg_type: Optional[Dict[str, Any]] = None + response_type: + request_id: str + member_id: str + method_id: str + reset_sessions: bool + organization_id: str + member: null + session_token: str + session_jwt: str + member_session: null + organization: null + method: post + api_path: /v1/b2b/magic_links/authenticate + - name: B2BMagicLinksEmailDiscoverySend + args: + - name: email_address + arg_type: str + - name: discovery_redirect_url + arg_type: Optional[str] = None + - name: pkce_code_challenge + arg_type: Optional[str] = None + - name: login_template_id + arg_type: Optional[str] = None + - name: locale + arg_type: Optional[str] = None + response_type: + request_id: str + method: post + api_path: /v1/b2b/magic_links/email/discovery/send + - name: B2BMagicLinksDiscoveryAuthenticate + args: + - name: discovery_magic_links_token + arg_type: str + - name: pkce_code_verifier + arg_type: Optional[str] = None + response_type: + request_id: str + intermediate_session_token: str + email_address: str + discovered_organizations: null + method: post + api_path: /v1/b2b/magic_links/discovery/authenticate diff --git a/codegen/specs/stytch_b2b/multitenant_password.yml b/codegen/specs/stytch_b2b/multitenant_password.yml new file mode 100644 index 00000000..f078aee0 --- /dev/null +++ b/codegen/specs/stytch_b2b/multitenant_password.yml @@ -0,0 +1,176 @@ +classname: MultiTenantPasswordService +methods: + - name: MultiTenantPasswordStrengthCheck + args: + - name: password + arg_type: str + - name: email_address + arg_type: Optional[str] = None + response_type: + request_id: str + valid_password: bool + score: null + breached_password: bool + luds_feedback: null + strength_policy: str + breach_detection_on_create: bool + zxcvbn_feedback: null + method: post + api_path: /v1/b2b/passwords/strength_check + - name: MultiTenantPasswordMigrate + args: + - name: email_address + arg_type: str + - name: hash + arg_type: str + - name: hash_type + arg_type: str + - name: md_5_config + arg_type: null + - name: argon_2_config + arg_type: null + - name: sha_1_config + arg_type: null + - name: scrypt_config + arg_type: null + - name: organization_id + arg_type: str + - name: name + arg_type: str + - name: trusted_metadata + arg_type: Optional[Dict[str, Any]] = None + - name: untrusted_metadata + arg_type: Optional[Dict[str, Any]] = None + response_type: + request_id: str + member_id: str + member_created: bool + member: null + organization: null + method: post + api_path: /v1/b2b/passwords/migrate + - name: MultiTenantPasswordAuthenticate + args: + - name: organization_id + arg_type: str + - name: email_address + arg_type: str + - name: password + arg_type: str + - name: session_token + arg_type: Optional[str] = None + - name: session_duration_minutes + arg_type: Optional[int] = None + - name: session_jwt + arg_type: Optional[str] = None + - name: session_custom_claims + arg_type: Optional[Dict[str, Any]] = None + response_type: + request_id: str + member_id: str + organization_id: str + member: null + session_token: str + session_jwt: str + member_session: null + organization: null + method: post + api_path: /v1/b2b/passwords/authenticate + - name: MultiTenantPasswordEmailResetStart + args: + - name: organization_id + arg_type: str + - name: email_address + arg_type: str + - name: reset_password_redirect_url + arg_type: str + - name: reset_password_expiration_minutes + arg_type: Optional[int] = None + - name: code_challenge + arg_type: Optional[str] = None + - name: login_redirect_url + arg_type: str + - name: locale + arg_type: Optional[str] = None + - name: reset_password_template_id + arg_type: Optional[str] = None + response_type: + request_id: str + member_id: str + member_email_id: str + method: post + api_path: /v1/b2b/passwords/email/reset/start + - name: MultiTenantPasswordEmailReset + args: + - name: password_reset_token + arg_type: str + - name: password + arg_type: str + - name: session_token + arg_type: Optional[str] = None + - name: session_duration_minutes + arg_type: Optional[int] = None + - name: session_jwt + arg_type: Optional[str] = None + - name: code_verifier + arg_type: Optional[str] = None + - name: session_custom_claims + arg_type: Optional[Dict[str, Any]] = None + response_type: + request_id: str + member_id: str + member_email_id: str + organization_id: str + member: null + session_token: str + session_jwt: str + member_session: null + organization: null + method: post + api_path: /v1/b2b/passwords/email/reset + - name: MultiTenantPasswordSessionReset + args: + - name: organization_id + arg_type: str + - name: password + arg_type: str + - name: session_token + arg_type: Optional[str] = None + - name: session_jwt + arg_type: Optional[str] = None + response_type: + request_id: str + member_id: str + member_session: null + member: null + organization: null + method: post + api_path: /v1/b2b/passwords/session/reset + - name: MultiTenantPasswordExistingPasswordReset + args: + - name: email_address + arg_type: str + - name: existing_password + arg_type: str + - name: new_password + arg_type: str + - name: session_token + arg_type: Optional[str] = None + - name: session_duration_minutes + arg_type: Optional[int] = None + - name: session_jwt + arg_type: Optional[str] = None + - name: session_custom_claims + arg_type: Optional[Dict[str, Any]] = None + - name: organization_id + arg_type: str + response_type: + request_id: str + member_id: str + member_session: null + member: null + session_token: str + session_jwt: str + organization: null + method: post + api_path: /v1/b2b/passwords/existing_password/reset diff --git a/codegen/specs/stytch_b2b/multitenant_session.yml b/codegen/specs/stytch_b2b/multitenant_session.yml new file mode 100644 index 00000000..97d0569a --- /dev/null +++ b/codegen/specs/stytch_b2b/multitenant_session.yml @@ -0,0 +1,68 @@ +classname: MultiTenantSessionService +methods: + - name: MultiTenantSessionsGet + args: + - name: organization_id + arg_type: str + - name: member_id + arg_type: str + response_type: + request_id: str + member_sessions: null + method: get + api_path: /v1/b2b/sessions + - name: MultiTenantSessionsAuthenticate + args: + - name: session_token + arg_type: Optional[str] = None + - name: session_duration_minutes + arg_type: Optional[int] = None + - name: session_jwt + arg_type: Optional[str] = None + - name: session_custom_claims + arg_type: Optional[Dict[str, Any]] = None + response_type: + request_id: str + member_session: null + session_token: str + session_jwt: str + member: null + organization: null + method: post + api_path: /v1/b2b/sessions/authenticate + - name: MultiTenantSessionsRevoke + args: + - name: member_session_id + arg_type: Optional[str] = None + - name: session_token + arg_type: Optional[str] = None + - name: session_jwt + arg_type: Optional[str] = None + - name: member_id + arg_type: Optional[str] = None + response_type: + request_id: str + method: post + api_path: /v1/b2b/sessions/revoke + - name: MultiTenantSessionsExchange + args: + - name: organization_id + arg_type: str + - name: session_token + arg_type: Optional[str] = None + - name: session_jwt + arg_type: Optional[str] = None + - name: session_duration_minutes + arg_type: Optional[int] = None + - name: session_custom_claims + arg_type: Optional[Dict[str, Any]] = None + response_type: + request_id: str + member_id: str + member_session: null + session_token: str + session_jwt: str + member: null + organization: null + method: post + api_path: /v1/b2b/sessions/exchange diff --git a/codegen/specs/stytch_b2b/organizations.yml b/codegen/specs/stytch_b2b/organization.yml similarity index 65% rename from codegen/specs/stytch_b2b/organizations.yml rename to codegen/specs/stytch_b2b/organization.yml index cb976806..da32f26b 100644 --- a/codegen/specs/stytch_b2b/organizations.yml +++ b/codegen/specs/stytch_b2b/organization.yml @@ -1,47 +1,42 @@ -classname: Organizations -additional_imports: - - from stytch.core.models import SearchQuery, SearchResultsMetadata - - from stytch.core.b2b.models import Member, Organization +classname: OrganizationService methods: - - name: create - use_base_path_as_api_path: True - method: POST + - name: OrganizationsCreate args: - name: organization_name arg_type: str - name: organization_slug arg_type: str - name: organization_logo_url - arg_type: Optional[str] = None + arg_type: str - name: trusted_metadata arg_type: Optional[Dict[str, Any]] = None + - name: sso_jit_provisioning + arg_type: Optional[str] = None + - name: email_allowed_domains + arg_type: List[str] - name: email_jit_provisioning arg_type: Optional[str] = None - name: email_invites arg_type: Optional[str] = None - - name: email_allowed_domains - arg_type: Optional[List[str]] = None - - name: sso_jit_provisioning - arg_type: Optional[str] = None - name: auth_methods arg_type: Optional[str] = None - name: allowed_auth_methods - arg_type: Optional[List[str]] = None + arg_type: List[str] response_type: + request_id: str organization: Organization - - name: get - api_path: organization_id - eval_api_path: true - method: GET + method: post + api_path: /v1/b2b/organizations + - name: OrganizationsGet args: - name: organization_id arg_type: str response_type: + request_id: str organization: Organization - - name: update - method: PUT - api_path: organization_id - eval_api_path: true + method: get + api_path: /v1/b2b/organizations/{organization_id} + - name: OrganizationsUpdate args: - name: organization_id arg_type: str @@ -55,10 +50,10 @@ methods: arg_type: Optional[Dict[str, Any]] = None - name: sso_default_connection_id arg_type: Optional[str] = None - - name: sso_jit_provisioning_allowed_connections - arg_type: Optional[List[str]] = None - name: sso_jit_provisioning arg_type: Optional[str] = None + - name: sso_jit_provisioning_allowed_connections + arg_type: Optional[List[str]] = None - name: email_allowed_domains arg_type: Optional[List[str]] = None - name: email_jit_provisioning @@ -70,35 +65,20 @@ methods: - name: allowed_auth_methods arg_type: Optional[List[str]] = None response_type: + request_id: str organization: Organization - - name: delete - method: DELETE - api_path: organization_id - eval_api_path: true + method: put + api_path: /v1/b2b/organizations/{organization_id} + - name: OrganizationsDelete args: - name: organization_id arg_type: str response_type: + request_id: str organization_id: str - - name: get_member - method: GET - api_path: 'f"{organization_id}/member"' - eval_api_path: true - args: - - name: organization_id - arg_type: str - - name: member_id - arg_type: Optional[str] = None - - name: email_address - arg_type: Optional[str] = None - response_type: - member_id: str - member: Member - organization: Organization - - name: create_member - method: POST - api_path: 'f"{organization_id}/members"' - eval_api_path: true + method: delete + api_path: /v1/b2b/organizations/{organization_id} + - name: OrganizationsMemberCreate args: - name: organization_id arg_type: str @@ -111,17 +91,17 @@ methods: - name: untrusted_metadata arg_type: Optional[Dict[str, Any]] = None - name: create_member_as_pending - arg_type: Optional[bool] = None + arg_type: bool - name: is_breakglass - arg_type: Optional[bool] = None + arg_type: bool response_type: + request_id: str member_id: str - member: Member + member: null organization: Organization - - name: update_member - method: PUT - api_path: 'f"{organization_id}/members/{member_id}"' - eval_api_path: true + method: post + api_path: /v1/b2b/organizations/{organization_id}/members + - name: OrganizationsMemberUpdate args: - name: organization_id arg_type: str @@ -136,58 +116,78 @@ methods: - name: is_breakglass arg_type: Optional[bool] = None response_type: + request_id: str member_id: str - member: Member + member: null organization: Organization - - name: delete_member - method: DELETE - api_path: 'f"{organization_id}/member/{member_id}"' - eval_api_path: True + method: put + api_path: /v1/b2b/organizations/{organization_id}/members/{member_id} + - name: OrganizationsMemberDelete args: - name: organization_id arg_type: str - name: member_id arg_type: str response_type: + request_id: str member_id: str - - name: delete_member_password - method: DELETE - api_path: 'f"{organization_id}/members/passwords/{member_password_id}"' - eval_api_path: true - args: - - name: organization_id - arg_type: str - - name: member_password_id - arg_type: str - response_type: - member_id: str - member: Member - organization: Organization - - name: search - method: POST + method: delete + api_path: /v1/b2b/organizations/{organization_id}/members/{member_id} + - name: OrganizationsSearchExternal args: - name: cursor - arg_type: Optional[str] = None + arg_type: str - name: limit arg_type: Optional[int] = None - name: query - arg_type: Optional[SearchQuery] = None + arg_type: ExternalSearchQuery response_type: + request_id: str organizations: List[Organization] - results_metadata: SearchResultsMetadata - - name: search_members - method: POST - api_path: members/search + results_metadata: ResultsMetadata + method: post + api_path: /v1/b2b/organizations/search + - name: OrganizationsMemberSearchExternal args: - - name: organization_ids - arg_type: List[str] - name: cursor - arg_type: Optional[str] = None + arg_type: str - name: limit arg_type: Optional[int] = None - name: query - arg_type: Optional[SearchQuery] = None - map_pydantic: true + arg_type: ExternalSearchQuery + - name: organization_ids + arg_type: List[str] response_type: + request_id: str members: List[Member] - results_metadata: SearchResultsMetadata + results_metadata: ResultsMetadata + method: post + api_path: /v1/b2b/organizations/members/search + - name: OrganizationsMemberDeletePassword + args: + - name: organization_id + arg_type: str + - name: member_password_id + arg_type: str + response_type: + request_id: str + member_id: str + member: null + organization: null + method: delete + api_path: /v1/b2b/organizations/{organization_id}/members/passwords/{member_password_id} + - name: OrganizationsMemberGet + args: + - name: organization_id + arg_type: str + - name: member_id + arg_type: Optional[str] = None + - name: email_address + arg_type: Optional[str] = None + response_type: + request_id: str + member_id: str + member: null + organization: null + method: get + api_path: /v1/b2b/organizations/{organization_id}/member diff --git a/codegen/specs/stytch_b2b/password.yml b/codegen/specs/stytch_b2b/password.yml new file mode 100644 index 00000000..033ee8dd --- /dev/null +++ b/codegen/specs/stytch_b2b/password.yml @@ -0,0 +1,18 @@ +classname: PasswordService +methods: + - name: PasswordsStrengthCheck + args: + - name: password + arg_type: str + - name: email + arg_type: Optional[str] = None + response_type: + request_id: str + valid_password: bool + score: null + breached_password: bool + feedback: null + strength_policy: str + breach_detection_on_create: bool + method: post + api_path: /v1/passwords/strength_check diff --git a/codegen/specs/stytch_b2b/passwords.yml b/codegen/specs/stytch_b2b/passwords.yml deleted file mode 100644 index c7d5c65a..00000000 --- a/codegen/specs/stytch_b2b/passwords.yml +++ /dev/null @@ -1,178 +0,0 @@ -classname: Passwords -additional_imports: - - from stytch.core.models import Name -methods: - - name: authenticate - method: POST - args: - - name: organization_id - arg_type: str - - name: email_address - arg_type: str - - name: password - arg_type: str - - name: session_token - arg_type: Optional[str] = None - - name: session_jwt - arg_type: Optional[str] = None - - name: session_duration_minutes - arg_type: Optional[int] = None - - name: session_custom_claims - arg_type: Optional[Dict[str, Any]] = None - response_type: - member: Member - member_id: str - organization_id: str - organization: Organization - session_token: str - session_jwt: str - member_session: Optional[B2BStytchSession] - - name: strength_check - method: POST - args: - - name: password - arg_type: str - - name: email_address - arg_type: Optional[str] = None - response_type: - breach_detection_on_create: bool - breached_password: bool - luds_feedback: dict - request_id: str - score: int - status_code: int - strength_policy: str - valid_password: bool - zxcvbn_feedback: dict - - name: migrate - method: POST - args: - - name: organization_id - arg_type: str - - name: email_address - arg_type: str - - name: hash - arg_type: str - - name: hash_type - arg_type: str - - name: md_5_config - arg_type: Optional[Dict[str, Any]] = None - - name: argon_2_config - arg_type: Optional[Dict[str, Any]] = None - - name: sha_1_config - arg_type: Optional[Dict[str, Any]] = None - - name: scrypt_config - arg_type: Optional[Dict[str, Any]] = None - - name: name - arg_type: Optional[Union[Name, Dict[str, str]]] = None - - name: trusted_metadata - arg_type: Optional[Dict[str, Any]] = None - - name: untrusted_metadata - arg_type: Optional[Dict[str, Any]] = None - response_type: - member: Member - member_id: str - organization: Organization -sub_apis: - - classname: Email - additional_imports: - - from stytch.core.b2b.models import B2BStytchSession, Member, Organization - sub_url: passwords/email - filename: passwords_email - methods: - - name: reset_start - api_path: reset/start - method: POST - args: - - name: organization_id - arg_type: str - - name: email_address - arg_type: str - - name: login_redirect_url - arg_type: Optional[str] = None - - name: reset_password_redirect_url - arg_type: Optional[str] = None - - name: reset_password_expiration_minutes - arg_type: Optional[int] = None - - name: locale - arg_type: Optional[str] = None - - name: reset_password_template_id - arg_type: Optional[str] = None - response_type: - member_id: str - member_email_id: str - - name: reset - method: POST - args: - - name: password_reset_token - arg_type: str - - name: password - arg_type: str - - name: session_token - arg_type: Optional[str] = None - - name: session_jwt - arg_type: Optional[str] = None - - name: session_duration_minutes - arg_type: Optional[int] = None - - name: session_custom_claims - arg_type: Optional[Dict[str, Any]] = None - response_type: - member: Member - member_id: str - member_email_id: str - organization_id: str - organization: Organization - session_token: str - session_jwt: str - member_session: Optional[B2BStytchSession] - - classname: ExistingPassword - sub_url: passwords/existing_password - filename: passwords_existing_password - methods: - - name: reset - method: POST - args: - - name: organization_id - arg_type: str - - name: email_address - arg_type: str - - name: existing_password - arg_type: str - - name: new_password - arg_type: str - - name: session_token - arg_type: Optional[str] = None - - name: session_jwt - arg_type: Optional[str] = None - - name: session_duration_minutes - arg_type: Optional[int] = None - - name: session_custom_claims - arg_type: Optional[Dict[str, Any]] = None - response_type: - member: Member - member_id: str - organization_id: str - organization: Organization - session_token: str - session_jwt: str - member_session: Optional[B2BStytchSession] - - classname: Session - sub_url: passwords/session - filename: passwords_session - methods: - - name: reset - method: POST - args: - - name: organization_id - arg_type: str - - name: password - arg_type: str - - name: session_token - arg_type: Optional[str] = None - - name: session_jwt - arg_type: Optional[str] = None - response_type: - member: Member - member_id: str - organization: Organization - member_session: Optional[B2BStytchSession] \ No newline at end of file diff --git a/codegen/specs/stytch_b2b/session.yml b/codegen/specs/stytch_b2b/session.yml new file mode 100644 index 00000000..a7a5b392 --- /dev/null +++ b/codegen/specs/stytch_b2b/session.yml @@ -0,0 +1,11 @@ +classname: SessionService +methods: + - name: MultiTenantSessionsJwks + args: + - name: project_id + arg_type: str + response_type: + keys: List[Dict[str, Any]] + request_id: str + method: get + api_path: /v1/b2b/sessions/jwks/{project_id} diff --git a/codegen/specs/stytch_b2b/sessions.yml b/codegen/specs/stytch_b2b/sessions.yml deleted file mode 100644 index 66ea34a5..00000000 --- a/codegen/specs/stytch_b2b/sessions.yml +++ /dev/null @@ -1,43 +0,0 @@ -classname: Sessions -additional_imports: - - from stytch.core.b2b.models import B2BStytchSession -methods: - - name: get - use_base_path_as_api_path: True - method: GET - args: - - name: organization_id - arg_type: str - - name: member_id - arg_type: str - response_type: - member_sessions: List[B2BStytchSession] - - name: authenticate - method: POST - args: - - name: session_token - arg_type: Optional[str] = None - - name: session_jwt - arg_type: Optional[str] = None - - name: session_duration_minutes - arg_type: Optional[int] = None - - name: session_custom_claims - arg_type: Optional[Dict[str, Any]] = None - response_type: - member_session: B2BStytchSession - session_token: str - session_jwt: str - member: Member - organization: Organization - - name: revoke - method: POST - args: - - name: member_session_id - arg_type: Optional[str] = None - - name: session_token - arg_type: Optional[str] = None - - name: session_jwt - arg_type: Optional[str] = None - - name: member_id - arg_type: Optional[str] = None - response_type: {} diff --git a/codegen/specs/stytch_b2b/sso.yml b/codegen/specs/stytch_b2b/sso.yml new file mode 100644 index 00000000..5f5282ee --- /dev/null +++ b/codegen/specs/stytch_b2b/sso.yml @@ -0,0 +1,157 @@ +classname: SSOService +methods: + - name: CreateOIDCConnection + args: + - name: organization_id + arg_type: str + - name: display_name + arg_type: str + response_type: + request_id: str + connection: null + method: post + api_path: /v1/b2b/sso/oidc/{organization_id} + - name: CreateSAMLConnection + args: + - name: organization_id + arg_type: str + - name: display_name + arg_type: str + response_type: + request_id: str + connection: null + method: post + api_path: /v1/b2b/sso/saml/{organization_id} + - name: UpdateOIDCConnection + args: + - name: organization_id + arg_type: str + - name: connection_id + arg_type: str + - name: display_name + arg_type: str + - name: client_id + arg_type: str + - name: client_secret + arg_type: str + - name: issuer + arg_type: str + - name: authorization_url + arg_type: str + - name: token_url + arg_type: str + - name: userinfo_url + arg_type: str + - name: jwks_url + arg_type: str + response_type: + request_id: str + connection: null + warning: Optional[str] = None + method: put + api_path: /v1/b2b/sso/oidc/{organization_id}/connections/{connection_id} + - name: UpdateSAMLConnection + args: + - name: organization_id + arg_type: str + - name: connection_id + arg_type: str + - name: idp_entity_id + arg_type: str + - name: display_name + arg_type: str + - name: attribute_mapping + arg_type: Optional[Dict[str, Any]] = None + - name: x509_certificate + arg_type: str + - name: idp_sso_url + arg_type: str + - name: null + arg_type: null + response_type: + request_id: str + connection: null + method: put + api_path: /v1/b2b/sso/saml/{organization_id}/connections/{connection_id} + - name: UpdateSAMLConnectionByURL + args: + - name: connection_id + arg_type: str + - name: metadata_url + arg_type: str + response_type: + request_id: str + connection: null + method: put + api_path: /v1/b2b/sso/saml/{connection_id}/url + - name: UpdateSAMLConnectionByDoc + args: + - name: connection_id + arg_type: str + - name: metadata + arg_type: null + response_type: + request_id: str + connection: null + method: put + api_path: /v1/b2b/sso/saml/{connection_id}/doc + - name: GetSSOConnections + args: + - name: organization_id + arg_type: str + response_type: + request_id: str + saml_connections: null + oidc_connections: null + method: get + api_path: /v1/b2b/sso/{organization_id} + - name: DeleteSSOConnection + args: + - name: organization_id + arg_type: str + - name: connection_id + arg_type: str + response_type: + request_id: str + connection_id: str + method: delete + api_path: /v1/b2b/sso/{organization_id}/connections/{connection_id} + - name: SSOAuthenticate + args: + - name: sso_token + arg_type: str + - name: pkce_code_verifier + arg_type: Optional[str] = None + - name: session_token + arg_type: Optional[str] = None + - name: session_jwt + arg_type: Optional[str] = None + - name: session_duration_minutes + arg_type: Optional[int] = None + - name: session_custom_claims + arg_type: Optional[Dict[str, Any]] = None + response_type: + request_id: str + member_id: str + organization_id: str + member: null + session_token: str + session_jwt: str + member_session: null + reset_session: bool + organization: null + method: post + api_path: /v1/b2b/sso/authenticate + - name: DeleteSAMLVerificationCertificate + args: + - name: organization_id + arg_type: str + - name: connection_id + arg_type: str + - name: certificate_id + arg_type: str + response_type: + request_id: str + certificate_id: str + method: delete + api_path: /v1/b2b/sso/saml/{organization_id}/connections/{connection_id}/verification_certificates/{certificate_id} diff --git a/stytch/api/billing_service.py b/stytch/api/billing_service.py new file mode 100644 index 00000000..30215617 --- /dev/null +++ b/stytch/api/billing_service.py @@ -0,0 +1,25 @@ +# !!! +# WARNING: This file is autogenerated +# Only modify code within MANUAL() sections +# or your changes may be overwritten later! +# !!! + + +from stytch.core.api_base import ApiBase +from stytch.core.http.client import AsyncClient, SyncClient + + +class BillingService: + def __init__( + self, + api_base: ApiBase, + sync_client: SyncClient, + async_client: AsyncClient, + ) -> None: + self.api_base = api_base + self.sync_client = sync_client + self.async_client = async_client + + @property + def sub_url(self) -> str: + return "billing_service" diff --git a/stytch/api/biometric_service.py b/stytch/api/biometric_service.py new file mode 100644 index 00000000..39a82dd1 --- /dev/null +++ b/stytch/api/biometric_service.py @@ -0,0 +1,208 @@ +# !!! +# WARNING: This file is autogenerated +# Only modify code within MANUAL() sections +# or your changes may be overwritten later! +# !!! + +from typing import Any, Dict, Optional + +from stytch.core.api_base import ApiBase +from stytch.core.http.client import AsyncClient, SyncClient +from stytch.models.biometric_service import ( + BiometricsauthenticateResponse, + BiometricsauthenticatestartResponse, + BiometricsregisterResponse, + BiometricsregisterstartResponse, +) + + +class BiometricService: + def __init__( + self, + api_base: ApiBase, + sync_client: SyncClient, + async_client: AsyncClient, + ) -> None: + self.api_base = api_base + self.sync_client = sync_client + self.async_client = async_client + + @property + def sub_url(self) -> str: + return "biometric_service" + + def BiometricsRegisterStart( + self, + user_id: str, + public_key: str, + ) -> BiometricsregisterstartResponse: + payload: Dict[str, Any] = { + "user_id": user_id, + "public_key": public_key, + } + + url = self.api_base.route_with_sub_url( + self.sub_url, "/v1/biometrics/register/start" + ) + + res = self.sync_client.post(url, json=payload) + return BiometricsregisterstartResponse.from_json( + res.response.status_code, res.json + ) + + async def BiometricsRegisterStart_async( + self, + user_id: str, + public_key: str, + ) -> BiometricsregisterstartResponse: + payload: Dict[str, Any] = { + "user_id": user_id, + "public_key": public_key, + } + + url = self.api_base.route_with_sub_url( + self.sub_url, "/v1/biometrics/register/start" + ) + + res = await self.async_client.post(url, json=payload) + return BiometricsregisterstartResponse.from_json(res.response.status, res.json) + + def BiometricsRegister( + self, + biometric_registration_id: str, + signature: str, + session_duration_minutes: Optional[int] = None, + session_custom_claims: Optional[Dict[str, Any]] = None, + ) -> BiometricsregisterResponse: + payload: Dict[str, Any] = { + "biometric_registration_id": biometric_registration_id, + "signature": signature, + } + + if session_duration_minutes is not None: + payload["session_duration_minutes"] = session_duration_minutes + if session_custom_claims is not None: + payload["session_custom_claims"] = session_custom_claims + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/biometrics/register") + + res = self.sync_client.post(url, json=payload) + return BiometricsregisterResponse.from_json(res.response.status_code, res.json) + + async def BiometricsRegister_async( + self, + biometric_registration_id: str, + signature: str, + session_duration_minutes: Optional[int] = None, + session_custom_claims: Optional[Dict[str, Any]] = None, + ) -> BiometricsregisterResponse: + payload: Dict[str, Any] = { + "biometric_registration_id": biometric_registration_id, + "signature": signature, + } + + if session_duration_minutes is not None: + payload["session_duration_minutes"] = session_duration_minutes + if session_custom_claims is not None: + payload["session_custom_claims"] = session_custom_claims + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/biometrics/register") + + res = await self.async_client.post(url, json=payload) + return BiometricsregisterResponse.from_json(res.response.status, res.json) + + def BiometricsAuthenticateStart( + self, + public_key: str, + ) -> BiometricsauthenticatestartResponse: + payload: Dict[str, Any] = { + "public_key": public_key, + } + + url = self.api_base.route_with_sub_url( + self.sub_url, "/v1/biometrics/authenticate/start" + ) + + res = self.sync_client.post(url, json=payload) + return BiometricsauthenticatestartResponse.from_json( + res.response.status_code, res.json + ) + + async def BiometricsAuthenticateStart_async( + self, + public_key: str, + ) -> BiometricsauthenticatestartResponse: + payload: Dict[str, Any] = { + "public_key": public_key, + } + + url = self.api_base.route_with_sub_url( + self.sub_url, "/v1/biometrics/authenticate/start" + ) + + res = await self.async_client.post(url, json=payload) + return BiometricsauthenticatestartResponse.from_json( + res.response.status, res.json + ) + + def BiometricsAuthenticate( + self, + biometric_registration_id: str, + signature: str, + session_token: Optional[str] = None, + session_duration_minutes: Optional[int] = None, + session_jwt: Optional[str] = None, + session_custom_claims: Optional[Dict[str, Any]] = None, + ) -> BiometricsauthenticateResponse: + payload: Dict[str, Any] = { + "biometric_registration_id": biometric_registration_id, + "signature": signature, + } + + if session_token is not None: + payload["session_token"] = session_token + if session_duration_minutes is not None: + payload["session_duration_minutes"] = session_duration_minutes + if session_jwt is not None: + payload["session_jwt"] = session_jwt + if session_custom_claims is not None: + payload["session_custom_claims"] = session_custom_claims + + url = self.api_base.route_with_sub_url( + self.sub_url, "/v1/biometrics/authenticate" + ) + + res = self.sync_client.post(url, json=payload) + return BiometricsauthenticateResponse.from_json( + res.response.status_code, res.json + ) + + async def BiometricsAuthenticate_async( + self, + biometric_registration_id: str, + signature: str, + session_token: Optional[str] = None, + session_duration_minutes: Optional[int] = None, + session_jwt: Optional[str] = None, + session_custom_claims: Optional[Dict[str, Any]] = None, + ) -> BiometricsauthenticateResponse: + payload: Dict[str, Any] = { + "biometric_registration_id": biometric_registration_id, + "signature": signature, + } + + if session_token is not None: + payload["session_token"] = session_token + if session_duration_minutes is not None: + payload["session_duration_minutes"] = session_duration_minutes + if session_jwt is not None: + payload["session_jwt"] = session_jwt + if session_custom_claims is not None: + payload["session_custom_claims"] = session_custom_claims + + url = self.api_base.route_with_sub_url( + self.sub_url, "/v1/biometrics/authenticate" + ) + + res = await self.async_client.post(url, json=payload) + return BiometricsauthenticateResponse.from_json(res.response.status, res.json) diff --git a/stytch/api/cname_record_service.py b/stytch/api/cname_record_service.py new file mode 100644 index 00000000..c4fa18ee --- /dev/null +++ b/stytch/api/cname_record_service.py @@ -0,0 +1,25 @@ +# !!! +# WARNING: This file is autogenerated +# Only modify code within MANUAL() sections +# or your changes may be overwritten later! +# !!! + + +from stytch.core.api_base import ApiBase +from stytch.core.http.client import AsyncClient, SyncClient + + +class CNAMERecordService: + def __init__( + self, + api_base: ApiBase, + sync_client: SyncClient, + async_client: AsyncClient, + ) -> None: + self.api_base = api_base + self.sync_client = sync_client + self.async_client = async_client + + @property + def sub_url(self) -> str: + return "cname_record_service" diff --git a/stytch/api/crypto_wallet_service.py b/stytch/api/crypto_wallet_service.py new file mode 100644 index 00000000..655e3047 --- /dev/null +++ b/stytch/api/crypto_wallet_service.py @@ -0,0 +1,156 @@ +# !!! +# WARNING: This file is autogenerated +# Only modify code within MANUAL() sections +# or your changes may be overwritten later! +# !!! + +from typing import Any, Dict, Optional + +from stytch.core.api_base import ApiBase +from stytch.core.http.client import AsyncClient, SyncClient +from stytch.models.crypto_wallet_service import ( + CryptowalletsauthenticateResponse, + CryptowalletsauthenticatestartResponse, +) + + +class CryptoWalletService: + def __init__( + self, + api_base: ApiBase, + sync_client: SyncClient, + async_client: AsyncClient, + ) -> None: + self.api_base = api_base + self.sync_client = sync_client + self.async_client = async_client + + @property + def sub_url(self) -> str: + return "crypto_wallet_service" + + def CryptoWalletsAuthenticateStart( + self, + crypto_wallet_type: str, + crypto_wallet_address: str, + user_id: Optional[str] = None, + session_token: Optional[str] = None, + session_jwt: Optional[str] = None, + ) -> CryptowalletsauthenticatestartResponse: + payload: Dict[str, Any] = { + "crypto_wallet_type": crypto_wallet_type, + "crypto_wallet_address": crypto_wallet_address, + } + + if user_id is not None: + payload["user_id"] = user_id + if session_token is not None: + payload["session_token"] = session_token + if session_jwt is not None: + payload["session_jwt"] = session_jwt + + url = self.api_base.route_with_sub_url( + self.sub_url, "/v1/crypto_wallets/authenticate/start" + ) + + res = self.sync_client.post(url, json=payload) + return CryptowalletsauthenticatestartResponse.from_json( + res.response.status_code, res.json + ) + + async def CryptoWalletsAuthenticateStart_async( + self, + crypto_wallet_type: str, + crypto_wallet_address: str, + user_id: Optional[str] = None, + session_token: Optional[str] = None, + session_jwt: Optional[str] = None, + ) -> CryptowalletsauthenticatestartResponse: + payload: Dict[str, Any] = { + "crypto_wallet_type": crypto_wallet_type, + "crypto_wallet_address": crypto_wallet_address, + } + + if user_id is not None: + payload["user_id"] = user_id + if session_token is not None: + payload["session_token"] = session_token + if session_jwt is not None: + payload["session_jwt"] = session_jwt + + url = self.api_base.route_with_sub_url( + self.sub_url, "/v1/crypto_wallets/authenticate/start" + ) + + res = await self.async_client.post(url, json=payload) + return CryptowalletsauthenticatestartResponse.from_json( + res.response.status, res.json + ) + + def CryptoWalletsAuthenticate( + self, + crypto_wallet_type: str, + crypto_wallet_address: str, + signature: str, + session_token: Optional[str] = None, + session_duration_minutes: Optional[int] = None, + session_jwt: Optional[str] = None, + session_custom_claims: Optional[Dict[str, Any]] = None, + ) -> CryptowalletsauthenticateResponse: + payload: Dict[str, Any] = { + "crypto_wallet_type": crypto_wallet_type, + "crypto_wallet_address": crypto_wallet_address, + "signature": signature, + } + + if session_token is not None: + payload["session_token"] = session_token + if session_duration_minutes is not None: + payload["session_duration_minutes"] = session_duration_minutes + if session_jwt is not None: + payload["session_jwt"] = session_jwt + if session_custom_claims is not None: + payload["session_custom_claims"] = session_custom_claims + + url = self.api_base.route_with_sub_url( + self.sub_url, "/v1/crypto_wallets/authenticate" + ) + + res = self.sync_client.post(url, json=payload) + return CryptowalletsauthenticateResponse.from_json( + res.response.status_code, res.json + ) + + async def CryptoWalletsAuthenticate_async( + self, + crypto_wallet_type: str, + crypto_wallet_address: str, + signature: str, + session_token: Optional[str] = None, + session_duration_minutes: Optional[int] = None, + session_jwt: Optional[str] = None, + session_custom_claims: Optional[Dict[str, Any]] = None, + ) -> CryptowalletsauthenticateResponse: + payload: Dict[str, Any] = { + "crypto_wallet_type": crypto_wallet_type, + "crypto_wallet_address": crypto_wallet_address, + "signature": signature, + } + + if session_token is not None: + payload["session_token"] = session_token + if session_duration_minutes is not None: + payload["session_duration_minutes"] = session_duration_minutes + if session_jwt is not None: + payload["session_jwt"] = session_jwt + if session_custom_claims is not None: + payload["session_custom_claims"] = session_custom_claims + + url = self.api_base.route_with_sub_url( + self.sub_url, "/v1/crypto_wallets/authenticate" + ) + + res = await self.async_client.post(url, json=payload) + return CryptowalletsauthenticateResponse.from_json( + res.response.status, res.json + ) diff --git a/stytch/api/debug_service.py b/stytch/api/debug_service.py new file mode 100644 index 00000000..7691ec9a --- /dev/null +++ b/stytch/api/debug_service.py @@ -0,0 +1,47 @@ +# !!! +# WARNING: This file is autogenerated +# Only modify code within MANUAL() sections +# or your changes may be overwritten later! +# !!! + +from typing import Any, Dict + +from stytch.core.api_base import ApiBase +from stytch.core.http.client import AsyncClient, SyncClient +from stytch.models.debug_service import WhoamiResponse + + +class DebugService: + def __init__( + self, + api_base: ApiBase, + sync_client: SyncClient, + async_client: AsyncClient, + ) -> None: + self.api_base = api_base + self.sync_client = sync_client + self.async_client = async_client + + @property + def sub_url(self) -> str: + return "debug_service" + + def WhoAmI( + self, + ) -> WhoamiResponse: + payload: Dict[str, Any] = {} + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/debug/whoami") + + res = self.sync_client.get(url, params=payload) + return WhoamiResponse.from_json(res.response.status_code, res.json) + + async def WhoAmI_async( + self, + ) -> WhoamiResponse: + payload: Dict[str, Any] = {} + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/debug/whoami") + + res = await self.async_client.get(url, params=payload) + return WhoamiResponse.from_json(res.response.status, res.json) diff --git a/stytch/api/discovery_service.py b/stytch/api/discovery_service.py new file mode 100644 index 00000000..a661a618 --- /dev/null +++ b/stytch/api/discovery_service.py @@ -0,0 +1,25 @@ +# !!! +# WARNING: This file is autogenerated +# Only modify code within MANUAL() sections +# or your changes may be overwritten later! +# !!! + + +from stytch.core.api_base import ApiBase +from stytch.core.http.client import AsyncClient, SyncClient + + +class DiscoveryService: + def __init__( + self, + api_base: ApiBase, + sync_client: SyncClient, + async_client: AsyncClient, + ) -> None: + self.api_base = api_base + self.sync_client = sync_client + self.async_client = async_client + + @property + def sub_url(self) -> str: + return "discovery_service" diff --git a/stytch/api/email_template_service.py b/stytch/api/email_template_service.py new file mode 100644 index 00000000..3d92cee7 --- /dev/null +++ b/stytch/api/email_template_service.py @@ -0,0 +1,25 @@ +# !!! +# WARNING: This file is autogenerated +# Only modify code within MANUAL() sections +# or your changes may be overwritten later! +# !!! + + +from stytch.core.api_base import ApiBase +from stytch.core.http.client import AsyncClient, SyncClient + + +class EmailTemplateService: + def __init__( + self, + api_base: ApiBase, + sync_client: SyncClient, + async_client: AsyncClient, + ) -> None: + self.api_base = api_base + self.sync_client = sync_client + self.async_client = async_client + + @property + def sub_url(self) -> str: + return "email_template_service" diff --git a/stytch/api/magic_link_url_service.py b/stytch/api/magic_link_url_service.py new file mode 100644 index 00000000..db2f10b1 --- /dev/null +++ b/stytch/api/magic_link_url_service.py @@ -0,0 +1,25 @@ +# !!! +# WARNING: This file is autogenerated +# Only modify code within MANUAL() sections +# or your changes may be overwritten later! +# !!! + + +from stytch.core.api_base import ApiBase +from stytch.core.http.client import AsyncClient, SyncClient + + +class MagicLinkURLService: + def __init__( + self, + api_base: ApiBase, + sync_client: SyncClient, + async_client: AsyncClient, + ) -> None: + self.api_base = api_base + self.sync_client = sync_client + self.async_client = async_client + + @property + def sub_url(self) -> str: + return "magic_link_url_service" diff --git a/stytch/api/magic_service.py b/stytch/api/magic_service.py new file mode 100644 index 00000000..a33031b6 --- /dev/null +++ b/stytch/api/magic_service.py @@ -0,0 +1,823 @@ +# !!! +# WARNING: This file is autogenerated +# Only modify code within MANUAL() sections +# or your changes may be overwritten later! +# !!! + +from typing import Any, Dict, List, Optional, Union + +import pydantic + +from stytch.core.api_base import ApiBase +from stytch.core.http.client import AsyncClient, SyncClient +from stytch.models.magic_service import ( + AuthenticatemagicResponse, + InvitebyemailResponse, + MagiclinkredirectResponse, + MagiclinksauthenticateResponse, + MagiclinkscreateResponse, + MagiclinksemailinviteResponse, + MagiclinksemailloginorcreateResponse, + MagiclinksemailrevokeinviteResponse, + MagiclinksemailsendResponse, + MagiclinksredirectcaptchaResponse, + SdkmagiclinksemailloginorcreateResponse, + SendmagicbyemailResponse, +) + + +class MagicService: + def __init__( + self, + api_base: ApiBase, + sync_client: SyncClient, + async_client: AsyncClient, + ) -> None: + self.api_base = api_base + self.sync_client = sync_client + self.async_client = async_client + + @property + def sub_url(self) -> str: + return "magic_service" + + def SendMagicByEmail( + self, + email: str, + magic_link_url: Optional[str] = None, + expiration_minutes: Optional[int] = None, + login_template_id: Optional[str] = None, + attributes: Optional[Dict[str, str]] = None, + login_magic_link_url: str, + signup_magic_link_url: str, + login_expiration_minutes: Optional[int] = None, + signup_expiration_minutes: Optional[int] = None, + code_challenge: Optional[str] = None, + user_id: str, + session_token: Optional[str] = None, + session_jwt: Optional[str] = None, + locale: Optional[str] = None, + signup_template_id: Optional[str] = None, + ) -> SendmagicbyemailResponse: + + payload: Dict[str, Any] = { + "email": email, + "login_magic_link_url": login_magic_link_url, + "signup_magic_link_url": signup_magic_link_url, + "user_id": user_id, + } + + if magic_link_url is not None: + payload["magic_link_url"] = magic_link_url + if expiration_minutes is not None: + payload["expiration_minutes"] = expiration_minutes + if login_template_id is not None: + payload["login_template_id"] = login_template_id + if attributes is not None: + payload["attributes"] = attributes + if login_expiration_minutes is not None: + payload["login_expiration_minutes"] = login_expiration_minutes + if signup_expiration_minutes is not None: + payload["signup_expiration_minutes"] = signup_expiration_minutes + if code_challenge is not None: + payload["code_challenge"] = code_challenge + if session_token is not None: + payload["session_token"] = session_token + if session_jwt is not None: + payload["session_jwt"] = session_jwt + if locale is not None: + payload["locale"] = locale + if signup_template_id is not None: + payload["signup_template_id"] = signup_template_id + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/magic_links/send_by_email") + + res = self.sync_client.post(url, json=payload) + return SendmagicbyemailResponse.from_json(res.response.status_code, res.json) + + async def SendMagicByEmail_async( + self, + email: str, + magic_link_url: Optional[str] = None, + expiration_minutes: Optional[int] = None, + login_template_id: Optional[str] = None, + attributes: Optional[Dict[str, str]] = None, + login_magic_link_url: str, + signup_magic_link_url: str, + login_expiration_minutes: Optional[int] = None, + signup_expiration_minutes: Optional[int] = None, + code_challenge: Optional[str] = None, + user_id: str, + session_token: Optional[str] = None, + session_jwt: Optional[str] = None, + locale: Optional[str] = None, + signup_template_id: Optional[str] = None, + ) -> SendmagicbyemailResponse: + + payload: Dict[str, Any] = { + "email": email, + "login_magic_link_url": login_magic_link_url, + "signup_magic_link_url": signup_magic_link_url, + "user_id": user_id, + } + + if magic_link_url is not None: + payload["magic_link_url"] = magic_link_url + if expiration_minutes is not None: + payload["expiration_minutes"] = expiration_minutes + if login_template_id is not None: + payload["login_template_id"] = login_template_id + if attributes is not None: + payload["attributes"] = attributes + if login_expiration_minutes is not None: + payload["login_expiration_minutes"] = login_expiration_minutes + if signup_expiration_minutes is not None: + payload["signup_expiration_minutes"] = signup_expiration_minutes + if code_challenge is not None: + payload["code_challenge"] = code_challenge + if session_token is not None: + payload["session_token"] = session_token + if session_jwt is not None: + payload["session_jwt"] = session_jwt + if locale is not None: + payload["locale"] = locale + if signup_template_id is not None: + payload["signup_template_id"] = signup_template_id + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/magic_links/send_by_email") + + res = await self.async_client.post(url, json=payload) + return SendmagicbyemailResponse.from_json(res.response.status, res.json) + + def MagicLinksEmailSend( + self, + email: str, + magic_link_url: Optional[str] = None, + expiration_minutes: Optional[int] = None, + login_template_id: Optional[str] = None, + attributes: Optional[Dict[str, str]] = None, + login_magic_link_url: str, + signup_magic_link_url: str, + login_expiration_minutes: Optional[int] = None, + signup_expiration_minutes: Optional[int] = None, + code_challenge: Optional[str] = None, + user_id: str, + session_token: Optional[str] = None, + session_jwt: Optional[str] = None, + locale: Optional[str] = None, + signup_template_id: Optional[str] = None, + ) -> MagiclinksemailsendResponse: + + payload: Dict[str, Any] = { + "email": email, + "login_magic_link_url": login_magic_link_url, + "signup_magic_link_url": signup_magic_link_url, + "user_id": user_id, + } + + if magic_link_url is not None: + payload["magic_link_url"] = magic_link_url + if expiration_minutes is not None: + payload["expiration_minutes"] = expiration_minutes + if login_template_id is not None: + payload["login_template_id"] = login_template_id + if attributes is not None: + payload["attributes"] = attributes + if login_expiration_minutes is not None: + payload["login_expiration_minutes"] = login_expiration_minutes + if signup_expiration_minutes is not None: + payload["signup_expiration_minutes"] = signup_expiration_minutes + if code_challenge is not None: + payload["code_challenge"] = code_challenge + if session_token is not None: + payload["session_token"] = session_token + if session_jwt is not None: + payload["session_jwt"] = session_jwt + if locale is not None: + payload["locale"] = locale + if signup_template_id is not None: + payload["signup_template_id"] = signup_template_id + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/magic_links/email/send") + + res = self.sync_client.post(url, json=payload) + return MagiclinksemailsendResponse.from_json(res.response.status_code, res.json) + + async def MagicLinksEmailSend_async( + self, + email: str, + magic_link_url: Optional[str] = None, + expiration_minutes: Optional[int] = None, + login_template_id: Optional[str] = None, + attributes: Optional[Dict[str, str]] = None, + login_magic_link_url: str, + signup_magic_link_url: str, + login_expiration_minutes: Optional[int] = None, + signup_expiration_minutes: Optional[int] = None, + code_challenge: Optional[str] = None, + user_id: str, + session_token: Optional[str] = None, + session_jwt: Optional[str] = None, + locale: Optional[str] = None, + signup_template_id: Optional[str] = None, + ) -> MagiclinksemailsendResponse: + + payload: Dict[str, Any] = { + "email": email, + "login_magic_link_url": login_magic_link_url, + "signup_magic_link_url": signup_magic_link_url, + "user_id": user_id, + } + + if magic_link_url is not None: + payload["magic_link_url"] = magic_link_url + if expiration_minutes is not None: + payload["expiration_minutes"] = expiration_minutes + if login_template_id is not None: + payload["login_template_id"] = login_template_id + if attributes is not None: + payload["attributes"] = attributes + if login_expiration_minutes is not None: + payload["login_expiration_minutes"] = login_expiration_minutes + if signup_expiration_minutes is not None: + payload["signup_expiration_minutes"] = signup_expiration_minutes + if code_challenge is not None: + payload["code_challenge"] = code_challenge + if session_token is not None: + payload["session_token"] = session_token + if session_jwt is not None: + payload["session_jwt"] = session_jwt + if locale is not None: + payload["locale"] = locale + if signup_template_id is not None: + payload["signup_template_id"] = signup_template_id + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/magic_links/email/send") + + res = await self.async_client.post(url, json=payload) + return MagiclinksemailsendResponse.from_json(res.response.status, res.json) + + def AuthenticateMagic( + self, + token: str, + attributes: Optional[Dict[str, str]] = None, + options: Optional[Dict[str, str]] = None, + session_token: Optional[str] = None, + session_duration_minutes: Optional[int] = None, + session_jwt: Optional[str] = None, + session_custom_claims: Optional[Dict[str, Any]] = None, + code_verifier: Optional[str] = None, + ) -> AuthenticatemagicResponse: + + payload: Dict[str, Any] = { + "token": token, + } + + if attributes is not None: + payload["attributes"] = attributes + if options is not None: + payload["options"] = options + if session_token is not None: + payload["session_token"] = session_token + if session_duration_minutes is not None: + payload["session_duration_minutes"] = session_duration_minutes + if session_jwt is not None: + payload["session_jwt"] = session_jwt + if session_custom_claims is not None: + payload["session_custom_claims"] = session_custom_claims + if code_verifier is not None: + payload["code_verifier"] = code_verifier + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/magic_links/{token}/authenticate") + + res = self.sync_client.post(url, json=payload) + return AuthenticatemagicResponse.from_json(res.response.status_code, res.json) + + async def AuthenticateMagic_async( + self, + token: str, + attributes: Optional[Dict[str, str]] = None, + options: Optional[Dict[str, str]] = None, + session_token: Optional[str] = None, + session_duration_minutes: Optional[int] = None, + session_jwt: Optional[str] = None, + session_custom_claims: Optional[Dict[str, Any]] = None, + code_verifier: Optional[str] = None, + ) -> AuthenticatemagicResponse: + + payload: Dict[str, Any] = { + "token": token, + } + + if attributes is not None: + payload["attributes"] = attributes + if options is not None: + payload["options"] = options + if session_token is not None: + payload["session_token"] = session_token + if session_duration_minutes is not None: + payload["session_duration_minutes"] = session_duration_minutes + if session_jwt is not None: + payload["session_jwt"] = session_jwt + if session_custom_claims is not None: + payload["session_custom_claims"] = session_custom_claims + if code_verifier is not None: + payload["code_verifier"] = code_verifier + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/magic_links/{token}/authenticate") + + res = await self.async_client.post(url, json=payload) + return AuthenticatemagicResponse.from_json(res.response.status, res.json) + + def MagicLinksAuthenticate( + self, + token: str, + attributes: Optional[Dict[str, str]] = None, + options: Optional[Dict[str, str]] = None, + session_token: Optional[str] = None, + session_duration_minutes: Optional[int] = None, + session_jwt: Optional[str] = None, + session_custom_claims: Optional[Dict[str, Any]] = None, + code_verifier: Optional[str] = None, + ) -> MagiclinksauthenticateResponse: + + payload: Dict[str, Any] = { + "token": token, + } + + if attributes is not None: + payload["attributes"] = attributes + if options is not None: + payload["options"] = options + if session_token is not None: + payload["session_token"] = session_token + if session_duration_minutes is not None: + payload["session_duration_minutes"] = session_duration_minutes + if session_jwt is not None: + payload["session_jwt"] = session_jwt + if session_custom_claims is not None: + payload["session_custom_claims"] = session_custom_claims + if code_verifier is not None: + payload["code_verifier"] = code_verifier + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/magic_links/authenticate") + + res = self.sync_client.post(url, json=payload) + return MagiclinksauthenticateResponse.from_json(res.response.status_code, res.json) + + async def MagicLinksAuthenticate_async( + self, + token: str, + attributes: Optional[Dict[str, str]] = None, + options: Optional[Dict[str, str]] = None, + session_token: Optional[str] = None, + session_duration_minutes: Optional[int] = None, + session_jwt: Optional[str] = None, + session_custom_claims: Optional[Dict[str, Any]] = None, + code_verifier: Optional[str] = None, + ) -> MagiclinksauthenticateResponse: + + payload: Dict[str, Any] = { + "token": token, + } + + if attributes is not None: + payload["attributes"] = attributes + if options is not None: + payload["options"] = options + if session_token is not None: + payload["session_token"] = session_token + if session_duration_minutes is not None: + payload["session_duration_minutes"] = session_duration_minutes + if session_jwt is not None: + payload["session_jwt"] = session_jwt + if session_custom_claims is not None: + payload["session_custom_claims"] = session_custom_claims + if code_verifier is not None: + payload["code_verifier"] = code_verifier + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/magic_links/authenticate") + + res = await self.async_client.post(url, json=payload) + return MagiclinksauthenticateResponse.from_json(res.response.status, res.json) + + def MagicLinksEmailLoginOrCreate( + self, + email: str, + login_magic_link_url: str, + signup_magic_link_url: str, + login_expiration_minutes: Optional[int] = None, + signup_expiration_minutes: Optional[int] = None, + login_template_id: Optional[str] = None, + signup_template_id: Optional[str] = None, + attributes: Optional[Dict[str, str]] = None, + create_user_as_pending: bool, + code_challenge: Optional[str] = None, + locale: Optional[str] = None, + ) -> MagiclinksemailloginorcreateResponse: + + payload: Dict[str, Any] = { + "email": email, + "login_magic_link_url": login_magic_link_url, + "signup_magic_link_url": signup_magic_link_url, + "create_user_as_pending": create_user_as_pending, + } + + if login_expiration_minutes is not None: + payload["login_expiration_minutes"] = login_expiration_minutes + if signup_expiration_minutes is not None: + payload["signup_expiration_minutes"] = signup_expiration_minutes + if login_template_id is not None: + payload["login_template_id"] = login_template_id + if signup_template_id is not None: + payload["signup_template_id"] = signup_template_id + if attributes is not None: + payload["attributes"] = attributes + if code_challenge is not None: + payload["code_challenge"] = code_challenge + if locale is not None: + payload["locale"] = locale + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/magic_links/email/login_or_create") + + res = self.sync_client.post(url, json=payload) + return MagiclinksemailloginorcreateResponse.from_json(res.response.status_code, res.json) + + async def MagicLinksEmailLoginOrCreate_async( + self, + email: str, + login_magic_link_url: str, + signup_magic_link_url: str, + login_expiration_minutes: Optional[int] = None, + signup_expiration_minutes: Optional[int] = None, + login_template_id: Optional[str] = None, + signup_template_id: Optional[str] = None, + attributes: Optional[Dict[str, str]] = None, + create_user_as_pending: bool, + code_challenge: Optional[str] = None, + locale: Optional[str] = None, + ) -> MagiclinksemailloginorcreateResponse: + + payload: Dict[str, Any] = { + "email": email, + "login_magic_link_url": login_magic_link_url, + "signup_magic_link_url": signup_magic_link_url, + "create_user_as_pending": create_user_as_pending, + } + + if login_expiration_minutes is not None: + payload["login_expiration_minutes"] = login_expiration_minutes + if signup_expiration_minutes is not None: + payload["signup_expiration_minutes"] = signup_expiration_minutes + if login_template_id is not None: + payload["login_template_id"] = login_template_id + if signup_template_id is not None: + payload["signup_template_id"] = signup_template_id + if attributes is not None: + payload["attributes"] = attributes + if code_challenge is not None: + payload["code_challenge"] = code_challenge + if locale is not None: + payload["locale"] = locale + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/magic_links/email/login_or_create") + + res = await self.async_client.post(url, json=payload) + return MagiclinksemailloginorcreateResponse.from_json(res.response.status, res.json) + + def SDKMagicLinksEmailLoginOrCreate( + self, + public_token: str, + request: None, + ) -> SdkmagiclinksemailloginorcreateResponse: + + payload: Dict[str, Any] = { + "public_token": public_token, + } + + if request is not None: + payload["request"] = request + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/sdk/magic_links/email/login_or_create") + + res = self.sync_client.post(url, json=payload) + return SdkmagiclinksemailloginorcreateResponse.from_json(res.response.status_code, res.json) + + async def SDKMagicLinksEmailLoginOrCreate_async( + self, + public_token: str, + request: None, + ) -> SdkmagiclinksemailloginorcreateResponse: + + payload: Dict[str, Any] = { + "public_token": public_token, + } + + if request is not None: + payload["request"] = request + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/sdk/magic_links/email/login_or_create") + + res = await self.async_client.post(url, json=payload) + return SdkmagiclinksemailloginorcreateResponse.from_json(res.response.status, res.json) + + def InviteByEmail( + self, + email: str, + magic_link_url: Optional[str] = None, + expiration_minutes: Optional[int] = None, + invite_template_id: Optional[str] = None, + attributes: Optional[Dict[str, str]] = None, + name: None, + invite_magic_link_url: str, + invite_expiration_minutes: Optional[int] = None, + locale: Optional[str] = None, + ) -> InvitebyemailResponse: + + payload: Dict[str, Any] = { + "email": email, + "invite_magic_link_url": invite_magic_link_url, + } + + if magic_link_url is not None: + payload["magic_link_url"] = magic_link_url + if expiration_minutes is not None: + payload["expiration_minutes"] = expiration_minutes + if invite_template_id is not None: + payload["invite_template_id"] = invite_template_id + if attributes is not None: + payload["attributes"] = attributes + if name is not None: + payload["name"] = name + if invite_expiration_minutes is not None: + payload["invite_expiration_minutes"] = invite_expiration_minutes + if locale is not None: + payload["locale"] = locale + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/magic_links/invite_by_email") + + res = self.sync_client.post(url, json=payload) + return InvitebyemailResponse.from_json(res.response.status_code, res.json) + + async def InviteByEmail_async( + self, + email: str, + magic_link_url: Optional[str] = None, + expiration_minutes: Optional[int] = None, + invite_template_id: Optional[str] = None, + attributes: Optional[Dict[str, str]] = None, + name: None, + invite_magic_link_url: str, + invite_expiration_minutes: Optional[int] = None, + locale: Optional[str] = None, + ) -> InvitebyemailResponse: + + payload: Dict[str, Any] = { + "email": email, + "invite_magic_link_url": invite_magic_link_url, + } + + if magic_link_url is not None: + payload["magic_link_url"] = magic_link_url + if expiration_minutes is not None: + payload["expiration_minutes"] = expiration_minutes + if invite_template_id is not None: + payload["invite_template_id"] = invite_template_id + if attributes is not None: + payload["attributes"] = attributes + if name is not None: + payload["name"] = name + if invite_expiration_minutes is not None: + payload["invite_expiration_minutes"] = invite_expiration_minutes + if locale is not None: + payload["locale"] = locale + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/magic_links/invite_by_email") + + res = await self.async_client.post(url, json=payload) + return InvitebyemailResponse.from_json(res.response.status, res.json) + + def MagicLinksEmailInvite( + self, + email: str, + magic_link_url: Optional[str] = None, + expiration_minutes: Optional[int] = None, + invite_template_id: Optional[str] = None, + attributes: Optional[Dict[str, str]] = None, + name: None, + invite_magic_link_url: str, + invite_expiration_minutes: Optional[int] = None, + locale: Optional[str] = None, + ) -> MagiclinksemailinviteResponse: + + payload: Dict[str, Any] = { + "email": email, + "invite_magic_link_url": invite_magic_link_url, + } + + if magic_link_url is not None: + payload["magic_link_url"] = magic_link_url + if expiration_minutes is not None: + payload["expiration_minutes"] = expiration_minutes + if invite_template_id is not None: + payload["invite_template_id"] = invite_template_id + if attributes is not None: + payload["attributes"] = attributes + if name is not None: + payload["name"] = name + if invite_expiration_minutes is not None: + payload["invite_expiration_minutes"] = invite_expiration_minutes + if locale is not None: + payload["locale"] = locale + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/magic_links/email/invite") + + res = self.sync_client.post(url, json=payload) + return MagiclinksemailinviteResponse.from_json(res.response.status_code, res.json) + + async def MagicLinksEmailInvite_async( + self, + email: str, + magic_link_url: Optional[str] = None, + expiration_minutes: Optional[int] = None, + invite_template_id: Optional[str] = None, + attributes: Optional[Dict[str, str]] = None, + name: None, + invite_magic_link_url: str, + invite_expiration_minutes: Optional[int] = None, + locale: Optional[str] = None, + ) -> MagiclinksemailinviteResponse: + + payload: Dict[str, Any] = { + "email": email, + "invite_magic_link_url": invite_magic_link_url, + } + + if magic_link_url is not None: + payload["magic_link_url"] = magic_link_url + if expiration_minutes is not None: + payload["expiration_minutes"] = expiration_minutes + if invite_template_id is not None: + payload["invite_template_id"] = invite_template_id + if attributes is not None: + payload["attributes"] = attributes + if name is not None: + payload["name"] = name + if invite_expiration_minutes is not None: + payload["invite_expiration_minutes"] = invite_expiration_minutes + if locale is not None: + payload["locale"] = locale + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/magic_links/email/invite") + + res = await self.async_client.post(url, json=payload) + return MagiclinksemailinviteResponse.from_json(res.response.status, res.json) + + def MagicLinksEmailRevokeInvite( + self, + email: str, + ) -> MagiclinksemailrevokeinviteResponse: + + payload: Dict[str, Any] = { + "email": email, + } + + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/magic_links/email/revoke_invite") + + res = self.sync_client.post(url, json=payload) + return MagiclinksemailrevokeinviteResponse.from_json(res.response.status_code, res.json) + + async def MagicLinksEmailRevokeInvite_async( + self, + email: str, + ) -> MagiclinksemailrevokeinviteResponse: + + payload: Dict[str, Any] = { + "email": email, + } + + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/magic_links/email/revoke_invite") + + res = await self.async_client.post(url, json=payload) + return MagiclinksemailrevokeinviteResponse.from_json(res.response.status, res.json) + + def MagicLinksCreate( + self, + user_id: str, + expiration_minutes: Optional[int] = None, + attributes: Optional[Dict[str, str]] = None, + ) -> MagiclinkscreateResponse: + + payload: Dict[str, Any] = { + "user_id": user_id, + } + + if expiration_minutes is not None: + payload["expiration_minutes"] = expiration_minutes + if attributes is not None: + payload["attributes"] = attributes + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/magic_links") + + res = self.sync_client.post(url, json=payload) + return MagiclinkscreateResponse.from_json(res.response.status_code, res.json) + + async def MagicLinksCreate_async( + self, + user_id: str, + expiration_minutes: Optional[int] = None, + attributes: Optional[Dict[str, str]] = None, + ) -> MagiclinkscreateResponse: + + payload: Dict[str, Any] = { + "user_id": user_id, + } + + if expiration_minutes is not None: + payload["expiration_minutes"] = expiration_minutes + if attributes is not None: + payload["attributes"] = attributes + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/magic_links") + + res = await self.async_client.post(url, json=payload) + return MagiclinkscreateResponse.from_json(res.response.status, res.json) + + def MagicLinkRedirect( + self, + public_token: str, + token: str, + stytch_token_type: str, + ) -> MagiclinkredirectResponse: + + payload: Dict[str, Any] = { + "public_token": public_token, + "token": token, + "stytch_token_type": stytch_token_type, + } + + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/magic_links/redirect") + + res = self.sync_client.get(url, params=payload) + return MagiclinkredirectResponse.from_json(res.response.status_code, res.json) + + async def MagicLinkRedirect_async( + self, + public_token: str, + token: str, + stytch_token_type: str, + ) -> MagiclinkredirectResponse: + + payload: Dict[str, Any] = { + "public_token": public_token, + "token": token, + "stytch_token_type": stytch_token_type, + } + + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/magic_links/redirect") + + res = await self.async_client.get(url, params=payload) + return MagiclinkredirectResponse.from_json(res.response.status, res.json) + + def MagicLinksRedirectCaptcha( + self, + public_token: str, + redirect_url: str, + captcha: str, + ) -> MagiclinksredirectcaptchaResponse: + + payload: Dict[str, Any] = { + "public_token": public_token, + "redirect_url": redirect_url, + "captcha": captcha, + } + + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/magic_links/redirect/captcha") + + res = self.sync_client.post(url, json=payload) + return MagiclinksredirectcaptchaResponse.from_json(res.response.status_code, res.json) + + async def MagicLinksRedirectCaptcha_async( + self, + public_token: str, + redirect_url: str, + captcha: str, + ) -> MagiclinksredirectcaptchaResponse: + + payload: Dict[str, Any] = { + "public_token": public_token, + "redirect_url": redirect_url, + "captcha": captcha, + } + + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/magic_links/redirect/captcha") + + res = await self.async_client.post(url, json=payload) + return MagiclinksredirectcaptchaResponse.from_json(res.response.status, res.json) + diff --git a/stytch/api/multi_tenant_magic_service.py b/stytch/api/multi_tenant_magic_service.py new file mode 100644 index 00000000..26eca60a --- /dev/null +++ b/stytch/api/multi_tenant_magic_service.py @@ -0,0 +1,359 @@ +# !!! +# WARNING: This file is autogenerated +# Only modify code within MANUAL() sections +# or your changes may be overwritten later! +# !!! + +from typing import Any, Dict, Optional + +from stytch.core.api_base import ApiBase +from stytch.core.http.client import AsyncClient, SyncClient +from stytch.models.multi_tenant_magic_service import ( + B2BmagiclinksdiscoveryauthenticateResponse, + B2BmagiclinksemaildiscoverysendResponse, + MultitenantmagiclinksauthenticateResponse, + MultitenantmagiclinksemailinviteResponse, + MultitenantmagiclinksemailloginorsignupResponse, +) + + +class MultiTenantMagicService: + def __init__( + self, + api_base: ApiBase, + sync_client: SyncClient, + async_client: AsyncClient, + ) -> None: + self.api_base = api_base + self.sync_client = sync_client + self.async_client = async_client + + @property + def sub_url(self) -> str: + return "multi_tenant_magic_service" + + def MultiTenantMagicLinksEmailLoginOrSignup( + self, + organization_id: str, + email_address: str, + login_redirect_url: Optional[str] = None, + signup_redirect_url: Optional[str] = None, + pkce_code_challenge: Optional[str] = None, + login_template_id: Optional[str] = None, + signup_template_id: Optional[str] = None, + locale: Optional[str] = None, + ) -> MultitenantmagiclinksemailloginorsignupResponse: + payload: Dict[str, Any] = { + "organization_id": organization_id, + "email_address": email_address, + } + + if login_redirect_url is not None: + payload["login_redirect_url"] = login_redirect_url + if signup_redirect_url is not None: + payload["signup_redirect_url"] = signup_redirect_url + if pkce_code_challenge is not None: + payload["pkce_code_challenge"] = pkce_code_challenge + if login_template_id is not None: + payload["login_template_id"] = login_template_id + if signup_template_id is not None: + payload["signup_template_id"] = signup_template_id + if locale is not None: + payload["locale"] = locale + + url = self.api_base.route_with_sub_url( + self.sub_url, "/v1/b2b/magic_links/email/login_or_signup" + ) + + res = self.sync_client.post(url, json=payload) + return MultitenantmagiclinksemailloginorsignupResponse.from_json( + res.response.status_code, res.json + ) + + async def MultiTenantMagicLinksEmailLoginOrSignup_async( + self, + organization_id: str, + email_address: str, + login_redirect_url: Optional[str] = None, + signup_redirect_url: Optional[str] = None, + pkce_code_challenge: Optional[str] = None, + login_template_id: Optional[str] = None, + signup_template_id: Optional[str] = None, + locale: Optional[str] = None, + ) -> MultitenantmagiclinksemailloginorsignupResponse: + payload: Dict[str, Any] = { + "organization_id": organization_id, + "email_address": email_address, + } + + if login_redirect_url is not None: + payload["login_redirect_url"] = login_redirect_url + if signup_redirect_url is not None: + payload["signup_redirect_url"] = signup_redirect_url + if pkce_code_challenge is not None: + payload["pkce_code_challenge"] = pkce_code_challenge + if login_template_id is not None: + payload["login_template_id"] = login_template_id + if signup_template_id is not None: + payload["signup_template_id"] = signup_template_id + if locale is not None: + payload["locale"] = locale + + url = self.api_base.route_with_sub_url( + self.sub_url, "/v1/b2b/magic_links/email/login_or_signup" + ) + + res = await self.async_client.post(url, json=payload) + return MultitenantmagiclinksemailloginorsignupResponse.from_json( + res.response.status, res.json + ) + + def MultiTenantMagicLinksEmailInvite( + self, + organization_id: str, + email_address: str, + invite_redirect_url: Optional[str] = None, + invited_by_member_id: Optional[str] = None, + name: Optional[str] = None, + trusted_metadata: Optional[Dict[str, str]] = None, + untrusted_metadata: Optional[Dict[str, str]] = None, + invite_template_id: Optional[str] = None, + locale: Optional[str] = None, + ) -> MultitenantmagiclinksemailinviteResponse: + payload: Dict[str, Any] = { + "organization_id": organization_id, + "email_address": email_address, + } + + if invite_redirect_url is not None: + payload["invite_redirect_url"] = invite_redirect_url + if invited_by_member_id is not None: + payload["invited_by_member_id"] = invited_by_member_id + if name is not None: + payload["name"] = name + if trusted_metadata is not None: + payload["trusted_metadata"] = trusted_metadata + if untrusted_metadata is not None: + payload["untrusted_metadata"] = untrusted_metadata + if invite_template_id is not None: + payload["invite_template_id"] = invite_template_id + if locale is not None: + payload["locale"] = locale + + url = self.api_base.route_with_sub_url( + self.sub_url, "/v1/b2b/magic_links/email/invite" + ) + + res = self.sync_client.post(url, json=payload) + return MultitenantmagiclinksemailinviteResponse.from_json( + res.response.status_code, res.json + ) + + async def MultiTenantMagicLinksEmailInvite_async( + self, + organization_id: str, + email_address: str, + invite_redirect_url: Optional[str] = None, + invited_by_member_id: Optional[str] = None, + name: Optional[str] = None, + trusted_metadata: Optional[Dict[str, str]] = None, + untrusted_metadata: Optional[Dict[str, str]] = None, + invite_template_id: Optional[str] = None, + locale: Optional[str] = None, + ) -> MultitenantmagiclinksemailinviteResponse: + payload: Dict[str, Any] = { + "organization_id": organization_id, + "email_address": email_address, + } + + if invite_redirect_url is not None: + payload["invite_redirect_url"] = invite_redirect_url + if invited_by_member_id is not None: + payload["invited_by_member_id"] = invited_by_member_id + if name is not None: + payload["name"] = name + if trusted_metadata is not None: + payload["trusted_metadata"] = trusted_metadata + if untrusted_metadata is not None: + payload["untrusted_metadata"] = untrusted_metadata + if invite_template_id is not None: + payload["invite_template_id"] = invite_template_id + if locale is not None: + payload["locale"] = locale + + url = self.api_base.route_with_sub_url( + self.sub_url, "/v1/b2b/magic_links/email/invite" + ) + + res = await self.async_client.post(url, json=payload) + return MultitenantmagiclinksemailinviteResponse.from_json( + res.response.status, res.json + ) + + def MultiTenantMagicLinksAuthenticate( + self, + magic_links_token: str, + pkce_code_verifier: Optional[str] = None, + session_token: Optional[str] = None, + session_jwt: Optional[str] = None, + session_duration_minutes: Optional[int] = None, + session_custom_claims: Optional[Dict[str, str]] = None, + ) -> MultitenantmagiclinksauthenticateResponse: + payload: Dict[str, Any] = { + "magic_links_token": magic_links_token, + } + + if pkce_code_verifier is not None: + payload["pkce_code_verifier"] = pkce_code_verifier + if session_token is not None: + payload["session_token"] = session_token + if session_jwt is not None: + payload["session_jwt"] = session_jwt + if session_duration_minutes is not None: + payload["session_duration_minutes"] = session_duration_minutes + if session_custom_claims is not None: + payload["session_custom_claims"] = session_custom_claims + + url = self.api_base.route_with_sub_url( + self.sub_url, "/v1/b2b/magic_links/authenticate" + ) + + res = self.sync_client.post(url, json=payload) + return MultitenantmagiclinksauthenticateResponse.from_json( + res.response.status_code, res.json + ) + + async def MultiTenantMagicLinksAuthenticate_async( + self, + magic_links_token: str, + pkce_code_verifier: Optional[str] = None, + session_token: Optional[str] = None, + session_jwt: Optional[str] = None, + session_duration_minutes: Optional[int] = None, + session_custom_claims: Optional[Dict[str, str]] = None, + ) -> MultitenantmagiclinksauthenticateResponse: + payload: Dict[str, Any] = { + "magic_links_token": magic_links_token, + } + + if pkce_code_verifier is not None: + payload["pkce_code_verifier"] = pkce_code_verifier + if session_token is not None: + payload["session_token"] = session_token + if session_jwt is not None: + payload["session_jwt"] = session_jwt + if session_duration_minutes is not None: + payload["session_duration_minutes"] = session_duration_minutes + if session_custom_claims is not None: + payload["session_custom_claims"] = session_custom_claims + + url = self.api_base.route_with_sub_url( + self.sub_url, "/v1/b2b/magic_links/authenticate" + ) + + res = await self.async_client.post(url, json=payload) + return MultitenantmagiclinksauthenticateResponse.from_json( + res.response.status, res.json + ) + + def B2BMagicLinksEmailDiscoverySend( + self, + email_address: str, + discovery_redirect_url: Optional[str] = None, + pkce_code_challenge: Optional[str] = None, + login_template_id: Optional[str] = None, + locale: Optional[str] = None, + ) -> B2BmagiclinksemaildiscoverysendResponse: + payload: Dict[str, Any] = { + "email_address": email_address, + } + + if discovery_redirect_url is not None: + payload["discovery_redirect_url"] = discovery_redirect_url + if pkce_code_challenge is not None: + payload["pkce_code_challenge"] = pkce_code_challenge + if login_template_id is not None: + payload["login_template_id"] = login_template_id + if locale is not None: + payload["locale"] = locale + + url = self.api_base.route_with_sub_url( + self.sub_url, "/v1/b2b/magic_links/email/discovery/send" + ) + + res = self.sync_client.post(url, json=payload) + return B2BmagiclinksemaildiscoverysendResponse.from_json( + res.response.status_code, res.json + ) + + async def B2BMagicLinksEmailDiscoverySend_async( + self, + email_address: str, + discovery_redirect_url: Optional[str] = None, + pkce_code_challenge: Optional[str] = None, + login_template_id: Optional[str] = None, + locale: Optional[str] = None, + ) -> B2BmagiclinksemaildiscoverysendResponse: + payload: Dict[str, Any] = { + "email_address": email_address, + } + + if discovery_redirect_url is not None: + payload["discovery_redirect_url"] = discovery_redirect_url + if pkce_code_challenge is not None: + payload["pkce_code_challenge"] = pkce_code_challenge + if login_template_id is not None: + payload["login_template_id"] = login_template_id + if locale is not None: + payload["locale"] = locale + + url = self.api_base.route_with_sub_url( + self.sub_url, "/v1/b2b/magic_links/email/discovery/send" + ) + + res = await self.async_client.post(url, json=payload) + return B2BmagiclinksemaildiscoverysendResponse.from_json( + res.response.status, res.json + ) + + def B2BMagicLinksDiscoveryAuthenticate( + self, + discovery_magic_links_token: str, + pkce_code_verifier: Optional[str] = None, + ) -> B2BmagiclinksdiscoveryauthenticateResponse: + payload: Dict[str, Any] = { + "discovery_magic_links_token": discovery_magic_links_token, + } + + if pkce_code_verifier is not None: + payload["pkce_code_verifier"] = pkce_code_verifier + + url = self.api_base.route_with_sub_url( + self.sub_url, "/v1/b2b/magic_links/discovery/authenticate" + ) + + res = self.sync_client.post(url, json=payload) + return B2BmagiclinksdiscoveryauthenticateResponse.from_json( + res.response.status_code, res.json + ) + + async def B2BMagicLinksDiscoveryAuthenticate_async( + self, + discovery_magic_links_token: str, + pkce_code_verifier: Optional[str] = None, + ) -> B2BmagiclinksdiscoveryauthenticateResponse: + payload: Dict[str, Any] = { + "discovery_magic_links_token": discovery_magic_links_token, + } + + if pkce_code_verifier is not None: + payload["pkce_code_verifier"] = pkce_code_verifier + + url = self.api_base.route_with_sub_url( + self.sub_url, "/v1/b2b/magic_links/discovery/authenticate" + ) + + res = await self.async_client.post(url, json=payload) + return B2BmagiclinksdiscoveryauthenticateResponse.from_json( + res.response.status, res.json + ) diff --git a/stytch/api/multi_tenant_password_service.py b/stytch/api/multi_tenant_password_service.py new file mode 100644 index 00000000..7c95d577 --- /dev/null +++ b/stytch/api/multi_tenant_password_service.py @@ -0,0 +1,25 @@ +# !!! +# WARNING: This file is autogenerated +# Only modify code within MANUAL() sections +# or your changes may be overwritten later! +# !!! + + +from stytch.core.api_base import ApiBase +from stytch.core.http.client import AsyncClient, SyncClient + + +class MultiTenantPasswordService: + def __init__( + self, + api_base: ApiBase, + sync_client: SyncClient, + async_client: AsyncClient, + ) -> None: + self.api_base = api_base + self.sync_client = sync_client + self.async_client = async_client + + @property + def sub_url(self) -> str: + return "multi_tenant_password_service" diff --git a/stytch/api/multi_tenant_session_service.py b/stytch/api/multi_tenant_session_service.py new file mode 100644 index 00000000..f31ff301 --- /dev/null +++ b/stytch/api/multi_tenant_session_service.py @@ -0,0 +1,25 @@ +# !!! +# WARNING: This file is autogenerated +# Only modify code within MANUAL() sections +# or your changes may be overwritten later! +# !!! + + +from stytch.core.api_base import ApiBase +from stytch.core.http.client import AsyncClient, SyncClient + + +class MultiTenantSessionService: + def __init__( + self, + api_base: ApiBase, + sync_client: SyncClient, + async_client: AsyncClient, + ) -> None: + self.api_base = api_base + self.sync_client = sync_client + self.async_client = async_client + + @property + def sub_url(self) -> str: + return "multi_tenant_session_service" diff --git a/stytch/api/o_auth_service.py b/stytch/api/o_auth_service.py new file mode 100644 index 00000000..43db8833 --- /dev/null +++ b/stytch/api/o_auth_service.py @@ -0,0 +1,135 @@ +# !!! +# WARNING: This file is autogenerated +# Only modify code within MANUAL() sections +# or your changes may be overwritten later! +# !!! + +from typing import Any, Dict, Optional + +from stytch.core.api_base import ApiBase +from stytch.core.http.client import AsyncClient, SyncClient +from stytch.models.o_auth_service import OauthattachResponse, OauthauthenticateResponse + + +class OAuthService: + def __init__( + self, + api_base: ApiBase, + sync_client: SyncClient, + async_client: AsyncClient, + ) -> None: + self.api_base = api_base + self.sync_client = sync_client + self.async_client = async_client + + @property + def sub_url(self) -> str: + return "o_auth_service" + + def OAuthAttach( + self, + provider: str, + user_id: str, + session_token: Optional[str] = None, + session_jwt: Optional[str] = None, + ) -> OauthattachResponse: + payload: Dict[str, Any] = { + "provider": provider, + "user_id": user_id, + } + + if session_token is not None: + payload["session_token"] = session_token + if session_jwt is not None: + payload["session_jwt"] = session_jwt + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/oauth/attach") + + res = self.sync_client.post(url, json=payload) + return OauthattachResponse.from_json(res.response.status_code, res.json) + + async def OAuthAttach_async( + self, + provider: str, + user_id: str, + session_token: Optional[str] = None, + session_jwt: Optional[str] = None, + ) -> OauthattachResponse: + payload: Dict[str, Any] = { + "provider": provider, + "user_id": user_id, + } + + if session_token is not None: + payload["session_token"] = session_token + if session_jwt is not None: + payload["session_jwt"] = session_jwt + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/oauth/attach") + + res = await self.async_client.post(url, json=payload) + return OauthattachResponse.from_json(res.response.status, res.json) + + def OAuthAuthenticate( + self, + token: str, + session_management_type: Optional[str] = None, + session_token: Optional[str] = None, + session_duration_minutes: Optional[int] = None, + session_jwt: Optional[str] = None, + session_custom_claims: Optional[Dict[str, Any]] = None, + code_verifier: Optional[str] = None, + ) -> OauthauthenticateResponse: + payload: Dict[str, Any] = { + "token": token, + } + + if session_management_type is not None: + payload["session_management_type"] = session_management_type + if session_token is not None: + payload["session_token"] = session_token + if session_duration_minutes is not None: + payload["session_duration_minutes"] = session_duration_minutes + if session_jwt is not None: + payload["session_jwt"] = session_jwt + if session_custom_claims is not None: + payload["session_custom_claims"] = session_custom_claims + if code_verifier is not None: + payload["code_verifier"] = code_verifier + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/oauth/authenticate") + + res = self.sync_client.post(url, json=payload) + return OauthauthenticateResponse.from_json(res.response.status_code, res.json) + + async def OAuthAuthenticate_async( + self, + token: str, + session_management_type: Optional[str] = None, + session_token: Optional[str] = None, + session_duration_minutes: Optional[int] = None, + session_jwt: Optional[str] = None, + session_custom_claims: Optional[Dict[str, Any]] = None, + code_verifier: Optional[str] = None, + ) -> OauthauthenticateResponse: + payload: Dict[str, Any] = { + "token": token, + } + + if session_management_type is not None: + payload["session_management_type"] = session_management_type + if session_token is not None: + payload["session_token"] = session_token + if session_duration_minutes is not None: + payload["session_duration_minutes"] = session_duration_minutes + if session_jwt is not None: + payload["session_jwt"] = session_jwt + if session_custom_claims is not None: + payload["session_custom_claims"] = session_custom_claims + if code_verifier is not None: + payload["code_verifier"] = code_verifier + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/oauth/authenticate") + + res = await self.async_client.post(url, json=payload) + return OauthauthenticateResponse.from_json(res.response.status, res.json) diff --git a/stytch/api/organization_service.py b/stytch/api/organization_service.py new file mode 100644 index 00000000..9c13c381 --- /dev/null +++ b/stytch/api/organization_service.py @@ -0,0 +1,25 @@ +# !!! +# WARNING: This file is autogenerated +# Only modify code within MANUAL() sections +# or your changes may be overwritten later! +# !!! + + +from stytch.core.api_base import ApiBase +from stytch.core.http.client import AsyncClient, SyncClient + + +class OrganizationService: + def __init__( + self, + api_base: ApiBase, + sync_client: SyncClient, + async_client: AsyncClient, + ) -> None: + self.api_base = api_base + self.sync_client = sync_client + self.async_client = async_client + + @property + def sub_url(self) -> str: + return "organization_service" diff --git a/stytch/api/otp_service.py b/stytch/api/otp_service.py new file mode 100644 index 00000000..6e31c4ab --- /dev/null +++ b/stytch/api/otp_service.py @@ -0,0 +1,480 @@ +# !!! +# WARNING: This file is autogenerated +# Only modify code within MANUAL() sections +# or your changes may be overwritten later! +# !!! + +from typing import Any, Dict, List, Optional, Union + +import pydantic + +from stytch.core.api_base import ApiBase +from stytch.core.http.client import AsyncClient, SyncClient +from stytch.models.otp_service import ( + OtpsauthenticateResponse, + OtpsemailloginorcreateResponse, + OtpsemailsendResponse, + OtpssmsloginorcreateResponse, + OtpssmssendResponse, + OtpswhatsapploginorcreateResponse, + OtpswhatsappsendResponse, +) + + +class OTPService: + def __init__( + self, + api_base: ApiBase, + sync_client: SyncClient, + async_client: AsyncClient, + ) -> None: + self.api_base = api_base + self.sync_client = sync_client + self.async_client = async_client + + @property + def sub_url(self) -> str: + return "otp_service" + + def OTPsSMSSend( + self, + phone_number: str, + expiration_minutes: Optional[int] = None, + attributes: Optional[Dict[str, str]] = None, + locale: Optional[str] = None, + user_id: str, + session_token: Optional[str] = None, + session_jwt: Optional[str] = None, + ) -> OtpssmssendResponse: + + payload: Dict[str, Any] = { + "phone_number": phone_number, + "user_id": user_id, + } + + if expiration_minutes is not None: + payload["expiration_minutes"] = expiration_minutes + if attributes is not None: + payload["attributes"] = attributes + if locale is not None: + payload["locale"] = locale + if session_token is not None: + payload["session_token"] = session_token + if session_jwt is not None: + payload["session_jwt"] = session_jwt + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/otps/sms/send") + + res = self.sync_client.post(url, json=payload) + return OtpssmssendResponse.from_json(res.response.status_code, res.json) + + async def OTPsSMSSend_async( + self, + phone_number: str, + expiration_minutes: Optional[int] = None, + attributes: Optional[Dict[str, str]] = None, + locale: Optional[str] = None, + user_id: str, + session_token: Optional[str] = None, + session_jwt: Optional[str] = None, + ) -> OtpssmssendResponse: + + payload: Dict[str, Any] = { + "phone_number": phone_number, + "user_id": user_id, + } + + if expiration_minutes is not None: + payload["expiration_minutes"] = expiration_minutes + if attributes is not None: + payload["attributes"] = attributes + if locale is not None: + payload["locale"] = locale + if session_token is not None: + payload["session_token"] = session_token + if session_jwt is not None: + payload["session_jwt"] = session_jwt + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/otps/sms/send") + + res = await self.async_client.post(url, json=payload) + return OtpssmssendResponse.from_json(res.response.status, res.json) + + def OTPsSMSLoginOrCreate( + self, + phone_number: str, + expiration_minutes: Optional[int] = None, + attributes: Optional[Dict[str, str]] = None, + create_user_as_pending: bool, + locale: Optional[str] = None, + ) -> OtpssmsloginorcreateResponse: + + payload: Dict[str, Any] = { + "phone_number": phone_number, + "create_user_as_pending": create_user_as_pending, + } + + if expiration_minutes is not None: + payload["expiration_minutes"] = expiration_minutes + if attributes is not None: + payload["attributes"] = attributes + if locale is not None: + payload["locale"] = locale + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/otps/sms/login_or_create") + + res = self.sync_client.post(url, json=payload) + return OtpssmsloginorcreateResponse.from_json(res.response.status_code, res.json) + + async def OTPsSMSLoginOrCreate_async( + self, + phone_number: str, + expiration_minutes: Optional[int] = None, + attributes: Optional[Dict[str, str]] = None, + create_user_as_pending: bool, + locale: Optional[str] = None, + ) -> OtpssmsloginorcreateResponse: + + payload: Dict[str, Any] = { + "phone_number": phone_number, + "create_user_as_pending": create_user_as_pending, + } + + if expiration_minutes is not None: + payload["expiration_minutes"] = expiration_minutes + if attributes is not None: + payload["attributes"] = attributes + if locale is not None: + payload["locale"] = locale + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/otps/sms/login_or_create") + + res = await self.async_client.post(url, json=payload) + return OtpssmsloginorcreateResponse.from_json(res.response.status, res.json) + + def OTPsWhatsAppSend( + self, + phone_number: str, + expiration_minutes: Optional[int] = None, + attributes: Optional[Dict[str, str]] = None, + locale: Optional[str] = None, + user_id: str, + session_token: Optional[str] = None, + session_jwt: Optional[str] = None, + ) -> OtpswhatsappsendResponse: + + payload: Dict[str, Any] = { + "phone_number": phone_number, + "user_id": user_id, + } + + if expiration_minutes is not None: + payload["expiration_minutes"] = expiration_minutes + if attributes is not None: + payload["attributes"] = attributes + if locale is not None: + payload["locale"] = locale + if session_token is not None: + payload["session_token"] = session_token + if session_jwt is not None: + payload["session_jwt"] = session_jwt + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/otps/whatsapp/send") + + res = self.sync_client.post(url, json=payload) + return OtpswhatsappsendResponse.from_json(res.response.status_code, res.json) + + async def OTPsWhatsAppSend_async( + self, + phone_number: str, + expiration_minutes: Optional[int] = None, + attributes: Optional[Dict[str, str]] = None, + locale: Optional[str] = None, + user_id: str, + session_token: Optional[str] = None, + session_jwt: Optional[str] = None, + ) -> OtpswhatsappsendResponse: + + payload: Dict[str, Any] = { + "phone_number": phone_number, + "user_id": user_id, + } + + if expiration_minutes is not None: + payload["expiration_minutes"] = expiration_minutes + if attributes is not None: + payload["attributes"] = attributes + if locale is not None: + payload["locale"] = locale + if session_token is not None: + payload["session_token"] = session_token + if session_jwt is not None: + payload["session_jwt"] = session_jwt + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/otps/whatsapp/send") + + res = await self.async_client.post(url, json=payload) + return OtpswhatsappsendResponse.from_json(res.response.status, res.json) + + def OTPsWhatsAppLoginOrCreate( + self, + phone_number: str, + expiration_minutes: Optional[int] = None, + attributes: Optional[Dict[str, str]] = None, + create_user_as_pending: bool, + locale: Optional[str] = None, + ) -> OtpswhatsapploginorcreateResponse: + + payload: Dict[str, Any] = { + "phone_number": phone_number, + "create_user_as_pending": create_user_as_pending, + } + + if expiration_minutes is not None: + payload["expiration_minutes"] = expiration_minutes + if attributes is not None: + payload["attributes"] = attributes + if locale is not None: + payload["locale"] = locale + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/otps/whatsapp/login_or_create") + + res = self.sync_client.post(url, json=payload) + return OtpswhatsapploginorcreateResponse.from_json(res.response.status_code, res.json) + + async def OTPsWhatsAppLoginOrCreate_async( + self, + phone_number: str, + expiration_minutes: Optional[int] = None, + attributes: Optional[Dict[str, str]] = None, + create_user_as_pending: bool, + locale: Optional[str] = None, + ) -> OtpswhatsapploginorcreateResponse: + + payload: Dict[str, Any] = { + "phone_number": phone_number, + "create_user_as_pending": create_user_as_pending, + } + + if expiration_minutes is not None: + payload["expiration_minutes"] = expiration_minutes + if attributes is not None: + payload["attributes"] = attributes + if locale is not None: + payload["locale"] = locale + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/otps/whatsapp/login_or_create") + + res = await self.async_client.post(url, json=payload) + return OtpswhatsapploginorcreateResponse.from_json(res.response.status, res.json) + + def OTPsEmailSend( + self, + email: str, + expiration_minutes: Optional[int] = None, + attributes: Optional[Dict[str, str]] = None, + locale: Optional[str] = None, + user_id: str, + session_token: Optional[str] = None, + session_jwt: Optional[str] = None, + login_template_id: Optional[str] = None, + signup_template_id: Optional[str] = None, + ) -> OtpsemailsendResponse: + + payload: Dict[str, Any] = { + "email": email, + "user_id": user_id, + } + + if expiration_minutes is not None: + payload["expiration_minutes"] = expiration_minutes + if attributes is not None: + payload["attributes"] = attributes + if locale is not None: + payload["locale"] = locale + if session_token is not None: + payload["session_token"] = session_token + if session_jwt is not None: + payload["session_jwt"] = session_jwt + if login_template_id is not None: + payload["login_template_id"] = login_template_id + if signup_template_id is not None: + payload["signup_template_id"] = signup_template_id + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/otps/email/send") + + res = self.sync_client.post(url, json=payload) + return OtpsemailsendResponse.from_json(res.response.status_code, res.json) + + async def OTPsEmailSend_async( + self, + email: str, + expiration_minutes: Optional[int] = None, + attributes: Optional[Dict[str, str]] = None, + locale: Optional[str] = None, + user_id: str, + session_token: Optional[str] = None, + session_jwt: Optional[str] = None, + login_template_id: Optional[str] = None, + signup_template_id: Optional[str] = None, + ) -> OtpsemailsendResponse: + + payload: Dict[str, Any] = { + "email": email, + "user_id": user_id, + } + + if expiration_minutes is not None: + payload["expiration_minutes"] = expiration_minutes + if attributes is not None: + payload["attributes"] = attributes + if locale is not None: + payload["locale"] = locale + if session_token is not None: + payload["session_token"] = session_token + if session_jwt is not None: + payload["session_jwt"] = session_jwt + if login_template_id is not None: + payload["login_template_id"] = login_template_id + if signup_template_id is not None: + payload["signup_template_id"] = signup_template_id + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/otps/email/send") + + res = await self.async_client.post(url, json=payload) + return OtpsemailsendResponse.from_json(res.response.status, res.json) + + def OTPsEmailLoginOrCreate( + self, + email: str, + expiration_minutes: Optional[int] = None, + attributes: Optional[Dict[str, str]] = None, + create_user_as_pending: bool, + locale: Optional[str] = None, + login_template_id: Optional[str] = None, + signup_template_id: Optional[str] = None, + ) -> OtpsemailloginorcreateResponse: + + payload: Dict[str, Any] = { + "email": email, + "create_user_as_pending": create_user_as_pending, + } + + if expiration_minutes is not None: + payload["expiration_minutes"] = expiration_minutes + if attributes is not None: + payload["attributes"] = attributes + if locale is not None: + payload["locale"] = locale + if login_template_id is not None: + payload["login_template_id"] = login_template_id + if signup_template_id is not None: + payload["signup_template_id"] = signup_template_id + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/otps/email/login_or_create") + + res = self.sync_client.post(url, json=payload) + return OtpsemailloginorcreateResponse.from_json(res.response.status_code, res.json) + + async def OTPsEmailLoginOrCreate_async( + self, + email: str, + expiration_minutes: Optional[int] = None, + attributes: Optional[Dict[str, str]] = None, + create_user_as_pending: bool, + locale: Optional[str] = None, + login_template_id: Optional[str] = None, + signup_template_id: Optional[str] = None, + ) -> OtpsemailloginorcreateResponse: + + payload: Dict[str, Any] = { + "email": email, + "create_user_as_pending": create_user_as_pending, + } + + if expiration_minutes is not None: + payload["expiration_minutes"] = expiration_minutes + if attributes is not None: + payload["attributes"] = attributes + if locale is not None: + payload["locale"] = locale + if login_template_id is not None: + payload["login_template_id"] = login_template_id + if signup_template_id is not None: + payload["signup_template_id"] = signup_template_id + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/otps/email/login_or_create") + + res = await self.async_client.post(url, json=payload) + return OtpsemailloginorcreateResponse.from_json(res.response.status, res.json) + + def OTPsAuthenticate( + self, + method_id: str, + code: str, + attributes: Optional[Dict[str, str]] = None, + options: Optional[Dict[str, str]] = None, + session_token: Optional[str] = None, + session_duration_minutes: Optional[int] = None, + session_jwt: Optional[str] = None, + session_custom_claims: Optional[Dict[str, Any]] = None, + ) -> OtpsauthenticateResponse: + + payload: Dict[str, Any] = { + "method_id": method_id, + "code": code, + } + + if attributes is not None: + payload["attributes"] = attributes + if options is not None: + payload["options"] = options + if session_token is not None: + payload["session_token"] = session_token + if session_duration_minutes is not None: + payload["session_duration_minutes"] = session_duration_minutes + if session_jwt is not None: + payload["session_jwt"] = session_jwt + if session_custom_claims is not None: + payload["session_custom_claims"] = session_custom_claims + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/otps/authenticate") + + res = self.sync_client.post(url, json=payload) + return OtpsauthenticateResponse.from_json(res.response.status_code, res.json) + + async def OTPsAuthenticate_async( + self, + method_id: str, + code: str, + attributes: Optional[Dict[str, str]] = None, + options: Optional[Dict[str, str]] = None, + session_token: Optional[str] = None, + session_duration_minutes: Optional[int] = None, + session_jwt: Optional[str] = None, + session_custom_claims: Optional[Dict[str, Any]] = None, + ) -> OtpsauthenticateResponse: + + payload: Dict[str, Any] = { + "method_id": method_id, + "code": code, + } + + if attributes is not None: + payload["attributes"] = attributes + if options is not None: + payload["options"] = options + if session_token is not None: + payload["session_token"] = session_token + if session_duration_minutes is not None: + payload["session_duration_minutes"] = session_duration_minutes + if session_jwt is not None: + payload["session_jwt"] = session_jwt + if session_custom_claims is not None: + payload["session_custom_claims"] = session_custom_claims + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/otps/authenticate") + + res = await self.async_client.post(url, json=payload) + return OtpsauthenticateResponse.from_json(res.response.status, res.json) + diff --git a/stytch/api/password_service.py b/stytch/api/password_service.py new file mode 100644 index 00000000..0a7fb99e --- /dev/null +++ b/stytch/api/password_service.py @@ -0,0 +1,531 @@ +# !!! +# WARNING: This file is autogenerated +# Only modify code within MANUAL() sections +# or your changes may be overwritten later! +# !!! + +from typing import Any, Dict, List, Optional, Union + +import pydantic + +from stytch.core.api_base import ApiBase +from stytch.core.http.client import AsyncClient, SyncClient +from stytch.models.password_service import ( + PasswordsauthenticateResponse, + PasswordscreateResponse, + PasswordsemailresetResponse, + PasswordsemailresetstartResponse, + PasswordsexistingpasswordresetResponse, + PasswordsmigrateResponse, + PasswordssessionresetResponse, + PasswordsstrengthcheckResponse, +) + + +class PasswordService: + def __init__( + self, + api_base: ApiBase, + sync_client: SyncClient, + async_client: AsyncClient, + ) -> None: + self.api_base = api_base + self.sync_client = sync_client + self.async_client = async_client + + @property + def sub_url(self) -> str: + return "password_service" + + def PasswordsCreate( + self, + email: str, + password: str, + session_duration_minutes: Optional[int] = None, + session_custom_claims: Optional[Dict[str, Any]] = None, + trusted_metadata: Optional[Dict[str, Any]] = None, + untrusted_metadata: Optional[Dict[str, Any]] = None, + name: None, + ) -> PasswordscreateResponse: + + payload: Dict[str, Any] = { + "email": email, + "password": password, + } + + if session_duration_minutes is not None: + payload["session_duration_minutes"] = session_duration_minutes + if session_custom_claims is not None: + payload["session_custom_claims"] = session_custom_claims + if trusted_metadata is not None: + payload["trusted_metadata"] = trusted_metadata + if untrusted_metadata is not None: + payload["untrusted_metadata"] = untrusted_metadata + if name is not None: + payload["name"] = name + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/passwords") + + res = self.sync_client.post(url, json=payload) + return PasswordscreateResponse.from_json(res.response.status_code, res.json) + + async def PasswordsCreate_async( + self, + email: str, + password: str, + session_duration_minutes: Optional[int] = None, + session_custom_claims: Optional[Dict[str, Any]] = None, + trusted_metadata: Optional[Dict[str, Any]] = None, + untrusted_metadata: Optional[Dict[str, Any]] = None, + name: None, + ) -> PasswordscreateResponse: + + payload: Dict[str, Any] = { + "email": email, + "password": password, + } + + if session_duration_minutes is not None: + payload["session_duration_minutes"] = session_duration_minutes + if session_custom_claims is not None: + payload["session_custom_claims"] = session_custom_claims + if trusted_metadata is not None: + payload["trusted_metadata"] = trusted_metadata + if untrusted_metadata is not None: + payload["untrusted_metadata"] = untrusted_metadata + if name is not None: + payload["name"] = name + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/passwords") + + res = await self.async_client.post(url, json=payload) + return PasswordscreateResponse.from_json(res.response.status, res.json) + + def PasswordsAuthenticate( + self, + email: str, + password: str, + session_token: Optional[str] = None, + session_duration_minutes: Optional[int] = None, + session_jwt: Optional[str] = None, + session_custom_claims: Optional[Dict[str, Any]] = None, + ) -> PasswordsauthenticateResponse: + + payload: Dict[str, Any] = { + "email": email, + "password": password, + } + + if session_token is not None: + payload["session_token"] = session_token + if session_duration_minutes is not None: + payload["session_duration_minutes"] = session_duration_minutes + if session_jwt is not None: + payload["session_jwt"] = session_jwt + if session_custom_claims is not None: + payload["session_custom_claims"] = session_custom_claims + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/passwords/authenticate") + + res = self.sync_client.post(url, json=payload) + return PasswordsauthenticateResponse.from_json(res.response.status_code, res.json) + + async def PasswordsAuthenticate_async( + self, + email: str, + password: str, + session_token: Optional[str] = None, + session_duration_minutes: Optional[int] = None, + session_jwt: Optional[str] = None, + session_custom_claims: Optional[Dict[str, Any]] = None, + ) -> PasswordsauthenticateResponse: + + payload: Dict[str, Any] = { + "email": email, + "password": password, + } + + if session_token is not None: + payload["session_token"] = session_token + if session_duration_minutes is not None: + payload["session_duration_minutes"] = session_duration_minutes + if session_jwt is not None: + payload["session_jwt"] = session_jwt + if session_custom_claims is not None: + payload["session_custom_claims"] = session_custom_claims + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/passwords/authenticate") + + res = await self.async_client.post(url, json=payload) + return PasswordsauthenticateResponse.from_json(res.response.status, res.json) + + def PasswordsEmailResetStart( + self, + email: str, + reset_password_redirect_url: str, + reset_password_expiration_minutes: Optional[int] = None, + code_challenge: Optional[str] = None, + attributes: Optional[Dict[str, str]] = None, + login_redirect_url: str, + locale: Optional[str] = None, + reset_password_template_id: Optional[str] = None, + ) -> PasswordsemailresetstartResponse: + + payload: Dict[str, Any] = { + "email": email, + "reset_password_redirect_url": reset_password_redirect_url, + "login_redirect_url": login_redirect_url, + } + + if reset_password_expiration_minutes is not None: + payload["reset_password_expiration_minutes"] = reset_password_expiration_minutes + if code_challenge is not None: + payload["code_challenge"] = code_challenge + if attributes is not None: + payload["attributes"] = attributes + if locale is not None: + payload["locale"] = locale + if reset_password_template_id is not None: + payload["reset_password_template_id"] = reset_password_template_id + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/passwords/email/reset/start") + + res = self.sync_client.post(url, json=payload) + return PasswordsemailresetstartResponse.from_json(res.response.status_code, res.json) + + async def PasswordsEmailResetStart_async( + self, + email: str, + reset_password_redirect_url: str, + reset_password_expiration_minutes: Optional[int] = None, + code_challenge: Optional[str] = None, + attributes: Optional[Dict[str, str]] = None, + login_redirect_url: str, + locale: Optional[str] = None, + reset_password_template_id: Optional[str] = None, + ) -> PasswordsemailresetstartResponse: + + payload: Dict[str, Any] = { + "email": email, + "reset_password_redirect_url": reset_password_redirect_url, + "login_redirect_url": login_redirect_url, + } + + if reset_password_expiration_minutes is not None: + payload["reset_password_expiration_minutes"] = reset_password_expiration_minutes + if code_challenge is not None: + payload["code_challenge"] = code_challenge + if attributes is not None: + payload["attributes"] = attributes + if locale is not None: + payload["locale"] = locale + if reset_password_template_id is not None: + payload["reset_password_template_id"] = reset_password_template_id + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/passwords/email/reset/start") + + res = await self.async_client.post(url, json=payload) + return PasswordsemailresetstartResponse.from_json(res.response.status, res.json) + + def PasswordsEmailReset( + self, + token: str, + password: str, + session_token: Optional[str] = None, + session_duration_minutes: Optional[int] = None, + session_jwt: Optional[str] = None, + code_verifier: Optional[str] = None, + session_custom_claims: Optional[Dict[str, Any]] = None, + attributes: Optional[Dict[str, str]] = None, + options: Optional[Dict[str, str]] = None, + ) -> PasswordsemailresetResponse: + + payload: Dict[str, Any] = { + "token": token, + "password": password, + } + + if session_token is not None: + payload["session_token"] = session_token + if session_duration_minutes is not None: + payload["session_duration_minutes"] = session_duration_minutes + if session_jwt is not None: + payload["session_jwt"] = session_jwt + if code_verifier is not None: + payload["code_verifier"] = code_verifier + if session_custom_claims is not None: + payload["session_custom_claims"] = session_custom_claims + if attributes is not None: + payload["attributes"] = attributes + if options is not None: + payload["options"] = options + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/passwords/email/reset") + + res = self.sync_client.post(url, json=payload) + return PasswordsemailresetResponse.from_json(res.response.status_code, res.json) + + async def PasswordsEmailReset_async( + self, + token: str, + password: str, + session_token: Optional[str] = None, + session_duration_minutes: Optional[int] = None, + session_jwt: Optional[str] = None, + code_verifier: Optional[str] = None, + session_custom_claims: Optional[Dict[str, Any]] = None, + attributes: Optional[Dict[str, str]] = None, + options: Optional[Dict[str, str]] = None, + ) -> PasswordsemailresetResponse: + + payload: Dict[str, Any] = { + "token": token, + "password": password, + } + + if session_token is not None: + payload["session_token"] = session_token + if session_duration_minutes is not None: + payload["session_duration_minutes"] = session_duration_minutes + if session_jwt is not None: + payload["session_jwt"] = session_jwt + if code_verifier is not None: + payload["code_verifier"] = code_verifier + if session_custom_claims is not None: + payload["session_custom_claims"] = session_custom_claims + if attributes is not None: + payload["attributes"] = attributes + if options is not None: + payload["options"] = options + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/passwords/email/reset") + + res = await self.async_client.post(url, json=payload) + return PasswordsemailresetResponse.from_json(res.response.status, res.json) + + def PasswordsExistingPasswordReset( + self, + email: str, + existing_password: str, + new_password: str, + session_token: Optional[str] = None, + session_duration_minutes: Optional[int] = None, + session_jwt: Optional[str] = None, + session_custom_claims: Optional[Dict[str, Any]] = None, + ) -> PasswordsexistingpasswordresetResponse: + + payload: Dict[str, Any] = { + "email": email, + "existing_password": existing_password, + "new_password": new_password, + } + + if session_token is not None: + payload["session_token"] = session_token + if session_duration_minutes is not None: + payload["session_duration_minutes"] = session_duration_minutes + if session_jwt is not None: + payload["session_jwt"] = session_jwt + if session_custom_claims is not None: + payload["session_custom_claims"] = session_custom_claims + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/passwords/existing_password/reset") + + res = self.sync_client.post(url, json=payload) + return PasswordsexistingpasswordresetResponse.from_json(res.response.status_code, res.json) + + async def PasswordsExistingPasswordReset_async( + self, + email: str, + existing_password: str, + new_password: str, + session_token: Optional[str] = None, + session_duration_minutes: Optional[int] = None, + session_jwt: Optional[str] = None, + session_custom_claims: Optional[Dict[str, Any]] = None, + ) -> PasswordsexistingpasswordresetResponse: + + payload: Dict[str, Any] = { + "email": email, + "existing_password": existing_password, + "new_password": new_password, + } + + if session_token is not None: + payload["session_token"] = session_token + if session_duration_minutes is not None: + payload["session_duration_minutes"] = session_duration_minutes + if session_jwt is not None: + payload["session_jwt"] = session_jwt + if session_custom_claims is not None: + payload["session_custom_claims"] = session_custom_claims + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/passwords/existing_password/reset") + + res = await self.async_client.post(url, json=payload) + return PasswordsexistingpasswordresetResponse.from_json(res.response.status, res.json) + + def PasswordsSessionReset( + self, + password: str, + session_token: Optional[str] = None, + session_jwt: Optional[str] = None, + ) -> PasswordssessionresetResponse: + + payload: Dict[str, Any] = { + "password": password, + } + + if session_token is not None: + payload["session_token"] = session_token + if session_jwt is not None: + payload["session_jwt"] = session_jwt + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/passwords/session/reset") + + res = self.sync_client.post(url, json=payload) + return PasswordssessionresetResponse.from_json(res.response.status_code, res.json) + + async def PasswordsSessionReset_async( + self, + password: str, + session_token: Optional[str] = None, + session_jwt: Optional[str] = None, + ) -> PasswordssessionresetResponse: + + payload: Dict[str, Any] = { + "password": password, + } + + if session_token is not None: + payload["session_token"] = session_token + if session_jwt is not None: + payload["session_jwt"] = session_jwt + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/passwords/session/reset") + + res = await self.async_client.post(url, json=payload) + return PasswordssessionresetResponse.from_json(res.response.status, res.json) + + def PasswordsMigrate( + self, + email: str, + hash: str, + hash_type: str, + md_5_config: None, + argon_2_config: None, + sha_1_config: None, + scrypt_config: None, + first_name: str, + last_name: str, + trusted_metadata: Optional[Dict[str, Any]] = None, + untrusted_metadata: Optional[Dict[str, Any]] = None, + set_email_verified: bool, + ) -> PasswordsmigrateResponse: + + payload: Dict[str, Any] = { + "email": email, + "hash": hash, + "hash_type": hash_type, + "first_name": first_name, + "last_name": last_name, + "set_email_verified": set_email_verified, + } + + if md_5_config is not None: + payload["md_5_config"] = md_5_config + if argon_2_config is not None: + payload["argon_2_config"] = argon_2_config + if sha_1_config is not None: + payload["sha_1_config"] = sha_1_config + if scrypt_config is not None: + payload["scrypt_config"] = scrypt_config + if trusted_metadata is not None: + payload["trusted_metadata"] = trusted_metadata + if untrusted_metadata is not None: + payload["untrusted_metadata"] = untrusted_metadata + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/passwords/migrate") + + res = self.sync_client.post(url, json=payload) + return PasswordsmigrateResponse.from_json(res.response.status_code, res.json) + + async def PasswordsMigrate_async( + self, + email: str, + hash: str, + hash_type: str, + md_5_config: None, + argon_2_config: None, + sha_1_config: None, + scrypt_config: None, + first_name: str, + last_name: str, + trusted_metadata: Optional[Dict[str, Any]] = None, + untrusted_metadata: Optional[Dict[str, Any]] = None, + set_email_verified: bool, + ) -> PasswordsmigrateResponse: + + payload: Dict[str, Any] = { + "email": email, + "hash": hash, + "hash_type": hash_type, + "first_name": first_name, + "last_name": last_name, + "set_email_verified": set_email_verified, + } + + if md_5_config is not None: + payload["md_5_config"] = md_5_config + if argon_2_config is not None: + payload["argon_2_config"] = argon_2_config + if sha_1_config is not None: + payload["sha_1_config"] = sha_1_config + if scrypt_config is not None: + payload["scrypt_config"] = scrypt_config + if trusted_metadata is not None: + payload["trusted_metadata"] = trusted_metadata + if untrusted_metadata is not None: + payload["untrusted_metadata"] = untrusted_metadata + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/passwords/migrate") + + res = await self.async_client.post(url, json=payload) + return PasswordsmigrateResponse.from_json(res.response.status, res.json) + + def PasswordsStrengthCheck( + self, + password: str, + email: Optional[str] = None, + ) -> PasswordsstrengthcheckResponse: + + payload: Dict[str, Any] = { + "password": password, + } + + if email is not None: + payload["email"] = email + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/passwords/strength_check") + + res = self.sync_client.post(url, json=payload) + return PasswordsstrengthcheckResponse.from_json(res.response.status_code, res.json) + + async def PasswordsStrengthCheck_async( + self, + password: str, + email: Optional[str] = None, + ) -> PasswordsstrengthcheckResponse: + + payload: Dict[str, Any] = { + "password": password, + } + + if email is not None: + payload["email"] = email + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/passwords/strength_check") + + res = await self.async_client.post(url, json=payload) + return PasswordsstrengthcheckResponse.from_json(res.response.status, res.json) + diff --git a/stytch/api/project_service.py b/stytch/api/project_service.py new file mode 100644 index 00000000..2a839741 --- /dev/null +++ b/stytch/api/project_service.py @@ -0,0 +1,25 @@ +# !!! +# WARNING: This file is autogenerated +# Only modify code within MANUAL() sections +# or your changes may be overwritten later! +# !!! + + +from stytch.core.api_base import ApiBase +from stytch.core.http.client import AsyncClient, SyncClient + + +class ProjectService: + def __init__( + self, + api_base: ApiBase, + sync_client: SyncClient, + async_client: AsyncClient, + ) -> None: + self.api_base = api_base + self.sync_client = sync_client + self.async_client = async_client + + @property + def sub_url(self) -> str: + return "project_service" diff --git a/stytch/api/public_token_service.py b/stytch/api/public_token_service.py new file mode 100644 index 00000000..6b04e2ac --- /dev/null +++ b/stytch/api/public_token_service.py @@ -0,0 +1,25 @@ +# !!! +# WARNING: This file is autogenerated +# Only modify code within MANUAL() sections +# or your changes may be overwritten later! +# !!! + + +from stytch.core.api_base import ApiBase +from stytch.core.http.client import AsyncClient, SyncClient + + +class PublicTokenService: + def __init__( + self, + api_base: ApiBase, + sync_client: SyncClient, + async_client: AsyncClient, + ) -> None: + self.api_base = api_base + self.sync_client = sync_client + self.async_client = async_client + + @property + def sub_url(self) -> str: + return "public_token_service" diff --git a/stytch/api/script_service.py b/stytch/api/script_service.py new file mode 100644 index 00000000..1367d3b1 --- /dev/null +++ b/stytch/api/script_service.py @@ -0,0 +1,25 @@ +# !!! +# WARNING: This file is autogenerated +# Only modify code within MANUAL() sections +# or your changes may be overwritten later! +# !!! + + +from stytch.core.api_base import ApiBase +from stytch.core.http.client import AsyncClient, SyncClient + + +class ScriptService: + def __init__( + self, + api_base: ApiBase, + sync_client: SyncClient, + async_client: AsyncClient, + ) -> None: + self.api_base = api_base + self.sync_client = sync_client + self.async_client = async_client + + @property + def sub_url(self) -> str: + return "script_service" diff --git a/stytch/api/sdk_service.py b/stytch/api/sdk_service.py new file mode 100644 index 00000000..7c21b42b --- /dev/null +++ b/stytch/api/sdk_service.py @@ -0,0 +1,25 @@ +# !!! +# WARNING: This file is autogenerated +# Only modify code within MANUAL() sections +# or your changes may be overwritten later! +# !!! + + +from stytch.core.api_base import ApiBase +from stytch.core.http.client import AsyncClient, SyncClient + + +class SDKService: + def __init__( + self, + api_base: ApiBase, + sync_client: SyncClient, + async_client: AsyncClient, + ) -> None: + self.api_base = api_base + self.sync_client = sync_client + self.async_client = async_client + + @property + def sub_url(self) -> str: + return "sdk_service" diff --git a/stytch/api/secret_service.py b/stytch/api/secret_service.py new file mode 100644 index 00000000..a3b32630 --- /dev/null +++ b/stytch/api/secret_service.py @@ -0,0 +1,25 @@ +# !!! +# WARNING: This file is autogenerated +# Only modify code within MANUAL() sections +# or your changes may be overwritten later! +# !!! + + +from stytch.core.api_base import ApiBase +from stytch.core.http.client import AsyncClient, SyncClient + + +class SecretService: + def __init__( + self, + api_base: ApiBase, + sync_client: SyncClient, + async_client: AsyncClient, + ) -> None: + self.api_base = api_base + self.sync_client = sync_client + self.async_client = async_client + + @property + def sub_url(self) -> str: + return "secret_service" diff --git a/stytch/api/session_service.py b/stytch/api/session_service.py new file mode 100644 index 00000000..1a64b35e --- /dev/null +++ b/stytch/api/session_service.py @@ -0,0 +1,180 @@ +# !!! +# WARNING: This file is autogenerated +# Only modify code within MANUAL() sections +# or your changes may be overwritten later! +# !!! + +from typing import Any, Dict, Optional + +from stytch.core.api_base import ApiBase +from stytch.core.http.client import AsyncClient, SyncClient +from stytch.models.session_service import ( + SessionsauthenticateResponse, + SessionsgetResponse, + SessionsjwksResponse, + SessionsrevokeResponse, +) + + +class SessionService: + def __init__( + self, + api_base: ApiBase, + sync_client: SyncClient, + async_client: AsyncClient, + ) -> None: + self.api_base = api_base + self.sync_client = sync_client + self.async_client = async_client + + @property + def sub_url(self) -> str: + return "session_service" + + def SessionsGet( + self, + user_id: str, + ) -> SessionsgetResponse: + payload: Dict[str, Any] = { + "user_id": user_id, + } + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/sessions") + + res = self.sync_client.get(url, params=payload) + return SessionsgetResponse.from_json(res.response.status_code, res.json) + + async def SessionsGet_async( + self, + user_id: str, + ) -> SessionsgetResponse: + payload: Dict[str, Any] = { + "user_id": user_id, + } + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/sessions") + + res = await self.async_client.get(url, params=payload) + return SessionsgetResponse.from_json(res.response.status, res.json) + + def SessionsAuthenticate( + self, + session_token: Optional[str] = None, + session_duration_minutes: Optional[int] = None, + session_jwt: Optional[str] = None, + session_custom_claims: Optional[Dict[str, Any]] = None, + ) -> SessionsauthenticateResponse: + payload: Dict[str, Any] = {} + + if session_token is not None: + payload["session_token"] = session_token + if session_duration_minutes is not None: + payload["session_duration_minutes"] = session_duration_minutes + if session_jwt is not None: + payload["session_jwt"] = session_jwt + if session_custom_claims is not None: + payload["session_custom_claims"] = session_custom_claims + + url = self.api_base.route_with_sub_url( + self.sub_url, "/v1/sessions/authenticate" + ) + + res = self.sync_client.post(url, json=payload) + return SessionsauthenticateResponse.from_json( + res.response.status_code, res.json + ) + + async def SessionsAuthenticate_async( + self, + session_token: Optional[str] = None, + session_duration_minutes: Optional[int] = None, + session_jwt: Optional[str] = None, + session_custom_claims: Optional[Dict[str, Any]] = None, + ) -> SessionsauthenticateResponse: + payload: Dict[str, Any] = {} + + if session_token is not None: + payload["session_token"] = session_token + if session_duration_minutes is not None: + payload["session_duration_minutes"] = session_duration_minutes + if session_jwt is not None: + payload["session_jwt"] = session_jwt + if session_custom_claims is not None: + payload["session_custom_claims"] = session_custom_claims + + url = self.api_base.route_with_sub_url( + self.sub_url, "/v1/sessions/authenticate" + ) + + res = await self.async_client.post(url, json=payload) + return SessionsauthenticateResponse.from_json(res.response.status, res.json) + + def SessionsRevoke( + self, + session_id: Optional[str] = None, + session_token: Optional[str] = None, + session_jwt: Optional[str] = None, + ) -> SessionsrevokeResponse: + payload: Dict[str, Any] = {} + + if session_id is not None: + payload["session_id"] = session_id + if session_token is not None: + payload["session_token"] = session_token + if session_jwt is not None: + payload["session_jwt"] = session_jwt + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/sessions/revoke") + + res = self.sync_client.post(url, json=payload) + return SessionsrevokeResponse.from_json(res.response.status_code, res.json) + + async def SessionsRevoke_async( + self, + session_id: Optional[str] = None, + session_token: Optional[str] = None, + session_jwt: Optional[str] = None, + ) -> SessionsrevokeResponse: + payload: Dict[str, Any] = {} + + if session_id is not None: + payload["session_id"] = session_id + if session_token is not None: + payload["session_token"] = session_token + if session_jwt is not None: + payload["session_jwt"] = session_jwt + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/sessions/revoke") + + res = await self.async_client.post(url, json=payload) + return SessionsrevokeResponse.from_json(res.response.status, res.json) + + def SessionsJwks( + self, + project_id: str, + ) -> SessionsjwksResponse: + payload: Dict[str, Any] = { + "project_id": project_id, + } + + url = self.api_base.route_with_sub_url( + self.sub_url, "/v1/sessions/jwks/{project_id}" + ) + + res = self.sync_client.get(url, params=payload) + return SessionsjwksResponse.from_json(res.response.status_code, res.json) + + async def SessionsJwks_async( + self, + project_id: str, + ) -> SessionsjwksResponse: + payload: Dict[str, Any] = { + "project_id": project_id, + } + + url = self.api_base.route_with_sub_url( + self.sub_url, "/v1/sessions/jwks/{project_id}" + ) + + res = await self.async_client.get(url, params=payload) + return SessionsjwksResponse.from_json(res.response.status, res.json) diff --git a/stytch/api/sso_service.py b/stytch/api/sso_service.py new file mode 100644 index 00000000..f9cca618 --- /dev/null +++ b/stytch/api/sso_service.py @@ -0,0 +1,25 @@ +# !!! +# WARNING: This file is autogenerated +# Only modify code within MANUAL() sections +# or your changes may be overwritten later! +# !!! + + +from stytch.core.api_base import ApiBase +from stytch.core.http.client import AsyncClient, SyncClient + + +class SSOService: + def __init__( + self, + api_base: ApiBase, + sync_client: SyncClient, + async_client: AsyncClient, + ) -> None: + self.api_base = api_base + self.sync_client = sync_client + self.async_client = async_client + + @property + def sub_url(self) -> str: + return "sso_service" diff --git a/stytch/api/totp_service.py b/stytch/api/totp_service.py new file mode 100644 index 00000000..c1038f9c --- /dev/null +++ b/stytch/api/totp_service.py @@ -0,0 +1,206 @@ +# !!! +# WARNING: This file is autogenerated +# Only modify code within MANUAL() sections +# or your changes may be overwritten later! +# !!! + +from typing import Any, Dict, Optional + +from stytch.core.api_base import ApiBase +from stytch.core.http.client import AsyncClient, SyncClient +from stytch.models.totp_service import ( + TotpsauthenticateResponse, + TotpscreateResponse, + TotpsgetrecoverycodesResponse, + TotpsrecoverResponse, +) + + +class TOTPService: + def __init__( + self, + api_base: ApiBase, + sync_client: SyncClient, + async_client: AsyncClient, + ) -> None: + self.api_base = api_base + self.sync_client = sync_client + self.async_client = async_client + + @property + def sub_url(self) -> str: + return "totp_service" + + def TOTPsCreate( + self, + user_id: str, + expiration_minutes: Optional[int] = None, + ) -> TotpscreateResponse: + payload: Dict[str, Any] = { + "user_id": user_id, + } + + if expiration_minutes is not None: + payload["expiration_minutes"] = expiration_minutes + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/totps") + + res = self.sync_client.post(url, json=payload) + return TotpscreateResponse.from_json(res.response.status_code, res.json) + + async def TOTPsCreate_async( + self, + user_id: str, + expiration_minutes: Optional[int] = None, + ) -> TotpscreateResponse: + payload: Dict[str, Any] = { + "user_id": user_id, + } + + if expiration_minutes is not None: + payload["expiration_minutes"] = expiration_minutes + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/totps") + + res = await self.async_client.post(url, json=payload) + return TotpscreateResponse.from_json(res.response.status, res.json) + + def TOTPsAuthenticate( + self, + user_id: str, + totp_code: str, + session_token: Optional[str] = None, + session_duration_minutes: Optional[int] = None, + session_jwt: Optional[str] = None, + session_custom_claims: Optional[Dict[str, Any]] = None, + ) -> TotpsauthenticateResponse: + payload: Dict[str, Any] = { + "user_id": user_id, + "totp_code": totp_code, + } + + if session_token is not None: + payload["session_token"] = session_token + if session_duration_minutes is not None: + payload["session_duration_minutes"] = session_duration_minutes + if session_jwt is not None: + payload["session_jwt"] = session_jwt + if session_custom_claims is not None: + payload["session_custom_claims"] = session_custom_claims + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/totps/authenticate") + + res = self.sync_client.post(url, json=payload) + return TotpsauthenticateResponse.from_json(res.response.status_code, res.json) + + async def TOTPsAuthenticate_async( + self, + user_id: str, + totp_code: str, + session_token: Optional[str] = None, + session_duration_minutes: Optional[int] = None, + session_jwt: Optional[str] = None, + session_custom_claims: Optional[Dict[str, Any]] = None, + ) -> TotpsauthenticateResponse: + payload: Dict[str, Any] = { + "user_id": user_id, + "totp_code": totp_code, + } + + if session_token is not None: + payload["session_token"] = session_token + if session_duration_minutes is not None: + payload["session_duration_minutes"] = session_duration_minutes + if session_jwt is not None: + payload["session_jwt"] = session_jwt + if session_custom_claims is not None: + payload["session_custom_claims"] = session_custom_claims + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/totps/authenticate") + + res = await self.async_client.post(url, json=payload) + return TotpsauthenticateResponse.from_json(res.response.status, res.json) + + def TOTPsGetRecoveryCodes( + self, + user_id: str, + ) -> TotpsgetrecoverycodesResponse: + payload: Dict[str, Any] = { + "user_id": user_id, + } + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/totps/recovery_codes") + + res = self.sync_client.post(url, json=payload) + return TotpsgetrecoverycodesResponse.from_json( + res.response.status_code, res.json + ) + + async def TOTPsGetRecoveryCodes_async( + self, + user_id: str, + ) -> TotpsgetrecoverycodesResponse: + payload: Dict[str, Any] = { + "user_id": user_id, + } + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/totps/recovery_codes") + + res = await self.async_client.post(url, json=payload) + return TotpsgetrecoverycodesResponse.from_json(res.response.status, res.json) + + def TOTPsRecover( + self, + user_id: str, + recovery_code: str, + session_token: Optional[str] = None, + session_duration_minutes: Optional[int] = None, + session_jwt: Optional[str] = None, + session_custom_claims: Optional[Dict[str, Any]] = None, + ) -> TotpsrecoverResponse: + payload: Dict[str, Any] = { + "user_id": user_id, + "recovery_code": recovery_code, + } + + if session_token is not None: + payload["session_token"] = session_token + if session_duration_minutes is not None: + payload["session_duration_minutes"] = session_duration_minutes + if session_jwt is not None: + payload["session_jwt"] = session_jwt + if session_custom_claims is not None: + payload["session_custom_claims"] = session_custom_claims + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/totps/recover") + + res = self.sync_client.post(url, json=payload) + return TotpsrecoverResponse.from_json(res.response.status_code, res.json) + + async def TOTPsRecover_async( + self, + user_id: str, + recovery_code: str, + session_token: Optional[str] = None, + session_duration_minutes: Optional[int] = None, + session_jwt: Optional[str] = None, + session_custom_claims: Optional[Dict[str, Any]] = None, + ) -> TotpsrecoverResponse: + payload: Dict[str, Any] = { + "user_id": user_id, + "recovery_code": recovery_code, + } + + if session_token is not None: + payload["session_token"] = session_token + if session_duration_minutes is not None: + payload["session_duration_minutes"] = session_duration_minutes + if session_jwt is not None: + payload["session_jwt"] = session_jwt + if session_custom_claims is not None: + payload["session_custom_claims"] = session_custom_claims + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/totps/recover") + + res = await self.async_client.post(url, json=payload) + return TotpsrecoverResponse.from_json(res.response.status, res.json) diff --git a/stytch/api/user_service.py b/stytch/api/user_service.py new file mode 100644 index 00000000..e20f7559 --- /dev/null +++ b/stytch/api/user_service.py @@ -0,0 +1,532 @@ +# !!! +# WARNING: This file is autogenerated +# Only modify code within MANUAL() sections +# or your changes may be overwritten later! +# !!! + +from typing import Any, Dict, List, Optional, Union + +import pydantic + +from stytch.core.api_base import ApiBase +from stytch.core.http.client import AsyncClient, SyncClient +from stytch.models.user_service import ( + CreateuserResponse, + DeleteuserbiometricregistrationResponse, + DeleteusercryptowalletResponse, + DeleteuseremailResponse, + DeleteuseroauthuserregistrationResponse, + DeleteuserpasswordResponse, + DeleteuserphonenumberResponse, + DeleteuserResponse, + DeleteusertotpResponse, + DeleteuserwebauthnregistrationResponse, + GetpendingusersResponse, + GetuserbyemailandprojectidResponse, + GetuserResponse, + SearchusersexternalResponse, + UpdateuserResponse, +) + + +class UserService: + def __init__( + self, + api_base: ApiBase, + sync_client: SyncClient, + async_client: AsyncClient, + ) -> None: + self.api_base = api_base + self.sync_client = sync_client + self.async_client = async_client + + @property + def sub_url(self) -> str: + return "user_service" + + def CreateUser( + self, + email: Optional[str] = None, + name: None, + attributes: Optional[Dict[str, str]] = None, + phone_number: Optional[str] = None, + create_user_as_pending: bool, + trusted_metadata: Optional[Dict[str, Any]] = None, + untrusted_metadata: Optional[Dict[str, Any]] = None, + ) -> CreateuserResponse: + + payload: Dict[str, Any] = { + "create_user_as_pending": create_user_as_pending, + } + + if email is not None: + payload["email"] = email + if name is not None: + payload["name"] = name + if attributes is not None: + payload["attributes"] = attributes + if phone_number is not None: + payload["phone_number"] = phone_number + if trusted_metadata is not None: + payload["trusted_metadata"] = trusted_metadata + if untrusted_metadata is not None: + payload["untrusted_metadata"] = untrusted_metadata + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/users") + + res = self.sync_client.post(url, json=payload) + return CreateuserResponse.from_json(res.response.status_code, res.json) + + async def CreateUser_async( + self, + email: Optional[str] = None, + name: None, + attributes: Optional[Dict[str, str]] = None, + phone_number: Optional[str] = None, + create_user_as_pending: bool, + trusted_metadata: Optional[Dict[str, Any]] = None, + untrusted_metadata: Optional[Dict[str, Any]] = None, + ) -> CreateuserResponse: + + payload: Dict[str, Any] = { + "create_user_as_pending": create_user_as_pending, + } + + if email is not None: + payload["email"] = email + if name is not None: + payload["name"] = name + if attributes is not None: + payload["attributes"] = attributes + if phone_number is not None: + payload["phone_number"] = phone_number + if trusted_metadata is not None: + payload["trusted_metadata"] = trusted_metadata + if untrusted_metadata is not None: + payload["untrusted_metadata"] = untrusted_metadata + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/users") + + res = await self.async_client.post(url, json=payload) + return CreateuserResponse.from_json(res.response.status, res.json) + + def GetPendingUsers( + self, + starting_after_id: Optional[str] = None, + limit: Optional[int] = None, + ) -> GetpendingusersResponse: + + payload: Dict[str, Any] = { + } + + if starting_after_id is not None: + payload["starting_after_id"] = starting_after_id + if limit is not None: + payload["limit"] = limit + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/users/pending") + + res = self.sync_client.get(url, params=payload) + return GetpendingusersResponse.from_json(res.response.status_code, res.json) + + async def GetPendingUsers_async( + self, + starting_after_id: Optional[str] = None, + limit: Optional[int] = None, + ) -> GetpendingusersResponse: + + payload: Dict[str, Any] = { + } + + if starting_after_id is not None: + payload["starting_after_id"] = starting_after_id + if limit is not None: + payload["limit"] = limit + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/users/pending") + + res = await self.async_client.get(url, params=payload) + return GetpendingusersResponse.from_json(res.response.status, res.json) + + def GetUser( + self, + user_id: str, + ) -> GetuserResponse: + + payload: Dict[str, Any] = { + "user_id": user_id, + } + + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/users/{user_id}") + + res = self.sync_client.get(url, params=payload) + return GetuserResponse.from_json(res.response.status_code, res.json) + + async def GetUser_async( + self, + user_id: str, + ) -> GetuserResponse: + + payload: Dict[str, Any] = { + "user_id": user_id, + } + + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/users/{user_id}") + + res = await self.async_client.get(url, params=payload) + return GetuserResponse.from_json(res.response.status, res.json) + + def SearchUsersExternal( + self, + cursor: str, + limit: Optional[int] = None, + SearchUsersExternalQuery: None, + operands: None, + ) -> SearchusersexternalResponse: + + payload: Dict[str, Any] = { + "cursor": cursor, + } + + if limit is not None: + payload["limit"] = limit + if SearchUsersExternalQuery is not None: + payload["SearchUsersExternalQuery"] = SearchUsersExternalQuery + if operands is not None: + payload["operands"] = operands + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/users/search") + + res = self.sync_client.post(url, json=payload) + return SearchusersexternalResponse.from_json(res.response.status_code, res.json) + + async def SearchUsersExternal_async( + self, + cursor: str, + limit: Optional[int] = None, + SearchUsersExternalQuery: None, + operands: None, + ) -> SearchusersexternalResponse: + + payload: Dict[str, Any] = { + "cursor": cursor, + } + + if limit is not None: + payload["limit"] = limit + if SearchUsersExternalQuery is not None: + payload["SearchUsersExternalQuery"] = SearchUsersExternalQuery + if operands is not None: + payload["operands"] = operands + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/users/search") + + res = await self.async_client.post(url, json=payload) + return SearchusersexternalResponse.from_json(res.response.status, res.json) + + def UpdateUser( + self, + user_id: str, + name: None, + emails: None, + attributes: Optional[Dict[str, str]] = None, + phone_numbers: None, + crypto_wallets: None, + trusted_metadata: Optional[Dict[str, Any]] = None, + untrusted_metadata: Optional[Dict[str, Any]] = None, + ) -> UpdateuserResponse: + + payload: Dict[str, Any] = { + "user_id": user_id, + } + + if name is not None: + payload["name"] = name + if emails is not None: + payload["emails"] = emails + if attributes is not None: + payload["attributes"] = attributes + if phone_numbers is not None: + payload["phone_numbers"] = phone_numbers + if crypto_wallets is not None: + payload["crypto_wallets"] = crypto_wallets + if trusted_metadata is not None: + payload["trusted_metadata"] = trusted_metadata + if untrusted_metadata is not None: + payload["untrusted_metadata"] = untrusted_metadata + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/users/{user_id}") + + res = self.sync_client.put(url, json=payload) + return UpdateuserResponse.from_json(res.response.status_code, res.json) + + async def UpdateUser_async( + self, + user_id: str, + name: None, + emails: None, + attributes: Optional[Dict[str, str]] = None, + phone_numbers: None, + crypto_wallets: None, + trusted_metadata: Optional[Dict[str, Any]] = None, + untrusted_metadata: Optional[Dict[str, Any]] = None, + ) -> UpdateuserResponse: + + payload: Dict[str, Any] = { + "user_id": user_id, + } + + if name is not None: + payload["name"] = name + if emails is not None: + payload["emails"] = emails + if attributes is not None: + payload["attributes"] = attributes + if phone_numbers is not None: + payload["phone_numbers"] = phone_numbers + if crypto_wallets is not None: + payload["crypto_wallets"] = crypto_wallets + if trusted_metadata is not None: + payload["trusted_metadata"] = trusted_metadata + if untrusted_metadata is not None: + payload["untrusted_metadata"] = untrusted_metadata + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/users/{user_id}") + + res = await self.async_client.put(url, json=payload) + return UpdateuserResponse.from_json(res.response.status, res.json) + + def DeleteUser( + self, + user_id: str, + ) -> DeleteuserResponse: + + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/users/{user_id}") + + res = self.sync_client.delete(url) + return DeleteuserResponse.from_json(res.response.status_code, res.json) + + async def DeleteUser_async( + self, + user_id: str, + ) -> DeleteuserResponse: + + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/users/{user_id}") + + res = await self.async_client.delete(url) + return DeleteuserResponse.from_json(res.response.status, res.json) + + def GetUserByEmailAndProjectID( + self, + email: str, + project_id: str, + ) -> GetuserbyemailandprojectidResponse: + + payload: Dict[str, Any] = { + "email": email, + "project_id": project_id, + } + + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/sdk/users") + + res = self.sync_client.get(url, params=payload) + return GetuserbyemailandprojectidResponse.from_json(res.response.status_code, res.json) + + async def GetUserByEmailAndProjectID_async( + self, + email: str, + project_id: str, + ) -> GetuserbyemailandprojectidResponse: + + payload: Dict[str, Any] = { + "email": email, + "project_id": project_id, + } + + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/sdk/users") + + res = await self.async_client.get(url, params=payload) + return GetuserbyemailandprojectidResponse.from_json(res.response.status, res.json) + + def DeleteUserEmail( + self, + email_id: str, + ) -> DeleteuseremailResponse: + + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/users/emails/{email_id}") + + res = self.sync_client.delete(url) + return DeleteuseremailResponse.from_json(res.response.status_code, res.json) + + async def DeleteUserEmail_async( + self, + email_id: str, + ) -> DeleteuseremailResponse: + + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/users/emails/{email_id}") + + res = await self.async_client.delete(url) + return DeleteuseremailResponse.from_json(res.response.status, res.json) + + def DeleteUserPhoneNumber( + self, + phone_id: str, + ) -> DeleteuserphonenumberResponse: + + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/users/phone_numbers/{phone_id}") + + res = self.sync_client.delete(url) + return DeleteuserphonenumberResponse.from_json(res.response.status_code, res.json) + + async def DeleteUserPhoneNumber_async( + self, + phone_id: str, + ) -> DeleteuserphonenumberResponse: + + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/users/phone_numbers/{phone_id}") + + res = await self.async_client.delete(url) + return DeleteuserphonenumberResponse.from_json(res.response.status, res.json) + + def DeleteUserWebAuthnRegistration( + self, + webauthn_registration_id: str, + ) -> DeleteuserwebauthnregistrationResponse: + + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/users/webauthn_registrations/{webauthn_registration_id}") + + res = self.sync_client.delete(url) + return DeleteuserwebauthnregistrationResponse.from_json(res.response.status_code, res.json) + + async def DeleteUserWebAuthnRegistration_async( + self, + webauthn_registration_id: str, + ) -> DeleteuserwebauthnregistrationResponse: + + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/users/webauthn_registrations/{webauthn_registration_id}") + + res = await self.async_client.delete(url) + return DeleteuserwebauthnregistrationResponse.from_json(res.response.status, res.json) + + def DeleteUserBiometricRegistration( + self, + biometric_registration_id: str, + ) -> DeleteuserbiometricregistrationResponse: + + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/users/biometric_registrations/{biometric_registration_id}") + + res = self.sync_client.delete(url) + return DeleteuserbiometricregistrationResponse.from_json(res.response.status_code, res.json) + + async def DeleteUserBiometricRegistration_async( + self, + biometric_registration_id: str, + ) -> DeleteuserbiometricregistrationResponse: + + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/users/biometric_registrations/{biometric_registration_id}") + + res = await self.async_client.delete(url) + return DeleteuserbiometricregistrationResponse.from_json(res.response.status, res.json) + + def DeleteUserTOTP( + self, + totp_id: str, + ) -> DeleteusertotpResponse: + + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/users/totps/{totp_id}") + + res = self.sync_client.delete(url) + return DeleteusertotpResponse.from_json(res.response.status_code, res.json) + + async def DeleteUserTOTP_async( + self, + totp_id: str, + ) -> DeleteusertotpResponse: + + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/users/totps/{totp_id}") + + res = await self.async_client.delete(url) + return DeleteusertotpResponse.from_json(res.response.status, res.json) + + def DeleteUserCryptoWallet( + self, + crypto_wallet_id: str, + ) -> DeleteusercryptowalletResponse: + + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/users/crypto_wallets/{crypto_wallet_id}") + + res = self.sync_client.delete(url) + return DeleteusercryptowalletResponse.from_json(res.response.status_code, res.json) + + async def DeleteUserCryptoWallet_async( + self, + crypto_wallet_id: str, + ) -> DeleteusercryptowalletResponse: + + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/users/crypto_wallets/{crypto_wallet_id}") + + res = await self.async_client.delete(url) + return DeleteusercryptowalletResponse.from_json(res.response.status, res.json) + + def DeleteUserPassword( + self, + password_id: str, + ) -> DeleteuserpasswordResponse: + + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/users/passwords/{password_id}") + + res = self.sync_client.delete(url) + return DeleteuserpasswordResponse.from_json(res.response.status_code, res.json) + + async def DeleteUserPassword_async( + self, + password_id: str, + ) -> DeleteuserpasswordResponse: + + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/users/passwords/{password_id}") + + res = await self.async_client.delete(url) + return DeleteuserpasswordResponse.from_json(res.response.status, res.json) + + def DeleteUserOAuthUserRegistration( + self, + oauth_user_registration_id: str, + ) -> DeleteuseroauthuserregistrationResponse: + + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/users/oauth/{oauth_user_registration_id}") + + res = self.sync_client.delete(url) + return DeleteuseroauthuserregistrationResponse.from_json(res.response.status_code, res.json) + + async def DeleteUserOAuthUserRegistration_async( + self, + oauth_user_registration_id: str, + ) -> DeleteuseroauthuserregistrationResponse: + + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/users/oauth/{oauth_user_registration_id}") + + res = await self.async_client.delete(url) + return DeleteuseroauthuserregistrationResponse.from_json(res.response.status, res.json) + diff --git a/stytch/api/web_authn_service.py b/stytch/api/web_authn_service.py new file mode 100644 index 00000000..818f0b6c --- /dev/null +++ b/stytch/api/web_authn_service.py @@ -0,0 +1,206 @@ +# !!! +# WARNING: This file is autogenerated +# Only modify code within MANUAL() sections +# or your changes may be overwritten later! +# !!! + +from typing import Any, Dict, Optional + +from stytch.core.api_base import ApiBase +from stytch.core.http.client import AsyncClient, SyncClient +from stytch.models.web_authn_service import ( + WebauthnauthenticateResponse, + WebauthnauthenticatestartResponse, + WebauthnregisterResponse, + WebauthnregisterstartResponse, +) + + +class WebAuthnService: + def __init__( + self, + api_base: ApiBase, + sync_client: SyncClient, + async_client: AsyncClient, + ) -> None: + self.api_base = api_base + self.sync_client = sync_client + self.async_client = async_client + + @property + def sub_url(self) -> str: + return "web_authn_service" + + def WebAuthnRegisterStart( + self, + user_id: str, + domain: str, + user_agent: str, + authenticator_type: Optional[str] = None, + ) -> WebauthnregisterstartResponse: + payload: Dict[str, Any] = { + "user_id": user_id, + "domain": domain, + "user_agent": user_agent, + } + + if authenticator_type is not None: + payload["authenticator_type"] = authenticator_type + + url = self.api_base.route_with_sub_url( + self.sub_url, "/v1/webauthn/register/start" + ) + + res = self.sync_client.post(url, json=payload) + return WebauthnregisterstartResponse.from_json( + res.response.status_code, res.json + ) + + async def WebAuthnRegisterStart_async( + self, + user_id: str, + domain: str, + user_agent: str, + authenticator_type: Optional[str] = None, + ) -> WebauthnregisterstartResponse: + payload: Dict[str, Any] = { + "user_id": user_id, + "domain": domain, + "user_agent": user_agent, + } + + if authenticator_type is not None: + payload["authenticator_type"] = authenticator_type + + url = self.api_base.route_with_sub_url( + self.sub_url, "/v1/webauthn/register/start" + ) + + res = await self.async_client.post(url, json=payload) + return WebauthnregisterstartResponse.from_json(res.response.status, res.json) + + def WebAuthnRegister( + self, + user_id: str, + public_key_credential: str, + ) -> WebauthnregisterResponse: + payload: Dict[str, Any] = { + "user_id": user_id, + "public_key_credential": public_key_credential, + } + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/webauthn/register") + + res = self.sync_client.post(url, json=payload) + return WebauthnregisterResponse.from_json(res.response.status_code, res.json) + + async def WebAuthnRegister_async( + self, + user_id: str, + public_key_credential: str, + ) -> WebauthnregisterResponse: + payload: Dict[str, Any] = { + "user_id": user_id, + "public_key_credential": public_key_credential, + } + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/webauthn/register") + + res = await self.async_client.post(url, json=payload) + return WebauthnregisterResponse.from_json(res.response.status, res.json) + + def WebAuthnAuthenticateStart( + self, + user_id: str, + domain: str, + ) -> WebauthnauthenticatestartResponse: + payload: Dict[str, Any] = { + "user_id": user_id, + "domain": domain, + } + + url = self.api_base.route_with_sub_url( + self.sub_url, "/v1/webauthn/authenticate/start" + ) + + res = self.sync_client.post(url, json=payload) + return WebauthnauthenticatestartResponse.from_json( + res.response.status_code, res.json + ) + + async def WebAuthnAuthenticateStart_async( + self, + user_id: str, + domain: str, + ) -> WebauthnauthenticatestartResponse: + payload: Dict[str, Any] = { + "user_id": user_id, + "domain": domain, + } + + url = self.api_base.route_with_sub_url( + self.sub_url, "/v1/webauthn/authenticate/start" + ) + + res = await self.async_client.post(url, json=payload) + return WebauthnauthenticatestartResponse.from_json( + res.response.status, res.json + ) + + def WebAuthnAuthenticate( + self, + public_key_credential: str, + session_token: Optional[str] = None, + session_duration_minutes: Optional[int] = None, + session_jwt: Optional[str] = None, + session_custom_claims: Optional[Dict[str, Any]] = None, + ) -> WebauthnauthenticateResponse: + payload: Dict[str, Any] = { + "public_key_credential": public_key_credential, + } + + if session_token is not None: + payload["session_token"] = session_token + if session_duration_minutes is not None: + payload["session_duration_minutes"] = session_duration_minutes + if session_jwt is not None: + payload["session_jwt"] = session_jwt + if session_custom_claims is not None: + payload["session_custom_claims"] = session_custom_claims + + url = self.api_base.route_with_sub_url( + self.sub_url, "/v1/webauthn/authenticate" + ) + + res = self.sync_client.post(url, json=payload) + return WebauthnauthenticateResponse.from_json( + res.response.status_code, res.json + ) + + async def WebAuthnAuthenticate_async( + self, + public_key_credential: str, + session_token: Optional[str] = None, + session_duration_minutes: Optional[int] = None, + session_jwt: Optional[str] = None, + session_custom_claims: Optional[Dict[str, Any]] = None, + ) -> WebauthnauthenticateResponse: + payload: Dict[str, Any] = { + "public_key_credential": public_key_credential, + } + + if session_token is not None: + payload["session_token"] = session_token + if session_duration_minutes is not None: + payload["session_duration_minutes"] = session_duration_minutes + if session_jwt is not None: + payload["session_jwt"] = session_jwt + if session_custom_claims is not None: + payload["session_custom_claims"] = session_custom_claims + + url = self.api_base.route_with_sub_url( + self.sub_url, "/v1/webauthn/authenticate" + ) + + res = await self.async_client.post(url, json=payload) + return WebauthnauthenticateResponse.from_json(res.response.status, res.json) diff --git a/stytch/b2b/api/debug_service.py b/stytch/b2b/api/debug_service.py new file mode 100644 index 00000000..033508f7 --- /dev/null +++ b/stytch/b2b/api/debug_service.py @@ -0,0 +1,47 @@ +# !!! +# WARNING: This file is autogenerated +# Only modify code within MANUAL() sections +# or your changes may be overwritten later! +# !!! + +from typing import Any, Dict + +from stytch.b2b.models.debug_service import WhoamiResponse +from stytch.core.api_base import ApiBase +from stytch.core.http.client import AsyncClient, SyncClient + + +class DebugService: + def __init__( + self, + api_base: ApiBase, + sync_client: SyncClient, + async_client: AsyncClient, + ) -> None: + self.api_base = api_base + self.sync_client = sync_client + self.async_client = async_client + + @property + def sub_url(self) -> str: + return "debug_service" + + def WhoAmI( + self, + ) -> WhoamiResponse: + payload: Dict[str, Any] = {} + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/debug/whoami") + + res = self.sync_client.get(url, params=payload) + return WhoamiResponse.from_json(res.response.status_code, res.json) + + async def WhoAmI_async( + self, + ) -> WhoamiResponse: + payload: Dict[str, Any] = {} + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/debug/whoami") + + res = await self.async_client.get(url, params=payload) + return WhoamiResponse.from_json(res.response.status, res.json) diff --git a/stytch/b2b/api/discovery_service.py b/stytch/b2b/api/discovery_service.py new file mode 100644 index 00000000..7b5ccdd2 --- /dev/null +++ b/stytch/b2b/api/discovery_service.py @@ -0,0 +1,216 @@ +# !!! +# WARNING: This file is autogenerated +# Only modify code within MANUAL() sections +# or your changes may be overwritten later! +# !!! + +from typing import Any, Dict, List, Optional, Union + +import pydantic + +from stytch.b2b.models.discovery_service import ( + DiscoveryintermediatesessionexchangeResponse, + DiscoveryorganizationcreateResponse, + DiscoveryorganizationsResponse, +) +from stytch.core.api_base import ApiBase +from stytch.core.http.client import AsyncClient, SyncClient + + +class DiscoveryService: + def __init__( + self, + api_base: ApiBase, + sync_client: SyncClient, + async_client: AsyncClient, + ) -> None: + self.api_base = api_base + self.sync_client = sync_client + self.async_client = async_client + + @property + def sub_url(self) -> str: + return "discovery_service" + + def DiscoveryOrganizations( + self, + intermediate_session_token: Optional[str] = None, + session_token: Optional[str] = None, + session_jwt: Optional[str] = None, + ) -> DiscoveryorganizationsResponse: + + payload: Dict[str, Any] = { + } + + if intermediate_session_token is not None: + payload["intermediate_session_token"] = intermediate_session_token + if session_token is not None: + payload["session_token"] = session_token + if session_jwt is not None: + payload["session_jwt"] = session_jwt + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/b2b/discovery/organizations") + + res = self.sync_client.post(url, json=payload) + return DiscoveryorganizationsResponse.from_json(res.response.status_code, res.json) + + async def DiscoveryOrganizations_async( + self, + intermediate_session_token: Optional[str] = None, + session_token: Optional[str] = None, + session_jwt: Optional[str] = None, + ) -> DiscoveryorganizationsResponse: + + payload: Dict[str, Any] = { + } + + if intermediate_session_token is not None: + payload["intermediate_session_token"] = intermediate_session_token + if session_token is not None: + payload["session_token"] = session_token + if session_jwt is not None: + payload["session_jwt"] = session_jwt + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/b2b/discovery/organizations") + + res = await self.async_client.post(url, json=payload) + return DiscoveryorganizationsResponse.from_json(res.response.status, res.json) + + def DiscoveryIntermediateSessionExchange( + self, + intermediate_session_token: str, + organization_id: str, + session_duration_minutes: Optional[int] = None, + session_custom_claims: Optional[Dict[str, Any]] = None, + ) -> DiscoveryintermediatesessionexchangeResponse: + + payload: Dict[str, Any] = { + "intermediate_session_token": intermediate_session_token, + "organization_id": organization_id, + } + + if session_duration_minutes is not None: + payload["session_duration_minutes"] = session_duration_minutes + if session_custom_claims is not None: + payload["session_custom_claims"] = session_custom_claims + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/b2b/discovery/intermediate_sessions/exchange") + + res = self.sync_client.post(url, json=payload) + return DiscoveryintermediatesessionexchangeResponse.from_json(res.response.status_code, res.json) + + async def DiscoveryIntermediateSessionExchange_async( + self, + intermediate_session_token: str, + organization_id: str, + session_duration_minutes: Optional[int] = None, + session_custom_claims: Optional[Dict[str, Any]] = None, + ) -> DiscoveryintermediatesessionexchangeResponse: + + payload: Dict[str, Any] = { + "intermediate_session_token": intermediate_session_token, + "organization_id": organization_id, + } + + if session_duration_minutes is not None: + payload["session_duration_minutes"] = session_duration_minutes + if session_custom_claims is not None: + payload["session_custom_claims"] = session_custom_claims + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/b2b/discovery/intermediate_sessions/exchange") + + res = await self.async_client.post(url, json=payload) + return DiscoveryintermediatesessionexchangeResponse.from_json(res.response.status, res.json) + + def DiscoveryOrganizationCreate( + self, + intermediate_session_token: str, + session_duration_minutes: Optional[int] = None, + session_custom_claims: Optional[Dict[str, Any]] = None, + organization_name: str, + organization_slug: str, + organization_logo_url: str, + trusted_metadata: Optional[Dict[str, Any]] = None, + sso_jit_provisioning: Optional[str] = None, + email_allowed_domains: List[str], + email_jit_provisioning: Optional[str] = None, + email_invites: Optional[str] = None, + auth_methods: Optional[str] = None, + allowed_auth_methods: List[str], + ) -> DiscoveryorganizationcreateResponse: + + payload: Dict[str, Any] = { + "intermediate_session_token": intermediate_session_token, + "organization_name": organization_name, + "organization_slug": organization_slug, + "organization_logo_url": organization_logo_url, + "email_allowed_domains": email_allowed_domains, + "allowed_auth_methods": allowed_auth_methods, + } + + if session_duration_minutes is not None: + payload["session_duration_minutes"] = session_duration_minutes + if session_custom_claims is not None: + payload["session_custom_claims"] = session_custom_claims + if trusted_metadata is not None: + payload["trusted_metadata"] = trusted_metadata + if sso_jit_provisioning is not None: + payload["sso_jit_provisioning"] = sso_jit_provisioning + if email_jit_provisioning is not None: + payload["email_jit_provisioning"] = email_jit_provisioning + if email_invites is not None: + payload["email_invites"] = email_invites + if auth_methods is not None: + payload["auth_methods"] = auth_methods + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/b2b/discovery/organizations/create") + + res = self.sync_client.post(url, json=payload) + return DiscoveryorganizationcreateResponse.from_json(res.response.status_code, res.json) + + async def DiscoveryOrganizationCreate_async( + self, + intermediate_session_token: str, + session_duration_minutes: Optional[int] = None, + session_custom_claims: Optional[Dict[str, Any]] = None, + organization_name: str, + organization_slug: str, + organization_logo_url: str, + trusted_metadata: Optional[Dict[str, Any]] = None, + sso_jit_provisioning: Optional[str] = None, + email_allowed_domains: List[str], + email_jit_provisioning: Optional[str] = None, + email_invites: Optional[str] = None, + auth_methods: Optional[str] = None, + allowed_auth_methods: List[str], + ) -> DiscoveryorganizationcreateResponse: + + payload: Dict[str, Any] = { + "intermediate_session_token": intermediate_session_token, + "organization_name": organization_name, + "organization_slug": organization_slug, + "organization_logo_url": organization_logo_url, + "email_allowed_domains": email_allowed_domains, + "allowed_auth_methods": allowed_auth_methods, + } + + if session_duration_minutes is not None: + payload["session_duration_minutes"] = session_duration_minutes + if session_custom_claims is not None: + payload["session_custom_claims"] = session_custom_claims + if trusted_metadata is not None: + payload["trusted_metadata"] = trusted_metadata + if sso_jit_provisioning is not None: + payload["sso_jit_provisioning"] = sso_jit_provisioning + if email_jit_provisioning is not None: + payload["email_jit_provisioning"] = email_jit_provisioning + if email_invites is not None: + payload["email_invites"] = email_invites + if auth_methods is not None: + payload["auth_methods"] = auth_methods + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/b2b/discovery/organizations/create") + + res = await self.async_client.post(url, json=payload) + return DiscoveryorganizationcreateResponse.from_json(res.response.status, res.json) + diff --git a/stytch/b2b/api/magic_service.py b/stytch/b2b/api/magic_service.py new file mode 100644 index 00000000..21152a61 --- /dev/null +++ b/stytch/b2b/api/magic_service.py @@ -0,0 +1,106 @@ +# !!! +# WARNING: This file is autogenerated +# Only modify code within MANUAL() sections +# or your changes may be overwritten later! +# !!! + +from typing import Any, Dict + +from stytch.b2b.models.magic_service import ( + MagiclinkredirectResponse, + MagiclinksredirectcaptchaResponse, +) +from stytch.core.api_base import ApiBase +from stytch.core.http.client import AsyncClient, SyncClient + + +class MagicService: + def __init__( + self, + api_base: ApiBase, + sync_client: SyncClient, + async_client: AsyncClient, + ) -> None: + self.api_base = api_base + self.sync_client = sync_client + self.async_client = async_client + + @property + def sub_url(self) -> str: + return "magic_service" + + def MagicLinkRedirect( + self, + public_token: str, + token: str, + stytch_token_type: str, + ) -> MagiclinkredirectResponse: + payload: Dict[str, Any] = { + "public_token": public_token, + "token": token, + "stytch_token_type": stytch_token_type, + } + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/magic_links/redirect") + + res = self.sync_client.get(url, params=payload) + return MagiclinkredirectResponse.from_json(res.response.status_code, res.json) + + async def MagicLinkRedirect_async( + self, + public_token: str, + token: str, + stytch_token_type: str, + ) -> MagiclinkredirectResponse: + payload: Dict[str, Any] = { + "public_token": public_token, + "token": token, + "stytch_token_type": stytch_token_type, + } + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/magic_links/redirect") + + res = await self.async_client.get(url, params=payload) + return MagiclinkredirectResponse.from_json(res.response.status, res.json) + + def MagicLinksRedirectCaptcha( + self, + public_token: str, + redirect_url: str, + captcha: str, + ) -> MagiclinksredirectcaptchaResponse: + payload: Dict[str, Any] = { + "public_token": public_token, + "redirect_url": redirect_url, + "captcha": captcha, + } + + url = self.api_base.route_with_sub_url( + self.sub_url, "/v1/magic_links/redirect/captcha" + ) + + res = self.sync_client.post(url, json=payload) + return MagiclinksredirectcaptchaResponse.from_json( + res.response.status_code, res.json + ) + + async def MagicLinksRedirectCaptcha_async( + self, + public_token: str, + redirect_url: str, + captcha: str, + ) -> MagiclinksredirectcaptchaResponse: + payload: Dict[str, Any] = { + "public_token": public_token, + "redirect_url": redirect_url, + "captcha": captcha, + } + + url = self.api_base.route_with_sub_url( + self.sub_url, "/v1/magic_links/redirect/captcha" + ) + + res = await self.async_client.post(url, json=payload) + return MagiclinksredirectcaptchaResponse.from_json( + res.response.status, res.json + ) diff --git a/stytch/b2b/api/multi_tenant_magic_service.py b/stytch/b2b/api/multi_tenant_magic_service.py new file mode 100644 index 00000000..2288d0c9 --- /dev/null +++ b/stytch/b2b/api/multi_tenant_magic_service.py @@ -0,0 +1,359 @@ +# !!! +# WARNING: This file is autogenerated +# Only modify code within MANUAL() sections +# or your changes may be overwritten later! +# !!! + +from typing import Any, Dict, Optional + +from stytch.b2b.models.multi_tenant_magic_service import ( + B2BmagiclinksdiscoveryauthenticateResponse, + B2BmagiclinksemaildiscoverysendResponse, + MultitenantmagiclinksauthenticateResponse, + MultitenantmagiclinksemailinviteResponse, + MultitenantmagiclinksemailloginorsignupResponse, +) +from stytch.core.api_base import ApiBase +from stytch.core.http.client import AsyncClient, SyncClient + + +class MultiTenantMagicService: + def __init__( + self, + api_base: ApiBase, + sync_client: SyncClient, + async_client: AsyncClient, + ) -> None: + self.api_base = api_base + self.sync_client = sync_client + self.async_client = async_client + + @property + def sub_url(self) -> str: + return "multi_tenant_magic_service" + + def MultiTenantMagicLinksEmailLoginOrSignup( + self, + organization_id: str, + email_address: str, + login_redirect_url: Optional[str] = None, + signup_redirect_url: Optional[str] = None, + pkce_code_challenge: Optional[str] = None, + login_template_id: Optional[str] = None, + signup_template_id: Optional[str] = None, + locale: Optional[str] = None, + ) -> MultitenantmagiclinksemailloginorsignupResponse: + payload: Dict[str, Any] = { + "organization_id": organization_id, + "email_address": email_address, + } + + if login_redirect_url is not None: + payload["login_redirect_url"] = login_redirect_url + if signup_redirect_url is not None: + payload["signup_redirect_url"] = signup_redirect_url + if pkce_code_challenge is not None: + payload["pkce_code_challenge"] = pkce_code_challenge + if login_template_id is not None: + payload["login_template_id"] = login_template_id + if signup_template_id is not None: + payload["signup_template_id"] = signup_template_id + if locale is not None: + payload["locale"] = locale + + url = self.api_base.route_with_sub_url( + self.sub_url, "/v1/b2b/magic_links/email/login_or_signup" + ) + + res = self.sync_client.post(url, json=payload) + return MultitenantmagiclinksemailloginorsignupResponse.from_json( + res.response.status_code, res.json + ) + + async def MultiTenantMagicLinksEmailLoginOrSignup_async( + self, + organization_id: str, + email_address: str, + login_redirect_url: Optional[str] = None, + signup_redirect_url: Optional[str] = None, + pkce_code_challenge: Optional[str] = None, + login_template_id: Optional[str] = None, + signup_template_id: Optional[str] = None, + locale: Optional[str] = None, + ) -> MultitenantmagiclinksemailloginorsignupResponse: + payload: Dict[str, Any] = { + "organization_id": organization_id, + "email_address": email_address, + } + + if login_redirect_url is not None: + payload["login_redirect_url"] = login_redirect_url + if signup_redirect_url is not None: + payload["signup_redirect_url"] = signup_redirect_url + if pkce_code_challenge is not None: + payload["pkce_code_challenge"] = pkce_code_challenge + if login_template_id is not None: + payload["login_template_id"] = login_template_id + if signup_template_id is not None: + payload["signup_template_id"] = signup_template_id + if locale is not None: + payload["locale"] = locale + + url = self.api_base.route_with_sub_url( + self.sub_url, "/v1/b2b/magic_links/email/login_or_signup" + ) + + res = await self.async_client.post(url, json=payload) + return MultitenantmagiclinksemailloginorsignupResponse.from_json( + res.response.status, res.json + ) + + def MultiTenantMagicLinksEmailInvite( + self, + organization_id: str, + email_address: str, + invite_redirect_url: Optional[str] = None, + invited_by_member_id: Optional[str] = None, + name: Optional[str] = None, + trusted_metadata: Optional[Dict[str, Any]] = None, + untrusted_metadata: Optional[Dict[str, Any]] = None, + invite_template_id: Optional[str] = None, + locale: Optional[str] = None, + ) -> MultitenantmagiclinksemailinviteResponse: + payload: Dict[str, Any] = { + "organization_id": organization_id, + "email_address": email_address, + } + + if invite_redirect_url is not None: + payload["invite_redirect_url"] = invite_redirect_url + if invited_by_member_id is not None: + payload["invited_by_member_id"] = invited_by_member_id + if name is not None: + payload["name"] = name + if trusted_metadata is not None: + payload["trusted_metadata"] = trusted_metadata + if untrusted_metadata is not None: + payload["untrusted_metadata"] = untrusted_metadata + if invite_template_id is not None: + payload["invite_template_id"] = invite_template_id + if locale is not None: + payload["locale"] = locale + + url = self.api_base.route_with_sub_url( + self.sub_url, "/v1/b2b/magic_links/email/invite" + ) + + res = self.sync_client.post(url, json=payload) + return MultitenantmagiclinksemailinviteResponse.from_json( + res.response.status_code, res.json + ) + + async def MultiTenantMagicLinksEmailInvite_async( + self, + organization_id: str, + email_address: str, + invite_redirect_url: Optional[str] = None, + invited_by_member_id: Optional[str] = None, + name: Optional[str] = None, + trusted_metadata: Optional[Dict[str, Any]] = None, + untrusted_metadata: Optional[Dict[str, Any]] = None, + invite_template_id: Optional[str] = None, + locale: Optional[str] = None, + ) -> MultitenantmagiclinksemailinviteResponse: + payload: Dict[str, Any] = { + "organization_id": organization_id, + "email_address": email_address, + } + + if invite_redirect_url is not None: + payload["invite_redirect_url"] = invite_redirect_url + if invited_by_member_id is not None: + payload["invited_by_member_id"] = invited_by_member_id + if name is not None: + payload["name"] = name + if trusted_metadata is not None: + payload["trusted_metadata"] = trusted_metadata + if untrusted_metadata is not None: + payload["untrusted_metadata"] = untrusted_metadata + if invite_template_id is not None: + payload["invite_template_id"] = invite_template_id + if locale is not None: + payload["locale"] = locale + + url = self.api_base.route_with_sub_url( + self.sub_url, "/v1/b2b/magic_links/email/invite" + ) + + res = await self.async_client.post(url, json=payload) + return MultitenantmagiclinksemailinviteResponse.from_json( + res.response.status, res.json + ) + + def MultiTenantMagicLinksAuthenticate( + self, + magic_links_token: str, + pkce_code_verifier: Optional[str] = None, + session_token: Optional[str] = None, + session_jwt: Optional[str] = None, + session_duration_minutes: Optional[int] = None, + session_custom_claims: Optional[Dict[str, Any]] = None, + ) -> MultitenantmagiclinksauthenticateResponse: + payload: Dict[str, Any] = { + "magic_links_token": magic_links_token, + } + + if pkce_code_verifier is not None: + payload["pkce_code_verifier"] = pkce_code_verifier + if session_token is not None: + payload["session_token"] = session_token + if session_jwt is not None: + payload["session_jwt"] = session_jwt + if session_duration_minutes is not None: + payload["session_duration_minutes"] = session_duration_minutes + if session_custom_claims is not None: + payload["session_custom_claims"] = session_custom_claims + + url = self.api_base.route_with_sub_url( + self.sub_url, "/v1/b2b/magic_links/authenticate" + ) + + res = self.sync_client.post(url, json=payload) + return MultitenantmagiclinksauthenticateResponse.from_json( + res.response.status_code, res.json + ) + + async def MultiTenantMagicLinksAuthenticate_async( + self, + magic_links_token: str, + pkce_code_verifier: Optional[str] = None, + session_token: Optional[str] = None, + session_jwt: Optional[str] = None, + session_duration_minutes: Optional[int] = None, + session_custom_claims: Optional[Dict[str, Any]] = None, + ) -> MultitenantmagiclinksauthenticateResponse: + payload: Dict[str, Any] = { + "magic_links_token": magic_links_token, + } + + if pkce_code_verifier is not None: + payload["pkce_code_verifier"] = pkce_code_verifier + if session_token is not None: + payload["session_token"] = session_token + if session_jwt is not None: + payload["session_jwt"] = session_jwt + if session_duration_minutes is not None: + payload["session_duration_minutes"] = session_duration_minutes + if session_custom_claims is not None: + payload["session_custom_claims"] = session_custom_claims + + url = self.api_base.route_with_sub_url( + self.sub_url, "/v1/b2b/magic_links/authenticate" + ) + + res = await self.async_client.post(url, json=payload) + return MultitenantmagiclinksauthenticateResponse.from_json( + res.response.status, res.json + ) + + def B2BMagicLinksEmailDiscoverySend( + self, + email_address: str, + discovery_redirect_url: Optional[str] = None, + pkce_code_challenge: Optional[str] = None, + login_template_id: Optional[str] = None, + locale: Optional[str] = None, + ) -> B2BmagiclinksemaildiscoverysendResponse: + payload: Dict[str, Any] = { + "email_address": email_address, + } + + if discovery_redirect_url is not None: + payload["discovery_redirect_url"] = discovery_redirect_url + if pkce_code_challenge is not None: + payload["pkce_code_challenge"] = pkce_code_challenge + if login_template_id is not None: + payload["login_template_id"] = login_template_id + if locale is not None: + payload["locale"] = locale + + url = self.api_base.route_with_sub_url( + self.sub_url, "/v1/b2b/magic_links/email/discovery/send" + ) + + res = self.sync_client.post(url, json=payload) + return B2BmagiclinksemaildiscoverysendResponse.from_json( + res.response.status_code, res.json + ) + + async def B2BMagicLinksEmailDiscoverySend_async( + self, + email_address: str, + discovery_redirect_url: Optional[str] = None, + pkce_code_challenge: Optional[str] = None, + login_template_id: Optional[str] = None, + locale: Optional[str] = None, + ) -> B2BmagiclinksemaildiscoverysendResponse: + payload: Dict[str, Any] = { + "email_address": email_address, + } + + if discovery_redirect_url is not None: + payload["discovery_redirect_url"] = discovery_redirect_url + if pkce_code_challenge is not None: + payload["pkce_code_challenge"] = pkce_code_challenge + if login_template_id is not None: + payload["login_template_id"] = login_template_id + if locale is not None: + payload["locale"] = locale + + url = self.api_base.route_with_sub_url( + self.sub_url, "/v1/b2b/magic_links/email/discovery/send" + ) + + res = await self.async_client.post(url, json=payload) + return B2BmagiclinksemaildiscoverysendResponse.from_json( + res.response.status, res.json + ) + + def B2BMagicLinksDiscoveryAuthenticate( + self, + discovery_magic_links_token: str, + pkce_code_verifier: Optional[str] = None, + ) -> B2BmagiclinksdiscoveryauthenticateResponse: + payload: Dict[str, Any] = { + "discovery_magic_links_token": discovery_magic_links_token, + } + + if pkce_code_verifier is not None: + payload["pkce_code_verifier"] = pkce_code_verifier + + url = self.api_base.route_with_sub_url( + self.sub_url, "/v1/b2b/magic_links/discovery/authenticate" + ) + + res = self.sync_client.post(url, json=payload) + return B2BmagiclinksdiscoveryauthenticateResponse.from_json( + res.response.status_code, res.json + ) + + async def B2BMagicLinksDiscoveryAuthenticate_async( + self, + discovery_magic_links_token: str, + pkce_code_verifier: Optional[str] = None, + ) -> B2BmagiclinksdiscoveryauthenticateResponse: + payload: Dict[str, Any] = { + "discovery_magic_links_token": discovery_magic_links_token, + } + + if pkce_code_verifier is not None: + payload["pkce_code_verifier"] = pkce_code_verifier + + url = self.api_base.route_with_sub_url( + self.sub_url, "/v1/b2b/magic_links/discovery/authenticate" + ) + + res = await self.async_client.post(url, json=payload) + return B2BmagiclinksdiscoveryauthenticateResponse.from_json( + res.response.status, res.json + ) diff --git a/stytch/b2b/api/multi_tenant_password_service.py b/stytch/b2b/api/multi_tenant_password_service.py new file mode 100644 index 00000000..f05583ce --- /dev/null +++ b/stytch/b2b/api/multi_tenant_password_service.py @@ -0,0 +1,460 @@ +# !!! +# WARNING: This file is autogenerated +# Only modify code within MANUAL() sections +# or your changes may be overwritten later! +# !!! + +from typing import Any, Dict, List, Optional, Union + +import pydantic + +from stytch.b2b.models.multi_tenant_password_service import ( + MultitenantpasswordauthenticateResponse, + MultitenantpasswordemailresetResponse, + MultitenantpasswordemailresetstartResponse, + MultitenantpasswordexistingpasswordresetResponse, + MultitenantpasswordmigrateResponse, + MultitenantpasswordsessionresetResponse, + MultitenantpasswordstrengthcheckResponse, +) +from stytch.core.api_base import ApiBase +from stytch.core.http.client import AsyncClient, SyncClient + + +class MultiTenantPasswordService: + def __init__( + self, + api_base: ApiBase, + sync_client: SyncClient, + async_client: AsyncClient, + ) -> None: + self.api_base = api_base + self.sync_client = sync_client + self.async_client = async_client + + @property + def sub_url(self) -> str: + return "multi_tenant_password_service" + + def MultiTenantPasswordStrengthCheck( + self, + password: str, + email_address: Optional[str] = None, + ) -> MultitenantpasswordstrengthcheckResponse: + + payload: Dict[str, Any] = { + "password": password, + } + + if email_address is not None: + payload["email_address"] = email_address + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/b2b/passwords/strength_check") + + res = self.sync_client.post(url, json=payload) + return MultitenantpasswordstrengthcheckResponse.from_json(res.response.status_code, res.json) + + async def MultiTenantPasswordStrengthCheck_async( + self, + password: str, + email_address: Optional[str] = None, + ) -> MultitenantpasswordstrengthcheckResponse: + + payload: Dict[str, Any] = { + "password": password, + } + + if email_address is not None: + payload["email_address"] = email_address + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/b2b/passwords/strength_check") + + res = await self.async_client.post(url, json=payload) + return MultitenantpasswordstrengthcheckResponse.from_json(res.response.status, res.json) + + def MultiTenantPasswordMigrate( + self, + email_address: str, + hash: str, + hash_type: str, + md_5_config: None, + argon_2_config: None, + sha_1_config: None, + scrypt_config: None, + organization_id: str, + name: str, + trusted_metadata: Optional[Dict[str, Any]] = None, + untrusted_metadata: Optional[Dict[str, Any]] = None, + ) -> MultitenantpasswordmigrateResponse: + + payload: Dict[str, Any] = { + "email_address": email_address, + "hash": hash, + "hash_type": hash_type, + "organization_id": organization_id, + "name": name, + } + + if md_5_config is not None: + payload["md_5_config"] = md_5_config + if argon_2_config is not None: + payload["argon_2_config"] = argon_2_config + if sha_1_config is not None: + payload["sha_1_config"] = sha_1_config + if scrypt_config is not None: + payload["scrypt_config"] = scrypt_config + if trusted_metadata is not None: + payload["trusted_metadata"] = trusted_metadata + if untrusted_metadata is not None: + payload["untrusted_metadata"] = untrusted_metadata + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/b2b/passwords/migrate") + + res = self.sync_client.post(url, json=payload) + return MultitenantpasswordmigrateResponse.from_json(res.response.status_code, res.json) + + async def MultiTenantPasswordMigrate_async( + self, + email_address: str, + hash: str, + hash_type: str, + md_5_config: None, + argon_2_config: None, + sha_1_config: None, + scrypt_config: None, + organization_id: str, + name: str, + trusted_metadata: Optional[Dict[str, Any]] = None, + untrusted_metadata: Optional[Dict[str, Any]] = None, + ) -> MultitenantpasswordmigrateResponse: + + payload: Dict[str, Any] = { + "email_address": email_address, + "hash": hash, + "hash_type": hash_type, + "organization_id": organization_id, + "name": name, + } + + if md_5_config is not None: + payload["md_5_config"] = md_5_config + if argon_2_config is not None: + payload["argon_2_config"] = argon_2_config + if sha_1_config is not None: + payload["sha_1_config"] = sha_1_config + if scrypt_config is not None: + payload["scrypt_config"] = scrypt_config + if trusted_metadata is not None: + payload["trusted_metadata"] = trusted_metadata + if untrusted_metadata is not None: + payload["untrusted_metadata"] = untrusted_metadata + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/b2b/passwords/migrate") + + res = await self.async_client.post(url, json=payload) + return MultitenantpasswordmigrateResponse.from_json(res.response.status, res.json) + + def MultiTenantPasswordAuthenticate( + self, + organization_id: str, + email_address: str, + password: str, + session_token: Optional[str] = None, + session_duration_minutes: Optional[int] = None, + session_jwt: Optional[str] = None, + session_custom_claims: Optional[Dict[str, Any]] = None, + ) -> MultitenantpasswordauthenticateResponse: + + payload: Dict[str, Any] = { + "organization_id": organization_id, + "email_address": email_address, + "password": password, + } + + if session_token is not None: + payload["session_token"] = session_token + if session_duration_minutes is not None: + payload["session_duration_minutes"] = session_duration_minutes + if session_jwt is not None: + payload["session_jwt"] = session_jwt + if session_custom_claims is not None: + payload["session_custom_claims"] = session_custom_claims + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/b2b/passwords/authenticate") + + res = self.sync_client.post(url, json=payload) + return MultitenantpasswordauthenticateResponse.from_json(res.response.status_code, res.json) + + async def MultiTenantPasswordAuthenticate_async( + self, + organization_id: str, + email_address: str, + password: str, + session_token: Optional[str] = None, + session_duration_minutes: Optional[int] = None, + session_jwt: Optional[str] = None, + session_custom_claims: Optional[Dict[str, Any]] = None, + ) -> MultitenantpasswordauthenticateResponse: + + payload: Dict[str, Any] = { + "organization_id": organization_id, + "email_address": email_address, + "password": password, + } + + if session_token is not None: + payload["session_token"] = session_token + if session_duration_minutes is not None: + payload["session_duration_minutes"] = session_duration_minutes + if session_jwt is not None: + payload["session_jwt"] = session_jwt + if session_custom_claims is not None: + payload["session_custom_claims"] = session_custom_claims + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/b2b/passwords/authenticate") + + res = await self.async_client.post(url, json=payload) + return MultitenantpasswordauthenticateResponse.from_json(res.response.status, res.json) + + def MultiTenantPasswordEmailResetStart( + self, + organization_id: str, + email_address: str, + reset_password_redirect_url: str, + reset_password_expiration_minutes: Optional[int] = None, + code_challenge: Optional[str] = None, + login_redirect_url: str, + locale: Optional[str] = None, + reset_password_template_id: Optional[str] = None, + ) -> MultitenantpasswordemailresetstartResponse: + + payload: Dict[str, Any] = { + "organization_id": organization_id, + "email_address": email_address, + "reset_password_redirect_url": reset_password_redirect_url, + "login_redirect_url": login_redirect_url, + } + + if reset_password_expiration_minutes is not None: + payload["reset_password_expiration_minutes"] = reset_password_expiration_minutes + if code_challenge is not None: + payload["code_challenge"] = code_challenge + if locale is not None: + payload["locale"] = locale + if reset_password_template_id is not None: + payload["reset_password_template_id"] = reset_password_template_id + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/b2b/passwords/email/reset/start") + + res = self.sync_client.post(url, json=payload) + return MultitenantpasswordemailresetstartResponse.from_json(res.response.status_code, res.json) + + async def MultiTenantPasswordEmailResetStart_async( + self, + organization_id: str, + email_address: str, + reset_password_redirect_url: str, + reset_password_expiration_minutes: Optional[int] = None, + code_challenge: Optional[str] = None, + login_redirect_url: str, + locale: Optional[str] = None, + reset_password_template_id: Optional[str] = None, + ) -> MultitenantpasswordemailresetstartResponse: + + payload: Dict[str, Any] = { + "organization_id": organization_id, + "email_address": email_address, + "reset_password_redirect_url": reset_password_redirect_url, + "login_redirect_url": login_redirect_url, + } + + if reset_password_expiration_minutes is not None: + payload["reset_password_expiration_minutes"] = reset_password_expiration_minutes + if code_challenge is not None: + payload["code_challenge"] = code_challenge + if locale is not None: + payload["locale"] = locale + if reset_password_template_id is not None: + payload["reset_password_template_id"] = reset_password_template_id + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/b2b/passwords/email/reset/start") + + res = await self.async_client.post(url, json=payload) + return MultitenantpasswordemailresetstartResponse.from_json(res.response.status, res.json) + + def MultiTenantPasswordEmailReset( + self, + password_reset_token: str, + password: str, + session_token: Optional[str] = None, + session_duration_minutes: Optional[int] = None, + session_jwt: Optional[str] = None, + code_verifier: Optional[str] = None, + session_custom_claims: Optional[Dict[str, Any]] = None, + ) -> MultitenantpasswordemailresetResponse: + + payload: Dict[str, Any] = { + "password_reset_token": password_reset_token, + "password": password, + } + + if session_token is not None: + payload["session_token"] = session_token + if session_duration_minutes is not None: + payload["session_duration_minutes"] = session_duration_minutes + if session_jwt is not None: + payload["session_jwt"] = session_jwt + if code_verifier is not None: + payload["code_verifier"] = code_verifier + if session_custom_claims is not None: + payload["session_custom_claims"] = session_custom_claims + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/b2b/passwords/email/reset") + + res = self.sync_client.post(url, json=payload) + return MultitenantpasswordemailresetResponse.from_json(res.response.status_code, res.json) + + async def MultiTenantPasswordEmailReset_async( + self, + password_reset_token: str, + password: str, + session_token: Optional[str] = None, + session_duration_minutes: Optional[int] = None, + session_jwt: Optional[str] = None, + code_verifier: Optional[str] = None, + session_custom_claims: Optional[Dict[str, Any]] = None, + ) -> MultitenantpasswordemailresetResponse: + + payload: Dict[str, Any] = { + "password_reset_token": password_reset_token, + "password": password, + } + + if session_token is not None: + payload["session_token"] = session_token + if session_duration_minutes is not None: + payload["session_duration_minutes"] = session_duration_minutes + if session_jwt is not None: + payload["session_jwt"] = session_jwt + if code_verifier is not None: + payload["code_verifier"] = code_verifier + if session_custom_claims is not None: + payload["session_custom_claims"] = session_custom_claims + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/b2b/passwords/email/reset") + + res = await self.async_client.post(url, json=payload) + return MultitenantpasswordemailresetResponse.from_json(res.response.status, res.json) + + def MultiTenantPasswordSessionReset( + self, + organization_id: str, + password: str, + session_token: Optional[str] = None, + session_jwt: Optional[str] = None, + ) -> MultitenantpasswordsessionresetResponse: + + payload: Dict[str, Any] = { + "organization_id": organization_id, + "password": password, + } + + if session_token is not None: + payload["session_token"] = session_token + if session_jwt is not None: + payload["session_jwt"] = session_jwt + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/b2b/passwords/session/reset") + + res = self.sync_client.post(url, json=payload) + return MultitenantpasswordsessionresetResponse.from_json(res.response.status_code, res.json) + + async def MultiTenantPasswordSessionReset_async( + self, + organization_id: str, + password: str, + session_token: Optional[str] = None, + session_jwt: Optional[str] = None, + ) -> MultitenantpasswordsessionresetResponse: + + payload: Dict[str, Any] = { + "organization_id": organization_id, + "password": password, + } + + if session_token is not None: + payload["session_token"] = session_token + if session_jwt is not None: + payload["session_jwt"] = session_jwt + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/b2b/passwords/session/reset") + + res = await self.async_client.post(url, json=payload) + return MultitenantpasswordsessionresetResponse.from_json(res.response.status, res.json) + + def MultiTenantPasswordExistingPasswordReset( + self, + email_address: str, + existing_password: str, + new_password: str, + session_token: Optional[str] = None, + session_duration_minutes: Optional[int] = None, + session_jwt: Optional[str] = None, + session_custom_claims: Optional[Dict[str, Any]] = None, + organization_id: str, + ) -> MultitenantpasswordexistingpasswordresetResponse: + + payload: Dict[str, Any] = { + "email_address": email_address, + "existing_password": existing_password, + "new_password": new_password, + "organization_id": organization_id, + } + + if session_token is not None: + payload["session_token"] = session_token + if session_duration_minutes is not None: + payload["session_duration_minutes"] = session_duration_minutes + if session_jwt is not None: + payload["session_jwt"] = session_jwt + if session_custom_claims is not None: + payload["session_custom_claims"] = session_custom_claims + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/b2b/passwords/existing_password/reset") + + res = self.sync_client.post(url, json=payload) + return MultitenantpasswordexistingpasswordresetResponse.from_json(res.response.status_code, res.json) + + async def MultiTenantPasswordExistingPasswordReset_async( + self, + email_address: str, + existing_password: str, + new_password: str, + session_token: Optional[str] = None, + session_duration_minutes: Optional[int] = None, + session_jwt: Optional[str] = None, + session_custom_claims: Optional[Dict[str, Any]] = None, + organization_id: str, + ) -> MultitenantpasswordexistingpasswordresetResponse: + + payload: Dict[str, Any] = { + "email_address": email_address, + "existing_password": existing_password, + "new_password": new_password, + "organization_id": organization_id, + } + + if session_token is not None: + payload["session_token"] = session_token + if session_duration_minutes is not None: + payload["session_duration_minutes"] = session_duration_minutes + if session_jwt is not None: + payload["session_jwt"] = session_jwt + if session_custom_claims is not None: + payload["session_custom_claims"] = session_custom_claims + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/b2b/passwords/existing_password/reset") + + res = await self.async_client.post(url, json=payload) + return MultitenantpasswordexistingpasswordresetResponse.from_json(res.response.status, res.json) + diff --git a/stytch/b2b/api/multi_tenant_session_service.py b/stytch/b2b/api/multi_tenant_session_service.py new file mode 100644 index 00000000..7a8d5d7b --- /dev/null +++ b/stytch/b2b/api/multi_tenant_session_service.py @@ -0,0 +1,228 @@ +# !!! +# WARNING: This file is autogenerated +# Only modify code within MANUAL() sections +# or your changes may be overwritten later! +# !!! + +from typing import Any, Dict, Optional + +from stytch.b2b.models.multi_tenant_session_service import ( + MultitenantsessionsauthenticateResponse, + MultitenantsessionsexchangeResponse, + MultitenantsessionsgetResponse, + MultitenantsessionsrevokeResponse, +) +from stytch.core.api_base import ApiBase +from stytch.core.http.client import AsyncClient, SyncClient + + +class MultiTenantSessionService: + def __init__( + self, + api_base: ApiBase, + sync_client: SyncClient, + async_client: AsyncClient, + ) -> None: + self.api_base = api_base + self.sync_client = sync_client + self.async_client = async_client + + @property + def sub_url(self) -> str: + return "multi_tenant_session_service" + + def MultiTenantSessionsGet( + self, + organization_id: str, + member_id: str, + ) -> MultitenantsessionsgetResponse: + payload: Dict[str, Any] = { + "organization_id": organization_id, + "member_id": member_id, + } + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/b2b/sessions") + + res = self.sync_client.get(url, params=payload) + return MultitenantsessionsgetResponse.from_json( + res.response.status_code, res.json + ) + + async def MultiTenantSessionsGet_async( + self, + organization_id: str, + member_id: str, + ) -> MultitenantsessionsgetResponse: + payload: Dict[str, Any] = { + "organization_id": organization_id, + "member_id": member_id, + } + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/b2b/sessions") + + res = await self.async_client.get(url, params=payload) + return MultitenantsessionsgetResponse.from_json(res.response.status, res.json) + + def MultiTenantSessionsAuthenticate( + self, + session_token: Optional[str] = None, + session_duration_minutes: Optional[int] = None, + session_jwt: Optional[str] = None, + session_custom_claims: Optional[Dict[str, Any]] = None, + ) -> MultitenantsessionsauthenticateResponse: + payload: Dict[str, Any] = {} + + if session_token is not None: + payload["session_token"] = session_token + if session_duration_minutes is not None: + payload["session_duration_minutes"] = session_duration_minutes + if session_jwt is not None: + payload["session_jwt"] = session_jwt + if session_custom_claims is not None: + payload["session_custom_claims"] = session_custom_claims + + url = self.api_base.route_with_sub_url( + self.sub_url, "/v1/b2b/sessions/authenticate" + ) + + res = self.sync_client.post(url, json=payload) + return MultitenantsessionsauthenticateResponse.from_json( + res.response.status_code, res.json + ) + + async def MultiTenantSessionsAuthenticate_async( + self, + session_token: Optional[str] = None, + session_duration_minutes: Optional[int] = None, + session_jwt: Optional[str] = None, + session_custom_claims: Optional[Dict[str, Any]] = None, + ) -> MultitenantsessionsauthenticateResponse: + payload: Dict[str, Any] = {} + + if session_token is not None: + payload["session_token"] = session_token + if session_duration_minutes is not None: + payload["session_duration_minutes"] = session_duration_minutes + if session_jwt is not None: + payload["session_jwt"] = session_jwt + if session_custom_claims is not None: + payload["session_custom_claims"] = session_custom_claims + + url = self.api_base.route_with_sub_url( + self.sub_url, "/v1/b2b/sessions/authenticate" + ) + + res = await self.async_client.post(url, json=payload) + return MultitenantsessionsauthenticateResponse.from_json( + res.response.status, res.json + ) + + def MultiTenantSessionsRevoke( + self, + member_session_id: Optional[str] = None, + session_token: Optional[str] = None, + session_jwt: Optional[str] = None, + member_id: Optional[str] = None, + ) -> MultitenantsessionsrevokeResponse: + payload: Dict[str, Any] = {} + + if member_session_id is not None: + payload["member_session_id"] = member_session_id + if session_token is not None: + payload["session_token"] = session_token + if session_jwt is not None: + payload["session_jwt"] = session_jwt + if member_id is not None: + payload["member_id"] = member_id + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/b2b/sessions/revoke") + + res = self.sync_client.post(url, json=payload) + return MultitenantsessionsrevokeResponse.from_json( + res.response.status_code, res.json + ) + + async def MultiTenantSessionsRevoke_async( + self, + member_session_id: Optional[str] = None, + session_token: Optional[str] = None, + session_jwt: Optional[str] = None, + member_id: Optional[str] = None, + ) -> MultitenantsessionsrevokeResponse: + payload: Dict[str, Any] = {} + + if member_session_id is not None: + payload["member_session_id"] = member_session_id + if session_token is not None: + payload["session_token"] = session_token + if session_jwt is not None: + payload["session_jwt"] = session_jwt + if member_id is not None: + payload["member_id"] = member_id + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/b2b/sessions/revoke") + + res = await self.async_client.post(url, json=payload) + return MultitenantsessionsrevokeResponse.from_json( + res.response.status, res.json + ) + + def MultiTenantSessionsExchange( + self, + organization_id: str, + session_token: Optional[str] = None, + session_jwt: Optional[str] = None, + session_duration_minutes: Optional[int] = None, + session_custom_claims: Optional[Dict[str, Any]] = None, + ) -> MultitenantsessionsexchangeResponse: + payload: Dict[str, Any] = { + "organization_id": organization_id, + } + + if session_token is not None: + payload["session_token"] = session_token + if session_jwt is not None: + payload["session_jwt"] = session_jwt + if session_duration_minutes is not None: + payload["session_duration_minutes"] = session_duration_minutes + if session_custom_claims is not None: + payload["session_custom_claims"] = session_custom_claims + + url = self.api_base.route_with_sub_url( + self.sub_url, "/v1/b2b/sessions/exchange" + ) + + res = self.sync_client.post(url, json=payload) + return MultitenantsessionsexchangeResponse.from_json( + res.response.status_code, res.json + ) + + async def MultiTenantSessionsExchange_async( + self, + organization_id: str, + session_token: Optional[str] = None, + session_jwt: Optional[str] = None, + session_duration_minutes: Optional[int] = None, + session_custom_claims: Optional[Dict[str, Any]] = None, + ) -> MultitenantsessionsexchangeResponse: + payload: Dict[str, Any] = { + "organization_id": organization_id, + } + + if session_token is not None: + payload["session_token"] = session_token + if session_jwt is not None: + payload["session_jwt"] = session_jwt + if session_duration_minutes is not None: + payload["session_duration_minutes"] = session_duration_minutes + if session_custom_claims is not None: + payload["session_custom_claims"] = session_custom_claims + + url = self.api_base.route_with_sub_url( + self.sub_url, "/v1/b2b/sessions/exchange" + ) + + res = await self.async_client.post(url, json=payload) + return MultitenantsessionsexchangeResponse.from_json( + res.response.status, res.json + ) diff --git a/stytch/b2b/api/organization_service.py b/stytch/b2b/api/organization_service.py new file mode 100644 index 00000000..197fa2dc --- /dev/null +++ b/stytch/b2b/api/organization_service.py @@ -0,0 +1,564 @@ +# !!! +# WARNING: This file is autogenerated +# Only modify code within MANUAL() sections +# or your changes may be overwritten later! +# !!! + +from typing import Any, Dict, List, Optional, Union + +import pydantic + +from stytch.b2b.models.organization_service import ( + OrganizationscreateResponse, + OrganizationsdeleteResponse, + OrganizationsgetResponse, + OrganizationsmembercreateResponse, + OrganizationsmemberdeletepasswordResponse, + OrganizationsmemberdeleteResponse, + OrganizationsmembergetResponse, + OrganizationsmembersearchexternalResponse, + OrganizationsmemberupdateResponse, + OrganizationssearchexternalResponse, + OrganizationsupdateResponse, +) +from stytch.core.api_base import ApiBase +from stytch.core.http.client import AsyncClient, SyncClient + + +class OrganizationService: + def __init__( + self, + api_base: ApiBase, + sync_client: SyncClient, + async_client: AsyncClient, + ) -> None: + self.api_base = api_base + self.sync_client = sync_client + self.async_client = async_client + + @property + def sub_url(self) -> str: + return "organization_service" + + def OrganizationsCreate( + self, + organization_name: str, + organization_slug: str, + organization_logo_url: str, + trusted_metadata: Optional[Dict[str, Any]] = None, + sso_jit_provisioning: Optional[str] = None, + email_allowed_domains: List[str], + email_jit_provisioning: Optional[str] = None, + email_invites: Optional[str] = None, + auth_methods: Optional[str] = None, + allowed_auth_methods: List[str], + ) -> OrganizationscreateResponse: + + payload: Dict[str, Any] = { + "organization_name": organization_name, + "organization_slug": organization_slug, + "organization_logo_url": organization_logo_url, + "email_allowed_domains": email_allowed_domains, + "allowed_auth_methods": allowed_auth_methods, + } + + if trusted_metadata is not None: + payload["trusted_metadata"] = trusted_metadata + if sso_jit_provisioning is not None: + payload["sso_jit_provisioning"] = sso_jit_provisioning + if email_jit_provisioning is not None: + payload["email_jit_provisioning"] = email_jit_provisioning + if email_invites is not None: + payload["email_invites"] = email_invites + if auth_methods is not None: + payload["auth_methods"] = auth_methods + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/b2b/organizations") + + res = self.sync_client.post(url, json=payload) + return OrganizationscreateResponse.from_json(res.response.status_code, res.json) + + async def OrganizationsCreate_async( + self, + organization_name: str, + organization_slug: str, + organization_logo_url: str, + trusted_metadata: Optional[Dict[str, Any]] = None, + sso_jit_provisioning: Optional[str] = None, + email_allowed_domains: List[str], + email_jit_provisioning: Optional[str] = None, + email_invites: Optional[str] = None, + auth_methods: Optional[str] = None, + allowed_auth_methods: List[str], + ) -> OrganizationscreateResponse: + + payload: Dict[str, Any] = { + "organization_name": organization_name, + "organization_slug": organization_slug, + "organization_logo_url": organization_logo_url, + "email_allowed_domains": email_allowed_domains, + "allowed_auth_methods": allowed_auth_methods, + } + + if trusted_metadata is not None: + payload["trusted_metadata"] = trusted_metadata + if sso_jit_provisioning is not None: + payload["sso_jit_provisioning"] = sso_jit_provisioning + if email_jit_provisioning is not None: + payload["email_jit_provisioning"] = email_jit_provisioning + if email_invites is not None: + payload["email_invites"] = email_invites + if auth_methods is not None: + payload["auth_methods"] = auth_methods + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/b2b/organizations") + + res = await self.async_client.post(url, json=payload) + return OrganizationscreateResponse.from_json(res.response.status, res.json) + + def OrganizationsGet( + self, + organization_id: str, + ) -> OrganizationsgetResponse: + + payload: Dict[str, Any] = { + "organization_id": organization_id, + } + + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/b2b/organizations/{organization_id}") + + res = self.sync_client.get(url, params=payload) + return OrganizationsgetResponse.from_json(res.response.status_code, res.json) + + async def OrganizationsGet_async( + self, + organization_id: str, + ) -> OrganizationsgetResponse: + + payload: Dict[str, Any] = { + "organization_id": organization_id, + } + + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/b2b/organizations/{organization_id}") + + res = await self.async_client.get(url, params=payload) + return OrganizationsgetResponse.from_json(res.response.status, res.json) + + def OrganizationsUpdate( + self, + organization_id: str, + organization_name: Optional[str] = None, + organization_slug: Optional[str] = None, + organization_logo_url: Optional[str] = None, + trusted_metadata: Optional[Dict[str, Any]] = None, + sso_default_connection_id: Optional[str] = None, + sso_jit_provisioning: Optional[str] = None, + sso_jit_provisioning_allowed_connections: Optional[List[str]] = None, + email_allowed_domains: Optional[List[str]] = None, + email_jit_provisioning: Optional[str] = None, + email_invites: Optional[str] = None, + auth_methods: Optional[str] = None, + allowed_auth_methods: Optional[List[str]] = None, + ) -> OrganizationsupdateResponse: + + payload: Dict[str, Any] = { + "organization_id": organization_id, + } + + if organization_name is not None: + payload["organization_name"] = organization_name + if organization_slug is not None: + payload["organization_slug"] = organization_slug + if organization_logo_url is not None: + payload["organization_logo_url"] = organization_logo_url + if trusted_metadata is not None: + payload["trusted_metadata"] = trusted_metadata + if sso_default_connection_id is not None: + payload["sso_default_connection_id"] = sso_default_connection_id + if sso_jit_provisioning is not None: + payload["sso_jit_provisioning"] = sso_jit_provisioning + if sso_jit_provisioning_allowed_connections is not None: + payload["sso_jit_provisioning_allowed_connections"] = sso_jit_provisioning_allowed_connections + if email_allowed_domains is not None: + payload["email_allowed_domains"] = email_allowed_domains + if email_jit_provisioning is not None: + payload["email_jit_provisioning"] = email_jit_provisioning + if email_invites is not None: + payload["email_invites"] = email_invites + if auth_methods is not None: + payload["auth_methods"] = auth_methods + if allowed_auth_methods is not None: + payload["allowed_auth_methods"] = allowed_auth_methods + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/b2b/organizations/{organization_id}") + + res = self.sync_client.put(url, json=payload) + return OrganizationsupdateResponse.from_json(res.response.status_code, res.json) + + async def OrganizationsUpdate_async( + self, + organization_id: str, + organization_name: Optional[str] = None, + organization_slug: Optional[str] = None, + organization_logo_url: Optional[str] = None, + trusted_metadata: Optional[Dict[str, Any]] = None, + sso_default_connection_id: Optional[str] = None, + sso_jit_provisioning: Optional[str] = None, + sso_jit_provisioning_allowed_connections: Optional[List[str]] = None, + email_allowed_domains: Optional[List[str]] = None, + email_jit_provisioning: Optional[str] = None, + email_invites: Optional[str] = None, + auth_methods: Optional[str] = None, + allowed_auth_methods: Optional[List[str]] = None, + ) -> OrganizationsupdateResponse: + + payload: Dict[str, Any] = { + "organization_id": organization_id, + } + + if organization_name is not None: + payload["organization_name"] = organization_name + if organization_slug is not None: + payload["organization_slug"] = organization_slug + if organization_logo_url is not None: + payload["organization_logo_url"] = organization_logo_url + if trusted_metadata is not None: + payload["trusted_metadata"] = trusted_metadata + if sso_default_connection_id is not None: + payload["sso_default_connection_id"] = sso_default_connection_id + if sso_jit_provisioning is not None: + payload["sso_jit_provisioning"] = sso_jit_provisioning + if sso_jit_provisioning_allowed_connections is not None: + payload["sso_jit_provisioning_allowed_connections"] = sso_jit_provisioning_allowed_connections + if email_allowed_domains is not None: + payload["email_allowed_domains"] = email_allowed_domains + if email_jit_provisioning is not None: + payload["email_jit_provisioning"] = email_jit_provisioning + if email_invites is not None: + payload["email_invites"] = email_invites + if auth_methods is not None: + payload["auth_methods"] = auth_methods + if allowed_auth_methods is not None: + payload["allowed_auth_methods"] = allowed_auth_methods + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/b2b/organizations/{organization_id}") + + res = await self.async_client.put(url, json=payload) + return OrganizationsupdateResponse.from_json(res.response.status, res.json) + + def OrganizationsDelete( + self, + organization_id: str, + ) -> OrganizationsdeleteResponse: + + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/b2b/organizations/{organization_id}") + + res = self.sync_client.delete(url) + return OrganizationsdeleteResponse.from_json(res.response.status_code, res.json) + + async def OrganizationsDelete_async( + self, + organization_id: str, + ) -> OrganizationsdeleteResponse: + + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/b2b/organizations/{organization_id}") + + res = await self.async_client.delete(url) + return OrganizationsdeleteResponse.from_json(res.response.status, res.json) + + def OrganizationsMemberCreate( + self, + organization_id: str, + email_address: str, + name: Optional[str] = None, + trusted_metadata: Optional[Dict[str, Any]] = None, + untrusted_metadata: Optional[Dict[str, Any]] = None, + create_member_as_pending: bool, + is_breakglass: bool, + ) -> OrganizationsmembercreateResponse: + + payload: Dict[str, Any] = { + "organization_id": organization_id, + "email_address": email_address, + "create_member_as_pending": create_member_as_pending, + "is_breakglass": is_breakglass, + } + + if name is not None: + payload["name"] = name + if trusted_metadata is not None: + payload["trusted_metadata"] = trusted_metadata + if untrusted_metadata is not None: + payload["untrusted_metadata"] = untrusted_metadata + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/b2b/organizations/{organization_id}/members") + + res = self.sync_client.post(url, json=payload) + return OrganizationsmembercreateResponse.from_json(res.response.status_code, res.json) + + async def OrganizationsMemberCreate_async( + self, + organization_id: str, + email_address: str, + name: Optional[str] = None, + trusted_metadata: Optional[Dict[str, Any]] = None, + untrusted_metadata: Optional[Dict[str, Any]] = None, + create_member_as_pending: bool, + is_breakglass: bool, + ) -> OrganizationsmembercreateResponse: + + payload: Dict[str, Any] = { + "organization_id": organization_id, + "email_address": email_address, + "create_member_as_pending": create_member_as_pending, + "is_breakglass": is_breakglass, + } + + if name is not None: + payload["name"] = name + if trusted_metadata is not None: + payload["trusted_metadata"] = trusted_metadata + if untrusted_metadata is not None: + payload["untrusted_metadata"] = untrusted_metadata + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/b2b/organizations/{organization_id}/members") + + res = await self.async_client.post(url, json=payload) + return OrganizationsmembercreateResponse.from_json(res.response.status, res.json) + + def OrganizationsMemberUpdate( + self, + organization_id: str, + member_id: str, + name: Optional[str] = None, + trusted_metadata: Optional[Dict[str, Any]] = None, + untrusted_metadata: Optional[Dict[str, Any]] = None, + is_breakglass: Optional[bool] = None, + ) -> OrganizationsmemberupdateResponse: + + payload: Dict[str, Any] = { + "organization_id": organization_id, + "member_id": member_id, + } + + if name is not None: + payload["name"] = name + if trusted_metadata is not None: + payload["trusted_metadata"] = trusted_metadata + if untrusted_metadata is not None: + payload["untrusted_metadata"] = untrusted_metadata + if is_breakglass is not None: + payload["is_breakglass"] = is_breakglass + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/b2b/organizations/{organization_id}/members/{member_id}") + + res = self.sync_client.put(url, json=payload) + return OrganizationsmemberupdateResponse.from_json(res.response.status_code, res.json) + + async def OrganizationsMemberUpdate_async( + self, + organization_id: str, + member_id: str, + name: Optional[str] = None, + trusted_metadata: Optional[Dict[str, Any]] = None, + untrusted_metadata: Optional[Dict[str, Any]] = None, + is_breakglass: Optional[bool] = None, + ) -> OrganizationsmemberupdateResponse: + + payload: Dict[str, Any] = { + "organization_id": organization_id, + "member_id": member_id, + } + + if name is not None: + payload["name"] = name + if trusted_metadata is not None: + payload["trusted_metadata"] = trusted_metadata + if untrusted_metadata is not None: + payload["untrusted_metadata"] = untrusted_metadata + if is_breakglass is not None: + payload["is_breakglass"] = is_breakglass + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/b2b/organizations/{organization_id}/members/{member_id}") + + res = await self.async_client.put(url, json=payload) + return OrganizationsmemberupdateResponse.from_json(res.response.status, res.json) + + def OrganizationsMemberDelete( + self, + organization_id: str, + member_id: str, + ) -> OrganizationsmemberdeleteResponse: + + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/b2b/organizations/{organization_id}/members/{member_id}") + + res = self.sync_client.delete(url) + return OrganizationsmemberdeleteResponse.from_json(res.response.status_code, res.json) + + async def OrganizationsMemberDelete_async( + self, + organization_id: str, + member_id: str, + ) -> OrganizationsmemberdeleteResponse: + + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/b2b/organizations/{organization_id}/members/{member_id}") + + res = await self.async_client.delete(url) + return OrganizationsmemberdeleteResponse.from_json(res.response.status, res.json) + + def OrganizationsSearchExternal( + self, + cursor: str, + limit: Optional[int] = None, + query: ExternalSearchQuery, + ) -> OrganizationssearchexternalResponse: + + payload: Dict[str, Any] = { + "cursor": cursor, + "query": query, + } + + if limit is not None: + payload["limit"] = limit + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/b2b/organizations/search") + + res = self.sync_client.post(url, json=payload) + return OrganizationssearchexternalResponse.from_json(res.response.status_code, res.json) + + async def OrganizationsSearchExternal_async( + self, + cursor: str, + limit: Optional[int] = None, + query: ExternalSearchQuery, + ) -> OrganizationssearchexternalResponse: + + payload: Dict[str, Any] = { + "cursor": cursor, + "query": query, + } + + if limit is not None: + payload["limit"] = limit + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/b2b/organizations/search") + + res = await self.async_client.post(url, json=payload) + return OrganizationssearchexternalResponse.from_json(res.response.status, res.json) + + def OrganizationsMemberSearchExternal( + self, + cursor: str, + limit: Optional[int] = None, + query: ExternalSearchQuery, + organization_ids: List[str], + ) -> OrganizationsmembersearchexternalResponse: + + payload: Dict[str, Any] = { + "cursor": cursor, + "query": query, + "organization_ids": organization_ids, + } + + if limit is not None: + payload["limit"] = limit + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/b2b/organizations/members/search") + + res = self.sync_client.post(url, json=payload) + return OrganizationsmembersearchexternalResponse.from_json(res.response.status_code, res.json) + + async def OrganizationsMemberSearchExternal_async( + self, + cursor: str, + limit: Optional[int] = None, + query: ExternalSearchQuery, + organization_ids: List[str], + ) -> OrganizationsmembersearchexternalResponse: + + payload: Dict[str, Any] = { + "cursor": cursor, + "query": query, + "organization_ids": organization_ids, + } + + if limit is not None: + payload["limit"] = limit + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/b2b/organizations/members/search") + + res = await self.async_client.post(url, json=payload) + return OrganizationsmembersearchexternalResponse.from_json(res.response.status, res.json) + + def OrganizationsMemberDeletePassword( + self, + organization_id: str, + member_password_id: str, + ) -> OrganizationsmemberdeletepasswordResponse: + + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/b2b/organizations/{organization_id}/members/passwords/{member_password_id}") + + res = self.sync_client.delete(url) + return OrganizationsmemberdeletepasswordResponse.from_json(res.response.status_code, res.json) + + async def OrganizationsMemberDeletePassword_async( + self, + organization_id: str, + member_password_id: str, + ) -> OrganizationsmemberdeletepasswordResponse: + + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/b2b/organizations/{organization_id}/members/passwords/{member_password_id}") + + res = await self.async_client.delete(url) + return OrganizationsmemberdeletepasswordResponse.from_json(res.response.status, res.json) + + def OrganizationsMemberGet( + self, + organization_id: str, + member_id: Optional[str] = None, + email_address: Optional[str] = None, + ) -> OrganizationsmembergetResponse: + + payload: Dict[str, Any] = { + "organization_id": organization_id, + } + + if member_id is not None: + payload["member_id"] = member_id + if email_address is not None: + payload["email_address"] = email_address + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/b2b/organizations/{organization_id}/member") + + res = self.sync_client.get(url, params=payload) + return OrganizationsmembergetResponse.from_json(res.response.status_code, res.json) + + async def OrganizationsMemberGet_async( + self, + organization_id: str, + member_id: Optional[str] = None, + email_address: Optional[str] = None, + ) -> OrganizationsmembergetResponse: + + payload: Dict[str, Any] = { + "organization_id": organization_id, + } + + if member_id is not None: + payload["member_id"] = member_id + if email_address is not None: + payload["email_address"] = email_address + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/b2b/organizations/{organization_id}/member") + + res = await self.async_client.get(url, params=payload) + return OrganizationsmembergetResponse.from_json(res.response.status, res.json) + diff --git a/stytch/b2b/api/password_service.py b/stytch/b2b/api/password_service.py new file mode 100644 index 00000000..5619ad1e --- /dev/null +++ b/stytch/b2b/api/password_service.py @@ -0,0 +1,67 @@ +# !!! +# WARNING: This file is autogenerated +# Only modify code within MANUAL() sections +# or your changes may be overwritten later! +# !!! + +from typing import Any, Dict, Optional + +from stytch.b2b.models.password_service import PasswordsstrengthcheckResponse +from stytch.core.api_base import ApiBase +from stytch.core.http.client import AsyncClient, SyncClient + + +class PasswordService: + def __init__( + self, + api_base: ApiBase, + sync_client: SyncClient, + async_client: AsyncClient, + ) -> None: + self.api_base = api_base + self.sync_client = sync_client + self.async_client = async_client + + @property + def sub_url(self) -> str: + return "password_service" + + def PasswordsStrengthCheck( + self, + password: str, + email: Optional[str] = None, + ) -> PasswordsstrengthcheckResponse: + payload: Dict[str, Any] = { + "password": password, + } + + if email is not None: + payload["email"] = email + + url = self.api_base.route_with_sub_url( + self.sub_url, "/v1/passwords/strength_check" + ) + + res = self.sync_client.post(url, json=payload) + return PasswordsstrengthcheckResponse.from_json( + res.response.status_code, res.json + ) + + async def PasswordsStrengthCheck_async( + self, + password: str, + email: Optional[str] = None, + ) -> PasswordsstrengthcheckResponse: + payload: Dict[str, Any] = { + "password": password, + } + + if email is not None: + payload["email"] = email + + url = self.api_base.route_with_sub_url( + self.sub_url, "/v1/passwords/strength_check" + ) + + res = await self.async_client.post(url, json=payload) + return PasswordsstrengthcheckResponse.from_json(res.response.status, res.json) diff --git a/stytch/b2b/api/session_service.py b/stytch/b2b/api/session_service.py new file mode 100644 index 00000000..da660809 --- /dev/null +++ b/stytch/b2b/api/session_service.py @@ -0,0 +1,59 @@ +# !!! +# WARNING: This file is autogenerated +# Only modify code within MANUAL() sections +# or your changes may be overwritten later! +# !!! + +from typing import Any, Dict + +from stytch.b2b.models.session_service import MultitenantsessionsjwksResponse +from stytch.core.api_base import ApiBase +from stytch.core.http.client import AsyncClient, SyncClient + + +class SessionService: + def __init__( + self, + api_base: ApiBase, + sync_client: SyncClient, + async_client: AsyncClient, + ) -> None: + self.api_base = api_base + self.sync_client = sync_client + self.async_client = async_client + + @property + def sub_url(self) -> str: + return "session_service" + + def MultiTenantSessionsJwks( + self, + project_id: str, + ) -> MultitenantsessionsjwksResponse: + payload: Dict[str, Any] = { + "project_id": project_id, + } + + url = self.api_base.route_with_sub_url( + self.sub_url, "/v1/b2b/sessions/jwks/{project_id}" + ) + + res = self.sync_client.get(url, params=payload) + return MultitenantsessionsjwksResponse.from_json( + res.response.status_code, res.json + ) + + async def MultiTenantSessionsJwks_async( + self, + project_id: str, + ) -> MultitenantsessionsjwksResponse: + payload: Dict[str, Any] = { + "project_id": project_id, + } + + url = self.api_base.route_with_sub_url( + self.sub_url, "/v1/b2b/sessions/jwks/{project_id}" + ) + + res = await self.async_client.get(url, params=payload) + return MultitenantsessionsjwksResponse.from_json(res.response.status, res.json) diff --git a/stytch/b2b/api/sso_service.py b/stytch/b2b/api/sso_service.py new file mode 100644 index 00000000..45113def --- /dev/null +++ b/stytch/b2b/api/sso_service.py @@ -0,0 +1,447 @@ +# !!! +# WARNING: This file is autogenerated +# Only modify code within MANUAL() sections +# or your changes may be overwritten later! +# !!! + +from typing import Any, Dict, List, Optional, Union + +import pydantic + +from stytch.b2b.models.sso_service import ( + CreateoidcconnectionResponse, + CreatesamlconnectionResponse, + DeletesamlverificationcertificateResponse, + DeletessoconnectionResponse, + GetssoconnectionsResponse, + SsoauthenticateResponse, + UpdateoidcconnectionResponse, + UpdatesamlconnectionbydocResponse, + UpdatesamlconnectionbyurlResponse, + UpdatesamlconnectionResponse, +) +from stytch.core.api_base import ApiBase +from stytch.core.http.client import AsyncClient, SyncClient + + +class SSOService: + def __init__( + self, + api_base: ApiBase, + sync_client: SyncClient, + async_client: AsyncClient, + ) -> None: + self.api_base = api_base + self.sync_client = sync_client + self.async_client = async_client + + @property + def sub_url(self) -> str: + return "sso_service" + + def CreateOIDCConnection( + self, + organization_id: str, + display_name: str, + ) -> CreateoidcconnectionResponse: + + payload: Dict[str, Any] = { + "organization_id": organization_id, + "display_name": display_name, + } + + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/b2b/sso/oidc/{organization_id}") + + res = self.sync_client.post(url, json=payload) + return CreateoidcconnectionResponse.from_json(res.response.status_code, res.json) + + async def CreateOIDCConnection_async( + self, + organization_id: str, + display_name: str, + ) -> CreateoidcconnectionResponse: + + payload: Dict[str, Any] = { + "organization_id": organization_id, + "display_name": display_name, + } + + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/b2b/sso/oidc/{organization_id}") + + res = await self.async_client.post(url, json=payload) + return CreateoidcconnectionResponse.from_json(res.response.status, res.json) + + def CreateSAMLConnection( + self, + organization_id: str, + display_name: str, + ) -> CreatesamlconnectionResponse: + + payload: Dict[str, Any] = { + "organization_id": organization_id, + "display_name": display_name, + } + + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/b2b/sso/saml/{organization_id}") + + res = self.sync_client.post(url, json=payload) + return CreatesamlconnectionResponse.from_json(res.response.status_code, res.json) + + async def CreateSAMLConnection_async( + self, + organization_id: str, + display_name: str, + ) -> CreatesamlconnectionResponse: + + payload: Dict[str, Any] = { + "organization_id": organization_id, + "display_name": display_name, + } + + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/b2b/sso/saml/{organization_id}") + + res = await self.async_client.post(url, json=payload) + return CreatesamlconnectionResponse.from_json(res.response.status, res.json) + + def UpdateOIDCConnection( + self, + organization_id: str, + connection_id: str, + display_name: str, + client_id: str, + client_secret: str, + issuer: str, + authorization_url: str, + token_url: str, + userinfo_url: str, + jwks_url: str, + ) -> UpdateoidcconnectionResponse: + + payload: Dict[str, Any] = { + "organization_id": organization_id, + "connection_id": connection_id, + "display_name": display_name, + "client_id": client_id, + "client_secret": client_secret, + "issuer": issuer, + "authorization_url": authorization_url, + "token_url": token_url, + "userinfo_url": userinfo_url, + "jwks_url": jwks_url, + } + + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/b2b/sso/oidc/{organization_id}/connections/{connection_id}") + + res = self.sync_client.put(url, json=payload) + return UpdateoidcconnectionResponse.from_json(res.response.status_code, res.json) + + async def UpdateOIDCConnection_async( + self, + organization_id: str, + connection_id: str, + display_name: str, + client_id: str, + client_secret: str, + issuer: str, + authorization_url: str, + token_url: str, + userinfo_url: str, + jwks_url: str, + ) -> UpdateoidcconnectionResponse: + + payload: Dict[str, Any] = { + "organization_id": organization_id, + "connection_id": connection_id, + "display_name": display_name, + "client_id": client_id, + "client_secret": client_secret, + "issuer": issuer, + "authorization_url": authorization_url, + "token_url": token_url, + "userinfo_url": userinfo_url, + "jwks_url": jwks_url, + } + + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/b2b/sso/oidc/{organization_id}/connections/{connection_id}") + + res = await self.async_client.put(url, json=payload) + return UpdateoidcconnectionResponse.from_json(res.response.status, res.json) + + def UpdateSAMLConnection( + self, + organization_id: str, + connection_id: str, + idp_entity_id: str, + display_name: str, + attribute_mapping: Optional[Dict[str, Any]] = None, + x509_certificate: str, + idp_sso_url: str, + None: None, + ) -> UpdatesamlconnectionResponse: + + payload: Dict[str, Any] = { + "organization_id": organization_id, + "connection_id": connection_id, + "idp_entity_id": idp_entity_id, + "display_name": display_name, + "x509_certificate": x509_certificate, + "idp_sso_url": idp_sso_url, + } + + if attribute_mapping is not None: + payload["attribute_mapping"] = attribute_mapping + if None is not None: + payload["None"] = None + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/b2b/sso/saml/{organization_id}/connections/{connection_id}") + + res = self.sync_client.put(url, json=payload) + return UpdatesamlconnectionResponse.from_json(res.response.status_code, res.json) + + async def UpdateSAMLConnection_async( + self, + organization_id: str, + connection_id: str, + idp_entity_id: str, + display_name: str, + attribute_mapping: Optional[Dict[str, Any]] = None, + x509_certificate: str, + idp_sso_url: str, + None: None, + ) -> UpdatesamlconnectionResponse: + + payload: Dict[str, Any] = { + "organization_id": organization_id, + "connection_id": connection_id, + "idp_entity_id": idp_entity_id, + "display_name": display_name, + "x509_certificate": x509_certificate, + "idp_sso_url": idp_sso_url, + } + + if attribute_mapping is not None: + payload["attribute_mapping"] = attribute_mapping + if None is not None: + payload["None"] = None + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/b2b/sso/saml/{organization_id}/connections/{connection_id}") + + res = await self.async_client.put(url, json=payload) + return UpdatesamlconnectionResponse.from_json(res.response.status, res.json) + + def UpdateSAMLConnectionByURL( + self, + connection_id: str, + metadata_url: str, + ) -> UpdatesamlconnectionbyurlResponse: + + payload: Dict[str, Any] = { + "connection_id": connection_id, + "metadata_url": metadata_url, + } + + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/b2b/sso/saml/{connection_id}/url") + + res = self.sync_client.put(url, json=payload) + return UpdatesamlconnectionbyurlResponse.from_json(res.response.status_code, res.json) + + async def UpdateSAMLConnectionByURL_async( + self, + connection_id: str, + metadata_url: str, + ) -> UpdatesamlconnectionbyurlResponse: + + payload: Dict[str, Any] = { + "connection_id": connection_id, + "metadata_url": metadata_url, + } + + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/b2b/sso/saml/{connection_id}/url") + + res = await self.async_client.put(url, json=payload) + return UpdatesamlconnectionbyurlResponse.from_json(res.response.status, res.json) + + def UpdateSAMLConnectionByDoc( + self, + connection_id: str, + metadata: None, + ) -> UpdatesamlconnectionbydocResponse: + + payload: Dict[str, Any] = { + "connection_id": connection_id, + } + + if metadata is not None: + payload["metadata"] = metadata + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/b2b/sso/saml/{connection_id}/doc") + + res = self.sync_client.put(url, json=payload) + return UpdatesamlconnectionbydocResponse.from_json(res.response.status_code, res.json) + + async def UpdateSAMLConnectionByDoc_async( + self, + connection_id: str, + metadata: None, + ) -> UpdatesamlconnectionbydocResponse: + + payload: Dict[str, Any] = { + "connection_id": connection_id, + } + + if metadata is not None: + payload["metadata"] = metadata + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/b2b/sso/saml/{connection_id}/doc") + + res = await self.async_client.put(url, json=payload) + return UpdatesamlconnectionbydocResponse.from_json(res.response.status, res.json) + + def GetSSOConnections( + self, + organization_id: str, + ) -> GetssoconnectionsResponse: + + payload: Dict[str, Any] = { + "organization_id": organization_id, + } + + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/b2b/sso/{organization_id}") + + res = self.sync_client.get(url, params=payload) + return GetssoconnectionsResponse.from_json(res.response.status_code, res.json) + + async def GetSSOConnections_async( + self, + organization_id: str, + ) -> GetssoconnectionsResponse: + + payload: Dict[str, Any] = { + "organization_id": organization_id, + } + + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/b2b/sso/{organization_id}") + + res = await self.async_client.get(url, params=payload) + return GetssoconnectionsResponse.from_json(res.response.status, res.json) + + def DeleteSSOConnection( + self, + organization_id: str, + connection_id: str, + ) -> DeletessoconnectionResponse: + + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/b2b/sso/{organization_id}/connections/{connection_id}") + + res = self.sync_client.delete(url) + return DeletessoconnectionResponse.from_json(res.response.status_code, res.json) + + async def DeleteSSOConnection_async( + self, + organization_id: str, + connection_id: str, + ) -> DeletessoconnectionResponse: + + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/b2b/sso/{organization_id}/connections/{connection_id}") + + res = await self.async_client.delete(url) + return DeletessoconnectionResponse.from_json(res.response.status, res.json) + + def SSOAuthenticate( + self, + sso_token: str, + pkce_code_verifier: Optional[str] = None, + session_token: Optional[str] = None, + session_jwt: Optional[str] = None, + session_duration_minutes: Optional[int] = None, + session_custom_claims: Optional[Dict[str, Any]] = None, + ) -> SsoauthenticateResponse: + + payload: Dict[str, Any] = { + "sso_token": sso_token, + } + + if pkce_code_verifier is not None: + payload["pkce_code_verifier"] = pkce_code_verifier + if session_token is not None: + payload["session_token"] = session_token + if session_jwt is not None: + payload["session_jwt"] = session_jwt + if session_duration_minutes is not None: + payload["session_duration_minutes"] = session_duration_minutes + if session_custom_claims is not None: + payload["session_custom_claims"] = session_custom_claims + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/b2b/sso/authenticate") + + res = self.sync_client.post(url, json=payload) + return SsoauthenticateResponse.from_json(res.response.status_code, res.json) + + async def SSOAuthenticate_async( + self, + sso_token: str, + pkce_code_verifier: Optional[str] = None, + session_token: Optional[str] = None, + session_jwt: Optional[str] = None, + session_duration_minutes: Optional[int] = None, + session_custom_claims: Optional[Dict[str, Any]] = None, + ) -> SsoauthenticateResponse: + + payload: Dict[str, Any] = { + "sso_token": sso_token, + } + + if pkce_code_verifier is not None: + payload["pkce_code_verifier"] = pkce_code_verifier + if session_token is not None: + payload["session_token"] = session_token + if session_jwt is not None: + payload["session_jwt"] = session_jwt + if session_duration_minutes is not None: + payload["session_duration_minutes"] = session_duration_minutes + if session_custom_claims is not None: + payload["session_custom_claims"] = session_custom_claims + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/b2b/sso/authenticate") + + res = await self.async_client.post(url, json=payload) + return SsoauthenticateResponse.from_json(res.response.status, res.json) + + def DeleteSAMLVerificationCertificate( + self, + organization_id: str, + connection_id: str, + certificate_id: str, + ) -> DeletesamlverificationcertificateResponse: + + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/b2b/sso/saml/{organization_id}/connections/{connection_id}/verification_certificates/{certificate_id}") + + res = self.sync_client.delete(url) + return DeletesamlverificationcertificateResponse.from_json(res.response.status_code, res.json) + + async def DeleteSAMLVerificationCertificate_async( + self, + organization_id: str, + connection_id: str, + certificate_id: str, + ) -> DeletesamlverificationcertificateResponse: + + + url = self.api_base.route_with_sub_url(self.sub_url, "/v1/b2b/sso/saml/{organization_id}/connections/{connection_id}/verification_certificates/{certificate_id}") + + res = await self.async_client.delete(url) + return DeletesamlverificationcertificateResponse.from_json(res.response.status, res.json) + diff --git a/stytch/b2b/models/debug_service.py b/stytch/b2b/models/debug_service.py new file mode 100644 index 00000000..5f6c96e5 --- /dev/null +++ b/stytch/b2b/models/debug_service.py @@ -0,0 +1,10 @@ +#!/usr/bin/env python3 + + +from stytch.core.models import ResponseBase + + +class WhoamiResponse(ResponseBase): + request_id: str + project_id: str + name: str diff --git a/stytch/b2b/models/discovery_service.py b/stytch/b2b/models/discovery_service.py new file mode 100644 index 00000000..dcfd20d5 --- /dev/null +++ b/stytch/b2b/models/discovery_service.py @@ -0,0 +1,30 @@ +#!/usr/bin/env python3 + + +from stytch.core.models import ResponseBase + + +class DiscoveryorganizationsResponse(ResponseBase): + request_id: str + email_address: str + discovered_organizations: None + + +class DiscoveryintermediatesessionexchangeResponse(ResponseBase): + request_id: str + member_id: str + member_session: None + session_token: str + session_jwt: str + member: None + organization: None + + +class DiscoveryorganizationcreateResponse(ResponseBase): + request_id: str + member_id: str + member_session: None + session_token: str + session_jwt: str + member: None + organization: None diff --git a/stytch/b2b/models/magic_service.py b/stytch/b2b/models/magic_service.py new file mode 100644 index 00000000..68ffd6f9 --- /dev/null +++ b/stytch/b2b/models/magic_service.py @@ -0,0 +1,15 @@ +#!/usr/bin/env python3 + + +from stytch.core.models import ResponseBase + + +class MagiclinkredirectResponse(ResponseBase): + request_id: str + redirect_url: str + html_response_data: None + + +class MagiclinksredirectcaptchaResponse(ResponseBase): + request_id: str + redirect_url: str diff --git a/stytch/b2b/models/multi_tenant_magic_service.py b/stytch/b2b/models/multi_tenant_magic_service.py new file mode 100644 index 00000000..e899fad4 --- /dev/null +++ b/stytch/b2b/models/multi_tenant_magic_service.py @@ -0,0 +1,43 @@ +#!/usr/bin/env python3 + + +from stytch.core.models import ResponseBase + + +class MultitenantmagiclinksemailloginorsignupResponse(ResponseBase): + request_id: str + member_id: str + member_created: bool + member: None + organization: None + + +class MultitenantmagiclinksemailinviteResponse(ResponseBase): + request_id: str + member_id: str + member: None + organization: None + + +class MultitenantmagiclinksauthenticateResponse(ResponseBase): + request_id: str + member_id: str + method_id: str + reset_sessions: bool + organization_id: str + member: None + session_token: str + session_jwt: str + member_session: None + organization: None + + +class B2BmagiclinksemaildiscoverysendResponse(ResponseBase): + request_id: str + + +class B2BmagiclinksdiscoveryauthenticateResponse(ResponseBase): + request_id: str + intermediate_session_token: str + email_address: str + discovered_organizations: None diff --git a/stytch/b2b/models/multi_tenant_password_service.py b/stytch/b2b/models/multi_tenant_password_service.py new file mode 100644 index 00000000..0384a13a --- /dev/null +++ b/stytch/b2b/models/multi_tenant_password_service.py @@ -0,0 +1,70 @@ +#!/usr/bin/env python3 + + +from stytch.core.models import ResponseBase + + +class MultitenantpasswordstrengthcheckResponse(ResponseBase): + request_id: str + valid_password: bool + score: None + breached_password: bool + luds_feedback: None + strength_policy: str + breach_detection_on_create: bool + zxcvbn_feedback: None + + +class MultitenantpasswordmigrateResponse(ResponseBase): + request_id: str + member_id: str + member_created: bool + member: None + organization: None + + +class MultitenantpasswordauthenticateResponse(ResponseBase): + request_id: str + member_id: str + organization_id: str + member: None + session_token: str + session_jwt: str + member_session: None + organization: None + + +class MultitenantpasswordemailresetstartResponse(ResponseBase): + request_id: str + member_id: str + member_email_id: str + + +class MultitenantpasswordemailresetResponse(ResponseBase): + request_id: str + member_id: str + member_email_id: str + organization_id: str + member: None + session_token: str + session_jwt: str + member_session: None + organization: None + + +class MultitenantpasswordsessionresetResponse(ResponseBase): + request_id: str + member_id: str + member_session: None + member: None + organization: None + + +class MultitenantpasswordexistingpasswordresetResponse(ResponseBase): + request_id: str + member_id: str + member_session: None + member: None + session_token: str + session_jwt: str + organization: None diff --git a/stytch/b2b/models/multi_tenant_session_service.py b/stytch/b2b/models/multi_tenant_session_service.py new file mode 100644 index 00000000..f68b421d --- /dev/null +++ b/stytch/b2b/models/multi_tenant_session_service.py @@ -0,0 +1,32 @@ +#!/usr/bin/env python3 + + +from stytch.core.models import ResponseBase + + +class MultitenantsessionsgetResponse(ResponseBase): + request_id: str + member_sessions: None + + +class MultitenantsessionsauthenticateResponse(ResponseBase): + request_id: str + member_session: None + session_token: str + session_jwt: str + member: None + organization: None + + +class MultitenantsessionsrevokeResponse(ResponseBase): + request_id: str + + +class MultitenantsessionsexchangeResponse(ResponseBase): + request_id: str + member_id: str + member_session: None + session_token: str + session_jwt: str + member: None + organization: None diff --git a/stytch/b2b/models/organization_service.py b/stytch/b2b/models/organization_service.py new file mode 100644 index 00000000..5baa949e --- /dev/null +++ b/stytch/b2b/models/organization_service.py @@ -0,0 +1,71 @@ +#!/usr/bin/env python3 + +from typing import List + +from stytch.b2b.core.models import Member, Organization +from stytch.core.models import ResponseBase + + +class OrganizationscreateResponse(ResponseBase): + request_id: str + organization: Organization + + +class OrganizationsgetResponse(ResponseBase): + request_id: str + organization: Organization + + +class OrganizationsupdateResponse(ResponseBase): + request_id: str + organization: Organization + + +class OrganizationsdeleteResponse(ResponseBase): + request_id: str + organization_id: str + + +class OrganizationsmembercreateResponse(ResponseBase): + request_id: str + member_id: str + member: None + organization: Organization + + +class OrganizationsmemberupdateResponse(ResponseBase): + request_id: str + member_id: str + member: None + organization: Organization + + +class OrganizationsmemberdeleteResponse(ResponseBase): + request_id: str + member_id: str + + +class OrganizationssearchexternalResponse(ResponseBase): + request_id: str + organizations: List[Organization] + results_metadata: ResultsMetadata + + +class OrganizationsmembersearchexternalResponse(ResponseBase): + request_id: str + members: List[Member] + results_metadata: ResultsMetadata + + +class OrganizationsmemberdeletepasswordResponse(ResponseBase): + request_id: str + member_id: str + member: None + organization: None + + +class OrganizationsmembergetResponse(ResponseBase): + request_id: str + member_id: str + member: None + organization: None diff --git a/stytch/b2b/models/password_service.py b/stytch/b2b/models/password_service.py new file mode 100644 index 00000000..8e3f6be3 --- /dev/null +++ b/stytch/b2b/models/password_service.py @@ -0,0 +1,14 @@ +#!/usr/bin/env python3 + + +from stytch.core.models import ResponseBase + + +class PasswordsstrengthcheckResponse(ResponseBase): + request_id: str + valid_password: bool + score: None + breached_password: bool + feedback: None + strength_policy: str + breach_detection_on_create: bool diff --git a/stytch/b2b/models/session_service.py b/stytch/b2b/models/session_service.py new file mode 100644 index 00000000..9323396e --- /dev/null +++ b/stytch/b2b/models/session_service.py @@ -0,0 +1,10 @@ +#!/usr/bin/env python3 + +from typing import Any, Dict, List + +from stytch.core.models import ResponseBase + + +class MultitenantsessionsjwksResponse(ResponseBase): + keys: List[Dict[str, Any]] + request_id: str diff --git a/stytch/b2b/models/sso_service.py b/stytch/b2b/models/sso_service.py new file mode 100644 index 00000000..9516b33f --- /dev/null +++ b/stytch/b2b/models/sso_service.py @@ -0,0 +1,64 @@ +#!/usr/bin/env python3 + +from typing import Optional + +from stytch.core.models import ResponseBase + + +class CreateoidcconnectionResponse(ResponseBase): + request_id: str + connection: None + + +class CreatesamlconnectionResponse(ResponseBase): + request_id: str + connection: None + + +class UpdateoidcconnectionResponse(ResponseBase): + request_id: str + connection: None + warning: Optional[str] = None + + +class UpdatesamlconnectionResponse(ResponseBase): + request_id: str + connection: None + + +class UpdatesamlconnectionbyurlResponse(ResponseBase): + request_id: str + connection: None + + +class UpdatesamlconnectionbydocResponse(ResponseBase): + request_id: str + connection: None + + +class GetssoconnectionsResponse(ResponseBase): + request_id: str + saml_connections: None + oidc_connections: None + + +class DeletessoconnectionResponse(ResponseBase): + request_id: str + connection_id: str + + +class SsoauthenticateResponse(ResponseBase): + request_id: str + member_id: str + organization_id: str + member: None + session_token: str + session_jwt: str + member_session: None + reset_session: bool + organization: None + + +class DeletesamlverificationcertificateResponse(ResponseBase): + request_id: str + certificate_id: str diff --git a/stytch/models/billing_service.py b/stytch/models/billing_service.py new file mode 100644 index 00000000..e5a0d9b4 --- /dev/null +++ b/stytch/models/billing_service.py @@ -0,0 +1 @@ +#!/usr/bin/env python3 diff --git a/stytch/models/biometric_service.py b/stytch/models/biometric_service.py new file mode 100644 index 00000000..c1c697b9 --- /dev/null +++ b/stytch/models/biometric_service.py @@ -0,0 +1,39 @@ +#!/usr/bin/env python3 + +from typing import Optional + +from stytch.core.models import ResponseBase, StytchSession, User + + +class BiometricsregisterstartResponse(ResponseBase): + request_id: str + user_id: str + biometric_registration_id: str + challenge: str + + +class BiometricsregisterResponse(ResponseBase): + request_id: str + user_id: str + biometric_registration_id: str + user: User + session_token: str + session: Optional[StytchSession] + session_jwt: str + + +class BiometricsauthenticatestartResponse(ResponseBase): + request_id: str + user_id: str + biometric_registration_id: str + challenge: str + + +class BiometricsauthenticateResponse(ResponseBase): + request_id: str + user_id: str + biometric_registration_id: str + session_token: str + session: Optional[StytchSession] + session_jwt: str + user: User diff --git a/stytch/models/cname_record_service.py b/stytch/models/cname_record_service.py new file mode 100644 index 00000000..e5a0d9b4 --- /dev/null +++ b/stytch/models/cname_record_service.py @@ -0,0 +1 @@ +#!/usr/bin/env python3 diff --git a/stytch/models/crypto_wallet_service.py b/stytch/models/crypto_wallet_service.py new file mode 100644 index 00000000..092cd2e4 --- /dev/null +++ b/stytch/models/crypto_wallet_service.py @@ -0,0 +1,21 @@ +#!/usr/bin/env python3 + +from typing import Optional + +from stytch.core.models import ResponseBase, StytchSession, User + + +class CryptowalletsauthenticatestartResponse(ResponseBase): + request_id: str + user_id: str + challenge: str + user_created: bool + + +class CryptowalletsauthenticateResponse(ResponseBase): + request_id: str + user_id: str + session_token: str + session: Optional[StytchSession] + session_jwt: str + user: User diff --git a/stytch/models/debug_service.py b/stytch/models/debug_service.py new file mode 100644 index 00000000..5f6c96e5 --- /dev/null +++ b/stytch/models/debug_service.py @@ -0,0 +1,10 @@ +#!/usr/bin/env python3 + + +from stytch.core.models import ResponseBase + + +class WhoamiResponse(ResponseBase): + request_id: str + project_id: str + name: str diff --git a/stytch/models/discovery_service.py b/stytch/models/discovery_service.py new file mode 100644 index 00000000..e5a0d9b4 --- /dev/null +++ b/stytch/models/discovery_service.py @@ -0,0 +1 @@ +#!/usr/bin/env python3 diff --git a/stytch/models/email_template_service.py b/stytch/models/email_template_service.py new file mode 100644 index 00000000..e5a0d9b4 --- /dev/null +++ b/stytch/models/email_template_service.py @@ -0,0 +1 @@ +#!/usr/bin/env python3 diff --git a/stytch/models/magic_link_url_service.py b/stytch/models/magic_link_url_service.py new file mode 100644 index 00000000..e5a0d9b4 --- /dev/null +++ b/stytch/models/magic_link_url_service.py @@ -0,0 +1 @@ +#!/usr/bin/env python3 diff --git a/stytch/models/magic_service.py b/stytch/models/magic_service.py new file mode 100644 index 00000000..019b658b --- /dev/null +++ b/stytch/models/magic_service.py @@ -0,0 +1,85 @@ +#!/usr/bin/env python3 + +from typing import Optional + +from stytch.core.models import ResponseBase, StytchSession, User + + +class SendmagicbyemailResponse(ResponseBase): + request_id: str + user_id: str + email_id: str + + +class MagiclinksemailsendResponse(ResponseBase): + request_id: str + user_id: str + email_id: str + + +class AuthenticatemagicResponse(ResponseBase): + request_id: str + user_id: str + method_id: str + session_token: str + session: Optional[StytchSession] + session_jwt: str + user: User + reset_sessions: bool + + +class MagiclinksauthenticateResponse(ResponseBase): + request_id: str + user_id: str + method_id: str + session_token: str + session: Optional[StytchSession] + session_jwt: str + user: User + reset_sessions: bool + + +class MagiclinksemailloginorcreateResponse(ResponseBase): + request_id: str + user_id: str + email_id: str + user_created: bool + + +class SdkmagiclinksemailloginorcreateResponse(ResponseBase): + request_id: str + user_id: str + email_id: str + + +class InvitebyemailResponse(ResponseBase): + request_id: str + user_id: str + email_id: str + + +class MagiclinksemailinviteResponse(ResponseBase): + request_id: str + user_id: str + email_id: str + + +class MagiclinksemailrevokeinviteResponse(ResponseBase): + request_id: str + + +class MagiclinkscreateResponse(ResponseBase): + request_id: str + user_id: str + token: str + + +class MagiclinkredirectResponse(ResponseBase): + request_id: str + redirect_url: str + html_response_data: None + + +class MagiclinksredirectcaptchaResponse(ResponseBase): + request_id: str + redirect_url: str diff --git a/stytch/models/multi_tenant_magic_service.py b/stytch/models/multi_tenant_magic_service.py new file mode 100644 index 00000000..e899fad4 --- /dev/null +++ b/stytch/models/multi_tenant_magic_service.py @@ -0,0 +1,43 @@ +#!/usr/bin/env python3 + + +from stytch.core.models import ResponseBase + + +class MultitenantmagiclinksemailloginorsignupResponse(ResponseBase): + request_id: str + member_id: str + member_created: bool + member: None + organization: None + + +class MultitenantmagiclinksemailinviteResponse(ResponseBase): + request_id: str + member_id: str + member: None + organization: None + + +class MultitenantmagiclinksauthenticateResponse(ResponseBase): + request_id: str + member_id: str + method_id: str + reset_sessions: bool + organization_id: str + member: None + session_token: str + session_jwt: str + member_session: None + organization: None + + +class B2BmagiclinksemaildiscoverysendResponse(ResponseBase): + request_id: str + + +class B2BmagiclinksdiscoveryauthenticateResponse(ResponseBase): + request_id: str + intermediate_session_token: str + email_address: str + discovered_organizations: None diff --git a/stytch/models/multi_tenant_password_service.py b/stytch/models/multi_tenant_password_service.py new file mode 100644 index 00000000..e5a0d9b4 --- /dev/null +++ b/stytch/models/multi_tenant_password_service.py @@ -0,0 +1 @@ +#!/usr/bin/env python3 diff --git a/stytch/models/multi_tenant_session_service.py b/stytch/models/multi_tenant_session_service.py new file mode 100644 index 00000000..e5a0d9b4 --- /dev/null +++ b/stytch/models/multi_tenant_session_service.py @@ -0,0 +1 @@ +#!/usr/bin/env python3 diff --git a/stytch/models/o_auth_service.py b/stytch/models/o_auth_service.py new file mode 100644 index 00000000..98bd59ac --- /dev/null +++ b/stytch/models/o_auth_service.py @@ -0,0 +1,23 @@ +#!/usr/bin/env python3 + + +from stytch.core.models import OAuthSession, ResponseBase, User + + +class OauthattachResponse(ResponseBase): + request_id: str + oauth_attach_token: str + + +class OauthauthenticateResponse(ResponseBase): + request_id: str + user_id: str + provider_subject: str + provider_type: str + session: OAuthSession + session_token: str + session_jwt: str + provider_values: None + user: User + reset_sessions: bool + oauth_user_registration_id: str diff --git a/stytch/models/organization_service.py b/stytch/models/organization_service.py new file mode 100644 index 00000000..e5a0d9b4 --- /dev/null +++ b/stytch/models/organization_service.py @@ -0,0 +1 @@ +#!/usr/bin/env python3 diff --git a/stytch/models/otp_service.py b/stytch/models/otp_service.py new file mode 100644 index 00000000..d9971069 --- /dev/null +++ b/stytch/models/otp_service.py @@ -0,0 +1,55 @@ +#!/usr/bin/env python3 + +from typing import Optional + +from stytch.core.models import ResponseBase, StytchSession, User + + +class OtpssmssendResponse(ResponseBase): + request_id: str + user_id: str + phone_id: str + + +class OtpssmsloginorcreateResponse(ResponseBase): + request_id: str + user_id: str + phone_id: str + user_created: bool + + +class OtpswhatsappsendResponse(ResponseBase): + request_id: str + user_id: str + phone_id: str + + +class OtpswhatsapploginorcreateResponse(ResponseBase): + request_id: str + user_id: str + phone_id: str + user_created: bool + + +class OtpsemailsendResponse(ResponseBase): + request_id: str + user_id: str + email_id: str + + +class OtpsemailloginorcreateResponse(ResponseBase): + request_id: str + user_id: str + email_id: str + user_created: bool + + +class OtpsauthenticateResponse(ResponseBase): + request_id: str + user_id: str + method_id: str + session_token: str + session: Optional[StytchSession] + session_jwt: str + user: User + reset_sessions: bool diff --git a/stytch/models/password_service.py b/stytch/models/password_service.py new file mode 100644 index 00000000..ba16b8b3 --- /dev/null +++ b/stytch/models/password_service.py @@ -0,0 +1,73 @@ +#!/usr/bin/env python3 + +from typing import Optional + +from stytch.core.models import ResponseBase, StytchSession, User + + +class PasswordscreateResponse(ResponseBase): + request_id: str + user_id: str + email_id: str + session_token: str + session: Optional[StytchSession] + session_jwt: str + user: User + + +class PasswordsauthenticateResponse(ResponseBase): + request_id: str + user_id: str + session_token: str + session: Optional[StytchSession] + session_jwt: str + user: User + + +class PasswordsemailresetstartResponse(ResponseBase): + request_id: str + user_id: str + email_id: str + + +class PasswordsemailresetResponse(ResponseBase): + request_id: str + user_id: str + session_token: str + session: Optional[StytchSession] + session_jwt: str + user: User + + +class PasswordsexistingpasswordresetResponse(ResponseBase): + request_id: str + user_id: str + session_token: str + session: Optional[StytchSession] + session_jwt: str + user: User + + +class PasswordssessionresetResponse(ResponseBase): + request_id: str + user_id: str + session: Optional[StytchSession] + user: User + + +class PasswordsmigrateResponse(ResponseBase): + request_id: str + user_id: str + email_id: str + user_created: bool + user: User + + +class PasswordsstrengthcheckResponse(ResponseBase): + request_id: str + valid_password: bool + score: None + breached_password: bool + feedback: None + strength_policy: str + breach_detection_on_create: bool diff --git a/stytch/models/project_service.py b/stytch/models/project_service.py new file mode 100644 index 00000000..e5a0d9b4 --- /dev/null +++ b/stytch/models/project_service.py @@ -0,0 +1 @@ +#!/usr/bin/env python3 diff --git a/stytch/models/public_token_service.py b/stytch/models/public_token_service.py new file mode 100644 index 00000000..e5a0d9b4 --- /dev/null +++ b/stytch/models/public_token_service.py @@ -0,0 +1 @@ +#!/usr/bin/env python3 diff --git a/stytch/models/script_service.py b/stytch/models/script_service.py new file mode 100644 index 00000000..e5a0d9b4 --- /dev/null +++ b/stytch/models/script_service.py @@ -0,0 +1 @@ +#!/usr/bin/env python3 diff --git a/stytch/models/sdk_service.py b/stytch/models/sdk_service.py new file mode 100644 index 00000000..e5a0d9b4 --- /dev/null +++ b/stytch/models/sdk_service.py @@ -0,0 +1 @@ +#!/usr/bin/env python3 diff --git a/stytch/models/secret_service.py b/stytch/models/secret_service.py new file mode 100644 index 00000000..e5a0d9b4 --- /dev/null +++ b/stytch/models/secret_service.py @@ -0,0 +1 @@ +#!/usr/bin/env python3 diff --git a/stytch/models/session_service.py b/stytch/models/session_service.py new file mode 100644 index 00000000..13802d0b --- /dev/null +++ b/stytch/models/session_service.py @@ -0,0 +1,27 @@ +#!/usr/bin/env python3 + +from typing import Any, Dict, List, Optional + +from stytch.core.models import ResponseBase, StytchSession, User + + +class SessionsgetResponse(ResponseBase): + request_id: str + sessions: List[StytchSession] + + +class SessionsauthenticateResponse(ResponseBase): + request_id: str + session: Optional[StytchSession] + session_token: str + session_jwt: str + user: User + + +class SessionsrevokeResponse(ResponseBase): + request_id: str + + +class SessionsjwksResponse(ResponseBase): + keys: List[Dict[str, Any]] + request_id: str diff --git a/stytch/models/sso_service.py b/stytch/models/sso_service.py new file mode 100644 index 00000000..e5a0d9b4 --- /dev/null +++ b/stytch/models/sso_service.py @@ -0,0 +1 @@ +#!/usr/bin/env python3 diff --git a/stytch/models/totp_service.py b/stytch/models/totp_service.py new file mode 100644 index 00000000..9a0c6fbf --- /dev/null +++ b/stytch/models/totp_service.py @@ -0,0 +1,41 @@ +#!/usr/bin/env python3 + +from typing import List, Optional + +from stytch.core.models import ResponseBase, StytchSession, User + + +class TotpscreateResponse(ResponseBase): + request_id: str + totp_id: str + secret: str + qr_code: str + recovery_codes: List[str] + user: User + user_id: str + + +class TotpsauthenticateResponse(ResponseBase): + request_id: str + user_id: str + session_token: str + session: Optional[StytchSession] + totp_id: str + session_jwt: str + user: User + + +class TotpsgetrecoverycodesResponse(ResponseBase): + request_id: str + user_id: str + totps: None + + +class TotpsrecoverResponse(ResponseBase): + request_id: str + totp_id: str + user_id: str + session_token: str + session: Optional[StytchSession] + session_jwt: str + user: User diff --git a/stytch/models/user_service.py b/stytch/models/user_service.py new file mode 100644 index 00000000..01d1505c --- /dev/null +++ b/stytch/models/user_service.py @@ -0,0 +1,117 @@ +#!/usr/bin/env python3 + +from typing import Any, Dict, Optional + +from stytch.core.models import ResponseBase, User + + +class CreateuserResponse(ResponseBase): + request_id: str + user_id: str + email_id: str + status: str + phone_id: str + user: User + + +class GetpendingusersResponse(ResponseBase): + request_id: str + users: None + has_more: bool + next_starting_after_id: str + total: None + + +class GetuserResponse(ResponseBase): + request_id: str + user_id: str + name: None + emails: None + status: str + phone_numbers: None + birthday: None + webauthn_registrations: None + created_at: None + providers: None + totps: None + crypto_wallets: None + password: None + biometric_registrations: None + trusted_metadata: Optional[Dict[str, Any]] = None + untrusted_metadata: Optional[Dict[str, Any]] = None + project_id: str + + +class SearchusersexternalResponse(ResponseBase): + request_id: str + results: None + ResultsMetadata: None + next_cursor: Optional[str] = None + + +class UpdateuserResponse(ResponseBase): + request_id: str + user_id: str + emails: None + phone_numbers: None + crypto_wallets: None + user: User + + +class DeleteuserResponse(ResponseBase): + request_id: str + user_id: str + + +class GetuserbyemailandprojectidResponse(ResponseBase): + request_id: str + user_id: str + email_id: str + + +class DeleteuseremailResponse(ResponseBase): + request_id: str + user_id: str + user: User + + +class DeleteuserphonenumberResponse(ResponseBase): + request_id: str + user_id: str + user: User + + +class DeleteuserwebauthnregistrationResponse(ResponseBase): + request_id: str + user_id: str + user: User + + +class DeleteuserbiometricregistrationResponse(ResponseBase): + request_id: str + user_id: str + user: User + + +class DeleteusertotpResponse(ResponseBase): + request_id: str + user_id: str + user: User + + +class DeleteusercryptowalletResponse(ResponseBase): + request_id: str + user_id: str + user: User + + +class DeleteuserpasswordResponse(ResponseBase): + request_id: str + user_id: str + user: User + + +class DeleteuseroauthuserregistrationResponse(ResponseBase): + request_id: str + user_id: str + user: User diff --git a/stytch/models/web_authn_service.py b/stytch/models/web_authn_service.py new file mode 100644 index 00000000..9d7d36e8 --- /dev/null +++ b/stytch/models/web_authn_service.py @@ -0,0 +1,33 @@ +#!/usr/bin/env python3 + +from typing import Optional + +from stytch.core.models import ResponseBase, StytchSession, User + + +class WebauthnregisterstartResponse(ResponseBase): + request_id: str + user_id: str + public_key_credential_creation_options: str + + +class WebauthnregisterResponse(ResponseBase): + request_id: str + user_id: str + webauthn_registration_id: str + + +class WebauthnauthenticatestartResponse(ResponseBase): + request_id: str + user_id: str + public_key_credential_request_options: str + + +class WebauthnauthenticateResponse(ResponseBase): + request_id: str + user_id: str + webauthn_registration_id: str + session_token: str + session: Optional[StytchSession] + session_jwt: str + user: User