diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..4d75d59 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +# This allows generated code to be indexed correctly +*.py linguist-generated=false \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4c12520 --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +venv/ +src/*.egg-info/ +__pycache__/ +.pytest_cache/ +.python-version +.DS_Store +pyrightconfig.json diff --git a/.speakeasy/gen.lock b/.speakeasy/gen.lock new file mode 100644 index 0000000..8216d35 --- /dev/null +++ b/.speakeasy/gen.lock @@ -0,0 +1,608 @@ +lockVersion: 2.0.0 +id: bfe29c99-6e67-43fe-b928-64d6a5ed6aa8 +management: + docChecksum: 86f1bd95298826763a948a4e2aa58f0f + docVersion: v1 + speakeasyVersion: 1.331.2 + generationVersion: 2.366.1 + releaseVersion: 0.5.0-alpha.5 + configChecksum: 1246c6c55736ffc673da5de130e493ab +features: + python: + additionalDependencies: 1.0.0 + constsAndDefaults: 1.0.0 + core: 5.0.0 + defaultEnabledRetries: 0.2.0 + deprecations: 3.0.0 + examples: 3.0.0 + flatRequests: 1.0.0 + flattening: 3.0.0 + globalSecurity: 3.0.0 + globalSecurityCallbacks: 1.0.0 + globalSecurityFlattening: 1.0.0 + globalServerURLs: 3.0.0 + groups: 3.0.0 + multipartFileContentType: 1.0.0 + nameOverrides: 3.0.0 + nullables: 1.0.0 + pagination: 3.0.0 + responseFormat: 1.0.0 + retries: 3.0.0 + sdkHooks: 1.0.0 + unions: 3.0.0 + uploadStreams: 1.0.0 +generatedFiles: + - src/clerk/sdkconfiguration.py + - src/clerk/misc.py + - src/clerk/jwks.py + - src/clerk/clients.py + - src/clerk/emailaddresses.py + - src/clerk/phonenumbers.py + - src/clerk/sessions.py + - src/clerk/templates.py + - src/clerk/users.py + - src/clerk/invitations.py + - src/clerk/allowlistidentifiers.py + - src/clerk/blocklistidentifiers_sdk.py + - src/clerk/betafeatures.py + - src/clerk/actortokens.py + - src/clerk/domains_sdk.py + - src/clerk/instancesettings_sdk.py + - src/clerk/webhooks.py + - src/clerk/jwttemplates.py + - src/clerk/organizations_sdk.py + - src/clerk/organizationinvitations_sdk.py + - src/clerk/organizationmemberships_sdk.py + - src/clerk/proxychecks.py + - src/clerk/redirecturls.py + - src/clerk/signintokens.py + - src/clerk/signups.py + - src/clerk/oauthapplications_sdk.py + - src/clerk/samlconnections_sdk.py + - src/clerk/testingtokens.py + - src/clerk/sdk.py + - py.typed + - pylintrc + - pyproject.toml + - scripts/publish.sh + - src/clerk/__init__.py + - src/clerk/basesdk.py + - src/clerk/httpclient.py + - src/clerk/types/__init__.py + - src/clerk/types/basemodel.py + - src/clerk/utils/__init__.py + - src/clerk/utils/enums.py + - src/clerk/utils/eventstreaming.py + - src/clerk/utils/forms.py + - src/clerk/utils/headers.py + - src/clerk/utils/metadata.py + - src/clerk/utils/queryparams.py + - src/clerk/utils/requestbodies.py + - src/clerk/utils/retries.py + - src/clerk/utils/security.py + - src/clerk/utils/serializers.py + - src/clerk/utils/url.py + - src/clerk/utils/values.py + - src/clerk/models/sdkerror.py + - src/clerk/models/getpublicinterstitialop.py + - src/clerk/models/getclientlistop.py + - src/clerk/models/client.py + - src/clerk/models/session.py + - src/clerk/models/clerkerrors.py + - src/clerk/models/clerkerror.py + - src/clerk/models/verifyclientop.py + - src/clerk/models/getclientop.py + - src/clerk/models/emailaddress.py + - src/clerk/models/identificationlink.py + - src/clerk/models/createemailaddressop.py + - src/clerk/models/getemailaddressop.py + - src/clerk/models/deletedobject.py + - src/clerk/models/deleteemailaddressop.py + - src/clerk/models/updateemailaddressop.py + - src/clerk/models/phonenumber.py + - src/clerk/models/createphonenumberop.py + - src/clerk/models/getphonenumberop.py + - src/clerk/models/deletephonenumberop.py + - src/clerk/models/updatephonenumberop.py + - src/clerk/models/getsessionlistop.py + - src/clerk/models/getsessionop.py + - src/clerk/models/revokesessionop.py + - src/clerk/models/verifysessionop.py + - src/clerk/models/createsessiontokenfromtemplateop.py + - src/clerk/models/template.py + - src/clerk/models/gettemplatelistop.py + - src/clerk/models/gettemplateop.py + - src/clerk/models/upserttemplateop.py + - src/clerk/models/reverttemplateop.py + - src/clerk/models/previewtemplateop.py + - src/clerk/models/toggletemplatedeliveryop.py + - src/clerk/models/user.py + - src/clerk/models/samlaccount.py + - src/clerk/models/schemas_passkey.py + - src/clerk/models/web3wallet.py + - src/clerk/models/getuserlistop.py + - src/clerk/models/createuserop.py + - src/clerk/models/totalcount.py + - src/clerk/models/getuserscountop.py + - src/clerk/models/getuserop.py + - src/clerk/models/updateuserop.py + - src/clerk/models/deleteuserop.py + - src/clerk/models/banuserop.py + - src/clerk/models/unbanuserop.py + - src/clerk/models/lockuserop.py + - src/clerk/models/unlockuserop.py + - src/clerk/models/setuserprofileimageop.py + - src/clerk/models/deleteuserprofileimageop.py + - src/clerk/models/updateusermetadataop.py + - src/clerk/models/getoauthaccesstokenop.py + - src/clerk/models/usersgetorganizationmembershipsop.py + - src/clerk/models/organizationmemberships.py + - src/clerk/models/organizationmembership.py + - src/clerk/models/verifypasswordop.py + - src/clerk/models/verifytotpop.py + - src/clerk/models/disablemfaop.py + - src/clerk/models/invitation.py + - src/clerk/models/createinvitationop.py + - src/clerk/models/listinvitationsop.py + - src/clerk/models/invitation_revoked.py + - src/clerk/models/revokeinvitationop.py + - src/clerk/models/allowlistidentifier.py + - src/clerk/models/createallowlistidentifierop.py + - src/clerk/models/deleteallowlistidentifierop.py + - src/clerk/models/blocklistidentifiers.py + - src/clerk/models/blocklistidentifier.py + - src/clerk/models/createblocklistidentifierop.py + - src/clerk/models/deleteblocklistidentifierop.py + - src/clerk/models/instancesettings.py + - src/clerk/models/updateinstanceauthconfigop.py + - src/clerk/models/updateproductioninstancedomainop.py + - src/clerk/models/changeproductioninstancedomainop.py + - src/clerk/models/actortoken.py + - src/clerk/models/createactortokenop.py + - src/clerk/models/revokeactortokenop.py + - src/clerk/models/domains.py + - src/clerk/models/domain.py + - src/clerk/models/cnametarget.py + - src/clerk/models/adddomainop.py + - src/clerk/models/deletedomainop.py + - src/clerk/models/updatedomainop.py + - src/clerk/models/updateinstanceop.py + - src/clerk/models/instancerestrictions.py + - src/clerk/models/updateinstancerestrictionsop.py + - src/clerk/models/organizationsettings.py + - src/clerk/models/updateinstanceorganizationsettingsop.py + - src/clerk/models/svixurl.py + - src/clerk/models/jwttemplate.py + - src/clerk/models/createjwttemplateop.py + - src/clerk/models/getjwttemplateop.py + - src/clerk/models/updatejwttemplateop.py + - src/clerk/models/deletejwttemplateop.py + - src/clerk/models/organizations.py + - src/clerk/models/organization.py + - src/clerk/models/listorganizationsop.py + - src/clerk/models/createorganizationop.py + - src/clerk/models/getorganizationop.py + - src/clerk/models/updateorganizationop.py + - src/clerk/models/deleteorganizationop.py + - src/clerk/models/mergeorganizationmetadataop.py + - src/clerk/models/organizationwithlogo.py + - src/clerk/models/uploadorganizationlogoop.py + - src/clerk/models/deleteorganizationlogoop.py + - src/clerk/models/organizationinvitation.py + - src/clerk/models/createorganizationinvitationop.py + - src/clerk/models/listorganizationinvitationsop.py + - src/clerk/models/organizationinvitations.py + - src/clerk/models/createorganizationinvitationbulkop.py + - src/clerk/models/listpendingorganizationinvitationsop.py + - src/clerk/models/getorganizationinvitationop.py + - src/clerk/models/revokeorganizationinvitationop.py + - src/clerk/models/createorganizationmembershipop.py + - src/clerk/models/listorganizationmembershipsop.py + - src/clerk/models/updateorganizationmembershipop.py + - src/clerk/models/deleteorganizationmembershipop.py + - src/clerk/models/updateorganizationmembershipmetadataop.py + - src/clerk/models/proxycheck.py + - src/clerk/models/verifydomainproxyop.py + - src/clerk/models/redirecturl.py + - src/clerk/models/createredirecturlop.py + - src/clerk/models/getredirecturlop.py + - src/clerk/models/deleteredirecturlop.py + - src/clerk/models/signintoken.py + - src/clerk/models/createsignintokenop.py + - src/clerk/models/revokesignintokenop.py + - src/clerk/models/signup.py + - src/clerk/models/updatesignupop.py + - src/clerk/models/listoauthapplicationsop.py + - src/clerk/models/oauthapplications.py + - src/clerk/models/oauthapplication.py + - src/clerk/models/oauthapplicationwithsecret.py + - src/clerk/models/createoauthapplicationop.py + - src/clerk/models/getoauthapplicationop.py + - src/clerk/models/updateoauthapplicationop.py + - src/clerk/models/deleteoauthapplicationop.py + - src/clerk/models/rotateoauthapplicationsecretop.py + - src/clerk/models/listsamlconnectionsop.py + - src/clerk/models/samlconnections.py + - src/clerk/models/samlconnection.py + - src/clerk/models/createsamlconnectionop.py + - src/clerk/models/getsamlconnectionop.py + - src/clerk/models/updatesamlconnectionop.py + - src/clerk/models/deletesamlconnectionop.py + - src/clerk/models/testingtoken.py + - src/clerk/models/security.py + - src/clerk/models/__init__.py + - docs/models/getpublicinterstitialrequest.md + - docs/models/getclientlistrequest.md + - docs/models/getclientlistresponse.md + - docs/models/object.md + - docs/models/client.md + - docs/models/sessionobject.md + - docs/models/actor.md + - docs/models/status.md + - docs/models/session.md + - docs/models/clerkerrorsmeta.md + - docs/models/clerkerrors.md + - docs/models/meta.md + - docs/models/clerkerror.md + - docs/models/verifyclientrequestbody.md + - docs/models/getclientrequest.md + - docs/models/emailaddressobject.md + - docs/models/oauthverificationstatus.md + - docs/models/oauthverificationstrategy.md + - docs/models/errormeta.md + - docs/models/errorclerkerror.md + - docs/models/error.md + - docs/models/oauth.md + - docs/models/adminverificationstatus.md + - docs/models/verificationstrategy.md + - docs/models/admin.md + - docs/models/verificationstatus.md + - docs/models/strategy.md + - docs/models/otp.md + - docs/models/verification.md + - docs/models/emailaddress.md + - docs/models/type.md + - docs/models/identificationlink.md + - docs/models/createemailaddressrequestbody.md + - docs/models/getemailaddressrequest.md + - docs/models/deletedobject.md + - docs/models/deleteemailaddressrequest.md + - docs/models/updateemailaddressrequestbody.md + - docs/models/updateemailaddressrequest.md + - docs/models/phonenumberobject.md + - docs/models/adminverificationphonenumberstatus.md + - docs/models/adminverificationstrategy.md + - docs/models/verificationadmin.md + - docs/models/otpverificationstatus.md + - docs/models/otpverificationstrategy.md + - docs/models/verificationotp.md + - docs/models/phonenumberverification.md + - docs/models/phonenumber.md + - docs/models/createphonenumberrequestbody.md + - docs/models/getphonenumberrequest.md + - docs/models/deletephonenumberrequest.md + - docs/models/updatephonenumberrequestbody.md + - docs/models/updatephonenumberrequest.md + - docs/models/queryparamstatus.md + - docs/models/getsessionlistrequest.md + - docs/models/getsessionrequest.md + - docs/models/revokesessionrequest.md + - docs/models/verifysessionrequestbody.md + - docs/models/verifysessionrequest.md + - docs/models/createsessiontokenfromtemplaterequest.md + - docs/models/createsessiontokenfromtemplateobject.md + - docs/models/createsessiontokenfromtemplateresponsebody.md + - docs/models/templateobject.md + - docs/models/template.md + - docs/models/templatetype.md + - docs/models/gettemplatelistrequest.md + - docs/models/pathparamtemplatetype.md + - docs/models/gettemplaterequest.md + - docs/models/upserttemplatepathparamtemplatetype.md + - docs/models/upserttemplaterequestbody.md + - docs/models/upserttemplaterequest.md + - docs/models/reverttemplatepathparamtemplatetype.md + - docs/models/reverttemplaterequest.md + - docs/models/previewtemplaterequestbody.md + - docs/models/previewtemplaterequest.md + - docs/models/previewtemplateresponsebody.md + - docs/models/toggletemplatedeliverypathparamtemplatetype.md + - docs/models/toggletemplatedeliveryrequestbody.md + - docs/models/toggletemplatedeliveryrequest.md + - docs/models/userobject.md + - docs/models/publicmetadata.md + - docs/models/privatemetadata.md + - docs/models/unsafemetadata.md + - docs/models/externalaccounts.md + - docs/models/user.md + - docs/models/samlaccountobject.md + - docs/models/samlaccountpublicmetadata.md + - docs/models/ticketverificationstatus.md + - docs/models/ticketverificationstrategy.md + - docs/models/ticket.md + - docs/models/samlverificationstatus.md + - docs/models/samlverificationstrategy.md + - docs/models/clerkerrorerrormeta.md + - docs/models/samlerrorclerkerror.md + - docs/models/verificationerror.md + - docs/models/saml.md + - docs/models/samlaccountverification.md + - docs/models/samlaccount.md + - docs/models/schemaspasskeyobject.md + - docs/models/passkeyverificationstatus.md + - docs/models/passkeyverificationstrategy.md + - docs/models/verificationnonce.md + - docs/models/passkey.md + - docs/models/schemaspasskeyverification.md + - docs/models/schemaspasskey.md + - docs/models/web3walletobject.md + - docs/models/adminverificationweb3walletstatus.md + - docs/models/adminverificationweb3walletstrategy.md + - docs/models/web3walletverificationadmin.md + - docs/models/web3signatureverificationstatus.md + - docs/models/web3signatureverificationstrategy.md + - docs/models/nonce.md + - docs/models/web3signature.md + - docs/models/web3walletverification.md + - docs/models/web3wallet.md + - docs/models/getuserlistrequest.md + - docs/models/passwordhasher.md + - docs/models/createuserpublicmetadata.md + - docs/models/createuserprivatemetadata.md + - docs/models/createuserunsafemetadata.md + - docs/models/createuserrequestbody.md + - docs/models/totalcountobject.md + - docs/models/totalcount.md + - docs/models/getuserscountrequest.md + - docs/models/getuserrequest.md + - docs/models/updateuserpasswordhasher.md + - docs/models/updateuserpublicmetadata.md + - docs/models/updateuserprivatemetadata.md + - docs/models/updateuserunsafemetadata.md + - docs/models/updateuserrequestbody.md + - docs/models/updateuserrequest.md + - docs/models/deleteuserrequest.md + - docs/models/banuserrequest.md + - docs/models/unbanuserrequest.md + - docs/models/lockuserrequest.md + - docs/models/unlockuserrequest.md + - docs/models/file.md + - docs/models/setuserprofileimagerequestbody.md + - docs/models/setuserprofileimagerequest.md + - docs/models/deleteuserprofileimagerequest.md + - docs/models/updateusermetadataprivatemetadata.md + - docs/models/updateusermetadataunsafemetadata.md + - docs/models/updateusermetadatarequestbody.md + - docs/models/updateusermetadatarequest.md + - docs/models/getoauthaccesstokenrequest.md + - docs/models/getoauthaccesstokenpublicmetadata.md + - docs/models/responsebody.md + - docs/models/usersgetorganizationmembershipsrequest.md + - docs/models/usersgetorganizationmembershipsresponse.md + - docs/models/organizationmemberships.md + - docs/models/organizationmembershipobject.md + - docs/models/organizationmembershippublicmetadata.md + - docs/models/organizationmembershipprivatemetadata.md + - docs/models/organizationmembershiporganizationobject.md + - docs/models/organizationmembershiporganizationpublicmetadata.md + - docs/models/organizationmembershiporganizationprivatemetadata.md + - docs/models/organizationmembershiporganization.md + - docs/models/publicuserdata.md + - docs/models/organizationmembership.md + - docs/models/verifypasswordrequestbody.md + - docs/models/verifypasswordrequest.md + - docs/models/verifypasswordresponsebody.md + - docs/models/verifytotprequestbody.md + - docs/models/verifytotprequest.md + - docs/models/codetype.md + - docs/models/verifytotpresponsebody.md + - docs/models/disablemfarequest.md + - docs/models/disablemfaresponsebody.md + - docs/models/invitationobject.md + - docs/models/invitationpublicmetadata.md + - docs/models/invitationstatus.md + - docs/models/invitation.md + - docs/models/createinvitationpublicmetadata.md + - docs/models/createinvitationrequestbody.md + - docs/models/listinvitationsqueryparamstatus.md + - docs/models/listinvitationsrequest.md + - docs/models/listinvitationsresponse.md + - docs/models/invitationrevokedobject.md + - docs/models/invitationrevokedpublicmetadata.md + - docs/models/invitationrevokedstatus.md + - docs/models/invitationrevoked.md + - docs/models/revokeinvitationrequest.md + - docs/models/allowlistidentifierobject.md + - docs/models/identifiertype.md + - docs/models/allowlistidentifier.md + - docs/models/createallowlistidentifierrequestbody.md + - docs/models/deleteallowlistidentifierrequest.md + - docs/models/blocklistidentifiers.md + - docs/models/blocklistidentifierobject.md + - docs/models/blocklistidentifieridentifiertype.md + - docs/models/blocklistidentifier.md + - docs/models/createblocklistidentifierrequestbody.md + - docs/models/deleteblocklistidentifierrequest.md + - docs/models/instancesettingsobject.md + - docs/models/instancesettings.md + - docs/models/updateinstanceauthconfigrequestbody.md + - docs/models/updateproductioninstancedomainrequestbody.md + - docs/models/changeproductioninstancedomainrequestbody.md + - docs/models/actortokenobject.md + - docs/models/actortokenstatus.md + - docs/models/actortokenactor.md + - docs/models/actortoken.md + - docs/models/createactortokenrequestbody.md + - docs/models/revokeactortokenrequest.md + - docs/models/domains.md + - docs/models/domainobject.md + - docs/models/domain.md + - docs/models/cnametarget.md + - docs/models/adddomainrequestbody.md + - docs/models/deletedomainrequest.md + - docs/models/updatedomainrequestbody.md + - docs/models/updatedomainrequest.md + - docs/models/updateinstancerequestbody.md + - docs/models/instancerestrictionsobject.md + - docs/models/instancerestrictions.md + - docs/models/updateinstancerestrictionsrequestbody.md + - docs/models/organizationsettingsobject.md + - docs/models/domainsenrollmentmodes.md + - docs/models/organizationsettings.md + - docs/models/updateinstanceorganizationsettingsrequestbody.md + - docs/models/svixurl.md + - docs/models/jwttemplateobject.md + - docs/models/claims.md + - docs/models/jwttemplate.md + - docs/models/createjwttemplateclaims.md + - docs/models/createjwttemplaterequestbody.md + - docs/models/getjwttemplaterequest.md + - docs/models/updatejwttemplateclaims.md + - docs/models/updatejwttemplaterequestbody.md + - docs/models/updatejwttemplaterequest.md + - docs/models/deletejwttemplaterequest.md + - docs/models/organizations.md + - docs/models/organizationobject.md + - docs/models/organizationpublicmetadata.md + - docs/models/organizationprivatemetadata.md + - docs/models/organization.md + - docs/models/listorganizationsrequest.md + - docs/models/createorganizationprivatemetadata.md + - docs/models/createorganizationpublicmetadata.md + - docs/models/createorganizationrequestbody.md + - docs/models/getorganizationrequest.md + - docs/models/updateorganizationpublicmetadata.md + - docs/models/updateorganizationprivatemetadata.md + - docs/models/updateorganizationrequestbody.md + - docs/models/updateorganizationrequest.md + - docs/models/deleteorganizationrequest.md + - docs/models/mergeorganizationmetadatapublicmetadata.md + - docs/models/mergeorganizationmetadataprivatemetadata.md + - docs/models/mergeorganizationmetadatarequestbody.md + - docs/models/mergeorganizationmetadatarequest.md + - docs/models/organizationwithlogoobject.md + - docs/models/organizationwithlogopublicmetadata.md + - docs/models/organizationwithlogoprivatemetadata.md + - docs/models/organizationwithlogo.md + - docs/models/uploadorganizationlogofile.md + - docs/models/uploadorganizationlogorequestbody.md + - docs/models/uploadorganizationlogorequest.md + - docs/models/deleteorganizationlogorequest.md + - docs/models/organizationinvitationobject.md + - docs/models/organizationinvitationpublicmetadata.md + - docs/models/organizationinvitationprivatemetadata.md + - docs/models/organizationinvitation.md + - docs/models/createorganizationinvitationpublicmetadata.md + - docs/models/createorganizationinvitationprivatemetadata.md + - docs/models/createorganizationinvitationrequestbody.md + - docs/models/createorganizationinvitationrequest.md + - docs/models/listorganizationinvitationsqueryparamstatus.md + - docs/models/listorganizationinvitationsrequest.md + - docs/models/listorganizationinvitationsresponse.md + - docs/models/organizationinvitations.md + - docs/models/createorganizationinvitationbulkpublicmetadata.md + - docs/models/createorganizationinvitationbulkprivatemetadata.md + - docs/models/requestbody.md + - docs/models/createorganizationinvitationbulkrequest.md + - docs/models/listpendingorganizationinvitationsrequest.md + - docs/models/listpendingorganizationinvitationsresponse.md + - docs/models/getorganizationinvitationrequest.md + - docs/models/revokeorganizationinvitationrequestbody.md + - docs/models/revokeorganizationinvitationrequest.md + - docs/models/createorganizationmembershiprequestbody.md + - docs/models/createorganizationmembershiprequest.md + - docs/models/listorganizationmembershipsrequest.md + - docs/models/listorganizationmembershipsresponse.md + - docs/models/updateorganizationmembershiprequestbody.md + - docs/models/updateorganizationmembershiprequest.md + - docs/models/deleteorganizationmembershiprequest.md + - docs/models/updateorganizationmembershipmetadatapublicmetadata.md + - docs/models/updateorganizationmembershipmetadataprivatemetadata.md + - docs/models/updateorganizationmembershipmetadatarequestbody.md + - docs/models/updateorganizationmembershipmetadatarequest.md + - docs/models/proxycheckobject.md + - docs/models/proxycheck.md + - docs/models/verifydomainproxyrequestbody.md + - docs/models/redirecturlobject.md + - docs/models/redirecturl.md + - docs/models/createredirecturlrequestbody.md + - docs/models/getredirecturlrequest.md + - docs/models/deleteredirecturlrequest.md + - docs/models/signintokenobject.md + - docs/models/signintokenstatus.md + - docs/models/signintoken.md + - docs/models/createsignintokenrequestbody.md + - docs/models/revokesignintokenrequest.md + - docs/models/signupobject.md + - docs/models/signupstatus.md + - docs/models/verifications.md + - docs/models/signupunsafemetadata.md + - docs/models/signuppublicmetadata.md + - docs/models/externalaccount.md + - docs/models/signup.md + - docs/models/updatesignuprequestbody.md + - docs/models/updatesignuprequest.md + - docs/models/listoauthapplicationsrequest.md + - docs/models/listoauthapplicationsresponse.md + - docs/models/oauthapplications.md + - docs/models/oauthapplicationobject.md + - docs/models/oauthapplication.md + - docs/models/oauthapplicationwithsecretobject.md + - docs/models/oauthapplicationwithsecret.md + - docs/models/createoauthapplicationrequestbody.md + - docs/models/getoauthapplicationrequest.md + - docs/models/updateoauthapplicationrequestbody.md + - docs/models/updateoauthapplicationrequest.md + - docs/models/deleteoauthapplicationrequest.md + - docs/models/rotateoauthapplicationsecretrequest.md + - docs/models/listsamlconnectionsrequest.md + - docs/models/listsamlconnectionsresponse.md + - docs/models/samlconnections.md + - docs/models/samlconnectionobject.md + - docs/models/attributemapping.md + - docs/models/samlconnection.md + - docs/models/provider.md + - docs/models/createsamlconnectionattributemapping.md + - docs/models/createsamlconnectionrequestbody.md + - docs/models/getsamlconnectionrequest.md + - docs/models/updatesamlconnectionattributemapping.md + - docs/models/updatesamlconnectionrequestbody.md + - docs/models/updatesamlconnectionrequest.md + - docs/models/deletesamlconnectionrequest.md + - docs/models/testingtokenobject.md + - docs/models/testingtoken.md + - docs/models/security.md + - docs/sdks/clerk/README.md + - docs/models/utils/retryconfig.md + - docs/sdks/misc/README.md + - docs/sdks/jwks/README.md + - docs/sdks/clients/README.md + - docs/sdks/emailaddresses/README.md + - docs/sdks/phonenumbers/README.md + - docs/sdks/sessions/README.md + - docs/sdks/templates/README.md + - docs/sdks/users/README.md + - docs/sdks/invitations/README.md + - docs/sdks/allowlistidentifiers/README.md + - docs/sdks/blocklistidentifierssdk/README.md + - docs/sdks/betafeatures/README.md + - docs/sdks/actortokens/README.md + - docs/sdks/domainssdk/README.md + - docs/sdks/instancesettingssdk/README.md + - docs/sdks/webhooks/README.md + - docs/sdks/jwttemplates/README.md + - docs/sdks/organizationssdk/README.md + - docs/sdks/organizationinvitationssdk/README.md + - docs/sdks/organizationmembershipssdk/README.md + - docs/sdks/proxychecks/README.md + - docs/sdks/redirecturls/README.md + - docs/sdks/signintokens/README.md + - docs/sdks/signups/README.md + - docs/sdks/oauthapplicationssdk/README.md + - docs/sdks/samlconnectionssdk/README.md + - docs/sdks/testingtokens/README.md + - USAGE.md + - .gitattributes + - src/clerk/_hooks/sdkhooks.py + - src/clerk/_hooks/types.py + - src/clerk/_hooks/__init__.py diff --git a/.speakeasy/gen.yaml b/.speakeasy/gen.yaml index 03156c3..fb19303 100644 --- a/.speakeasy/gen.yaml +++ b/.speakeasy/gen.yaml @@ -12,11 +12,11 @@ generation: auth: oAuth2ClientCredentialsEnabled: true python: - version: 0.5.0-alpha.4 + version: 0.5.0-alpha.5 additionalDependencies: dev: {} main: {} - author: Speakeasy + author: Clerk authors: - Clerk clientServerStatusCodesAsErrors: true @@ -35,6 +35,6 @@ python: maxMethodParams: 4 methodArguments: infer-optional-args outputModelSuffix: output - packageName: clerk-dev + packageName: clerk responseFormat: flat templateVersion: v2 diff --git a/.speakeasy/workflow.lock b/.speakeasy/workflow.lock new file mode 100644 index 0000000..b6ffc7c --- /dev/null +++ b/.speakeasy/workflow.lock @@ -0,0 +1,32 @@ +speakeasyVersion: 1.331.2 +sources: + clerk-openapi: + sourceNamespace: clerk-openapi + sourceRevisionDigest: sha256:305f26f9f1337077dd77c9bbb2bf5e1591f776fa1807740519f2e0e2502f9ece + sourceBlobDigest: sha256:f9fece020b113815baec25cc383b3d55dce300cfa983972195c2a5391299f412 + tags: + - latest +targets: + clerk-sdk-python: + source: clerk-openapi + sourceNamespace: clerk-openapi + sourceRevisionDigest: sha256:305f26f9f1337077dd77c9bbb2bf5e1591f776fa1807740519f2e0e2502f9ece + sourceBlobDigest: sha256:f9fece020b113815baec25cc383b3d55dce300cfa983972195c2a5391299f412 + outLocation: . +workflow: + workflowVersion: 1.0.0 + speakeasyVersion: latest + sources: + clerk-openapi: + inputs: + - location: openapi.yaml + overlays: + - location: ./fixes.yaml + - location: ./examples.yaml + registry: + location: registry.speakeasyapi.dev/clerk/clerk/clerk-openapi + targets: + clerk-sdk-python: + target: python + source: clerk-openapi + output: . diff --git a/.speakeasy/workflow.yaml b/.speakeasy/workflow.yaml new file mode 100644 index 0000000..9e0e3f7 --- /dev/null +++ b/.speakeasy/workflow.yaml @@ -0,0 +1,16 @@ +workflowVersion: 1.0.0 +speakeasyVersion: latest +sources: + clerk-openapi: + inputs: + - location: openapi.yaml + overlays: + - location: ./fixes.yaml + - location: ./examples.yaml + registry: + location: registry.speakeasyapi.dev/clerk/clerk/clerk-openapi +targets: + clerk-sdk-python: + target: python + source: clerk-openapi + output: . diff --git a/README.md b/README.md index 345ebd6..ee92ff3 100644 --- a/README.md +++ b/README.md @@ -1 +1,585 @@ -# clerk-sdk-python +# clerk + +
+ + + + +
+ + +## 🏗 **Welcome to your new SDK!** 🏗 + +It has been generated successfully based on your OpenAPI spec. However, it is not yet ready for production use. Here are some next steps: +- [ ] 🛠 Make your SDK feel handcrafted by [customizing it](https://www.speakeasyapi.dev/docs/customize-sdks) +- [ ] ♻️ Refine your SDK quickly by iterating locally with the [Speakeasy CLI](https://github.com/speakeasy-api/speakeasy) +- [ ] 🎁 Publish your SDK to package managers by [configuring automatic publishing](https://www.speakeasyapi.dev/docs/advanced-setup/publish-sdks) +- [ ] ✨ When ready to productionize, delete this section from the README + + +## SDK Installation + +PIP +```bash +pip install git+.git +``` + +Poetry +```bash +poetry add git+.git +``` + + + +## SDK Example Usage + +### Example + +```python +# Synchronous Example +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +res = s.email_addresses.get(email_address_id="email_address_id_example") + +if res is not None: + # handle response + pass +``` + +
+ +The same SDK client can also be used to make asychronous requests by importing asyncio. +```python +# Asynchronous Example +import asyncio +from clerk import Clerk +import os + +async def main(): + s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), + ) + res = await s.email_addresses.get_async(email_address_id="email_address_id_example") + if res is not None: + # handle response + pass + +asyncio.run(main()) +``` + + + +## Available Resources and Operations + +### [misc](docs/sdks/misc/README.md) + +* [get_public_interstitial](docs/sdks/misc/README.md#get_public_interstitial) - Returns the markup for the interstitial page + +### [jwks](docs/sdks/jwks/README.md) + +* [get](docs/sdks/jwks/README.md#get) - Retrieve the JSON Web Key Set of the instance + +### [clients](docs/sdks/clients/README.md) + +* [~~list~~](docs/sdks/clients/README.md#list) - List all clients :warning: **Deprecated** +* [verify](docs/sdks/clients/README.md#verify) - Verify a client +* [get](docs/sdks/clients/README.md#get) - Get a client + +### [email_addresses](docs/sdks/emailaddresses/README.md) + +* [create](docs/sdks/emailaddresses/README.md#create) - Create an email address +* [get](docs/sdks/emailaddresses/README.md#get) - Retrieve an email address +* [delete](docs/sdks/emailaddresses/README.md#delete) - Delete an email address +* [update](docs/sdks/emailaddresses/README.md#update) - Update an email address + +### [phone_numbers](docs/sdks/phonenumbers/README.md) + +* [create](docs/sdks/phonenumbers/README.md#create) - Create a phone number +* [get](docs/sdks/phonenumbers/README.md#get) - Retrieve a phone number +* [delete](docs/sdks/phonenumbers/README.md#delete) - Delete a phone number +* [update](docs/sdks/phonenumbers/README.md#update) - Update a phone number + +### [sessions](docs/sdks/sessions/README.md) + +* [list](docs/sdks/sessions/README.md#list) - List all sessions +* [get](docs/sdks/sessions/README.md#get) - Retrieve a session +* [revoke](docs/sdks/sessions/README.md#revoke) - Revoke a session +* [~~verify~~](docs/sdks/sessions/README.md#verify) - Verify a session :warning: **Deprecated** +* [create_token_from_template](docs/sdks/sessions/README.md#create_token_from_template) - Create a session token from a jwt template + +### [templates](docs/sdks/templates/README.md) + +* [list](docs/sdks/templates/README.md#list) - List all templates +* [get](docs/sdks/templates/README.md#get) - Retrieve a template +* [upsert](docs/sdks/templates/README.md#upsert) - Update a template for a given type and slug +* [revert](docs/sdks/templates/README.md#revert) - Revert a template +* [preview](docs/sdks/templates/README.md#preview) - Preview changes to a template +* [toggle_delivery](docs/sdks/templates/README.md#toggle_delivery) - Toggle the delivery by Clerk for a template of a given type and slug + +### [users](docs/sdks/users/README.md) + +* [list](docs/sdks/users/README.md#list) - List all users +* [create](docs/sdks/users/README.md#create) - Create a new user +* [count](docs/sdks/users/README.md#count) - Count users +* [get](docs/sdks/users/README.md#get) - Retrieve a user +* [update](docs/sdks/users/README.md#update) - Update a user +* [delete](docs/sdks/users/README.md#delete) - Delete a user +* [ban](docs/sdks/users/README.md#ban) - Ban a user +* [unban](docs/sdks/users/README.md#unban) - Unban a user +* [lock](docs/sdks/users/README.md#lock) - Lock a user +* [unlock](docs/sdks/users/README.md#unlock) - Unlock a user +* [set_profile_image](docs/sdks/users/README.md#set_profile_image) - Set user profile image +* [delete_profile_image](docs/sdks/users/README.md#delete_profile_image) - Delete user profile image +* [update_metadata](docs/sdks/users/README.md#update_metadata) - Merge and update a user's metadata +* [get_o_auth_access_token](docs/sdks/users/README.md#get_o_auth_access_token) - Retrieve the OAuth access token of a user +* [get_organization_memberships](docs/sdks/users/README.md#get_organization_memberships) - Retrieve all memberships for a user +* [verify_password](docs/sdks/users/README.md#verify_password) - Verify the password of a user +* [verify_totp](docs/sdks/users/README.md#verify_totp) - Verify a TOTP or backup code for a user +* [disable_mfa](docs/sdks/users/README.md#disable_mfa) - Disable a user's MFA methods + +### [invitations](docs/sdks/invitations/README.md) + +* [create](docs/sdks/invitations/README.md#create) - Create an invitation +* [list](docs/sdks/invitations/README.md#list) - List all invitations +* [revoke](docs/sdks/invitations/README.md#revoke) - Revokes an invitation + +### [allowlist_identifiers](docs/sdks/allowlistidentifiers/README.md) + +* [list](docs/sdks/allowlistidentifiers/README.md#list) - List all identifiers on the allow-list +* [create](docs/sdks/allowlistidentifiers/README.md#create) - Add identifier to the allow-list +* [delete](docs/sdks/allowlistidentifiers/README.md#delete) - Delete identifier from allow-list + +### [blocklist_identifiers](docs/sdks/blocklistidentifierssdk/README.md) + +* [list](docs/sdks/blocklistidentifierssdk/README.md#list) - List all identifiers on the block-list +* [create](docs/sdks/blocklistidentifierssdk/README.md#create) - Add identifier to the block-list +* [delete](docs/sdks/blocklistidentifierssdk/README.md#delete) - Delete identifier from block-list + +### [beta_features](docs/sdks/betafeatures/README.md) + +* [update_instance_auth_config](docs/sdks/betafeatures/README.md#update_instance_auth_config) - Update instance settings +* [~~update_production_instance_domain~~](docs/sdks/betafeatures/README.md#update_production_instance_domain) - Update production instance domain :warning: **Deprecated** +* [change_production_instance_domain](docs/sdks/betafeatures/README.md#change_production_instance_domain) - Update production instance domain + +### [actor_tokens](docs/sdks/actortokens/README.md) + +* [create](docs/sdks/actortokens/README.md#create) - Create actor token +* [revoke](docs/sdks/actortokens/README.md#revoke) - Revoke actor token + +### [domains](docs/sdks/domainssdk/README.md) + +* [list](docs/sdks/domainssdk/README.md#list) - List all instance domains +* [add](docs/sdks/domainssdk/README.md#add) - Add a domain +* [delete](docs/sdks/domainssdk/README.md#delete) - Delete a satellite domain +* [update](docs/sdks/domainssdk/README.md#update) - Update a domain + +### [instance_settings](docs/sdks/instancesettingssdk/README.md) + +* [update](docs/sdks/instancesettingssdk/README.md#update) - Update instance settings +* [update_restrictions](docs/sdks/instancesettingssdk/README.md#update_restrictions) - Update instance restrictions +* [update_organization_settings](docs/sdks/instancesettingssdk/README.md#update_organization_settings) - Update instance organization settings + +### [webhooks](docs/sdks/webhooks/README.md) + +* [create_svix_app](docs/sdks/webhooks/README.md#create_svix_app) - Create a Svix app +* [delete_svix_app](docs/sdks/webhooks/README.md#delete_svix_app) - Delete a Svix app +* [generate_svix_auth_url](docs/sdks/webhooks/README.md#generate_svix_auth_url) - Create a Svix Dashboard URL + +### [jwt_templates](docs/sdks/jwttemplates/README.md) + +* [list](docs/sdks/jwttemplates/README.md#list) - List all templates +* [create](docs/sdks/jwttemplates/README.md#create) - Create a JWT template +* [get](docs/sdks/jwttemplates/README.md#get) - Retrieve a template +* [update](docs/sdks/jwttemplates/README.md#update) - Update a JWT template +* [delete](docs/sdks/jwttemplates/README.md#delete) - Delete a Template + +### [organizations](docs/sdks/organizationssdk/README.md) + +* [list](docs/sdks/organizationssdk/README.md#list) - Get a list of organizations for an instance +* [create](docs/sdks/organizationssdk/README.md#create) - Create an organization +* [get](docs/sdks/organizationssdk/README.md#get) - Retrieve an organization by ID or slug +* [update](docs/sdks/organizationssdk/README.md#update) - Update an organization +* [delete](docs/sdks/organizationssdk/README.md#delete) - Delete an organization +* [merge_metadata](docs/sdks/organizationssdk/README.md#merge_metadata) - Merge and update metadata for an organization +* [upload_logo](docs/sdks/organizationssdk/README.md#upload_logo) - Upload a logo for the organization +* [delete_logo](docs/sdks/organizationssdk/README.md#delete_logo) - Delete the organization's logo. + +### [organization_invitations](docs/sdks/organizationinvitationssdk/README.md) + +* [create](docs/sdks/organizationinvitationssdk/README.md#create) - Create and send an organization invitation +* [list](docs/sdks/organizationinvitationssdk/README.md#list) - Get a list of organization invitations +* [create_bulk](docs/sdks/organizationinvitationssdk/README.md#create_bulk) - Bulk create and send organization invitations +* [~~list_pending~~](docs/sdks/organizationinvitationssdk/README.md#list_pending) - Get a list of pending organization invitations :warning: **Deprecated** +* [get](docs/sdks/organizationinvitationssdk/README.md#get) - Retrieve an organization invitation by ID +* [revoke](docs/sdks/organizationinvitationssdk/README.md#revoke) - Revoke a pending organization invitation + +### [organization_memberships](docs/sdks/organizationmembershipssdk/README.md) + +* [create](docs/sdks/organizationmembershipssdk/README.md#create) - Create a new organization membership +* [list](docs/sdks/organizationmembershipssdk/README.md#list) - Get a list of all members of an organization +* [update](docs/sdks/organizationmembershipssdk/README.md#update) - Update an organization membership +* [delete](docs/sdks/organizationmembershipssdk/README.md#delete) - Remove a member from an organization +* [update_metadata](docs/sdks/organizationmembershipssdk/README.md#update_metadata) - Merge and update organization membership metadata + +### [proxy_checks](docs/sdks/proxychecks/README.md) + +* [verify](docs/sdks/proxychecks/README.md#verify) - Verify the proxy configuration for your domain + +### [redirect_urls](docs/sdks/redirecturls/README.md) + +* [list](docs/sdks/redirecturls/README.md#list) - List all redirect URLs +* [create](docs/sdks/redirecturls/README.md#create) - Create a redirect URL +* [get](docs/sdks/redirecturls/README.md#get) - Retrieve a redirect URL +* [delete](docs/sdks/redirecturls/README.md#delete) - Delete a redirect URL + +### [sign_in_tokens](docs/sdks/signintokens/README.md) + +* [create](docs/sdks/signintokens/README.md#create) - Create sign-in token +* [revoke](docs/sdks/signintokens/README.md#revoke) - Revoke the given sign-in token + +### [sign_ups](docs/sdks/signups/README.md) + +* [update](docs/sdks/signups/README.md#update) - Update a sign-up + +### [o_auth_applications](docs/sdks/oauthapplicationssdk/README.md) + +* [list](docs/sdks/oauthapplicationssdk/README.md#list) - Get a list of OAuth applications for an instance +* [create](docs/sdks/oauthapplicationssdk/README.md#create) - Create an OAuth application +* [get](docs/sdks/oauthapplicationssdk/README.md#get) - Retrieve an OAuth application by ID +* [update](docs/sdks/oauthapplicationssdk/README.md#update) - Update an OAuth application +* [delete](docs/sdks/oauthapplicationssdk/README.md#delete) - Delete an OAuth application +* [rotate_secret](docs/sdks/oauthapplicationssdk/README.md#rotate_secret) - Rotate the client secret of the given OAuth application + +### [saml_connections](docs/sdks/samlconnectionssdk/README.md) + +* [list](docs/sdks/samlconnectionssdk/README.md#list) - Get a list of SAML Connections for an instance +* [create](docs/sdks/samlconnectionssdk/README.md#create) - Create a SAML Connection +* [get](docs/sdks/samlconnectionssdk/README.md#get) - Retrieve a SAML Connection by ID +* [update](docs/sdks/samlconnectionssdk/README.md#update) - Update a SAML Connection +* [delete](docs/sdks/samlconnectionssdk/README.md#delete) - Delete a SAML Connection + +### [testing_tokens](docs/sdks/testingtokens/README.md) + +* [create](docs/sdks/testingtokens/README.md#create) - Retrieve a new testing token + + + +## Pagination + +Some of the endpoints in this SDK support pagination. To use pagination, you make your SDK calls as usual, but the +returned response object will have a `Next` method that can be called to pull down the next group of results. If the +return value of `Next` is `None`, then there are no more pages to be fetched. + +Here's an example of one such pagination call: +```python +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +res = s.clients.list(limit=20, offset=10) + +if res is not None: + while True: + # handle items + + res = res.Next() + if res is None: + break + + +``` + + + +## File uploads + +Certain SDK methods accept file objects as part of a request body or multi-part request. It is possible and typically recommended to upload files as a stream rather than reading the entire contents into memory. This avoids excessive memory consumption and potentially crashing with out-of-memory errors when working with very large files. The following example demonstrates how to attach a file stream to a request. + +> [!TIP] +> +> For endpoints that handle file uploads bytes arrays can also be used. However, using streams is recommended for large files. +> + +```python +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +res = s.users.set_profile_image(user_id="usr_test123", file={ + "file_name": "your_file_here", + "content": open("", "rb"), + "content_type": "", +}) + +if res is not None: + # handle response + pass + +``` + + + +## Retries + +Some of the endpoints in this SDK support retries. If you use the SDK without any configuration, it will fall back to the default retry strategy provided by the API. However, the default retry strategy can be overridden on a per-operation basis, or across the entire SDK. + +To change the default retry strategy for a single API call, simply provide a `RetryConfig` object to the call: +```python +from clerk import Clerk +from clerk.utils import BackoffStrategy, RetryConfig + +s = Clerk() + + +s.misc.get_public_interstitial(frontend_api="frontend-api_1a2b3c4d", publishable_key="pub_1a2b3c4d", + RetryConfig("backoff", BackoffStrategy(1, 50, 1.1, 100), False)) + +# Use the SDK ... + +``` + +If you'd like to override the default retry strategy for all operations that support retries, you can use the `retry_config` optional parameter when initializing the SDK: +```python +from clerk import Clerk +from clerk.utils import BackoffStrategy, RetryConfig + +s = Clerk( + retry_config=RetryConfig("backoff", BackoffStrategy(1, 50, 1.1, 100), False), +) + + +s.misc.get_public_interstitial(frontend_api="frontend-api_1a2b3c4d", publishable_key="pub_1a2b3c4d") + +# Use the SDK ... + +``` + + + +## Error Handling + +Handling errors in this SDK should largely match your expectations. All operations return a response object or raise an error. If Error objects are specified in your OpenAPI Spec, the SDK will raise the appropriate Error type. + +| Error Object | Status Code | Content Type | +| ------------------ | ------------------ | ------------------ | +| models.ClerkErrors | 400,401,410,422 | application/json | +| models.SDKError | 4xx-5xx | */* | + +### Example + +```python +from clerk import Clerk, models +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + +res = None +try: + res = s.clients.list(limit=20, offset=10) + +except models.ClerkErrors as e: + # handle exception + raise(e) +except models.SDKError as e: + # handle exception + raise(e) + +if res is not None: + while True: + # handle items + + res = res.Next() + if res is None: + break + + +``` + + + +## Server Selection + +### Select Server by Index + +You can override the default server globally by passing a server index to the `server_idx: int` optional parameter when initializing the SDK client instance. The selected server will then be used as the default on the operations that use it. This table lists the indexes associated with the available servers: + +| # | Server | Variables | +| - | ------ | --------- | +| 0 | `https://api.clerk.com/v1` | None | + +#### Example + +```python +from clerk import Clerk + +s = Clerk( + server_idx=0, +) + + +s.misc.get_public_interstitial(frontend_api="frontend-api_1a2b3c4d", publishable_key="pub_1a2b3c4d") + +# Use the SDK ... + +``` + + +### Override Server URL Per-Client + +The default server can also be overridden globally by passing a URL to the `server_url: str` optional parameter when initializing the SDK client instance. For example: +```python +from clerk import Clerk + +s = Clerk( + server_url="https://api.clerk.com/v1", +) + + +s.misc.get_public_interstitial(frontend_api="frontend-api_1a2b3c4d", publishable_key="pub_1a2b3c4d") + +# Use the SDK ... + +``` + + + +## Custom HTTP Client + +The Python SDK makes API calls using the [httpx](https://www.python-httpx.org/) HTTP library. In order to provide a convenient way to configure timeouts, cookies, proxies, custom headers, and other low-level configuration, you can initialize the SDK client with your own HTTP client instance. +Depending on whether you are using the sync or async version of the SDK, you can pass an instance of `HttpClient` or `AsyncHttpClient` respectively, which are Protocol's ensuring that the client has the necessary methods to make API calls. +This allows you to wrap the client with your own custom logic, such as adding custom headers, logging, or error handling, or you can just pass an instance of `httpx.Client` or `httpx.AsyncClient` directly. + +For example, you could specify a header for every request that this sdk makes as follows: +```python +from clerk import Clerk +import httpx + +http_client = httpx.Client(headers={"x-custom-header": "someValue"}) +s = Clerk(client=http_client) +``` + +or you could wrap the client with your own custom logic: +```python +from clerk import Clerk +from clerk.httpclient import AsyncHttpClient +import httpx + +class CustomClient(AsyncHttpClient): + client: AsyncHttpClient + + def __init__(self, client: AsyncHttpClient): + self.client = client + + async def send( + self, + request: httpx.Request, + *, + stream: bool = False, + auth: Union[ + httpx._types.AuthTypes, httpx._client.UseClientDefault, None + ] = httpx.USE_CLIENT_DEFAULT, + follow_redirects: Union[ + bool, httpx._client.UseClientDefault + ] = httpx.USE_CLIENT_DEFAULT, + ) -> httpx.Response: + request.headers["Client-Level-Header"] = "added by client" + + return await self.client.send( + request, stream=stream, auth=auth, follow_redirects=follow_redirects + ) + + def build_request( + self, + method: str, + url: httpx._types.URLTypes, + *, + content: Optional[httpx._types.RequestContent] = None, + data: Optional[httpx._types.RequestData] = None, + files: Optional[httpx._types.RequestFiles] = None, + json: Optional[Any] = None, + params: Optional[httpx._types.QueryParamTypes] = None, + headers: Optional[httpx._types.HeaderTypes] = None, + cookies: Optional[httpx._types.CookieTypes] = None, + timeout: Union[ + httpx._types.TimeoutTypes, httpx._client.UseClientDefault + ] = httpx.USE_CLIENT_DEFAULT, + extensions: Optional[httpx._types.RequestExtensions] = None, + ) -> httpx.Request: + return self.client.build_request( + method, + url, + content=content, + data=data, + files=files, + json=json, + params=params, + headers=headers, + cookies=cookies, + timeout=timeout, + extensions=extensions, + ) + +s = Clerk(async_client=CustomClient(httpx.AsyncClient())) +``` + + + +## Authentication + +### Per-Client Security Schemes + +This SDK supports the following security scheme globally: + +| Name | Type | Scheme | +| ------------- | ------------- | ------------- | +| `bearer_auth` | http | HTTP Bearer | + +To authenticate with the API the `bearer_auth` parameter must be set when initializing the SDK client instance. For example: +```python +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +s.misc.get_public_interstitial(frontend_api="frontend-api_1a2b3c4d", publishable_key="pub_1a2b3c4d") + +# Use the SDK ... + +``` + + + + +# Development + +## Maturity + +This SDK is in beta, and there may be breaking changes between versions without a major version update. Therefore, we recommend pinning usage +to a specific package version. This way, you can install the same version each time without breaking changes unless you are intentionally +looking for the latest version. + +## Contributions + +While we value open-source contributions to this SDK, this library is generated programmatically. Any manual changes added to internal files will be overwritten on the next generation. +We look forward to hearing your feedback. Feel free to open a PR or an issue with a proof of concept and we'll do our best to include it in a future release. + +### SDK Created by [Speakeasy](https://docs.speakeasyapi.dev/docs/using-speakeasy/client-sdks) diff --git a/USAGE.md b/USAGE.md new file mode 100644 index 0000000..3becc19 --- /dev/null +++ b/USAGE.md @@ -0,0 +1,39 @@ + +```python +# Synchronous Example +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +res = s.email_addresses.get(email_address_id="email_address_id_example") + +if res is not None: + # handle response + pass +``` + +
+ +The same SDK client can also be used to make asychronous requests by importing asyncio. +```python +# Asynchronous Example +import asyncio +from clerk import Clerk +import os + +async def main(): + s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), + ) + res = await s.email_addresses.get_async(email_address_id="email_address_id_example") + if res is not None: + # handle response + pass + +asyncio.run(main()) +``` + \ No newline at end of file diff --git a/docs/models/actor.md b/docs/models/actor.md new file mode 100644 index 0000000..45b5a6d --- /dev/null +++ b/docs/models/actor.md @@ -0,0 +1,7 @@ +# Actor + + +## Fields + +| Field | Type | Required | Description | +| ----------- | ----------- | ----------- | ----------- | \ No newline at end of file diff --git a/docs/models/actortoken.md b/docs/models/actortoken.md new file mode 100644 index 0000000..fe1be10 --- /dev/null +++ b/docs/models/actortoken.md @@ -0,0 +1,16 @@ +# ActorToken + + +## Fields + +| Field | Type | Required | Description | Example | +| -------------------------------------------------------- | -------------------------------------------------------- | -------------------------------------------------------- | -------------------------------------------------------- | -------------------------------------------------------- | +| `object` | [models.ActorTokenObject](../models/actortokenobject.md) | :heavy_check_mark: | N/A | actor_token | +| `id` | *str* | :heavy_check_mark: | N/A | actor_tok_1a2b3c | +| `status` | [models.ActorTokenStatus](../models/actortokenstatus.md) | :heavy_check_mark: | N/A | pending | +| `user_id` | *str* | :heavy_check_mark: | N/A | user_1a2b3c | +| `actor` | [models.ActorTokenActor](../models/actortokenactor.md) | :heavy_check_mark: | N/A | {
"sub": "user_2OEpKhcCN1Lat9NQ0G6puh7q5Rb"
} | +| `created_at` | *int* | :heavy_check_mark: | Unix timestamp of creation.
| 1609459200 | +| `updated_at` | *int* | :heavy_check_mark: | Unix timestamp of last update.
| 1612137600 | +| `token` | *Optional[Nullable[str]]* | :heavy_minus_sign: | N/A | token_string | +| `url` | *Optional[Nullable[str]]* | :heavy_minus_sign: | N/A | https://example.com/token | \ No newline at end of file diff --git a/docs/models/actortokenactor.md b/docs/models/actortokenactor.md new file mode 100644 index 0000000..16e49d4 --- /dev/null +++ b/docs/models/actortokenactor.md @@ -0,0 +1,7 @@ +# ActorTokenActor + + +## Fields + +| Field | Type | Required | Description | +| ----------- | ----------- | ----------- | ----------- | \ No newline at end of file diff --git a/docs/models/actortokenobject.md b/docs/models/actortokenobject.md new file mode 100644 index 0000000..354c3af --- /dev/null +++ b/docs/models/actortokenobject.md @@ -0,0 +1,8 @@ +# ActorTokenObject + + +## Values + +| Name | Value | +| ------------- | ------------- | +| `ACTOR_TOKEN` | actor_token | \ No newline at end of file diff --git a/docs/models/actortokenstatus.md b/docs/models/actortokenstatus.md new file mode 100644 index 0000000..f7dd577 --- /dev/null +++ b/docs/models/actortokenstatus.md @@ -0,0 +1,10 @@ +# ActorTokenStatus + + +## Values + +| Name | Value | +| ---------- | ---------- | +| `PENDING` | pending | +| `ACCEPTED` | accepted | +| `REVOKED` | revoked | \ No newline at end of file diff --git a/docs/models/adddomainrequestbody.md b/docs/models/adddomainrequestbody.md new file mode 100644 index 0000000..3a975cc --- /dev/null +++ b/docs/models/adddomainrequestbody.md @@ -0,0 +1,10 @@ +# AddDomainRequestBody + + +## Fields + +| Field | Type | Required | Description | Example | +| ----------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | +| `name` | *str* | :heavy_check_mark: | The new domain name. Can contain the port for development instances. | example.com | +| `is_satellite` | *bool* | :heavy_check_mark: | Marks the new domain as satellite. Only `true` is accepted at the moment. | true | +| `proxy_url` | *Optional[str]* | :heavy_minus_sign: | The full URL of the proxy which will forward requests to the Clerk Frontend API for this domain. Applicable only to production instances. | https://proxy.example.com | \ No newline at end of file diff --git a/docs/models/admin.md b/docs/models/admin.md new file mode 100644 index 0000000..9a8b5e7 --- /dev/null +++ b/docs/models/admin.md @@ -0,0 +1,11 @@ +# Admin + + +## Fields + +| Field | Type | Required | Description | Example | +| ---------------------------------------------------------------------- | ---------------------------------------------------------------------- | ---------------------------------------------------------------------- | ---------------------------------------------------------------------- | ---------------------------------------------------------------------- | +| `status` | [models.AdminVerificationStatus](../models/adminverificationstatus.md) | :heavy_check_mark: | N/A | verified | +| `strategy` | [models.VerificationStrategy](../models/verificationstrategy.md) | :heavy_check_mark: | N/A | admin | +| `attempts` | *Optional[Nullable[int]]* | :heavy_minus_sign: | N/A | 0 | +| `expire_at` | *Optional[Nullable[int]]* | :heavy_minus_sign: | N/A | 1620000000 | \ No newline at end of file diff --git a/docs/models/adminverificationphonenumberstatus.md b/docs/models/adminverificationphonenumberstatus.md new file mode 100644 index 0000000..51b3f93 --- /dev/null +++ b/docs/models/adminverificationphonenumberstatus.md @@ -0,0 +1,8 @@ +# AdminVerificationPhoneNumberStatus + + +## Values + +| Name | Value | +| ---------- | ---------- | +| `VERIFIED` | verified | \ No newline at end of file diff --git a/docs/models/adminverificationstatus.md b/docs/models/adminverificationstatus.md new file mode 100644 index 0000000..927253e --- /dev/null +++ b/docs/models/adminverificationstatus.md @@ -0,0 +1,8 @@ +# AdminVerificationStatus + + +## Values + +| Name | Value | +| ---------- | ---------- | +| `VERIFIED` | verified | \ No newline at end of file diff --git a/docs/models/adminverificationstrategy.md b/docs/models/adminverificationstrategy.md new file mode 100644 index 0000000..a4c1800 --- /dev/null +++ b/docs/models/adminverificationstrategy.md @@ -0,0 +1,9 @@ +# AdminVerificationStrategy + + +## Values + +| Name | Value | +| -------------------- | -------------------- | +| `ADMIN` | admin | +| `FROM_OAUTH_DISCORD` | from_oauth_discord | \ No newline at end of file diff --git a/docs/models/adminverificationweb3walletstatus.md b/docs/models/adminverificationweb3walletstatus.md new file mode 100644 index 0000000..f16de1d --- /dev/null +++ b/docs/models/adminverificationweb3walletstatus.md @@ -0,0 +1,8 @@ +# AdminVerificationWeb3WalletStatus + + +## Values + +| Name | Value | +| ---------- | ---------- | +| `VERIFIED` | verified | \ No newline at end of file diff --git a/docs/models/adminverificationweb3walletstrategy.md b/docs/models/adminverificationweb3walletstrategy.md new file mode 100644 index 0000000..5d5f9f6 --- /dev/null +++ b/docs/models/adminverificationweb3walletstrategy.md @@ -0,0 +1,9 @@ +# AdminVerificationWeb3WalletStrategy + + +## Values + +| Name | Value | +| -------------------- | -------------------- | +| `ADMIN` | admin | +| `FROM_OAUTH_DISCORD` | from_oauth_discord | \ No newline at end of file diff --git a/docs/models/allowlistidentifier.md b/docs/models/allowlistidentifier.md new file mode 100644 index 0000000..03b3209 --- /dev/null +++ b/docs/models/allowlistidentifier.md @@ -0,0 +1,15 @@ +# AllowlistIdentifier + + +## Fields + +| Field | Type | Required | Description | Example | +| -------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | +| `object` | [Optional[models.AllowlistIdentifierObject]](../models/allowlistidentifierobject.md) | :heavy_minus_sign: | String representing the object's type. Objects of the same type share the same value.
| allowlist_identifier | +| `id` | *Optional[str]* | :heavy_minus_sign: | N/A | alid_123456 | +| `invitation_id` | *Optional[str]* | :heavy_minus_sign: | N/A | inv_123456 | +| `identifier` | *Optional[str]* | :heavy_minus_sign: | An email address or a phone number.
| user@example.com | +| `identifier_type` | [Optional[models.IdentifierType]](../models/identifiertype.md) | :heavy_minus_sign: | N/A | email_address | +| `instance_id` | *Optional[str]* | :heavy_minus_sign: | N/A | instance_12345 | +| `created_at` | *Optional[int]* | :heavy_minus_sign: | Unix timestamp of creation
| 1622547600 | +| `updated_at` | *Optional[int]* | :heavy_minus_sign: | Unix timestamp of last update.
| 1622648600 | \ No newline at end of file diff --git a/docs/models/allowlistidentifierobject.md b/docs/models/allowlistidentifierobject.md new file mode 100644 index 0000000..5473a90 --- /dev/null +++ b/docs/models/allowlistidentifierobject.md @@ -0,0 +1,11 @@ +# AllowlistIdentifierObject + +String representing the object's type. Objects of the same type share the same value. + + + +## Values + +| Name | Value | +| ---------------------- | ---------------------- | +| `ALLOWLIST_IDENTIFIER` | allowlist_identifier | \ No newline at end of file diff --git a/docs/models/attributemapping.md b/docs/models/attributemapping.md new file mode 100644 index 0000000..672999f --- /dev/null +++ b/docs/models/attributemapping.md @@ -0,0 +1,11 @@ +# AttributeMapping + + +## Fields + +| Field | Type | Required | Description | Example | +| ------------------ | ------------------ | ------------------ | ------------------ | ------------------ | +| `user_id` | *Optional[str]* | :heavy_minus_sign: | N/A | nameid | +| `email_address` | *Optional[str]* | :heavy_minus_sign: | N/A | email | +| `first_name` | *Optional[str]* | :heavy_minus_sign: | N/A | firstName | +| `last_name` | *Optional[str]* | :heavy_minus_sign: | N/A | lastName | \ No newline at end of file diff --git a/docs/models/banuserrequest.md b/docs/models/banuserrequest.md new file mode 100644 index 0000000..9500735 --- /dev/null +++ b/docs/models/banuserrequest.md @@ -0,0 +1,8 @@ +# BanUserRequest + + +## Fields + +| Field | Type | Required | Description | Example | +| ------------------------- | ------------------------- | ------------------------- | ------------------------- | ------------------------- | +| `user_id` | *str* | :heavy_check_mark: | The ID of the user to ban | user_12345 | \ No newline at end of file diff --git a/docs/models/blocklistidentifier.md b/docs/models/blocklistidentifier.md new file mode 100644 index 0000000..a5ddaea --- /dev/null +++ b/docs/models/blocklistidentifier.md @@ -0,0 +1,14 @@ +# BlocklistIdentifier + + +## Fields + +| Field | Type | Required | Description | Example | +| ---------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- | +| `object` | [Optional[models.BlocklistIdentifierObject]](../models/blocklistidentifierobject.md) | :heavy_minus_sign: | String representing the object's type. Objects of the same type share the same value.
| blocklist_identifier | +| `id` | *Optional[str]* | :heavy_minus_sign: | N/A | identifier_id | +| `identifier` | *Optional[str]* | :heavy_minus_sign: | An email address, email domain, phone number or web3 wallet.
| blocked@example.com | +| `identifier_type` | [Optional[models.BlocklistIdentifierIdentifierType]](../models/blocklistidentifieridentifiertype.md) | :heavy_minus_sign: | N/A | email_address | +| `instance_id` | *Optional[str]* | :heavy_minus_sign: | N/A | instance_id_here | +| `created_at` | *Optional[int]* | :heavy_minus_sign: | Unix timestamp of creation
| 1609459200 | +| `updated_at` | *Optional[int]* | :heavy_minus_sign: | Unix timestamp of last update.
| 1612137600 | \ No newline at end of file diff --git a/docs/models/blocklistidentifieridentifiertype.md b/docs/models/blocklistidentifieridentifiertype.md new file mode 100644 index 0000000..21f7db0 --- /dev/null +++ b/docs/models/blocklistidentifieridentifiertype.md @@ -0,0 +1,10 @@ +# BlocklistIdentifierIdentifierType + + +## Values + +| Name | Value | +| --------------- | --------------- | +| `EMAIL_ADDRESS` | email_address | +| `PHONE_NUMBER` | phone_number | +| `WEB3_WALLET` | web3_wallet | \ No newline at end of file diff --git a/docs/models/blocklistidentifierobject.md b/docs/models/blocklistidentifierobject.md new file mode 100644 index 0000000..9efb8af --- /dev/null +++ b/docs/models/blocklistidentifierobject.md @@ -0,0 +1,11 @@ +# BlocklistIdentifierObject + +String representing the object's type. Objects of the same type share the same value. + + + +## Values + +| Name | Value | +| ---------------------- | ---------------------- | +| `BLOCKLIST_IDENTIFIER` | blocklist_identifier | \ No newline at end of file diff --git a/docs/models/blocklistidentifiers.md b/docs/models/blocklistidentifiers.md new file mode 100644 index 0000000..68fa3ff --- /dev/null +++ b/docs/models/blocklistidentifiers.md @@ -0,0 +1,9 @@ +# BlocklistIdentifiers + + +## Fields + +| Field | Type | Required | Description | Example | +| -------------------------------------------------------------------- | -------------------------------------------------------------------- | -------------------------------------------------------------------- | -------------------------------------------------------------------- | -------------------------------------------------------------------- | +| `data` | List[[models.BlocklistIdentifier](../models/blocklistidentifier.md)] | :heavy_check_mark: | N/A | | +| `total_count` | *int* | :heavy_check_mark: | Total number of blocklist identifiers
| 100 | \ No newline at end of file diff --git a/docs/models/changeproductioninstancedomainrequestbody.md b/docs/models/changeproductioninstancedomainrequestbody.md new file mode 100644 index 0000000..386b122 --- /dev/null +++ b/docs/models/changeproductioninstancedomainrequestbody.md @@ -0,0 +1,8 @@ +# ChangeProductionInstanceDomainRequestBody + + +## Fields + +| Field | Type | Required | Description | Example | +| ------------------------------------------------------------------------ | ------------------------------------------------------------------------ | ------------------------------------------------------------------------ | ------------------------------------------------------------------------ | ------------------------------------------------------------------------ | +| `home_url` | *Optional[str]* | :heavy_minus_sign: | The new home URL of the production instance e.g. https://www.example.com | https://www.newdomain.com | \ No newline at end of file diff --git a/docs/models/claims.md b/docs/models/claims.md new file mode 100644 index 0000000..5c4b4bd --- /dev/null +++ b/docs/models/claims.md @@ -0,0 +1,7 @@ +# Claims + + +## Fields + +| Field | Type | Required | Description | +| ----------- | ----------- | ----------- | ----------- | \ No newline at end of file diff --git a/docs/models/clerkerror.md b/docs/models/clerkerror.md new file mode 100644 index 0000000..c0b1e6d --- /dev/null +++ b/docs/models/clerkerror.md @@ -0,0 +1,12 @@ +# ClerkError + + +## Fields + +| Field | Type | Required | Description | Example | +| -------------------------------------------------- | -------------------------------------------------- | -------------------------------------------------- | -------------------------------------------------- | -------------------------------------------------- | +| `message` | *str* | :heavy_check_mark: | N/A | Invalid input | +| `long_message` | *str* | :heavy_check_mark: | N/A | The input provided does not meet the requirements. | +| `code` | *str* | :heavy_check_mark: | N/A | 400_bad_request | +| `meta` | [Optional[models.Meta]](../models/meta.md) | :heavy_minus_sign: | N/A | {} | +| `clerk_trace_id` | *Optional[str]* | :heavy_minus_sign: | N/A | trace_123456789abcd | \ No newline at end of file diff --git a/docs/models/clerkerrorerrormeta.md b/docs/models/clerkerrorerrormeta.md new file mode 100644 index 0000000..e705a2f --- /dev/null +++ b/docs/models/clerkerrorerrormeta.md @@ -0,0 +1,7 @@ +# ClerkErrorErrorMeta + + +## Fields + +| Field | Type | Required | Description | +| ----------- | ----------- | ----------- | ----------- | \ No newline at end of file diff --git a/docs/models/clerkerrors.md b/docs/models/clerkerrors.md new file mode 100644 index 0000000..cbcac9a --- /dev/null +++ b/docs/models/clerkerrors.md @@ -0,0 +1,11 @@ +# ClerkErrors + +Request was not successful + + +## Fields + +| Field | Type | Required | Description | Example | +| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `errors` | List[[models.ClerkError](../models/clerkerror.md)] | :heavy_check_mark: | N/A | [
{
"message": "Invalid input",
"long_message": "The input provided does not meet the requirements.",
"code": "400_bad_request",
"clerk_trace_id": "trace_123456789abcd"
}
] | +| `meta` | [Optional[models.ClerkErrorsMeta]](../models/clerkerrorsmeta.md) | :heavy_minus_sign: | N/A | {} | \ No newline at end of file diff --git a/docs/models/clerkerrorsmeta.md b/docs/models/clerkerrorsmeta.md new file mode 100644 index 0000000..c82450f --- /dev/null +++ b/docs/models/clerkerrorsmeta.md @@ -0,0 +1,7 @@ +# ClerkErrorsMeta + + +## Fields + +| Field | Type | Required | Description | +| ----------- | ----------- | ----------- | ----------- | \ No newline at end of file diff --git a/docs/models/client.md b/docs/models/client.md new file mode 100644 index 0000000..b33f7f4 --- /dev/null +++ b/docs/models/client.md @@ -0,0 +1,16 @@ +# Client + + +## Fields + +| Field | Type | Required | Description | Example | +| -------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | +| `object` | [models.Object](../models/object.md) | :heavy_check_mark: | String representing the object's type. Objects of the same type share the same value.
| client | +| `id` | *str* | :heavy_check_mark: | String representing the identifier of the session.
| client_123456789abcd | +| `session_ids` | List[*str*] | :heavy_check_mark: | N/A | [
"sess_123456789abcd",
"sess_23456789abcd"
] | +| `sessions` | List[[models.Session](../models/session.md)] | :heavy_check_mark: | N/A | | +| `sign_in_id` | *Nullable[str]* | :heavy_check_mark: | N/A | signin_123456789abcd | +| `sign_up_id` | *Nullable[str]* | :heavy_check_mark: | N/A | signup_123456789abcd | +| `last_active_session_id` | *Nullable[str]* | :heavy_check_mark: | Last active session_id.
| session_123456789abcd | +| `updated_at` | *int* | :heavy_check_mark: | Unix timestamp of last update.
| 1632580323 | +| `created_at` | *int* | :heavy_check_mark: | Unix timestamp of creation.
| 1622481123 | \ No newline at end of file diff --git a/docs/models/cnametarget.md b/docs/models/cnametarget.md new file mode 100644 index 0000000..d9f987d --- /dev/null +++ b/docs/models/cnametarget.md @@ -0,0 +1,10 @@ +# CNameTarget + + +## Fields + +| Field | Type | Required | Description | Example | +| ----------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- | +| `host` | *str* | :heavy_check_mark: | N/A | cname.example.com | +| `value` | *str* | :heavy_check_mark: | N/A | value.example.com | +| `required` | *bool* | :heavy_check_mark: | Denotes whether this CNAME target is required to be set in order for the domain to be considered deployed.
| true | \ No newline at end of file diff --git a/docs/models/codetype.md b/docs/models/codetype.md new file mode 100644 index 0000000..e3d81ce --- /dev/null +++ b/docs/models/codetype.md @@ -0,0 +1,9 @@ +# CodeType + + +## Values + +| Name | Value | +| ------------- | ------------- | +| `TOTP` | totp | +| `BACKUP_CODE` | backup_code | \ No newline at end of file diff --git a/docs/models/createactortokenrequestbody.md b/docs/models/createactortokenrequestbody.md new file mode 100644 index 0000000..02055db --- /dev/null +++ b/docs/models/createactortokenrequestbody.md @@ -0,0 +1,11 @@ +# CreateActorTokenRequestBody + + +## Fields + +| Field | Type | Required | Description | Example | +| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `user_id` | *str* | :heavy_check_mark: | The ID of the user that can use the newly created sign in token. | user_1a2b3c | +| `actor` | Dict[str, *Any*] | :heavy_check_mark: | The actor payload. It needs to include a sub property which should contain the ID of the actor.
This whole payload will be also included in the JWT session token. | {
"sub": "user_2OEpKhcCN1Lat9NQ0G6puh7q5Rb"
} | +| `expires_in_seconds` | *Optional[int]* | :heavy_minus_sign: | Optional parameter to specify the life duration of the actor token in seconds.
By default, the duration is 1 hour. | 3600 | +| `session_max_duration_in_seconds` | *Optional[int]* | :heavy_minus_sign: | The maximum duration that the session which will be created by the generated actor token should last.
By default, the duration of a session created via an actor token, lasts 30 minutes. | 1800 | \ No newline at end of file diff --git a/docs/models/createallowlistidentifierrequestbody.md b/docs/models/createallowlistidentifierrequestbody.md new file mode 100644 index 0000000..804fe10 --- /dev/null +++ b/docs/models/createallowlistidentifierrequestbody.md @@ -0,0 +1,9 @@ +# CreateAllowlistIdentifierRequestBody + + +## Fields + +| Field | Type | Required | Description | Example | +| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `identifier` | *str* | :heavy_check_mark: | The identifier to be added in the allow-list.
This can be an email address, a phone number or a web3 wallet. | user@example.com | +| `notify` | *Optional[bool]* | :heavy_minus_sign: | This flag denotes whether the given identifier will receive an invitation to join the application.
Note that this only works for email address and phone number identifiers. | true | \ No newline at end of file diff --git a/docs/models/createblocklistidentifierrequestbody.md b/docs/models/createblocklistidentifierrequestbody.md new file mode 100644 index 0000000..3735ef4 --- /dev/null +++ b/docs/models/createblocklistidentifierrequestbody.md @@ -0,0 +1,8 @@ +# CreateBlocklistIdentifierRequestBody + + +## Fields + +| Field | Type | Required | Description | Example | +| ------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------ | +| `identifier` | *str* | :heavy_check_mark: | The identifier to be added in the block-list.
This can be an email address, a phone number or a web3 wallet. | example@example.com | \ No newline at end of file diff --git a/docs/models/createemailaddressrequestbody.md b/docs/models/createemailaddressrequestbody.md new file mode 100644 index 0000000..9a030c9 --- /dev/null +++ b/docs/models/createemailaddressrequestbody.md @@ -0,0 +1,11 @@ +# CreateEmailAddressRequestBody + + +## Fields + +| Field | Type | Required | Description | Example | +| -------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- | +| `user_id` | *Optional[str]* | :heavy_minus_sign: | The ID representing the user | user_12345 | +| `email_address` | *Optional[str]* | :heavy_minus_sign: | The new email address. Must adhere to the RFC 5322 specification for email address format. | example@clerk.com | +| `verified` | *Optional[Nullable[bool]]* | :heavy_minus_sign: | When created, the email address will be marked as verified. | false | +| `primary` | *Optional[Nullable[bool]]* | :heavy_minus_sign: | Create this email address as the primary email address for the user.
Default: false, unless it is the first email address. | true | \ No newline at end of file diff --git a/docs/models/createinvitationpublicmetadata.md b/docs/models/createinvitationpublicmetadata.md new file mode 100644 index 0000000..0ae2ee3 --- /dev/null +++ b/docs/models/createinvitationpublicmetadata.md @@ -0,0 +1,11 @@ +# CreateInvitationPublicMetadata + +Metadata that will be attached to the newly created invitation. +The value of this property should be a well-formed JSON object. +Once the user accepts the invitation and signs up, these metadata will end up in the user's public metadata. + + +## Fields + +| Field | Type | Required | Description | +| ----------- | ----------- | ----------- | ----------- | \ No newline at end of file diff --git a/docs/models/createinvitationrequestbody.md b/docs/models/createinvitationrequestbody.md new file mode 100644 index 0000000..a7f14be --- /dev/null +++ b/docs/models/createinvitationrequestbody.md @@ -0,0 +1,14 @@ +# CreateInvitationRequestBody + +Required parameters + + +## Fields + +| Field | Type | Required | Description | Example | +| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `email_address` | *str* | :heavy_check_mark: | The email address the invitation will be sent to | user@example.com | +| `public_metadata` | [Optional[models.CreateInvitationPublicMetadata]](../models/createinvitationpublicmetadata.md) | :heavy_minus_sign: | Metadata that will be attached to the newly created invitation.
The value of this property should be a well-formed JSON object.
Once the user accepts the invitation and signs up, these metadata will end up in the user's public metadata. | {} | +| `redirect_url` | *Optional[str]* | :heavy_minus_sign: | Optional URL which specifies where to redirect the user once they click the invitation link.
This is only required if you have implemented a [custom flow](https://clerk.com/docs/authentication/invitations#custom-flow) and you're not using Clerk Hosted Pages or Clerk Components. | https://example.com/welcome | +| `notify` | *Optional[Nullable[bool]]* | :heavy_minus_sign: | Optional flag which denotes whether an email invitation should be sent to the given email address.
Defaults to true. | true | +| `ignore_existing` | *Optional[Nullable[bool]]* | :heavy_minus_sign: | Whether an invitation should be created if there is already an existing invitation for this email address, or it's claimed by another user. | ​false | \ No newline at end of file diff --git a/docs/models/createjwttemplateclaims.md b/docs/models/createjwttemplateclaims.md new file mode 100644 index 0000000..c9d98ad --- /dev/null +++ b/docs/models/createjwttemplateclaims.md @@ -0,0 +1,9 @@ +# CreateJWTTemplateClaims + +JWT template claims in JSON format + + +## Fields + +| Field | Type | Required | Description | +| ----------- | ----------- | ----------- | ----------- | \ No newline at end of file diff --git a/docs/models/createjwttemplaterequestbody.md b/docs/models/createjwttemplaterequestbody.md new file mode 100644 index 0000000..ff00750 --- /dev/null +++ b/docs/models/createjwttemplaterequestbody.md @@ -0,0 +1,14 @@ +# CreateJWTTemplateRequestBody + + +## Fields + +| Field | Type | Required | Description | Example | +| -------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | +| `name` | *Optional[str]* | :heavy_minus_sign: | JWT template name | Example Template | +| `claims` | [Optional[models.CreateJWTTemplateClaims]](../models/createjwttemplateclaims.md) | :heavy_minus_sign: | JWT template claims in JSON format | {} | +| `lifetime` | *Optional[Nullable[float]]* | :heavy_minus_sign: | JWT token lifetime | 3600 | +| `allowed_clock_skew` | *Optional[Nullable[float]]* | :heavy_minus_sign: | JWT token allowed clock skew | 5 | +| `custom_signing_key` | *Optional[bool]* | :heavy_minus_sign: | Whether a custom signing key/algorithm is also provided for this template | false | +| `signing_algorithm` | *Optional[Nullable[str]]* | :heavy_minus_sign: | The custom signing algorithm to use when minting JWTs | RS256 | +| `signing_key` | *Optional[Nullable[str]]* | :heavy_minus_sign: | The custom signing private key to use when minting JWTs | PRIVATE_KEY_PLACEHOLDER | \ No newline at end of file diff --git a/docs/models/createoauthapplicationrequestbody.md b/docs/models/createoauthapplicationrequestbody.md new file mode 100644 index 0000000..6a5791a --- /dev/null +++ b/docs/models/createoauthapplicationrequestbody.md @@ -0,0 +1,11 @@ +# CreateOAuthApplicationRequestBody + + +## Fields + +| Field | Type | Required | Description | Example | +| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `name` | *str* | :heavy_check_mark: | The name of the new OAuth application | Example App | +| `callback_url` | *str* | :heavy_check_mark: | The callback URL of the new OAuth application | https://example.com/oauth/callback | +| `scopes` | *Optional[str]* | :heavy_minus_sign: | Define the allowed scopes for the new OAuth applications that dictate the user payload of the OAuth user info endpoint. Available scopes are `profile`, `email`, `public_metadata`, `private_metadata`. Provide the requested scopes as a string, separated by spaces. | profile email public_metadata | +| `public` | *Optional[bool]* | :heavy_minus_sign: | If true, this client is public and cannot securely store a client secret.
Only the authorization code flow with proof key for code exchange (PKCE) may be used.
Public clients cannot be updated to be confidential clients, and vice versa. | true | \ No newline at end of file diff --git a/docs/models/createorganizationinvitationbulkprivatemetadata.md b/docs/models/createorganizationinvitationbulkprivatemetadata.md new file mode 100644 index 0000000..36a117b --- /dev/null +++ b/docs/models/createorganizationinvitationbulkprivatemetadata.md @@ -0,0 +1,9 @@ +# CreateOrganizationInvitationBulkPrivateMetadata + +Metadata saved on the organization invitation, fully accessible (read/write) from the Backend API but not visible from the Frontend API. + + +## Fields + +| Field | Type | Required | Description | +| ----------- | ----------- | ----------- | ----------- | \ No newline at end of file diff --git a/docs/models/createorganizationinvitationbulkpublicmetadata.md b/docs/models/createorganizationinvitationbulkpublicmetadata.md new file mode 100644 index 0000000..6b0de6e --- /dev/null +++ b/docs/models/createorganizationinvitationbulkpublicmetadata.md @@ -0,0 +1,9 @@ +# CreateOrganizationInvitationBulkPublicMetadata + +Metadata saved on the organization invitation, read-only from the Frontend API and fully accessible (read/write) from the Backend API. + + +## Fields + +| Field | Type | Required | Description | +| ----------- | ----------- | ----------- | ----------- | \ No newline at end of file diff --git a/docs/models/createorganizationinvitationbulkrequest.md b/docs/models/createorganizationinvitationbulkrequest.md new file mode 100644 index 0000000..763c6fe --- /dev/null +++ b/docs/models/createorganizationinvitationbulkrequest.md @@ -0,0 +1,9 @@ +# CreateOrganizationInvitationBulkRequest + + +## Fields + +| Field | Type | Required | Description | Example | +| ---------------------------------------------------- | ---------------------------------------------------- | ---------------------------------------------------- | ---------------------------------------------------- | ---------------------------------------------------- | +| `organization_id` | *str* | :heavy_check_mark: | The organization ID. | org_12345 | +| `request_body` | List[[models.RequestBody](../models/requestbody.md)] | :heavy_check_mark: | N/A | | \ No newline at end of file diff --git a/docs/models/createorganizationinvitationprivatemetadata.md b/docs/models/createorganizationinvitationprivatemetadata.md new file mode 100644 index 0000000..cb30466 --- /dev/null +++ b/docs/models/createorganizationinvitationprivatemetadata.md @@ -0,0 +1,9 @@ +# CreateOrganizationInvitationPrivateMetadata + +Metadata saved on the organization invitation, fully accessible (read/write) from the Backend API but not visible from the Frontend API. + + +## Fields + +| Field | Type | Required | Description | +| ----------- | ----------- | ----------- | ----------- | \ No newline at end of file diff --git a/docs/models/createorganizationinvitationpublicmetadata.md b/docs/models/createorganizationinvitationpublicmetadata.md new file mode 100644 index 0000000..59477dd --- /dev/null +++ b/docs/models/createorganizationinvitationpublicmetadata.md @@ -0,0 +1,9 @@ +# CreateOrganizationInvitationPublicMetadata + +Metadata saved on the organization invitation, read-only from the Frontend API and fully accessible (read/write) from the Backend API. + + +## Fields + +| Field | Type | Required | Description | +| ----------- | ----------- | ----------- | ----------- | \ No newline at end of file diff --git a/docs/models/createorganizationinvitationrequest.md b/docs/models/createorganizationinvitationrequest.md new file mode 100644 index 0000000..528a9a1 --- /dev/null +++ b/docs/models/createorganizationinvitationrequest.md @@ -0,0 +1,9 @@ +# CreateOrganizationInvitationRequest + + +## Fields + +| Field | Type | Required | Description | Example | +| ------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------ | +| `organization_id` | *str* | :heavy_check_mark: | The ID of the organization for which to send the invitation | org_12345 | +| `request_body` | [models.CreateOrganizationInvitationRequestBody](../models/createorganizationinvitationrequestbody.md) | :heavy_check_mark: | N/A | | \ No newline at end of file diff --git a/docs/models/createorganizationinvitationrequestbody.md b/docs/models/createorganizationinvitationrequestbody.md new file mode 100644 index 0000000..6497982 --- /dev/null +++ b/docs/models/createorganizationinvitationrequestbody.md @@ -0,0 +1,13 @@ +# CreateOrganizationInvitationRequestBody + + +## Fields + +| Field | Type | Required | Description | Example | +| ---------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | +| `email_address` | *str* | :heavy_check_mark: | The email address of the new member that is going to be invited to the organization | user@example.com | +| `inviter_user_id` | *str* | :heavy_check_mark: | The ID of the user that invites the new member to the organization.
Must be an administrator in the organization. | user_67890 | +| `role` | *str* | :heavy_check_mark: | The role of the new member in the organization | admin | +| `public_metadata` | [Optional[models.CreateOrganizationInvitationPublicMetadata]](../models/createorganizationinvitationpublicmetadata.md) | :heavy_minus_sign: | Metadata saved on the organization invitation, read-only from the Frontend API and fully accessible (read/write) from the Backend API. | {
"key": "value"
} | +| `private_metadata` | [Optional[models.CreateOrganizationInvitationPrivateMetadata]](../models/createorganizationinvitationprivatemetadata.md) | :heavy_minus_sign: | Metadata saved on the organization invitation, fully accessible (read/write) from the Backend API but not visible from the Frontend API. | {
"private_key": "secret_value"
} | +| `redirect_url` | *Optional[str]* | :heavy_minus_sign: | Optional URL that the invitee will be redirected to once they accept the invitation by clicking the join link in the invitation email. | https://example.com/welcome | \ No newline at end of file diff --git a/docs/models/createorganizationmembershiprequest.md b/docs/models/createorganizationmembershiprequest.md new file mode 100644 index 0000000..76ab457 --- /dev/null +++ b/docs/models/createorganizationmembershiprequest.md @@ -0,0 +1,9 @@ +# CreateOrganizationMembershipRequest + + +## Fields + +| Field | Type | Required | Description | Example | +| ------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------ | +| `organization_id` | *str* | :heavy_check_mark: | The ID of the organization where the new membership will be created | org_123 | +| `request_body` | [models.CreateOrganizationMembershipRequestBody](../models/createorganizationmembershiprequestbody.md) | :heavy_check_mark: | N/A | | \ No newline at end of file diff --git a/docs/models/createorganizationmembershiprequestbody.md b/docs/models/createorganizationmembershiprequestbody.md new file mode 100644 index 0000000..2b6fb02 --- /dev/null +++ b/docs/models/createorganizationmembershiprequestbody.md @@ -0,0 +1,9 @@ +# CreateOrganizationMembershipRequestBody + + +## Fields + +| Field | Type | Required | Description | Example | +| ---------------------------------------------------------------------- | ---------------------------------------------------------------------- | ---------------------------------------------------------------------- | ---------------------------------------------------------------------- | ---------------------------------------------------------------------- | +| `user_id` | *str* | :heavy_check_mark: | The ID of the user that will be added as a member in the organization. | user_456 | +| `role` | *str* | :heavy_check_mark: | The role that the new member will have in the organization. | admin | \ No newline at end of file diff --git a/docs/models/createorganizationprivatemetadata.md b/docs/models/createorganizationprivatemetadata.md new file mode 100644 index 0000000..f2f829a --- /dev/null +++ b/docs/models/createorganizationprivatemetadata.md @@ -0,0 +1,9 @@ +# CreateOrganizationPrivateMetadata + +Metadata saved on the organization, accessible only from the Backend API + + +## Fields + +| Field | Type | Required | Description | +| ----------- | ----------- | ----------- | ----------- | \ No newline at end of file diff --git a/docs/models/createorganizationpublicmetadata.md b/docs/models/createorganizationpublicmetadata.md new file mode 100644 index 0000000..b80d04c --- /dev/null +++ b/docs/models/createorganizationpublicmetadata.md @@ -0,0 +1,9 @@ +# CreateOrganizationPublicMetadata + +Metadata saved on the organization, read-only from the Frontend API and fully accessible (read/write) from the Backend API + + +## Fields + +| Field | Type | Required | Description | +| ----------- | ----------- | ----------- | ----------- | \ No newline at end of file diff --git a/docs/models/createorganizationrequestbody.md b/docs/models/createorganizationrequestbody.md new file mode 100644 index 0000000..aabe9f6 --- /dev/null +++ b/docs/models/createorganizationrequestbody.md @@ -0,0 +1,13 @@ +# CreateOrganizationRequestBody + + +## Fields + +| Field | Type | Required | Description | Example | +| -------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- | +| `name` | *str* | :heavy_check_mark: | The name of the new organization | NewOrg | +| `created_by` | *str* | :heavy_check_mark: | The ID of the User who will become the administrator for the new organization | user_123 | +| `private_metadata` | [Optional[models.CreateOrganizationPrivateMetadata]](../models/createorganizationprivatemetadata.md) | :heavy_minus_sign: | Metadata saved on the organization, accessible only from the Backend API | {
"internal_code": "ABC123"
} | +| `public_metadata` | [Optional[models.CreateOrganizationPublicMetadata]](../models/createorganizationpublicmetadata.md) | :heavy_minus_sign: | Metadata saved on the organization, read-only from the Frontend API and fully accessible (read/write) from the Backend API | {
"public_event": "Annual Summit"
} | +| `slug` | *Optional[str]* | :heavy_minus_sign: | A slug for the new organization.
Can contain only lowercase alphanumeric characters and the dash "-".
Must be unique for the instance. | neworg | +| `max_allowed_memberships` | *Optional[int]* | :heavy_minus_sign: | The maximum number of memberships allowed for this organization | 100 | \ No newline at end of file diff --git a/docs/models/createphonenumberrequestbody.md b/docs/models/createphonenumberrequestbody.md new file mode 100644 index 0000000..acf7f0c --- /dev/null +++ b/docs/models/createphonenumberrequestbody.md @@ -0,0 +1,12 @@ +# CreatePhoneNumberRequestBody + + +## Fields + +| Field | Type | Required | Description | Example | +| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `user_id` | *Optional[str]* | :heavy_minus_sign: | The ID representing the user | usr_12345 | +| `phone_number` | *Optional[str]* | :heavy_minus_sign: | The new phone number. Must adhere to the E.164 standard for phone number format. | +11234567890 | +| `verified` | *Optional[Nullable[bool]]* | :heavy_minus_sign: | When created, the phone number will be marked as verified. | true | +| `primary` | *Optional[Nullable[bool]]* | :heavy_minus_sign: | Create this phone number as the primary phone number for the user.
Default: false, unless it is the first phone number. | false | +| `reserved_for_second_factor` | *Optional[Nullable[bool]]* | :heavy_minus_sign: | Create this phone number as reserved for multi-factor authentication.
The phone number must also be verified.
If there are no other reserved second factors, the phone number will be set as the default second factor. | false | \ No newline at end of file diff --git a/docs/models/createredirecturlrequestbody.md b/docs/models/createredirecturlrequestbody.md new file mode 100644 index 0000000..a3069a7 --- /dev/null +++ b/docs/models/createredirecturlrequestbody.md @@ -0,0 +1,8 @@ +# CreateRedirectURLRequestBody + + +## Fields + +| Field | Type | Required | Description | Example | +| ---------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | +| `url` | *Optional[str]* | :heavy_minus_sign: | The full url value prefixed with `https://` or a custom scheme e.g. `"https://my-app.com/oauth-callback"` or `"my-app://oauth-callback"` | https://my-app.com/oauth-callback | \ No newline at end of file diff --git a/docs/models/createsamlconnectionattributemapping.md b/docs/models/createsamlconnectionattributemapping.md new file mode 100644 index 0000000..664b09c --- /dev/null +++ b/docs/models/createsamlconnectionattributemapping.md @@ -0,0 +1,13 @@ +# CreateSAMLConnectionAttributeMapping + +Define the attribute name mapping between Identity Provider and Clerk's user properties + + +## Fields + +| Field | Type | Required | Description | Example | +| ------------------ | ------------------ | ------------------ | ------------------ | ------------------ | +| `user_id` | *Optional[str]* | :heavy_minus_sign: | N/A | nameid | +| `email_address` | *Optional[str]* | :heavy_minus_sign: | N/A | mail | +| `first_name` | *Optional[str]* | :heavy_minus_sign: | N/A | givenName | +| `last_name` | *Optional[str]* | :heavy_minus_sign: | N/A | surname | \ No newline at end of file diff --git a/docs/models/createsamlconnectionrequestbody.md b/docs/models/createsamlconnectionrequestbody.md new file mode 100644 index 0000000..cb5fd7c --- /dev/null +++ b/docs/models/createsamlconnectionrequestbody.md @@ -0,0 +1,16 @@ +# CreateSAMLConnectionRequestBody + + +## Fields + +| Field | Type | Required | Description | Example | +| -------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- | +| `name` | *str* | :heavy_check_mark: | The name to use as a label for this SAML Connection | My SAML Connection | +| `domain` | *str* | :heavy_check_mark: | The domain of your organization. Sign in flows using an email with this domain, will use this SAML Connection. | example.org | +| `provider` | [models.Provider](../models/provider.md) | :heavy_check_mark: | The IdP provider of the connection. | saml_custom | +| `idp_entity_id` | *Optional[Nullable[str]]* | :heavy_minus_sign: | The Entity ID as provided by the IdP | http://idp.example.org/ | +| `idp_sso_url` | *Optional[Nullable[str]]* | :heavy_minus_sign: | The Single-Sign On URL as provided by the IdP | http://idp.example.org/sso | +| `idp_certificate` | *Optional[Nullable[str]]* | :heavy_minus_sign: | The X.509 certificate as provided by the IdP | MIIDdzCCAl+gAwIBAgIJAKcyBaiiz+DT... | +| `idp_metadata_url` | *Optional[Nullable[str]]* | :heavy_minus_sign: | The URL which serves the IdP metadata. If present, it takes priority over the corresponding individual properties | http://idp.example.org/metadata.xml | +| `idp_metadata` | *Optional[Nullable[str]]* | :heavy_minus_sign: | The XML content of the IdP metadata file. If present, it takes priority over the corresponding individual properties | By default, the duration is 30 days. | 2592000 | \ No newline at end of file diff --git a/docs/models/createuserprivatemetadata.md b/docs/models/createuserprivatemetadata.md new file mode 100644 index 0000000..72f62d2 --- /dev/null +++ b/docs/models/createuserprivatemetadata.md @@ -0,0 +1,9 @@ +# CreateUserPrivateMetadata + +Metadata saved on the user, that is only visible to your Backend API + + +## Fields + +| Field | Type | Required | Description | +| ----------- | ----------- | ----------- | ----------- | \ No newline at end of file diff --git a/docs/models/createuserpublicmetadata.md b/docs/models/createuserpublicmetadata.md new file mode 100644 index 0000000..7f94e06 --- /dev/null +++ b/docs/models/createuserpublicmetadata.md @@ -0,0 +1,9 @@ +# CreateUserPublicMetadata + +Metadata saved on the user, that is visible to both your Frontend and Backend APIs + + +## Fields + +| Field | Type | Required | Description | +| ----------- | ----------- | ----------- | ----------- | \ No newline at end of file diff --git a/docs/models/createuserrequestbody.md b/docs/models/createuserrequestbody.md new file mode 100644 index 0000000..3049056 --- /dev/null +++ b/docs/models/createuserrequestbody.md @@ -0,0 +1,25 @@ +# CreateUserRequestBody + + +## Fields + +| Field | Type | Required | Description | Example | +| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `external_id` | *Optional[Nullable[str]]* | :heavy_minus_sign: | The ID of the user as used in your external systems or your previous authentication solution.
Must be unique across your instance. | ext-id-001 | +| `first_name` | *Optional[Nullable[str]]* | :heavy_minus_sign: | The first name to assign to the user | John | +| `last_name` | *Optional[Nullable[str]]* | :heavy_minus_sign: | The last name to assign to the user | Doe | +| `email_address` | List[*str*] | :heavy_minus_sign: | Email addresses to add to the user.
Must be unique across your instance.
The first email address will be set as the user's primary email address. | | +| `phone_number` | List[*str*] | :heavy_minus_sign: | Phone numbers to add to the user.
Must be unique across your instance.
The first phone number will be set as the user's primary phone number. | | +| `web3_wallet` | List[*str*] | :heavy_minus_sign: | Web3 wallets to add to the user.
Must be unique across your instance.
The first wallet will be set as the user's primary wallet. | | +| `username` | *Optional[Nullable[str]]* | :heavy_minus_sign: | The username to give to the user.
It must be unique across your instance. | johndoe123 | +| `password` | *Optional[Nullable[str]]* | :heavy_minus_sign: | The plaintext password to give the user.
Must be at least 8 characters long, and can not be in any list of hacked passwords. | Secure*Pass4 | +| `password_digest` | *Optional[str]* | :heavy_minus_sign: | In case you already have the password digests and not the passwords, you can use them for the newly created user via this property.
The digests should be generated with one of the supported algorithms.
The hashing algorithm can be specified using the `password_hasher` property. | $argon2i$v=19$m=4096,t=3,p=1$4t6CL3P7YiHBtwESXawI8Hm20zJj4cs7/4/G3c187e0$m7RQFczcKr5bIR0IIxbpO2P0tyrLjf3eUW3M3QSwnLc | +| `password_hasher` | [Optional[models.PasswordHasher]](../models/passwordhasher.md) | :heavy_minus_sign: | The hashing algorithm that was used to generate the password digest.
The algorithms we support at the moment are [bcrypt](https://en.wikipedia.org/wiki/Bcrypt), [bcrypt_sha256_django](https://docs.djangoproject.com/en/4.0/topics/auth/passwords/),
[md5](https://en.wikipedia.org/wiki/MD5), pbkdf2_sha256, pbkdf2_sha512, [pbkdf2_sha256_django](https://docs.djangoproject.com/en/4.0/topics/auth/passwords/),
[phpass](https://www.openwall.com/phpass/), [scrypt_firebase](https://firebaseopensource.com/projects/firebase/scrypt/),
[scrypt_werkzeug](https://werkzeug.palletsprojects.com/en/3.0.x/utils/#werkzeug.security.generate_password_hash), [sha256](https://en.wikipedia.org/wiki/SHA-2)
and the [argon2](https://argon2.online/) variants argon2i and argon2id.

If you need support for any particular hashing algorithm, [please let us know](https://clerk.com/support).

Note: for password hashers considered insecure (at this moment MD5 and SHA256), the corresponding user password hashes will be transparently migrated to Bcrypt (a secure hasher) upon the user's first successful password sign in.
Insecure schemes are marked with `(insecure)` in the list below.

Each of the supported hashers expects the incoming digest to be in a particular format. Specifically:

**bcrypt:** The digest should be of the following form:

`$$$`

**bcrypt_sha256_django:** This is the Django-specific variant of Bcrypt, using SHA256 hashing function. The format should be as follows (as exported from Django):

`bcrypt_sha256$$$$`

**md5** (insecure): The digest should follow the regular form e.g.:

`5f4dcc3b5aa765d61d8327deb882cf99`

**pbkdf2_sha256:** This is the PBKDF2 algorithm using the SHA256 hashing function. The format should be as follows:

`pbkdf2_sha256$$$`

Note: Both the salt and the hash are expected to be base64-encoded.

**pbkdf2_sha512:** This is the PBKDF2 algorithm using the SHA512 hashing function. The format should be as follows:

`pbkdf2_sha512$$$`

_iterations:_ The number of iterations used. Must be an integer less than 420000.
_salt:_ The salt used when generating the hash. Must be less than 1024 bytes.
_hash:_ The hex-encoded hash. Must have been generated with a key length less than 1024 bytes.

**pbkdf2_sha256_django:** This is the Django-specific variant of PBKDF2 and the digest should have the following format (as exported from Django):

`pbkdf2_sha256$$$`

Note: The salt is expected to be un-encoded, the hash is expected base64-encoded.

**pbkdf2_sha1:** This is similar to pkbdf2_sha256_django, but with two differences:
1. uses sha1 instead of sha256
2. accepts the hash as a hex-encoded string

The format is the following:

`pbkdf2_sha1$$$`

**phpass:** Portable public domain password hashing framework for use in PHP applications. Digests hashed with phpass have the following sections:

The format is the following:

`$P$`

- $P$ is the prefix used to identify phpass hashes.
- rounds is a single character encoding a 6-bit integer representing the number of rounds used.
- salt is eight characters drawn from [./0-9A-Za-z], providing a 48-bit salt.
- checksum is 22 characters drawn from the same set, encoding the 128-bit checksum with MD5.

**scrypt_firebase:** The Firebase-specific variant of scrypt.
The value is expected to have 6 segments separated by the $ character and include the following information:

_hash:_ The actual Base64 hash. This can be retrieved when exporting the user from Firebase.
_salt:_ The salt used to generate the above hash. Again, this is given when exporting the user.
_signer key:_ The base64 encoded signer key.
_salt separator:_ The base64 encoded salt separator.
_rounds:_ The number of rounds the algorithm needs to run.
_memory cost:_ The cost of the algorithm run

The first 2 (hash and salt) are per user and can be retrieved when exporting the user from Firebase.
The other 4 values (signer key, salt separator, rounds and memory cost) are project-wide settings and can be retrieved from the project's password hash parameters.

Once you have all these, you can combine it in the following format and send this as the digest in order for Clerk to accept it:

`$$$$$`

**scrypt_werkzeug:** The Werkzeug-specific variant of scrypt.

The value is expected to have 3 segments separated by the $ character and include the following information:

_algorithm args:_ The algorithm used to generate the hash.
_salt:_ The salt used to generate the above hash.
_hash:_ The actual Base64 hash.

The algorithm args are the parameters used to generate the hash and are included in the digest.

**argon2i:** Algorithms in the argon2 family generate digests that encode the following information:

_version (v):_ The argon version, version 19 is assumed
_memory (m):_ The memory used by the algorithm (in kibibytes)
_iterations (t):_ The number of iterations to perform
_parallelism (p):_ The number of threads to use

Parts are demarcated by the `$` character, with the first part identifying the algorithm variant.
The middle part is a comma-separated list of the encoding options (memory, iterations, parallelism).
The final part is the actual digest.

`$argon2i$v=19$m=4096,t=3,p=1$4t6CL3P7YiHBtwESXawI8Hm20zJj4cs7/4/G3c187e0$m7RQFczcKr5bIR0IIxbpO2P0tyrLjf3eUW3M3QSwnLc`

**argon2id:** See the previous algorithm for an explanation of the formatting.

For the argon2id case, the value of the algorithm in the first part of the digest is `argon2id`:

`$argon2id$v=19$m=64,t=4,p=8$Z2liZXJyaXNo$iGXEpMBTDYQ8G/71tF0qGjxRHEmR3gpGULcE93zUJVU`

**sha256** (insecure): The digest should be a 64-length hex string, e.g.:

`9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08`

**sha256_salted** (insecure): The digest should be a 64-length hex string with a salt.

The format is the following:
`$`

The value is expected to have 2 segments separated by the $ character and include the following information:
_hash:_ The sha256 hash, a 64-length hex string.
_salt:_ The salt used to generate the above hash. Must be between 1 and 1024 bits. | argon2i | +| `skip_password_checks` | *Optional[bool]* | :heavy_minus_sign: | When set to `true` all password checks are skipped.
It is recommended to use this method only when migrating plaintext passwords to Clerk.
Upon migration the user base should be prompted to pick stronger password. | false | +| `skip_password_requirement` | *Optional[bool]* | :heavy_minus_sign: | When set to `true`, `password` is not required anymore when creating the user and can be omitted.
This is useful when you are trying to create a user that doesn't have a password, in an instance that is using passwords.
Please note that you cannot use this flag if password is the only way for a user to sign into your instance. | false | +| `totp_secret` | *Optional[str]* | :heavy_minus_sign: | In case TOTP is configured on the instance, you can provide the secret to enable it on the newly created user without the need to reset it.
Please note that currently the supported options are:
* Period: 30 seconds
* Code length: 6 digits
* Algorithm: SHA1 | base32totpsecretkey | +| `backup_codes` | List[*str*] | :heavy_minus_sign: | If Backup Codes are configured on the instance, you can provide them to enable it on the newly created user without the need to reset them.
You must provide the backup codes in plain format or the corresponding bcrypt digest. | [
"123456",
"654321"
] | +| `public_metadata` | [Optional[models.CreateUserPublicMetadata]](../models/createuserpublicmetadata.md) | :heavy_minus_sign: | Metadata saved on the user, that is visible to both your Frontend and Backend APIs | {
"role": "user"
} | +| `private_metadata` | [Optional[models.CreateUserPrivateMetadata]](../models/createuserprivatemetadata.md) | :heavy_minus_sign: | Metadata saved on the user, that is only visible to your Backend API | {
"internal_id": "789"
} | +| `unsafe_metadata` | [Optional[models.CreateUserUnsafeMetadata]](../models/createuserunsafemetadata.md) | :heavy_minus_sign: | Metadata saved on the user, that can be updated from both the Frontend and Backend APIs.
Note: Since this data can be modified from the frontend, it is not guaranteed to be safe. | {
"preferences": {
"theme": "dark"
}
} | +| `created_at` | *Optional[str]* | :heavy_minus_sign: | A custom date/time denoting _when_ the user signed up to the application, specified in RFC3339 format (e.g. `2012-10-20T07:15:20.902Z`). | 2023-03-15T07:15:20.902Z | \ No newline at end of file diff --git a/docs/models/createuserunsafemetadata.md b/docs/models/createuserunsafemetadata.md new file mode 100644 index 0000000..9513e30 --- /dev/null +++ b/docs/models/createuserunsafemetadata.md @@ -0,0 +1,10 @@ +# CreateUserUnsafeMetadata + +Metadata saved on the user, that can be updated from both the Frontend and Backend APIs. +Note: Since this data can be modified from the frontend, it is not guaranteed to be safe. + + +## Fields + +| Field | Type | Required | Description | +| ----------- | ----------- | ----------- | ----------- | \ No newline at end of file diff --git a/docs/models/deleteallowlistidentifierrequest.md b/docs/models/deleteallowlistidentifierrequest.md new file mode 100644 index 0000000..ae57c92 --- /dev/null +++ b/docs/models/deleteallowlistidentifierrequest.md @@ -0,0 +1,8 @@ +# DeleteAllowlistIdentifierRequest + + +## Fields + +| Field | Type | Required | Description | Example | +| ------------------------------------------------------ | ------------------------------------------------------ | ------------------------------------------------------ | ------------------------------------------------------ | ------------------------------------------------------ | +| `identifier_id` | *str* | :heavy_check_mark: | The ID of the identifier to delete from the allow-list | example_identifier_id | \ No newline at end of file diff --git a/docs/models/deleteblocklistidentifierrequest.md b/docs/models/deleteblocklistidentifierrequest.md new file mode 100644 index 0000000..436cc0c --- /dev/null +++ b/docs/models/deleteblocklistidentifierrequest.md @@ -0,0 +1,8 @@ +# DeleteBlocklistIdentifierRequest + + +## Fields + +| Field | Type | Required | Description | Example | +| ------------------------------------------------------ | ------------------------------------------------------ | ------------------------------------------------------ | ------------------------------------------------------ | ------------------------------------------------------ | +| `identifier_id` | *str* | :heavy_check_mark: | The ID of the identifier to delete from the block-list | identifier123 | \ No newline at end of file diff --git a/docs/models/deletedobject.md b/docs/models/deletedobject.md new file mode 100644 index 0000000..26a0f98 --- /dev/null +++ b/docs/models/deletedobject.md @@ -0,0 +1,11 @@ +# DeletedObject + + +## Fields + +| Field | Type | Required | Description | Example | +| ------------------------- | ------------------------- | ------------------------- | ------------------------- | ------------------------- | +| `object` | *str* | :heavy_check_mark: | N/A | deleted_object | +| `deleted` | *bool* | :heavy_check_mark: | N/A | true | +| `id` | *Optional[str]* | :heavy_minus_sign: | N/A | deleted_object_id_example | +| `slug` | *Optional[str]* | :heavy_minus_sign: | N/A | deleted-object-slug | \ No newline at end of file diff --git a/docs/models/deletedomainrequest.md b/docs/models/deletedomainrequest.md new file mode 100644 index 0000000..a0fe096 --- /dev/null +++ b/docs/models/deletedomainrequest.md @@ -0,0 +1,8 @@ +# DeleteDomainRequest + + +## Fields + +| Field | Type | Required | Description | Example | +| ---------------------------------------------------------------------- | ---------------------------------------------------------------------- | ---------------------------------------------------------------------- | ---------------------------------------------------------------------- | ---------------------------------------------------------------------- | +| `domain_id` | *str* | :heavy_check_mark: | The ID of the domain that will be deleted. Must be a satellite domain. | domain_12345 | \ No newline at end of file diff --git a/docs/models/deleteemailaddressrequest.md b/docs/models/deleteemailaddressrequest.md new file mode 100644 index 0000000..0e5e103 --- /dev/null +++ b/docs/models/deleteemailaddressrequest.md @@ -0,0 +1,8 @@ +# DeleteEmailAddressRequest + + +## Fields + +| Field | Type | Required | Description | Example | +| ------------------------------------- | ------------------------------------- | ------------------------------------- | ------------------------------------- | ------------------------------------- | +| `email_address_id` | *str* | :heavy_check_mark: | The ID of the email address to delete | email_address_id_example | \ No newline at end of file diff --git a/docs/models/deletejwttemplaterequest.md b/docs/models/deletejwttemplaterequest.md new file mode 100644 index 0000000..2e9fd1a --- /dev/null +++ b/docs/models/deletejwttemplaterequest.md @@ -0,0 +1,8 @@ +# DeleteJWTTemplateRequest + + +## Fields + +| Field | Type | Required | Description | +| ------------------ | ------------------ | ------------------ | ------------------ | +| `template_id` | *str* | :heavy_check_mark: | JWT Template ID | \ No newline at end of file diff --git a/docs/models/deleteoauthapplicationrequest.md b/docs/models/deleteoauthapplicationrequest.md new file mode 100644 index 0000000..eddaa38 --- /dev/null +++ b/docs/models/deleteoauthapplicationrequest.md @@ -0,0 +1,8 @@ +# DeleteOAuthApplicationRequest + + +## Fields + +| Field | Type | Required | Description | Example | +| ----------------------------------------- | ----------------------------------------- | ----------------------------------------- | ----------------------------------------- | ----------------------------------------- | +| `oauth_application_id` | *str* | :heavy_check_mark: | The ID of the OAuth application to delete | oauth_app_09876 | \ No newline at end of file diff --git a/docs/models/deleteorganizationlogorequest.md b/docs/models/deleteorganizationlogorequest.md new file mode 100644 index 0000000..0b0019a --- /dev/null +++ b/docs/models/deleteorganizationlogorequest.md @@ -0,0 +1,8 @@ +# DeleteOrganizationLogoRequest + + +## Fields + +| Field | Type | Required | Description | Example | +| -------------------------------------------------------------- | -------------------------------------------------------------- | -------------------------------------------------------------- | -------------------------------------------------------------- | -------------------------------------------------------------- | +| `organization_id` | *str* | :heavy_check_mark: | The ID of the organization for which the logo will be deleted. | org_12345 | \ No newline at end of file diff --git a/docs/models/deleteorganizationmembershiprequest.md b/docs/models/deleteorganizationmembershiprequest.md new file mode 100644 index 0000000..f31344c --- /dev/null +++ b/docs/models/deleteorganizationmembershiprequest.md @@ -0,0 +1,9 @@ +# DeleteOrganizationMembershipRequest + + +## Fields + +| Field | Type | Required | Description | Example | +| ---------------------------------------------------- | ---------------------------------------------------- | ---------------------------------------------------- | ---------------------------------------------------- | ---------------------------------------------------- | +| `organization_id` | *str* | :heavy_check_mark: | The ID of the organization the membership belongs to | org_12345 | +| `user_id` | *str* | :heavy_check_mark: | The ID of the user that this membership belongs to | user_67890 | \ No newline at end of file diff --git a/docs/models/deleteorganizationrequest.md b/docs/models/deleteorganizationrequest.md new file mode 100644 index 0000000..4ac7c35 --- /dev/null +++ b/docs/models/deleteorganizationrequest.md @@ -0,0 +1,8 @@ +# DeleteOrganizationRequest + + +## Fields + +| Field | Type | Required | Description | Example | +| ------------------------------------ | ------------------------------------ | ------------------------------------ | ------------------------------------ | ------------------------------------ | +| `organization_id` | *str* | :heavy_check_mark: | The ID of the organization to delete | org_321_delete | \ No newline at end of file diff --git a/docs/models/deletephonenumberrequest.md b/docs/models/deletephonenumberrequest.md new file mode 100644 index 0000000..f4c5e2a --- /dev/null +++ b/docs/models/deletephonenumberrequest.md @@ -0,0 +1,8 @@ +# DeletePhoneNumberRequest + + +## Fields + +| Field | Type | Required | Description | Example | +| ------------------------------------ | ------------------------------------ | ------------------------------------ | ------------------------------------ | ------------------------------------ | +| `phone_number_id` | *str* | :heavy_check_mark: | The ID of the phone number to delete | phone_12345 | \ No newline at end of file diff --git a/docs/models/deleteredirecturlrequest.md b/docs/models/deleteredirecturlrequest.md new file mode 100644 index 0000000..21b1a08 --- /dev/null +++ b/docs/models/deleteredirecturlrequest.md @@ -0,0 +1,8 @@ +# DeleteRedirectURLRequest + + +## Fields + +| Field | Type | Required | Description | Example | +| -------------------------------- | -------------------------------- | -------------------------------- | -------------------------------- | -------------------------------- | +| `id` | *str* | :heavy_check_mark: | The ID of the redirect URL | redir_01FG4K9G5NWSQ4ZPT4TQE4Z7G3 | \ No newline at end of file diff --git a/docs/models/deletesamlconnectionrequest.md b/docs/models/deletesamlconnectionrequest.md new file mode 100644 index 0000000..ef4a7a8 --- /dev/null +++ b/docs/models/deletesamlconnectionrequest.md @@ -0,0 +1,8 @@ +# DeleteSAMLConnectionRequest + + +## Fields + +| Field | Type | Required | Description | Example | +| --------------------------------------- | --------------------------------------- | --------------------------------------- | --------------------------------------- | --------------------------------------- | +| `saml_connection_id` | *str* | :heavy_check_mark: | The ID of the SAML Connection to delete | saml_conn_123_delete | \ No newline at end of file diff --git a/docs/models/deleteuserprofileimagerequest.md b/docs/models/deleteuserprofileimagerequest.md new file mode 100644 index 0000000..6a0d7f4 --- /dev/null +++ b/docs/models/deleteuserprofileimagerequest.md @@ -0,0 +1,8 @@ +# DeleteUserProfileImageRequest + + +## Fields + +| Field | Type | Required | Description | Example | +| -------------------------------------------------- | -------------------------------------------------- | -------------------------------------------------- | -------------------------------------------------- | -------------------------------------------------- | +| `user_id` | *str* | :heavy_check_mark: | The ID of the user to delete the profile image for | usr_test123 | \ No newline at end of file diff --git a/docs/models/deleteuserrequest.md b/docs/models/deleteuserrequest.md new file mode 100644 index 0000000..09c5f87 --- /dev/null +++ b/docs/models/deleteuserrequest.md @@ -0,0 +1,8 @@ +# DeleteUserRequest + + +## Fields + +| Field | Type | Required | Description | Example | +| ---------------------------- | ---------------------------- | ---------------------------- | ---------------------------- | ---------------------------- | +| `user_id` | *str* | :heavy_check_mark: | The ID of the user to delete | usr_1 | \ No newline at end of file diff --git a/docs/models/disablemfarequest.md b/docs/models/disablemfarequest.md new file mode 100644 index 0000000..3e7002c --- /dev/null +++ b/docs/models/disablemfarequest.md @@ -0,0 +1,8 @@ +# DisableMFARequest + + +## Fields + +| Field | Type | Required | Description | Example | +| ------------------------------------------------------- | ------------------------------------------------------- | ------------------------------------------------------- | ------------------------------------------------------- | ------------------------------------------------------- | +| `user_id` | *str* | :heavy_check_mark: | The ID of the user whose MFA methods are to be disabled | user_123456 | \ No newline at end of file diff --git a/docs/models/disablemfaresponsebody.md b/docs/models/disablemfaresponsebody.md new file mode 100644 index 0000000..1c48f5d --- /dev/null +++ b/docs/models/disablemfaresponsebody.md @@ -0,0 +1,10 @@ +# DisableMFAResponseBody + +Successful operation. + + +## Fields + +| Field | Type | Required | Description | Example | +| ------------------ | ------------------ | ------------------ | ------------------ | ------------------ | +| `user_id` | *Optional[str]* | :heavy_minus_sign: | N/A | user_123456 | \ No newline at end of file diff --git a/docs/models/domain.md b/docs/models/domain.md new file mode 100644 index 0000000..6e90d3f --- /dev/null +++ b/docs/models/domain.md @@ -0,0 +1,16 @@ +# Domain + + +## Fields + +| Field | Type | Required | Description | Example | +| --------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------- | +| `object` | [models.DomainObject](../models/domainobject.md) | :heavy_check_mark: | N/A | domain | +| `id` | *str* | :heavy_check_mark: | N/A | domain_id | +| `name` | *str* | :heavy_check_mark: | N/A | example.com | +| `is_satellite` | *bool* | :heavy_check_mark: | N/A | false | +| `frontend_api_url` | *str* | :heavy_check_mark: | N/A | https://frontend.example.com | +| `development_origin` | *str* | :heavy_check_mark: | N/A | http://localhost:3000 | +| `accounts_portal_url` | *Optional[Nullable[str]]* | :heavy_minus_sign: | Null for satellite domains.
| | +| `proxy_url` | *Optional[Nullable[str]]* | :heavy_minus_sign: | N/A | | +| `cname_targets` | List[[models.CNameTarget](../models/cnametarget.md)] | :heavy_minus_sign: | N/A | [
{
"host": "example-host.clerk.com",
"value": "example-value.clerk.services",
"required": true
}
] | \ No newline at end of file diff --git a/docs/models/domainobject.md b/docs/models/domainobject.md new file mode 100644 index 0000000..893b03e --- /dev/null +++ b/docs/models/domainobject.md @@ -0,0 +1,8 @@ +# DomainObject + + +## Values + +| Name | Value | +| -------- | -------- | +| `DOMAIN` | domain | \ No newline at end of file diff --git a/docs/models/domains.md b/docs/models/domains.md new file mode 100644 index 0000000..845c4ba --- /dev/null +++ b/docs/models/domains.md @@ -0,0 +1,9 @@ +# Domains + + +## Fields + +| Field | Type | Required | Description | Example | +| ------------------------------------------ | ------------------------------------------ | ------------------------------------------ | ------------------------------------------ | ------------------------------------------ | +| `data` | List[[models.Domain](../models/domain.md)] | :heavy_check_mark: | N/A | | +| `total_count` | *int* | :heavy_check_mark: | Total number of domains
| 1 | \ No newline at end of file diff --git a/docs/models/domainsenrollmentmodes.md b/docs/models/domainsenrollmentmodes.md new file mode 100644 index 0000000..5af92ef --- /dev/null +++ b/docs/models/domainsenrollmentmodes.md @@ -0,0 +1,10 @@ +# DomainsEnrollmentModes + + +## Values + +| Name | Value | +| ---------------------- | ---------------------- | +| `MANUAL_INVITATION` | manual_invitation | +| `AUTOMATIC_INVITATION` | automatic_invitation | +| `AUTOMATIC_SUGGESTION` | automatic_suggestion | \ No newline at end of file diff --git a/docs/models/emailaddress.md b/docs/models/emailaddress.md new file mode 100644 index 0000000..f555ce3 --- /dev/null +++ b/docs/models/emailaddress.md @@ -0,0 +1,15 @@ +# EmailAddress + + +## Fields + +| Field | Type | Required | Description | Example | +| -------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | +| `object` | [models.EmailAddressObject](../models/emailaddressobject.md) | :heavy_check_mark: | String representing the object's type. Objects of the same type share the same value.
| email_address | +| `email_address` | *str* | :heavy_check_mark: | N/A | example@clerk.com | +| `reserved` | *bool* | :heavy_check_mark: | N/A | false | +| `verification` | [Nullable[models.Verification]](../models/verification.md) | :heavy_check_mark: | N/A | {
"status": "verified",
"strategy": "admin"
} | +| `linked_to` | List[[models.IdentificationLink](../models/identificationlink.md)] | :heavy_check_mark: | N/A | [
{
"type": "oauth_google",
"id": "link_12345"
}
] | +| `created_at` | *int* | :heavy_check_mark: | Unix timestamp of creation
| 1615458901 | +| `updated_at` | *int* | :heavy_check_mark: | Unix timestamp of creation
| 1615459001 | +| `id` | *Optional[str]* | :heavy_minus_sign: | N/A | email_id_56789 | \ No newline at end of file diff --git a/docs/models/emailaddressobject.md b/docs/models/emailaddressobject.md new file mode 100644 index 0000000..d04e242 --- /dev/null +++ b/docs/models/emailaddressobject.md @@ -0,0 +1,11 @@ +# EmailAddressObject + +String representing the object's type. Objects of the same type share the same value. + + + +## Values + +| Name | Value | +| --------------- | --------------- | +| `EMAIL_ADDRESS` | email_address | \ No newline at end of file diff --git a/docs/models/error.md b/docs/models/error.md new file mode 100644 index 0000000..426585b --- /dev/null +++ b/docs/models/error.md @@ -0,0 +1,11 @@ +# Error + + +## Supported Types + +### `models.ErrorClerkError` + +```python +value: models.ErrorClerkError = /* values here */ +``` + diff --git a/docs/models/errorclerkerror.md b/docs/models/errorclerkerror.md new file mode 100644 index 0000000..6c451ee --- /dev/null +++ b/docs/models/errorclerkerror.md @@ -0,0 +1,12 @@ +# ErrorClerkError + + +## Fields + +| Field | Type | Required | Description | Example | +| ---------------------------------------------------- | ---------------------------------------------------- | ---------------------------------------------------- | ---------------------------------------------------- | ---------------------------------------------------- | +| `message` | *str* | :heavy_check_mark: | N/A | Invalid input | +| `long_message` | *str* | :heavy_check_mark: | N/A | The input provided does not meet the requirements. | +| `code` | *str* | :heavy_check_mark: | N/A | 400_bad_request | +| `meta` | [Optional[models.ErrorMeta]](../models/errormeta.md) | :heavy_minus_sign: | N/A | {} | +| `clerk_trace_id` | *Optional[str]* | :heavy_minus_sign: | N/A | trace_123456789abcd | \ No newline at end of file diff --git a/docs/models/errormeta.md b/docs/models/errormeta.md new file mode 100644 index 0000000..e498afa --- /dev/null +++ b/docs/models/errormeta.md @@ -0,0 +1,7 @@ +# ErrorMeta + + +## Fields + +| Field | Type | Required | Description | +| ----------- | ----------- | ----------- | ----------- | \ No newline at end of file diff --git a/docs/models/externalaccount.md b/docs/models/externalaccount.md new file mode 100644 index 0000000..2d331fb --- /dev/null +++ b/docs/models/externalaccount.md @@ -0,0 +1,7 @@ +# ExternalAccount + + +## Fields + +| Field | Type | Required | Description | +| ----------- | ----------- | ----------- | ----------- | \ No newline at end of file diff --git a/docs/models/externalaccounts.md b/docs/models/externalaccounts.md new file mode 100644 index 0000000..7bbc958 --- /dev/null +++ b/docs/models/externalaccounts.md @@ -0,0 +1,7 @@ +# ExternalAccounts + + +## Fields + +| Field | Type | Required | Description | +| ----------- | ----------- | ----------- | ----------- | \ No newline at end of file diff --git a/docs/models/file.md b/docs/models/file.md new file mode 100644 index 0000000..37cc418 --- /dev/null +++ b/docs/models/file.md @@ -0,0 +1,10 @@ +# File + + +## Fields + +| Field | Type | Required | Description | +| -------------------------------------------- | -------------------------------------------- | -------------------------------------------- | -------------------------------------------- | +| `file_name` | *str* | :heavy_check_mark: | N/A | +| `content` | *Union[bytes, IO[bytes], io.BufferedReader]* | :heavy_check_mark: | N/A | +| `content_type` | *Optional[str]* | :heavy_minus_sign: | N/A | \ No newline at end of file diff --git a/docs/models/getclientlistrequest.md b/docs/models/getclientlistrequest.md new file mode 100644 index 0000000..dd3b622 --- /dev/null +++ b/docs/models/getclientlistrequest.md @@ -0,0 +1,9 @@ +# GetClientListRequest + + +## Fields + +| Field | Type | Required | Description | Example | +| ----------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | +| `limit` | *Optional[float]* | :heavy_minus_sign: | Applies a limit to the number of results returned.
Can be used for paginating the results together with `offset`. | 20 | +| `offset` | *Optional[float]* | :heavy_minus_sign: | Skip the first `offset` results when paginating.
Needs to be an integer greater or equal to zero.
To be used in conjunction with `limit`. | 10 | \ No newline at end of file diff --git a/docs/models/getclientlistresponse.md b/docs/models/getclientlistresponse.md new file mode 100644 index 0000000..835d685 --- /dev/null +++ b/docs/models/getclientlistresponse.md @@ -0,0 +1,8 @@ +# GetClientListResponse + + +## Fields + +| Field | Type | Required | Description | +| ------------------------------------------ | ------------------------------------------ | ------------------------------------------ | ------------------------------------------ | +| `result` | List[[models.Client](../models/client.md)] | :heavy_check_mark: | N/A | \ No newline at end of file diff --git a/docs/models/getclientrequest.md b/docs/models/getclientrequest.md new file mode 100644 index 0000000..bf9d460 --- /dev/null +++ b/docs/models/getclientrequest.md @@ -0,0 +1,8 @@ +# GetClientRequest + + +## Fields + +| Field | Type | Required | Description | Example | +| ------------------ | ------------------ | ------------------ | ------------------ | ------------------ | +| `client_id` | *str* | :heavy_check_mark: | Client ID. | cli_123456789 | \ No newline at end of file diff --git a/docs/models/getemailaddressrequest.md b/docs/models/getemailaddressrequest.md new file mode 100644 index 0000000..e964391 --- /dev/null +++ b/docs/models/getemailaddressrequest.md @@ -0,0 +1,8 @@ +# GetEmailAddressRequest + + +## Fields + +| Field | Type | Required | Description | Example | +| --------------------------------------- | --------------------------------------- | --------------------------------------- | --------------------------------------- | --------------------------------------- | +| `email_address_id` | *str* | :heavy_check_mark: | The ID of the email address to retrieve | email_address_id_example | \ No newline at end of file diff --git a/docs/models/getjwttemplaterequest.md b/docs/models/getjwttemplaterequest.md new file mode 100644 index 0000000..45f1760 --- /dev/null +++ b/docs/models/getjwttemplaterequest.md @@ -0,0 +1,8 @@ +# GetJWTTemplateRequest + + +## Fields + +| Field | Type | Required | Description | Example | +| ------------------ | ------------------ | ------------------ | ------------------ | ------------------ | +| `template_id` | *str* | :heavy_check_mark: | JWT Template ID | template_123 | \ No newline at end of file diff --git a/docs/models/getoauthaccesstokenpublicmetadata.md b/docs/models/getoauthaccesstokenpublicmetadata.md new file mode 100644 index 0000000..a6e935a --- /dev/null +++ b/docs/models/getoauthaccesstokenpublicmetadata.md @@ -0,0 +1,7 @@ +# GetOAuthAccessTokenPublicMetadata + + +## Fields + +| Field | Type | Required | Description | +| ----------- | ----------- | ----------- | ----------- | \ No newline at end of file diff --git a/docs/models/getoauthaccesstokenrequest.md b/docs/models/getoauthaccesstokenrequest.md new file mode 100644 index 0000000..6a24863 --- /dev/null +++ b/docs/models/getoauthaccesstokenrequest.md @@ -0,0 +1,9 @@ +# GetOAuthAccessTokenRequest + + +## Fields + +| Field | Type | Required | Description | Example | +| --------------------------------------------------------------- | --------------------------------------------------------------- | --------------------------------------------------------------- | --------------------------------------------------------------- | --------------------------------------------------------------- | +| `user_id` | *str* | :heavy_check_mark: | The ID of the user for which to retrieve the OAuth access token | user_123 | +| `provider` | *str* | :heavy_check_mark: | The ID of the OAuth provider (e.g. `oauth_google`) | oauth_google | \ No newline at end of file diff --git a/docs/models/getoauthapplicationrequest.md b/docs/models/getoauthapplicationrequest.md new file mode 100644 index 0000000..781eb1b --- /dev/null +++ b/docs/models/getoauthapplicationrequest.md @@ -0,0 +1,8 @@ +# GetOAuthApplicationRequest + + +## Fields + +| Field | Type | Required | Description | Example | +| ------------------------------- | ------------------------------- | ------------------------------- | ------------------------------- | ------------------------------- | +| `oauth_application_id` | *str* | :heavy_check_mark: | The ID of the OAuth application | oauth_app_12345 | \ No newline at end of file diff --git a/docs/models/getorganizationinvitationrequest.md b/docs/models/getorganizationinvitationrequest.md new file mode 100644 index 0000000..d80ebbc --- /dev/null +++ b/docs/models/getorganizationinvitationrequest.md @@ -0,0 +1,9 @@ +# GetOrganizationInvitationRequest + + +## Fields + +| Field | Type | Required | Description | Example | +| ------------------------------- | ------------------------------- | ------------------------------- | ------------------------------- | ------------------------------- | +| `organization_id` | *str* | :heavy_check_mark: | The organization ID. | org_123456789 | +| `invitation_id` | *str* | :heavy_check_mark: | The organization invitation ID. | inv_987654321 | \ No newline at end of file diff --git a/docs/models/getorganizationrequest.md b/docs/models/getorganizationrequest.md new file mode 100644 index 0000000..7972fd3 --- /dev/null +++ b/docs/models/getorganizationrequest.md @@ -0,0 +1,8 @@ +# GetOrganizationRequest + + +## Fields + +| Field | Type | Required | Description | Example | +| ---------------------------------- | ---------------------------------- | ---------------------------------- | ---------------------------------- | ---------------------------------- | +| `organization_id` | *str* | :heavy_check_mark: | The ID or slug of the organization | org_123 | \ No newline at end of file diff --git a/docs/models/getphonenumberrequest.md b/docs/models/getphonenumberrequest.md new file mode 100644 index 0000000..d0506bd --- /dev/null +++ b/docs/models/getphonenumberrequest.md @@ -0,0 +1,8 @@ +# GetPhoneNumberRequest + + +## Fields + +| Field | Type | Required | Description | Example | +| -------------------------------------- | -------------------------------------- | -------------------------------------- | -------------------------------------- | -------------------------------------- | +| `phone_number_id` | *str* | :heavy_check_mark: | The ID of the phone number to retrieve | phone_12345 | \ No newline at end of file diff --git a/docs/models/getpublicinterstitialrequest.md b/docs/models/getpublicinterstitialrequest.md new file mode 100644 index 0000000..e628388 --- /dev/null +++ b/docs/models/getpublicinterstitialrequest.md @@ -0,0 +1,9 @@ +# GetPublicInterstitialRequest + + +## Fields + +| Field | Type | Required | Description | Example | +| ------------------------------------- | ------------------------------------- | ------------------------------------- | ------------------------------------- | ------------------------------------- | +| `frontend_api` | *Optional[str]* | :heavy_minus_sign: | The Frontend API key of your instance | frontend-api_1a2b3c4d | +| `publishable_key` | *Optional[str]* | :heavy_minus_sign: | The publishable key of your instance | pub_1a2b3c4d | \ No newline at end of file diff --git a/docs/models/getredirecturlrequest.md b/docs/models/getredirecturlrequest.md new file mode 100644 index 0000000..25cd11d --- /dev/null +++ b/docs/models/getredirecturlrequest.md @@ -0,0 +1,8 @@ +# GetRedirectURLRequest + + +## Fields + +| Field | Type | Required | Description | Example | +| -------------------------------- | -------------------------------- | -------------------------------- | -------------------------------- | -------------------------------- | +| `id` | *str* | :heavy_check_mark: | The ID of the redirect URL | redir_01FG4K9G5NWSQ4ZPT4TQE4Z7G3 | \ No newline at end of file diff --git a/docs/models/getsamlconnectionrequest.md b/docs/models/getsamlconnectionrequest.md new file mode 100644 index 0000000..3ad48ad --- /dev/null +++ b/docs/models/getsamlconnectionrequest.md @@ -0,0 +1,8 @@ +# GetSAMLConnectionRequest + + +## Fields + +| Field | Type | Required | Description | Example | +| ----------------------------- | ----------------------------- | ----------------------------- | ----------------------------- | ----------------------------- | +| `saml_connection_id` | *str* | :heavy_check_mark: | The ID of the SAML Connection | saml_conn_123 | \ No newline at end of file diff --git a/docs/models/getsessionlistrequest.md b/docs/models/getsessionlistrequest.md new file mode 100644 index 0000000..29dfafb --- /dev/null +++ b/docs/models/getsessionlistrequest.md @@ -0,0 +1,12 @@ +# GetSessionListRequest + + +## Fields + +| Field | Type | Required | Description | Example | +| ----------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | +| `client_id` | *Optional[str]* | :heavy_minus_sign: | List sessions for the given client | client_123 | +| `user_id` | *Optional[str]* | :heavy_minus_sign: | List sessions for the given user | user_456 | +| `status` | [Optional[models.QueryParamStatus]](../models/queryparamstatus.md) | :heavy_minus_sign: | Filter sessions by the provided status | active | +| `limit` | *Optional[float]* | :heavy_minus_sign: | Applies a limit to the number of results returned.
Can be used for paginating the results together with `offset`. | 20 | +| `offset` | *Optional[float]* | :heavy_minus_sign: | Skip the first `offset` results when paginating.
Needs to be an integer greater or equal to zero.
To be used in conjunction with `limit`. | 10 | \ No newline at end of file diff --git a/docs/models/getsessionrequest.md b/docs/models/getsessionrequest.md new file mode 100644 index 0000000..6695048 --- /dev/null +++ b/docs/models/getsessionrequest.md @@ -0,0 +1,8 @@ +# GetSessionRequest + + +## Fields + +| Field | Type | Required | Description | Example | +| --------------------- | --------------------- | --------------------- | --------------------- | --------------------- | +| `session_id` | *str* | :heavy_check_mark: | The ID of the session | sess_1234567890abcdef | \ No newline at end of file diff --git a/docs/models/gettemplatelistrequest.md b/docs/models/gettemplatelistrequest.md new file mode 100644 index 0000000..9c82aea --- /dev/null +++ b/docs/models/gettemplatelistrequest.md @@ -0,0 +1,8 @@ +# GetTemplateListRequest + + +## Fields + +| Field | Type | Required | Description | Example | +| ------------------------------------------------ | ------------------------------------------------ | ------------------------------------------------ | ------------------------------------------------ | ------------------------------------------------ | +| `template_type` | [models.TemplateType](../models/templatetype.md) | :heavy_check_mark: | The type of templates to list (email or SMS) | email | \ No newline at end of file diff --git a/docs/models/gettemplaterequest.md b/docs/models/gettemplaterequest.md new file mode 100644 index 0000000..f4dc62b --- /dev/null +++ b/docs/models/gettemplaterequest.md @@ -0,0 +1,9 @@ +# GetTemplateRequest + + +## Fields + +| Field | Type | Required | Description | Example | +| ------------------------------------------------------------------ | ------------------------------------------------------------------ | ------------------------------------------------------------------ | ------------------------------------------------------------------ | ------------------------------------------------------------------ | +| `template_type` | [models.PathParamTemplateType](../models/pathparamtemplatetype.md) | :heavy_check_mark: | The type of templates to retrieve (email or SMS) | email | +| `slug` | *str* | :heavy_check_mark: | The slug (i.e. machine-friendly name) of the template to retrieve | welcome-email | \ No newline at end of file diff --git a/docs/models/getuserlistrequest.md b/docs/models/getuserlistrequest.md new file mode 100644 index 0000000..528bd27 --- /dev/null +++ b/docs/models/getuserlistrequest.md @@ -0,0 +1,19 @@ +# GetUserListRequest + + +## Fields + +| Field | Type | Required | Description | Example | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `email_address` | List[*str*] | :heavy_minus_sign: | Returns users with the specified email addresses.
Accepts up to 100 email addresses.
Any email addresses not found are ignored. | [
"test@example.com"
] | +| `phone_number` | List[*str*] | :heavy_minus_sign: | Returns users with the specified phone numbers.
Accepts up to 100 phone numbers.
Any phone numbers not found are ignored. | [
"+12345678901"
] | +| `external_id` | List[*str*] | :heavy_minus_sign: | Returns users with the specified external ids.
For each external id, the `+` and `-` can be
prepended to the id, which denote whether the
respective external id should be included or
excluded from the result set.
Accepts up to 100 external ids.
Any external ids not found are ignored. | [
"external-id-123"
] | +| `username` | List[*str*] | :heavy_minus_sign: | Returns users with the specified usernames.
Accepts up to 100 usernames.
Any usernames not found are ignored. | [
"user123"
] | +| `web3_wallet` | List[*str*] | :heavy_minus_sign: | Returns users with the specified web3 wallet addresses.
Accepts up to 100 web3 wallet addresses.
Any web3 wallet addressed not found are ignored. | [
"0x123456789abcdef0x123456789abcdef"
] | +| `user_id` | List[*str*] | :heavy_minus_sign: | Returns users with the user ids specified.
For each user id, the `+` and `-` can be
prepended to the id, which denote whether the
respective user id should be included or
excluded from the result set.
Accepts up to 100 user ids.
Any user ids not found are ignored. | [
"user-id-123"
] | +| `organization_id` | List[*str*] | :heavy_minus_sign: | Returns users that have memberships to the
given organizations.
For each organization id, the `+` and `-` can be
prepended to the id, which denote whether the
respective organization should be included or
excluded from the result set.
Accepts up to 100 organization ids. | [
"org-id-123"
] | +| `query` | *Optional[str]* | :heavy_minus_sign: | Returns users that match the given query.
For possible matches, we check the email addresses, phone numbers, usernames, web3 wallets, user ids, first and last names.
The query value doesn't need to match the exact value you are looking for, it is capable of partial matches as well. | John | +| `last_active_at_since` | *Optional[int]* | :heavy_minus_sign: | Returns users that had session activity since the given date, with day precision.
Providing a value with higher precision than day will result in an error.
Example: use 1700690400000 to retrieve users that had session activity from 2023-11-23 until the current day. | 1700690400000 | +| `limit` | *Optional[float]* | :heavy_minus_sign: | Applies a limit to the number of results returned.
Can be used for paginating the results together with `offset`. | 20 | +| `offset` | *Optional[float]* | :heavy_minus_sign: | Skip the first `offset` results when paginating.
Needs to be an integer greater or equal to zero.
To be used in conjunction with `limit`. | 10 | +| `order_by` | *Optional[str]* | :heavy_minus_sign: | Allows to return users in a particular order.
At the moment, you can order the returned users by their `created_at`,`updated_at`,`email_address`,`web3wallet`,`first_name`,`last_name`,`phone_number`,`username`,`last_active_at`,`last_sign_in_at`.
In order to specify the direction, you can use the `+/-` symbols prepended in the property to order by.
For example, if you want users to be returned in descending order according to their `created_at` property, you can use `-created_at`.
If you don't use `+` or `-`, then `+` is implied. We only support one `order_by` parameter, and if multiple `order_by` parameters are provided, we will only keep the first one. For example,
if you pass `order_by=username&order_by=created_at`, we will consider only the first `order_by` parameter, which is `username`. The `created_at` parameter will be ignored in this case. | | \ No newline at end of file diff --git a/docs/models/getuserrequest.md b/docs/models/getuserrequest.md new file mode 100644 index 0000000..8d337f0 --- /dev/null +++ b/docs/models/getuserrequest.md @@ -0,0 +1,8 @@ +# GetUserRequest + + +## Fields + +| Field | Type | Required | Description | Example | +| ------------------------------ | ------------------------------ | ------------------------------ | ------------------------------ | ------------------------------ | +| `user_id` | *str* | :heavy_check_mark: | The ID of the user to retrieve | usr_1 | \ No newline at end of file diff --git a/docs/models/getuserscountrequest.md b/docs/models/getuserscountrequest.md new file mode 100644 index 0000000..945f287 --- /dev/null +++ b/docs/models/getuserscountrequest.md @@ -0,0 +1,14 @@ +# GetUsersCountRequest + + +## Fields + +| Field | Type | Required | Description | Example | +| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `email_address` | List[*str*] | :heavy_minus_sign: | Counts users with the specified email addresses.
Accepts up to 100 email addresses.
Any email addresses not found are ignored. | [
"user@example.com"
] | +| `phone_number` | List[*str*] | :heavy_minus_sign: | Counts users with the specified phone numbers.
Accepts up to 100 phone numbers.
Any phone numbers not found are ignored. | [
"+1234567890"
] | +| `external_id` | List[*str*] | :heavy_minus_sign: | Counts users with the specified external ids.
Accepts up to 100 external ids.
Any external ids not found are ignored. | [
"external-id-123"
] | +| `username` | List[*str*] | :heavy_minus_sign: | Counts users with the specified usernames.
Accepts up to 100 usernames.
Any usernames not found are ignored. | [
"username123"
] | +| `web3_wallet` | List[*str*] | :heavy_minus_sign: | Counts users with the specified web3 wallet addresses.
Accepts up to 100 web3 wallet addresses.
Any web3 wallet addressed not found are ignored. | [
"0x123456789abcdef"
] | +| `user_id` | List[*str*] | :heavy_minus_sign: | Counts users with the user ids specified.
Accepts up to 100 user ids.
Any user ids not found are ignored. | [
"user-id-123"
] | +| `query` | *Optional[str]* | :heavy_minus_sign: | Counts users that match the given query.
For possible matches, we check the email addresses, phone numbers, usernames, web3 wallets, user ids, first and last names.
The query value doesn't need to match the exact value you are looking for, it is capable of partial matches as well. | John Doe | \ No newline at end of file diff --git a/docs/models/identificationlink.md b/docs/models/identificationlink.md new file mode 100644 index 0000000..e9d20dd --- /dev/null +++ b/docs/models/identificationlink.md @@ -0,0 +1,9 @@ +# IdentificationLink + + +## Fields + +| Field | Type | Required | Description | Example | +| -------------------------------- | -------------------------------- | -------------------------------- | -------------------------------- | -------------------------------- | +| `type` | [models.Type](../models/type.md) | :heavy_check_mark: | N/A | oauth_google | +| `id` | *str* | :heavy_check_mark: | N/A | link_12345 | \ No newline at end of file diff --git a/docs/models/identifiertype.md b/docs/models/identifiertype.md new file mode 100644 index 0000000..40d4d41 --- /dev/null +++ b/docs/models/identifiertype.md @@ -0,0 +1,10 @@ +# IdentifierType + + +## Values + +| Name | Value | +| --------------- | --------------- | +| `EMAIL_ADDRESS` | email_address | +| `PHONE_NUMBER` | phone_number | +| `WEB3_WALLET` | web3_wallet | \ No newline at end of file diff --git a/docs/models/instancerestrictions.md b/docs/models/instancerestrictions.md new file mode 100644 index 0000000..ea35870 --- /dev/null +++ b/docs/models/instancerestrictions.md @@ -0,0 +1,12 @@ +# InstanceRestrictions + + +## Fields + +| Field | Type | Required | Description | Example | +| -------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | +| `object` | [Optional[models.InstanceRestrictionsObject]](../models/instancerestrictionsobject.md) | :heavy_minus_sign: | String representing the object's type. Objects of the same type share the same value. | instance_restrictions | +| `allowlist` | *Optional[bool]* | :heavy_minus_sign: | N/A | false | +| `blocklist` | *Optional[bool]* | :heavy_minus_sign: | N/A | true | +| `block_email_subaddresses` | *Optional[bool]* | :heavy_minus_sign: | N/A | true | +| `ignore_dots_for_gmail_addresses` | *Optional[bool]* | :heavy_minus_sign: | N/A | false | \ No newline at end of file diff --git a/docs/models/instancerestrictionsobject.md b/docs/models/instancerestrictionsobject.md new file mode 100644 index 0000000..142f45a --- /dev/null +++ b/docs/models/instancerestrictionsobject.md @@ -0,0 +1,10 @@ +# InstanceRestrictionsObject + +String representing the object's type. Objects of the same type share the same value. + + +## Values + +| Name | Value | +| ----------------------- | ----------------------- | +| `INSTANCE_RESTRICTIONS` | instance_restrictions | \ No newline at end of file diff --git a/docs/models/instancesettings.md b/docs/models/instancesettings.md new file mode 100644 index 0000000..58ffe34 --- /dev/null +++ b/docs/models/instancesettings.md @@ -0,0 +1,13 @@ +# InstanceSettings + + +## Fields + +| Field | Type | Required | Description | Example | +| ------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- | +| `object` | [Optional[models.InstanceSettingsObject]](../models/instancesettingsobject.md) | :heavy_minus_sign: | String representing the object's type. Objects of the same type share the same value. | instance_settings | +| `id` | *Optional[str]* | :heavy_minus_sign: | N/A | inst_123456789 | +| `restricted_to_allowlist` | *Optional[bool]* | :heavy_minus_sign: | N/A | false | +| `from_email_address` | *Optional[str]* | :heavy_minus_sign: | N/A | noreply@clerk.dev | +| `progressive_sign_up` | *Optional[bool]* | :heavy_minus_sign: | N/A | true | +| `enhanced_email_deliverability` | *Optional[bool]* | :heavy_minus_sign: | N/A | true | \ No newline at end of file diff --git a/docs/models/instancesettingsobject.md b/docs/models/instancesettingsobject.md new file mode 100644 index 0000000..0b1bac6 --- /dev/null +++ b/docs/models/instancesettingsobject.md @@ -0,0 +1,10 @@ +# InstanceSettingsObject + +String representing the object's type. Objects of the same type share the same value. + + +## Values + +| Name | Value | +| ------------------- | ------------------- | +| `INSTANCE_SETTINGS` | instance_settings | \ No newline at end of file diff --git a/docs/models/invitation.md b/docs/models/invitation.md new file mode 100644 index 0000000..f2f9a7d --- /dev/null +++ b/docs/models/invitation.md @@ -0,0 +1,16 @@ +# Invitation + + +## Fields + +| Field | Type | Required | Description | Example | +| ---------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- | +| `object` | [models.InvitationObject](../models/invitationobject.md) | :heavy_check_mark: | N/A | invitation | +| `id` | *str* | :heavy_check_mark: | N/A | inv_f02930r3 | +| `email_address` | *str* | :heavy_check_mark: | N/A | invitee@example.com | +| `status` | [models.InvitationStatus](../models/invitationstatus.md) | :heavy_check_mark: | N/A | pending | +| `created_at` | *int* | :heavy_check_mark: | Unix timestamp of creation.
| 1622549600 | +| `updated_at` | *int* | :heavy_check_mark: | Unix timestamp of last update.
| 1622553200 | +| `public_metadata` | [Optional[models.InvitationPublicMetadata]](../models/invitationpublicmetadata.md) | :heavy_minus_sign: | N/A | {} | +| `revoked` | *Optional[bool]* | :heavy_minus_sign: | N/A | false | +| `url` | *Optional[Nullable[str]]* | :heavy_minus_sign: | N/A | https://example.com/invitations/accept?code=abcd1234 | \ No newline at end of file diff --git a/docs/models/invitationobject.md b/docs/models/invitationobject.md new file mode 100644 index 0000000..c70a864 --- /dev/null +++ b/docs/models/invitationobject.md @@ -0,0 +1,8 @@ +# InvitationObject + + +## Values + +| Name | Value | +| ------------ | ------------ | +| `INVITATION` | invitation | \ No newline at end of file diff --git a/docs/models/invitationpublicmetadata.md b/docs/models/invitationpublicmetadata.md new file mode 100644 index 0000000..86cefd3 --- /dev/null +++ b/docs/models/invitationpublicmetadata.md @@ -0,0 +1,7 @@ +# InvitationPublicMetadata + + +## Fields + +| Field | Type | Required | Description | +| ----------- | ----------- | ----------- | ----------- | \ No newline at end of file diff --git a/docs/models/invitationrevoked.md b/docs/models/invitationrevoked.md new file mode 100644 index 0000000..2748514 --- /dev/null +++ b/docs/models/invitationrevoked.md @@ -0,0 +1,16 @@ +# InvitationRevoked + + +## Fields + +| Field | Type | Required | Description | Example | +| ------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------ | +| `object` | [models.InvitationRevokedObject](../models/invitationrevokedobject.md) | :heavy_check_mark: | N/A | invitation | +| `id` | *str* | :heavy_check_mark: | N/A | inv_f02930r3 | +| `email_address` | *str* | :heavy_check_mark: | N/A | invitee@example.com | +| `status` | [models.InvitationRevokedStatus](../models/invitationrevokedstatus.md) | :heavy_check_mark: | N/A | revoked | +| `created_at` | *int* | :heavy_check_mark: | Unix timestamp of creation.
| 1622549600 | +| `updated_at` | *int* | :heavy_check_mark: | Unix timestamp of last update.
| 1622553200 | +| `public_metadata` | [Optional[models.InvitationRevokedPublicMetadata]](../models/invitationrevokedpublicmetadata.md) | :heavy_minus_sign: | N/A | {} | +| `revoked` | *Optional[bool]* | :heavy_minus_sign: | N/A | true | +| `url` | *Optional[Nullable[str]]* | :heavy_minus_sign: | N/A | https://example.com/invitations/accept?code=abcd1234 | \ No newline at end of file diff --git a/docs/models/invitationrevokedobject.md b/docs/models/invitationrevokedobject.md new file mode 100644 index 0000000..8e8675f --- /dev/null +++ b/docs/models/invitationrevokedobject.md @@ -0,0 +1,8 @@ +# InvitationRevokedObject + + +## Values + +| Name | Value | +| ------------ | ------------ | +| `INVITATION` | invitation | \ No newline at end of file diff --git a/docs/models/invitationrevokedpublicmetadata.md b/docs/models/invitationrevokedpublicmetadata.md new file mode 100644 index 0000000..7a57063 --- /dev/null +++ b/docs/models/invitationrevokedpublicmetadata.md @@ -0,0 +1,7 @@ +# InvitationRevokedPublicMetadata + + +## Fields + +| Field | Type | Required | Description | +| ----------- | ----------- | ----------- | ----------- | \ No newline at end of file diff --git a/docs/models/invitationrevokedstatus.md b/docs/models/invitationrevokedstatus.md new file mode 100644 index 0000000..36eda6a --- /dev/null +++ b/docs/models/invitationrevokedstatus.md @@ -0,0 +1,8 @@ +# InvitationRevokedStatus + + +## Values + +| Name | Value | +| --------- | --------- | +| `REVOKED` | revoked | \ No newline at end of file diff --git a/docs/models/invitationstatus.md b/docs/models/invitationstatus.md new file mode 100644 index 0000000..fa867b7 --- /dev/null +++ b/docs/models/invitationstatus.md @@ -0,0 +1,10 @@ +# InvitationStatus + + +## Values + +| Name | Value | +| ---------- | ---------- | +| `PENDING` | pending | +| `ACCEPTED` | accepted | +| `REVOKED` | revoked | \ No newline at end of file diff --git a/docs/models/jwttemplate.md b/docs/models/jwttemplate.md new file mode 100644 index 0000000..8e97860 --- /dev/null +++ b/docs/models/jwttemplate.md @@ -0,0 +1,17 @@ +# JWTTemplate + + +## Fields + +| Field | Type | Required | Description | Example | +| ---------------------------------------------------------- | ---------------------------------------------------------- | ---------------------------------------------------------- | ---------------------------------------------------------- | ---------------------------------------------------------- | +| `object` | [models.JWTTemplateObject](../models/jwttemplateobject.md) | :heavy_check_mark: | N/A | jwt_template | +| `id` | *str* | :heavy_check_mark: | N/A | jt_1234567890abcdef | +| `name` | *str* | :heavy_check_mark: | N/A | My First JWT Template | +| `claims` | [models.Claims](../models/claims.md) | :heavy_check_mark: | N/A | {} | +| `lifetime` | *int* | :heavy_check_mark: | N/A | 3600 | +| `allowed_clock_skew` | *int* | :heavy_check_mark: | N/A | 5 | +| `created_at` | *int* | :heavy_check_mark: | Unix timestamp of creation.
| 1609459200 | +| `updated_at` | *int* | :heavy_check_mark: | Unix timestamp of last update.
| 1612137600 | +| `custom_signing_key` | *Optional[bool]* | :heavy_minus_sign: | N/A | false | +| `signing_algorithm` | *Optional[str]* | :heavy_minus_sign: | N/A | RS256 | \ No newline at end of file diff --git a/docs/models/jwttemplateobject.md b/docs/models/jwttemplateobject.md new file mode 100644 index 0000000..707c0e1 --- /dev/null +++ b/docs/models/jwttemplateobject.md @@ -0,0 +1,8 @@ +# JWTTemplateObject + + +## Values + +| Name | Value | +| -------------- | -------------- | +| `JWT_TEMPLATE` | jwt_template | \ No newline at end of file diff --git a/docs/models/listinvitationsqueryparamstatus.md b/docs/models/listinvitationsqueryparamstatus.md new file mode 100644 index 0000000..a251218 --- /dev/null +++ b/docs/models/listinvitationsqueryparamstatus.md @@ -0,0 +1,12 @@ +# ListInvitationsQueryParamStatus + +Filter invitations based on their status + + +## Values + +| Name | Value | +| ---------- | ---------- | +| `PENDING` | pending | +| `ACCEPTED` | accepted | +| `REVOKED` | revoked | \ No newline at end of file diff --git a/docs/models/listinvitationsrequest.md b/docs/models/listinvitationsrequest.md new file mode 100644 index 0000000..ed00d28 --- /dev/null +++ b/docs/models/listinvitationsrequest.md @@ -0,0 +1,10 @@ +# ListInvitationsRequest + + +## Fields + +| Field | Type | Required | Description | Example | +| ----------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | +| `limit` | *Optional[float]* | :heavy_minus_sign: | Applies a limit to the number of results returned.
Can be used for paginating the results together with `offset`. | 20 | +| `offset` | *Optional[float]* | :heavy_minus_sign: | Skip the first `offset` results when paginating.
Needs to be an integer greater or equal to zero.
To be used in conjunction with `limit`. | 10 | +| `status` | [Optional[models.ListInvitationsQueryParamStatus]](../models/listinvitationsqueryparamstatus.md) | :heavy_minus_sign: | Filter invitations based on their status | pending | \ No newline at end of file diff --git a/docs/models/listinvitationsresponse.md b/docs/models/listinvitationsresponse.md new file mode 100644 index 0000000..67064ed --- /dev/null +++ b/docs/models/listinvitationsresponse.md @@ -0,0 +1,8 @@ +# ListInvitationsResponse + + +## Fields + +| Field | Type | Required | Description | +| -------------------------------------------------- | -------------------------------------------------- | -------------------------------------------------- | -------------------------------------------------- | +| `result` | List[[models.Invitation](../models/invitation.md)] | :heavy_check_mark: | N/A | \ No newline at end of file diff --git a/docs/models/listoauthapplicationsrequest.md b/docs/models/listoauthapplicationsrequest.md new file mode 100644 index 0000000..d65515f --- /dev/null +++ b/docs/models/listoauthapplicationsrequest.md @@ -0,0 +1,9 @@ +# ListOAuthApplicationsRequest + + +## Fields + +| Field | Type | Required | Description | Example | +| ----------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | +| `limit` | *Optional[float]* | :heavy_minus_sign: | Applies a limit to the number of results returned.
Can be used for paginating the results together with `offset`. | 20 | +| `offset` | *Optional[float]* | :heavy_minus_sign: | Skip the first `offset` results when paginating.
Needs to be an integer greater or equal to zero.
To be used in conjunction with `limit`. | 10 | \ No newline at end of file diff --git a/docs/models/listoauthapplicationsresponse.md b/docs/models/listoauthapplicationsresponse.md new file mode 100644 index 0000000..c86847a --- /dev/null +++ b/docs/models/listoauthapplicationsresponse.md @@ -0,0 +1,8 @@ +# ListOAuthApplicationsResponse + + +## Fields + +| Field | Type | Required | Description | +| ---------------------------------------------------------- | ---------------------------------------------------------- | ---------------------------------------------------------- | ---------------------------------------------------------- | +| `result` | [models.OAuthApplications](../models/oauthapplications.md) | :heavy_check_mark: | N/A | \ No newline at end of file diff --git a/docs/models/listorganizationinvitationsqueryparamstatus.md b/docs/models/listorganizationinvitationsqueryparamstatus.md new file mode 100644 index 0000000..f7d0225 --- /dev/null +++ b/docs/models/listorganizationinvitationsqueryparamstatus.md @@ -0,0 +1,12 @@ +# ListOrganizationInvitationsQueryParamStatus + +Filter organization invitations based on their status + + +## Values + +| Name | Value | +| ---------- | ---------- | +| `PENDING` | pending | +| `ACCEPTED` | accepted | +| `REVOKED` | revoked | \ No newline at end of file diff --git a/docs/models/listorganizationinvitationsrequest.md b/docs/models/listorganizationinvitationsrequest.md new file mode 100644 index 0000000..be221fe --- /dev/null +++ b/docs/models/listorganizationinvitationsrequest.md @@ -0,0 +1,11 @@ +# ListOrganizationInvitationsRequest + + +## Fields + +| Field | Type | Required | Description | Example | +| ----------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | +| `organization_id` | *str* | :heavy_check_mark: | The organization ID. | org_12345 | +| `limit` | *Optional[float]* | :heavy_minus_sign: | Applies a limit to the number of results returned.
Can be used for paginating the results together with `offset`. | 20 | +| `offset` | *Optional[float]* | :heavy_minus_sign: | Skip the first `offset` results when paginating.
Needs to be an integer greater or equal to zero.
To be used in conjunction with `limit`. | 10 | +| `status` | [Optional[models.ListOrganizationInvitationsQueryParamStatus]](../models/listorganizationinvitationsqueryparamstatus.md) | :heavy_minus_sign: | Filter organization invitations based on their status | pending | \ No newline at end of file diff --git a/docs/models/listorganizationinvitationsresponse.md b/docs/models/listorganizationinvitationsresponse.md new file mode 100644 index 0000000..7f3f773 --- /dev/null +++ b/docs/models/listorganizationinvitationsresponse.md @@ -0,0 +1,8 @@ +# ListOrganizationInvitationsResponse + + +## Fields + +| Field | Type | Required | Description | +| ---------------------------------------------------------------------- | ---------------------------------------------------------------------- | ---------------------------------------------------------------------- | ---------------------------------------------------------------------- | +| `result` | [models.OrganizationInvitations](../models/organizationinvitations.md) | :heavy_check_mark: | N/A | \ No newline at end of file diff --git a/docs/models/listorganizationmembershipsrequest.md b/docs/models/listorganizationmembershipsrequest.md new file mode 100644 index 0000000..a69ed42 --- /dev/null +++ b/docs/models/listorganizationmembershipsrequest.md @@ -0,0 +1,11 @@ +# ListOrganizationMembershipsRequest + + +## Fields + +| Field | Type | Required | Description | Example | +| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `organization_id` | *str* | :heavy_check_mark: | The organization ID. | org_789 | +| `limit` | *Optional[float]* | :heavy_minus_sign: | Applies a limit to the number of results returned.
Can be used for paginating the results together with `offset`. | 20 | +| `offset` | *Optional[float]* | :heavy_minus_sign: | Skip the first `offset` results when paginating.
Needs to be an integer greater or equal to zero.
To be used in conjunction with `limit`. | 10 | +| `order_by` | *Optional[str]* | :heavy_minus_sign: | Sorts organizations memberships by phone_number, email_address, created_at, first_name, last_name or username.
By prepending one of those values with + or -,
we can choose to sort in ascending (ASC) or descending (DESC) order." | +created_at | \ No newline at end of file diff --git a/docs/models/listorganizationmembershipsresponse.md b/docs/models/listorganizationmembershipsresponse.md new file mode 100644 index 0000000..cab9c22 --- /dev/null +++ b/docs/models/listorganizationmembershipsresponse.md @@ -0,0 +1,8 @@ +# ListOrganizationMembershipsResponse + + +## Fields + +| Field | Type | Required | Description | +| ---------------------------------------------------------------------- | ---------------------------------------------------------------------- | ---------------------------------------------------------------------- | ---------------------------------------------------------------------- | +| `result` | [models.OrganizationMemberships](../models/organizationmemberships.md) | :heavy_check_mark: | N/A | \ No newline at end of file diff --git a/docs/models/listorganizationsrequest.md b/docs/models/listorganizationsrequest.md new file mode 100644 index 0000000..7289fce --- /dev/null +++ b/docs/models/listorganizationsrequest.md @@ -0,0 +1,12 @@ +# ListOrganizationsRequest + + +## Fields + +| Field | Type | Required | Description | Example | +| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `limit` | *Optional[float]* | :heavy_minus_sign: | Applies a limit to the number of results returned.
Can be used for paginating the results together with `offset`. | 20 | +| `offset` | *Optional[float]* | :heavy_minus_sign: | Skip the first `offset` results when paginating.
Needs to be an integer greater or equal to zero.
To be used in conjunction with `limit`. | 10 | +| `include_members_count` | *Optional[bool]* | :heavy_minus_sign: | Flag to denote whether the member counts of each organization should be included in the response or not. | false | +| `query` | *Optional[str]* | :heavy_minus_sign: | Returns organizations with ID, name, or slug that match the given query.
Uses exact match for organization ID and partial match for name and slug. | clerk | +| `order_by` | *Optional[str]* | :heavy_minus_sign: | Allows to return organizations in a particular order.
At the moment, you can order the returned organizations either by their `name`, `created_at` or `members_count`.
In order to specify the direction, you can use the `+/-` symbols prepended in the property to order by.
For example, if you want organizations to be returned in descending order according to their `created_at` property, you can use `-created_at`.
If you don't use `+` or `-`, then `+` is implied.
Defaults to `-created_at`. | -name | \ No newline at end of file diff --git a/docs/models/listpendingorganizationinvitationsrequest.md b/docs/models/listpendingorganizationinvitationsrequest.md new file mode 100644 index 0000000..2b71ccb --- /dev/null +++ b/docs/models/listpendingorganizationinvitationsrequest.md @@ -0,0 +1,10 @@ +# ListPendingOrganizationInvitationsRequest + + +## Fields + +| Field | Type | Required | Description | Example | +| ----------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | +| `organization_id` | *str* | :heavy_check_mark: | The organization ID. | org_12345 | +| `limit` | *Optional[float]* | :heavy_minus_sign: | Applies a limit to the number of results returned.
Can be used for paginating the results together with `offset`. | 20 | +| `offset` | *Optional[float]* | :heavy_minus_sign: | Skip the first `offset` results when paginating.
Needs to be an integer greater or equal to zero.
To be used in conjunction with `limit`. | 10 | \ No newline at end of file diff --git a/docs/models/listpendingorganizationinvitationsresponse.md b/docs/models/listpendingorganizationinvitationsresponse.md new file mode 100644 index 0000000..666b08a --- /dev/null +++ b/docs/models/listpendingorganizationinvitationsresponse.md @@ -0,0 +1,8 @@ +# ListPendingOrganizationInvitationsResponse + + +## Fields + +| Field | Type | Required | Description | +| ---------------------------------------------------------------------- | ---------------------------------------------------------------------- | ---------------------------------------------------------------------- | ---------------------------------------------------------------------- | +| `result` | [models.OrganizationInvitations](../models/organizationinvitations.md) | :heavy_check_mark: | N/A | \ No newline at end of file diff --git a/docs/models/listsamlconnectionsrequest.md b/docs/models/listsamlconnectionsrequest.md new file mode 100644 index 0000000..157c5e8 --- /dev/null +++ b/docs/models/listsamlconnectionsrequest.md @@ -0,0 +1,9 @@ +# ListSAMLConnectionsRequest + + +## Fields + +| Field | Type | Required | Description | Example | +| ----------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | +| `limit` | *Optional[float]* | :heavy_minus_sign: | Applies a limit to the number of results returned.
Can be used for paginating the results together with `offset`. | 20 | +| `offset` | *Optional[float]* | :heavy_minus_sign: | Skip the first `offset` results when paginating.
Needs to be an integer greater or equal to zero.
To be used in conjunction with `limit`. | 10 | \ No newline at end of file diff --git a/docs/models/listsamlconnectionsresponse.md b/docs/models/listsamlconnectionsresponse.md new file mode 100644 index 0000000..94843b6 --- /dev/null +++ b/docs/models/listsamlconnectionsresponse.md @@ -0,0 +1,8 @@ +# ListSAMLConnectionsResponse + + +## Fields + +| Field | Type | Required | Description | +| ------------------------------------------------------ | ------------------------------------------------------ | ------------------------------------------------------ | ------------------------------------------------------ | +| `result` | [models.SAMLConnections](../models/samlconnections.md) | :heavy_check_mark: | N/A | \ No newline at end of file diff --git a/docs/models/lockuserrequest.md b/docs/models/lockuserrequest.md new file mode 100644 index 0000000..d1fb842 --- /dev/null +++ b/docs/models/lockuserrequest.md @@ -0,0 +1,8 @@ +# LockUserRequest + + +## Fields + +| Field | Type | Required | Description | Example | +| -------------------------- | -------------------------- | -------------------------- | -------------------------- | -------------------------- | +| `user_id` | *str* | :heavy_check_mark: | The ID of the user to lock | user_123456789 | \ No newline at end of file diff --git a/docs/models/mergeorganizationmetadataprivatemetadata.md b/docs/models/mergeorganizationmetadataprivatemetadata.md new file mode 100644 index 0000000..cc4792e --- /dev/null +++ b/docs/models/mergeorganizationmetadataprivatemetadata.md @@ -0,0 +1,10 @@ +# MergeOrganizationMetadataPrivateMetadata + +Metadata saved on the organization that is only visible to your backend. +The new object will be merged with the existing value. + + +## Fields + +| Field | Type | Required | Description | +| ----------- | ----------- | ----------- | ----------- | \ No newline at end of file diff --git a/docs/models/mergeorganizationmetadatapublicmetadata.md b/docs/models/mergeorganizationmetadatapublicmetadata.md new file mode 100644 index 0000000..7dac9e8 --- /dev/null +++ b/docs/models/mergeorganizationmetadatapublicmetadata.md @@ -0,0 +1,10 @@ +# MergeOrganizationMetadataPublicMetadata + +Metadata saved on the organization, that is visible to both your frontend and backend. +The new object will be merged with the existing value. + + +## Fields + +| Field | Type | Required | Description | +| ----------- | ----------- | ----------- | ----------- | \ No newline at end of file diff --git a/docs/models/mergeorganizationmetadatarequest.md b/docs/models/mergeorganizationmetadatarequest.md new file mode 100644 index 0000000..5948599 --- /dev/null +++ b/docs/models/mergeorganizationmetadatarequest.md @@ -0,0 +1,9 @@ +# MergeOrganizationMetadataRequest + + +## Fields + +| Field | Type | Required | Description | Example | +| ------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------ | +| `organization_id` | *str* | :heavy_check_mark: | The ID of the organization for which metadata will be merged or updated | org_12345 | +| `request_body` | [models.MergeOrganizationMetadataRequestBody](../models/mergeorganizationmetadatarequestbody.md) | :heavy_check_mark: | N/A | | \ No newline at end of file diff --git a/docs/models/mergeorganizationmetadatarequestbody.md b/docs/models/mergeorganizationmetadatarequestbody.md new file mode 100644 index 0000000..27a9a96 --- /dev/null +++ b/docs/models/mergeorganizationmetadatarequestbody.md @@ -0,0 +1,9 @@ +# MergeOrganizationMetadataRequestBody + + +## Fields + +| Field | Type | Required | Description | Example | +| --------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | +| `public_metadata` | [Optional[models.MergeOrganizationMetadataPublicMetadata]](../models/mergeorganizationmetadatapublicmetadata.md) | :heavy_minus_sign: | Metadata saved on the organization, that is visible to both your frontend and backend.
The new object will be merged with the existing value. | {
"announcement": "We are opening a new office!"
} | +| `private_metadata` | [Optional[models.MergeOrganizationMetadataPrivateMetadata]](../models/mergeorganizationmetadataprivatemetadata.md) | :heavy_minus_sign: | Metadata saved on the organization that is only visible to your backend.
The new object will be merged with the existing value. | {
"internal_use_only": "Future plans discussion."
} | \ No newline at end of file diff --git a/docs/models/meta.md b/docs/models/meta.md new file mode 100644 index 0000000..93f98d6 --- /dev/null +++ b/docs/models/meta.md @@ -0,0 +1,7 @@ +# Meta + + +## Fields + +| Field | Type | Required | Description | +| ----------- | ----------- | ----------- | ----------- | \ No newline at end of file diff --git a/docs/models/nonce.md b/docs/models/nonce.md new file mode 100644 index 0000000..29706b1 --- /dev/null +++ b/docs/models/nonce.md @@ -0,0 +1,8 @@ +# Nonce + + +## Values + +| Name | Value | +| ------- | ------- | +| `NONCE` | nonce | \ No newline at end of file diff --git a/docs/models/oauth.md b/docs/models/oauth.md new file mode 100644 index 0000000..b1cd871 --- /dev/null +++ b/docs/models/oauth.md @@ -0,0 +1,13 @@ +# Oauth + + +## Fields + +| Field | Type | Required | Description | Example | +| -------------------------------------------------------------------------- | -------------------------------------------------------------------------- | -------------------------------------------------------------------------- | -------------------------------------------------------------------------- | -------------------------------------------------------------------------- | +| `status` | [models.OauthVerificationStatus](../models/oauthverificationstatus.md) | :heavy_check_mark: | N/A | verified | +| `strategy` | [models.OauthVerificationStrategy](../models/oauthverificationstrategy.md) | :heavy_check_mark: | N/A | oauth_google | +| `expire_at` | *Nullable[int]* | :heavy_check_mark: | N/A | 1615462399 | +| `external_verification_redirect_url` | *Optional[str]* | :heavy_minus_sign: | N/A | https://oauth.google.com/verify | +| `error` | [Optional[Nullable[models.Error]]](../models/error.md) | :heavy_minus_sign: | N/A | | +| `attempts` | *Optional[Nullable[int]]* | :heavy_minus_sign: | N/A | 1 | \ No newline at end of file diff --git a/docs/models/oauthapplication.md b/docs/models/oauthapplication.md new file mode 100644 index 0000000..78c0f1c --- /dev/null +++ b/docs/models/oauthapplication.md @@ -0,0 +1,20 @@ +# OAuthApplication + + +## Fields + +| Field | Type | Required | Description | Example | +| -------------------------------------------------------------------- | -------------------------------------------------------------------- | -------------------------------------------------------------------- | -------------------------------------------------------------------- | -------------------------------------------------------------------- | +| `object` | [models.OAuthApplicationObject](../models/oauthapplicationobject.md) | :heavy_check_mark: | N/A | oauth_application | +| `id` | *str* | :heavy_check_mark: | N/A | oauth_app_1234 | +| `instance_id` | *str* | :heavy_check_mark: | N/A | instance_5678 | +| `name` | *str* | :heavy_check_mark: | N/A | Example OAuth App | +| `client_id` | *str* | :heavy_check_mark: | N/A | client_12345 | +| `public` | *bool* | :heavy_check_mark: | N/A | false | +| `scopes` | *str* | :heavy_check_mark: | N/A | profile email | +| `callback_url` | *str* | :heavy_check_mark: | N/A | https://example.com/oauth/callback | +| `authorize_url` | *str* | :heavy_check_mark: | N/A | https://example.com/authorize | +| `token_fetch_url` | *str* | :heavy_check_mark: | N/A | https://example.com/oauth/token | +| `user_info_url` | *str* | :heavy_check_mark: | N/A | https://example.com/userinfo | +| `created_at` | *int* | :heavy_check_mark: | Unix timestamp of creation.
| 1609459200 | +| `updated_at` | *int* | :heavy_check_mark: | Unix timestamp of last update.
| 1612137600 | \ No newline at end of file diff --git a/docs/models/oauthapplicationobject.md b/docs/models/oauthapplicationobject.md new file mode 100644 index 0000000..a24dc96 --- /dev/null +++ b/docs/models/oauthapplicationobject.md @@ -0,0 +1,8 @@ +# OAuthApplicationObject + + +## Values + +| Name | Value | +| ------------------- | ------------------- | +| `OAUTH_APPLICATION` | oauth_application | \ No newline at end of file diff --git a/docs/models/oauthapplications.md b/docs/models/oauthapplications.md new file mode 100644 index 0000000..f894c84 --- /dev/null +++ b/docs/models/oauthapplications.md @@ -0,0 +1,9 @@ +# OAuthApplications + + +## Fields + +| Field | Type | Required | Description | Example | +| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `data` | List[[models.OAuthApplication](../models/oauthapplication.md)] | :heavy_check_mark: | N/A | [
{
"object": "oauth_application",
"id": "oauth_app_1234",
"instance_id": "instance_5678",
"name": "Example OAuth App",
"client_id": "client_12345",
"public": false,
"scopes": "profile email",
"callback_url": "https://example.com/oauth/callback",
"authorize_url": "https://example.com/authorize",
"token_fetch_url": "https://example.com/oauth/token",
"user_info_url": "https://example.com/userinfo",
"created_at": 1609459200,
"updated_at": 1612137600
}
] | +| `total_count` | *int* | :heavy_check_mark: | Total number of OAuth applications
| 1 | \ No newline at end of file diff --git a/docs/models/oauthapplicationwithsecret.md b/docs/models/oauthapplicationwithsecret.md new file mode 100644 index 0000000..b3fe2b8 --- /dev/null +++ b/docs/models/oauthapplicationwithsecret.md @@ -0,0 +1,21 @@ +# OAuthApplicationWithSecret + + +## Fields + +| Field | Type | Required | Description | Example | +| ---------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- | +| `object` | [models.OAuthApplicationWithSecretObject](../models/oauthapplicationwithsecretobject.md) | :heavy_check_mark: | N/A | oauth_application | +| `id` | *str* | :heavy_check_mark: | N/A | oauth_app_1234 | +| `instance_id` | *str* | :heavy_check_mark: | N/A | instance_5678 | +| `name` | *str* | :heavy_check_mark: | N/A | Example OAuth App | +| `client_id` | *str* | :heavy_check_mark: | N/A | client_12345 | +| `public` | *bool* | :heavy_check_mark: | N/A | false | +| `scopes` | *str* | :heavy_check_mark: | N/A | profile email | +| `callback_url` | *str* | :heavy_check_mark: | N/A | https://example.com/oauth/callback | +| `authorize_url` | *str* | :heavy_check_mark: | N/A | https://example.com/authorize | +| `token_fetch_url` | *str* | :heavy_check_mark: | N/A | https://example.com/oauth/token | +| `user_info_url` | *str* | :heavy_check_mark: | N/A | https://example.com/userinfo | +| `created_at` | *int* | :heavy_check_mark: | Unix timestamp of creation.
| 1609459200 | +| `updated_at` | *int* | :heavy_check_mark: | Unix timestamp of last update.
| 1612137600 | +| `client_secret` | *Optional[str]* | :heavy_minus_sign: | Empty if public client.
| secretXYZ123 | \ No newline at end of file diff --git a/docs/models/oauthapplicationwithsecretobject.md b/docs/models/oauthapplicationwithsecretobject.md new file mode 100644 index 0000000..f305752 --- /dev/null +++ b/docs/models/oauthapplicationwithsecretobject.md @@ -0,0 +1,8 @@ +# OAuthApplicationWithSecretObject + + +## Values + +| Name | Value | +| ------------------- | ------------------- | +| `OAUTH_APPLICATION` | oauth_application | \ No newline at end of file diff --git a/docs/models/oauthverificationstatus.md b/docs/models/oauthverificationstatus.md new file mode 100644 index 0000000..9638035 --- /dev/null +++ b/docs/models/oauthverificationstatus.md @@ -0,0 +1,12 @@ +# OauthVerificationStatus + + +## Values + +| Name | Value | +| -------------- | -------------- | +| `UNVERIFIED` | unverified | +| `VERIFIED` | verified | +| `FAILED` | failed | +| `EXPIRED` | expired | +| `TRANSFERABLE` | transferable | \ No newline at end of file diff --git a/docs/models/oauthverificationstrategy.md b/docs/models/oauthverificationstrategy.md new file mode 100644 index 0000000..fb6993c --- /dev/null +++ b/docs/models/oauthverificationstrategy.md @@ -0,0 +1,11 @@ +# OauthVerificationStrategy + + +## Values + +| Name | Value | +| -------------------- | -------------------- | +| `OAUTH_GOOGLE` | oauth_google | +| `OAUTH_MOCK` | oauth_mock | +| `FROM_OAUTH_DISCORD` | from_oauth_discord | +| `FROM_OAUTH_GOOGLE` | from_oauth_google | \ No newline at end of file diff --git a/docs/models/object.md b/docs/models/object.md new file mode 100644 index 0000000..ec43ade --- /dev/null +++ b/docs/models/object.md @@ -0,0 +1,11 @@ +# Object + +String representing the object's type. Objects of the same type share the same value. + + + +## Values + +| Name | Value | +| -------- | -------- | +| `CLIENT` | client | \ No newline at end of file diff --git a/docs/models/organization.md b/docs/models/organization.md new file mode 100644 index 0000000..caea47a --- /dev/null +++ b/docs/models/organization.md @@ -0,0 +1,19 @@ +# Organization + + +## Fields + +| Field | Type | Required | Description | Example | +| ------------------------------------------------------------------------------ | ------------------------------------------------------------------------------ | ------------------------------------------------------------------------------ | ------------------------------------------------------------------------------ | ------------------------------------------------------------------------------ | +| `object` | [models.OrganizationObject](../models/organizationobject.md) | :heavy_check_mark: | N/A | organization | +| `id` | *str* | :heavy_check_mark: | N/A | org_123 | +| `name` | *str* | :heavy_check_mark: | N/A | Acme Corp | +| `slug` | *str* | :heavy_check_mark: | N/A | acme-corp | +| `max_allowed_memberships` | *int* | :heavy_check_mark: | N/A | 300 | +| `public_metadata` | [models.OrganizationPublicMetadata](../models/organizationpublicmetadata.md) | :heavy_check_mark: | N/A | {
"public_info": "Info visible to everyone"
} | +| `private_metadata` | [models.OrganizationPrivateMetadata](../models/organizationprivatemetadata.md) | :heavy_check_mark: | N/A | {
"internal_use_only": "Sensitive data"
} | +| `created_at` | *int* | :heavy_check_mark: | Unix timestamp of creation.
| 1625078400 | +| `updated_at` | *int* | :heavy_check_mark: | Unix timestamp of last update.
| 1625164800 | +| `members_count` | *Optional[Nullable[int]]* | :heavy_minus_sign: | N/A | 150 | +| `admin_delete_enabled` | *Optional[bool]* | :heavy_minus_sign: | N/A | true | +| `created_by` | *Optional[str]* | :heavy_minus_sign: | N/A | user_123456 | \ No newline at end of file diff --git a/docs/models/organizationinvitation.md b/docs/models/organizationinvitation.md new file mode 100644 index 0000000..0a76125 --- /dev/null +++ b/docs/models/organizationinvitation.md @@ -0,0 +1,19 @@ +# OrganizationInvitation + +An organization invitation + + +## Fields + +| Field | Type | Required | Description | Example | +| ------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------ | +| `id` | *Optional[str]* | :heavy_minus_sign: | N/A | inv_12345 | +| `object` | [Optional[models.OrganizationInvitationObject]](../models/organizationinvitationobject.md) | :heavy_minus_sign: | String representing the object's type. Objects of the same type share the same value.
| organization_invitation | +| `email_address` | *Optional[str]* | :heavy_minus_sign: | N/A | user@example.com | +| `role` | *Optional[str]* | :heavy_minus_sign: | N/A | admin | +| `organization_id` | *Optional[str]* | :heavy_minus_sign: | N/A | org_12345 | +| `status` | *Optional[str]* | :heavy_minus_sign: | N/A | pending | +| `public_metadata` | [Optional[models.OrganizationInvitationPublicMetadata]](../models/organizationinvitationpublicmetadata.md) | :heavy_minus_sign: | N/A | {
"key": "value"
} | +| `private_metadata` | [Optional[models.OrganizationInvitationPrivateMetadata]](../models/organizationinvitationprivatemetadata.md) | :heavy_minus_sign: | N/A | {
"private_key": "secret_value"
} | +| `created_at` | *Optional[int]* | :heavy_minus_sign: | Unix timestamp of creation. | 1622547600 | +| `updated_at` | *Optional[int]* | :heavy_minus_sign: | Unix timestamp of last update. | 1622551200 | \ No newline at end of file diff --git a/docs/models/organizationinvitationobject.md b/docs/models/organizationinvitationobject.md new file mode 100644 index 0000000..be5a971 --- /dev/null +++ b/docs/models/organizationinvitationobject.md @@ -0,0 +1,11 @@ +# OrganizationInvitationObject + +String representing the object's type. Objects of the same type share the same value. + + + +## Values + +| Name | Value | +| ------------------------- | ------------------------- | +| `ORGANIZATION_INVITATION` | organization_invitation | \ No newline at end of file diff --git a/docs/models/organizationinvitationprivatemetadata.md b/docs/models/organizationinvitationprivatemetadata.md new file mode 100644 index 0000000..179f38a --- /dev/null +++ b/docs/models/organizationinvitationprivatemetadata.md @@ -0,0 +1,7 @@ +# OrganizationInvitationPrivateMetadata + + +## Fields + +| Field | Type | Required | Description | +| ----------- | ----------- | ----------- | ----------- | \ No newline at end of file diff --git a/docs/models/organizationinvitationpublicmetadata.md b/docs/models/organizationinvitationpublicmetadata.md new file mode 100644 index 0000000..f0b62d1 --- /dev/null +++ b/docs/models/organizationinvitationpublicmetadata.md @@ -0,0 +1,7 @@ +# OrganizationInvitationPublicMetadata + + +## Fields + +| Field | Type | Required | Description | +| ----------- | ----------- | ----------- | ----------- | \ No newline at end of file diff --git a/docs/models/organizationinvitations.md b/docs/models/organizationinvitations.md new file mode 100644 index 0000000..503d73b --- /dev/null +++ b/docs/models/organizationinvitations.md @@ -0,0 +1,9 @@ +# OrganizationInvitations + + +## Fields + +| Field | Type | Required | Description | Example | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `data` | List[[models.OrganizationInvitation](../models/organizationinvitation.md)] | :heavy_check_mark: | N/A | [
{
"id": "inv_12345",
"object": "organization_invitation",
"email_address": "user@example.com",
"role": "member",
"organization_id": "org_12345",
"status": "pending",
"created_at": 1617981379,
"updated_at": 1625581379
}
] | +| `total_count` | *int* | :heavy_check_mark: | Total number of organization invitations
| 10 | \ No newline at end of file diff --git a/docs/models/organizationmembership.md b/docs/models/organizationmembership.md new file mode 100644 index 0000000..9c6befd --- /dev/null +++ b/docs/models/organizationmembership.md @@ -0,0 +1,19 @@ +# OrganizationMembership + +Hello world + + +## Fields + +| Field | Type | Required | Description | Example | +| --------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `id` | *Optional[str]* | :heavy_minus_sign: | N/A | org_mem_123 | +| `object` | [Optional[models.OrganizationMembershipObject]](../models/organizationmembershipobject.md) | :heavy_minus_sign: | String representing the object's type. Objects of the same type share the same value.
| organization_membership | +| `role` | *Optional[str]* | :heavy_minus_sign: | N/A | member | +| `permissions` | List[*str*] | :heavy_minus_sign: | N/A | [
"read",
"write"
] | +| `public_metadata` | [Optional[models.OrganizationMembershipPublicMetadata]](../models/organizationmembershippublicmetadata.md) | :heavy_minus_sign: | Metadata saved on the organization membership, accessible from both Frontend and Backend APIs | {} | +| `private_metadata` | [Optional[models.OrganizationMembershipPrivateMetadata]](../models/organizationmembershipprivatemetadata.md) | :heavy_minus_sign: | Metadata saved on the organization membership, accessible only from the Backend API | {} | +| `organization` | [Optional[models.OrganizationMembershipOrganization]](../models/organizationmembershiporganization.md) | :heavy_minus_sign: | N/A | | +| `public_user_data` | [Optional[models.PublicUserData]](../models/publicuserdata.md) | :heavy_minus_sign: | N/A | {
"user_id": "user_123",
"first_name": "John",
"last_name": "Doe",
"image_url": "https://example.com/profile.jpg",
"has_image": true,
"identifier": "johndoe"
} | +| `created_at` | *Optional[int]* | :heavy_minus_sign: | Unix timestamp of creation. | 1625078400 | +| `updated_at` | *Optional[int]* | :heavy_minus_sign: | Unix timestamp of last update. | 1625164800 | \ No newline at end of file diff --git a/docs/models/organizationmembershipobject.md b/docs/models/organizationmembershipobject.md new file mode 100644 index 0000000..b06b6f2 --- /dev/null +++ b/docs/models/organizationmembershipobject.md @@ -0,0 +1,11 @@ +# OrganizationMembershipObject + +String representing the object's type. Objects of the same type share the same value. + + + +## Values + +| Name | Value | +| ------------------------- | ------------------------- | +| `ORGANIZATION_MEMBERSHIP` | organization_membership | \ No newline at end of file diff --git a/docs/models/organizationmembershiporganization.md b/docs/models/organizationmembershiporganization.md new file mode 100644 index 0000000..be830bf --- /dev/null +++ b/docs/models/organizationmembershiporganization.md @@ -0,0 +1,19 @@ +# OrganizationMembershipOrganization + + +## Fields + +| Field | Type | Required | Description | Example | +| -------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- | +| `object` | [models.OrganizationMembershipOrganizationObject](../models/organizationmembershiporganizationobject.md) | :heavy_check_mark: | N/A | organization | +| `id` | *str* | :heavy_check_mark: | N/A | org_123 | +| `name` | *str* | :heavy_check_mark: | N/A | Acme Corp | +| `slug` | *str* | :heavy_check_mark: | N/A | acme-corp | +| `max_allowed_memberships` | *int* | :heavy_check_mark: | N/A | 300 | +| `public_metadata` | [models.OrganizationMembershipOrganizationPublicMetadata](../models/organizationmembershiporganizationpublicmetadata.md) | :heavy_check_mark: | N/A | {
"public_info": "Info visible to everyone"
} | +| `private_metadata` | [models.OrganizationMembershipOrganizationPrivateMetadata](../models/organizationmembershiporganizationprivatemetadata.md) | :heavy_check_mark: | N/A | {
"internal_use_only": "Sensitive data"
} | +| `created_at` | *int* | :heavy_check_mark: | Unix timestamp of creation.
| 1625078400 | +| `updated_at` | *int* | :heavy_check_mark: | Unix timestamp of last update.
| 1625164800 | +| `members_count` | *Optional[Nullable[int]]* | :heavy_minus_sign: | N/A | 150 | +| `admin_delete_enabled` | *Optional[bool]* | :heavy_minus_sign: | N/A | true | +| `created_by` | *Optional[str]* | :heavy_minus_sign: | N/A | user_123456 | \ No newline at end of file diff --git a/docs/models/organizationmembershiporganizationobject.md b/docs/models/organizationmembershiporganizationobject.md new file mode 100644 index 0000000..aa6222b --- /dev/null +++ b/docs/models/organizationmembershiporganizationobject.md @@ -0,0 +1,8 @@ +# OrganizationMembershipOrganizationObject + + +## Values + +| Name | Value | +| -------------- | -------------- | +| `ORGANIZATION` | organization | \ No newline at end of file diff --git a/docs/models/organizationmembershiporganizationprivatemetadata.md b/docs/models/organizationmembershiporganizationprivatemetadata.md new file mode 100644 index 0000000..361b894 --- /dev/null +++ b/docs/models/organizationmembershiporganizationprivatemetadata.md @@ -0,0 +1,7 @@ +# OrganizationMembershipOrganizationPrivateMetadata + + +## Fields + +| Field | Type | Required | Description | +| ----------- | ----------- | ----------- | ----------- | \ No newline at end of file diff --git a/docs/models/organizationmembershiporganizationpublicmetadata.md b/docs/models/organizationmembershiporganizationpublicmetadata.md new file mode 100644 index 0000000..7040de0 --- /dev/null +++ b/docs/models/organizationmembershiporganizationpublicmetadata.md @@ -0,0 +1,7 @@ +# OrganizationMembershipOrganizationPublicMetadata + + +## Fields + +| Field | Type | Required | Description | +| ----------- | ----------- | ----------- | ----------- | \ No newline at end of file diff --git a/docs/models/organizationmembershipprivatemetadata.md b/docs/models/organizationmembershipprivatemetadata.md new file mode 100644 index 0000000..82b7b53 --- /dev/null +++ b/docs/models/organizationmembershipprivatemetadata.md @@ -0,0 +1,9 @@ +# OrganizationMembershipPrivateMetadata + +Metadata saved on the organization membership, accessible only from the Backend API + + +## Fields + +| Field | Type | Required | Description | +| ----------- | ----------- | ----------- | ----------- | \ No newline at end of file diff --git a/docs/models/organizationmembershippublicmetadata.md b/docs/models/organizationmembershippublicmetadata.md new file mode 100644 index 0000000..e9197dd --- /dev/null +++ b/docs/models/organizationmembershippublicmetadata.md @@ -0,0 +1,9 @@ +# OrganizationMembershipPublicMetadata + +Metadata saved on the organization membership, accessible from both Frontend and Backend APIs + + +## Fields + +| Field | Type | Required | Description | +| ----------- | ----------- | ----------- | ----------- | \ No newline at end of file diff --git a/docs/models/organizationmemberships.md b/docs/models/organizationmemberships.md new file mode 100644 index 0000000..92faaa2 --- /dev/null +++ b/docs/models/organizationmemberships.md @@ -0,0 +1,9 @@ +# OrganizationMemberships + + +## Fields + +| Field | Type | Required | Description | Example | +| -------------------------------------------------------------------------- | -------------------------------------------------------------------------- | -------------------------------------------------------------------------- | -------------------------------------------------------------------------- | -------------------------------------------------------------------------- | +| `data` | List[[models.OrganizationMembership](../models/organizationmembership.md)] | :heavy_check_mark: | N/A | | +| `total_count` | *int* | :heavy_check_mark: | Total number of organization memberships
| 1 | \ No newline at end of file diff --git a/docs/models/organizationobject.md b/docs/models/organizationobject.md new file mode 100644 index 0000000..30e26e2 --- /dev/null +++ b/docs/models/organizationobject.md @@ -0,0 +1,8 @@ +# OrganizationObject + + +## Values + +| Name | Value | +| -------------- | -------------- | +| `ORGANIZATION` | organization | \ No newline at end of file diff --git a/docs/models/organizationprivatemetadata.md b/docs/models/organizationprivatemetadata.md new file mode 100644 index 0000000..a6c2475 --- /dev/null +++ b/docs/models/organizationprivatemetadata.md @@ -0,0 +1,7 @@ +# OrganizationPrivateMetadata + + +## Fields + +| Field | Type | Required | Description | +| ----------- | ----------- | ----------- | ----------- | \ No newline at end of file diff --git a/docs/models/organizationpublicmetadata.md b/docs/models/organizationpublicmetadata.md new file mode 100644 index 0000000..9beca5e --- /dev/null +++ b/docs/models/organizationpublicmetadata.md @@ -0,0 +1,7 @@ +# OrganizationPublicMetadata + + +## Fields + +| Field | Type | Required | Description | +| ----------- | ----------- | ----------- | ----------- | \ No newline at end of file diff --git a/docs/models/organizations.md b/docs/models/organizations.md new file mode 100644 index 0000000..50f347c --- /dev/null +++ b/docs/models/organizations.md @@ -0,0 +1,9 @@ +# Organizations + + +## Fields + +| Field | Type | Required | Description | Example | +| ------------------------------------------------------- | ------------------------------------------------------- | ------------------------------------------------------- | ------------------------------------------------------- | ------------------------------------------------------- | +| `data` | List[[models.Organization](../models/organization.md)] | :heavy_check_mark: | N/A | [
{
"id": "org_1234",
"name": "Sample Organization"
}
] | +| `total_count` | *int* | :heavy_check_mark: | Total number of organizations
| 1 | \ No newline at end of file diff --git a/docs/models/organizationsettings.md b/docs/models/organizationsettings.md new file mode 100644 index 0000000..7ff6028 --- /dev/null +++ b/docs/models/organizationsettings.md @@ -0,0 +1,17 @@ +# OrganizationSettings + + +## Fields + +| Field | Type | Required | Description | Example | +| ---------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- | +| `object` | [models.OrganizationSettingsObject](../models/organizationsettingsobject.md) | :heavy_check_mark: | String representing the object's type. Objects of the same type share the same value. | organization_settings | +| `enabled` | *bool* | :heavy_check_mark: | N/A | true | +| `max_allowed_memberships` | *int* | :heavy_check_mark: | N/A | 5 | +| `creator_role` | *str* | :heavy_check_mark: | The role key that a user will be assigned after creating an organization. | admin | +| `admin_delete_enabled` | *bool* | :heavy_check_mark: | The default for whether an admin can delete an organization with the Frontend API. | true | +| `domains_enabled` | *bool* | :heavy_check_mark: | N/A | true | +| `domains_enrollment_modes` | List[[models.DomainsEnrollmentModes](../models/domainsenrollmentmodes.md)] | :heavy_check_mark: | N/A | [
"automatic_invitation",
"automatic_suggestion"
] | +| `domains_default_role` | *str* | :heavy_check_mark: | The role key that it will be used in order to create an organization invitation or suggestion. | member | +| `max_allowed_roles` | *Optional[int]* | :heavy_minus_sign: | N/A | 3 | +| `max_allowed_permissions` | *Optional[int]* | :heavy_minus_sign: | N/A | 15 | \ No newline at end of file diff --git a/docs/models/organizationsettingsobject.md b/docs/models/organizationsettingsobject.md new file mode 100644 index 0000000..023bd08 --- /dev/null +++ b/docs/models/organizationsettingsobject.md @@ -0,0 +1,10 @@ +# OrganizationSettingsObject + +String representing the object's type. Objects of the same type share the same value. + + +## Values + +| Name | Value | +| ----------------------- | ----------------------- | +| `ORGANIZATION_SETTINGS` | organization_settings | \ No newline at end of file diff --git a/docs/models/organizationwithlogo.md b/docs/models/organizationwithlogo.md new file mode 100644 index 0000000..45b48bd --- /dev/null +++ b/docs/models/organizationwithlogo.md @@ -0,0 +1,22 @@ +# OrganizationWithLogo + + +## Fields + +| Field | Type | Required | Description | Example | +| ----------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- | +| `object` | [models.OrganizationWithLogoObject](../models/organizationwithlogoobject.md) | :heavy_check_mark: | N/A | organization | +| `id` | *str* | :heavy_check_mark: | N/A | org_123 | +| `name` | *str* | :heavy_check_mark: | N/A | Acme Corp | +| `slug` | *str* | :heavy_check_mark: | N/A | acme-corp | +| `max_allowed_memberships` | *int* | :heavy_check_mark: | N/A | 300 | +| `public_metadata` | [models.OrganizationWithLogoPublicMetadata](../models/organizationwithlogopublicmetadata.md) | :heavy_check_mark: | N/A | {
"public_info": "Info visible to everyone"
} | +| `private_metadata` | [models.OrganizationWithLogoPrivateMetadata](../models/organizationwithlogoprivatemetadata.md) | :heavy_check_mark: | N/A | {
"internal_use_only": "Sensitive data"
} | +| `created_at` | *int* | :heavy_check_mark: | Unix timestamp of creation.
| 1625078400 | +| `updated_at` | *int* | :heavy_check_mark: | Unix timestamp of last update.
| 1625164800 | +| `image_url` | *str* | :heavy_check_mark: | N/A | https://example.com/image_url.png | +| `members_count` | *Optional[Nullable[int]]* | :heavy_minus_sign: | N/A | 150 | +| `admin_delete_enabled` | *Optional[bool]* | :heavy_minus_sign: | N/A | true | +| `created_by` | *Optional[str]* | :heavy_minus_sign: | N/A | user_123456 | +| ~~`logo_url`~~ | *Optional[str]* | :heavy_minus_sign: | : warning: ** DEPRECATED **: This will be removed in a future release, please migrate away from it as soon as possible. | https://example.com/logo_url.png | +| `has_image` | *Optional[bool]* | :heavy_minus_sign: | N/A | true | \ No newline at end of file diff --git a/docs/models/organizationwithlogoobject.md b/docs/models/organizationwithlogoobject.md new file mode 100644 index 0000000..cdb1d2e --- /dev/null +++ b/docs/models/organizationwithlogoobject.md @@ -0,0 +1,8 @@ +# OrganizationWithLogoObject + + +## Values + +| Name | Value | +| -------------- | -------------- | +| `ORGANIZATION` | organization | \ No newline at end of file diff --git a/docs/models/organizationwithlogoprivatemetadata.md b/docs/models/organizationwithlogoprivatemetadata.md new file mode 100644 index 0000000..3c6b8d7 --- /dev/null +++ b/docs/models/organizationwithlogoprivatemetadata.md @@ -0,0 +1,7 @@ +# OrganizationWithLogoPrivateMetadata + + +## Fields + +| Field | Type | Required | Description | +| ----------- | ----------- | ----------- | ----------- | \ No newline at end of file diff --git a/docs/models/organizationwithlogopublicmetadata.md b/docs/models/organizationwithlogopublicmetadata.md new file mode 100644 index 0000000..fb7c525 --- /dev/null +++ b/docs/models/organizationwithlogopublicmetadata.md @@ -0,0 +1,7 @@ +# OrganizationWithLogoPublicMetadata + + +## Fields + +| Field | Type | Required | Description | +| ----------- | ----------- | ----------- | ----------- | \ No newline at end of file diff --git a/docs/models/otp.md b/docs/models/otp.md new file mode 100644 index 0000000..af11182 --- /dev/null +++ b/docs/models/otp.md @@ -0,0 +1,11 @@ +# Otp + + +## Fields + +| Field | Type | Required | Description | Example | +| ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | +| `status` | [models.VerificationStatus](../models/verificationstatus.md) | :heavy_check_mark: | N/A | verified | +| `strategy` | [models.Strategy](../models/strategy.md) | :heavy_check_mark: | N/A | email_code | +| `attempts` | *Nullable[int]* | :heavy_check_mark: | N/A | 1 | +| `expire_at` | *Nullable[int]* | :heavy_check_mark: | N/A | 1615462399 | \ No newline at end of file diff --git a/docs/models/otpverificationstatus.md b/docs/models/otpverificationstatus.md new file mode 100644 index 0000000..788b4f9 --- /dev/null +++ b/docs/models/otpverificationstatus.md @@ -0,0 +1,11 @@ +# OTPVerificationStatus + + +## Values + +| Name | Value | +| ------------ | ------------ | +| `UNVERIFIED` | unverified | +| `VERIFIED` | verified | +| `FAILED` | failed | +| `EXPIRED` | expired | \ No newline at end of file diff --git a/docs/models/otpverificationstrategy.md b/docs/models/otpverificationstrategy.md new file mode 100644 index 0000000..653cf18 --- /dev/null +++ b/docs/models/otpverificationstrategy.md @@ -0,0 +1,11 @@ +# OTPVerificationStrategy + + +## Values + +| Name | Value | +| --------------------------- | --------------------------- | +| `PHONE_CODE` | phone_code | +| `EMAIL_CODE` | email_code | +| `RESET_PASSWORD_EMAIL_CODE` | reset_password_email_code | +| `FROM_OAUTH_DISCORD` | from_oauth_discord | \ No newline at end of file diff --git a/docs/models/passkey.md b/docs/models/passkey.md new file mode 100644 index 0000000..74e9e70 --- /dev/null +++ b/docs/models/passkey.md @@ -0,0 +1,12 @@ +# Passkey + + +## Fields + +| Field | Type | Required | Description | Example | +| ------------------------------------------------------------------------------ | ------------------------------------------------------------------------------ | ------------------------------------------------------------------------------ | ------------------------------------------------------------------------------ | ------------------------------------------------------------------------------ | +| `status` | [models.PasskeyVerificationStatus](../models/passkeyverificationstatus.md) | :heavy_check_mark: | N/A | verified | +| `strategy` | [models.PasskeyVerificationStrategy](../models/passkeyverificationstrategy.md) | :heavy_check_mark: | N/A | passkey | +| `nonce` | [Optional[models.VerificationNonce]](../models/verificationnonce.md) | :heavy_minus_sign: | N/A | nonce_value | +| `attempts` | *Optional[Nullable[int]]* | :heavy_minus_sign: | N/A | | +| `expire_at` | *Optional[Nullable[int]]* | :heavy_minus_sign: | N/A | | \ No newline at end of file diff --git a/docs/models/passkeyverificationstatus.md b/docs/models/passkeyverificationstatus.md new file mode 100644 index 0000000..2fe4f12 --- /dev/null +++ b/docs/models/passkeyverificationstatus.md @@ -0,0 +1,8 @@ +# PasskeyVerificationStatus + + +## Values + +| Name | Value | +| ---------- | ---------- | +| `VERIFIED` | verified | \ No newline at end of file diff --git a/docs/models/passkeyverificationstrategy.md b/docs/models/passkeyverificationstrategy.md new file mode 100644 index 0000000..af43d3f --- /dev/null +++ b/docs/models/passkeyverificationstrategy.md @@ -0,0 +1,8 @@ +# PasskeyVerificationStrategy + + +## Values + +| Name | Value | +| --------- | --------- | +| `PASSKEY` | passkey | \ No newline at end of file diff --git a/docs/models/passwordhasher.md b/docs/models/passwordhasher.md new file mode 100644 index 0000000..6eb3113 --- /dev/null +++ b/docs/models/passwordhasher.md @@ -0,0 +1,145 @@ +# PasswordHasher + +The hashing algorithm that was used to generate the password digest. +The algorithms we support at the moment are [bcrypt](https://en.wikipedia.org/wiki/Bcrypt), [bcrypt_sha256_django](https://docs.djangoproject.com/en/4.0/topics/auth/passwords/), +[md5](https://en.wikipedia.org/wiki/MD5), pbkdf2_sha256, pbkdf2_sha512, [pbkdf2_sha256_django](https://docs.djangoproject.com/en/4.0/topics/auth/passwords/), +[phpass](https://www.openwall.com/phpass/), [scrypt_firebase](https://firebaseopensource.com/projects/firebase/scrypt/), +[scrypt_werkzeug](https://werkzeug.palletsprojects.com/en/3.0.x/utils/#werkzeug.security.generate_password_hash), [sha256](https://en.wikipedia.org/wiki/SHA-2) +and the [argon2](https://argon2.online/) variants argon2i and argon2id. + +If you need support for any particular hashing algorithm, [please let us know](https://clerk.com/support). + +Note: for password hashers considered insecure (at this moment MD5 and SHA256), the corresponding user password hashes will be transparently migrated to Bcrypt (a secure hasher) upon the user's first successful password sign in. +Insecure schemes are marked with `(insecure)` in the list below. + +Each of the supported hashers expects the incoming digest to be in a particular format. Specifically: + +**bcrypt:** The digest should be of the following form: + +`$$$` + +**bcrypt_sha256_django:** This is the Django-specific variant of Bcrypt, using SHA256 hashing function. The format should be as follows (as exported from Django): + +`bcrypt_sha256$$$$` + +**md5** (insecure): The digest should follow the regular form e.g.: + +`5f4dcc3b5aa765d61d8327deb882cf99` + +**pbkdf2_sha256:** This is the PBKDF2 algorithm using the SHA256 hashing function. The format should be as follows: + +`pbkdf2_sha256$$$` + +Note: Both the salt and the hash are expected to be base64-encoded. + +**pbkdf2_sha512:** This is the PBKDF2 algorithm using the SHA512 hashing function. The format should be as follows: + +`pbkdf2_sha512$$$` + + _iterations:_ The number of iterations used. Must be an integer less than 420000. + _salt:_ The salt used when generating the hash. Must be less than 1024 bytes. + _hash:_ The hex-encoded hash. Must have been generated with a key length less than 1024 bytes. + +**pbkdf2_sha256_django:** This is the Django-specific variant of PBKDF2 and the digest should have the following format (as exported from Django): + +`pbkdf2_sha256$$$` + +Note: The salt is expected to be un-encoded, the hash is expected base64-encoded. + +**pbkdf2_sha1:** This is similar to pkbdf2_sha256_django, but with two differences: +1. uses sha1 instead of sha256 +2. accepts the hash as a hex-encoded string + +The format is the following: + +`pbkdf2_sha1$$$` + +**phpass:** Portable public domain password hashing framework for use in PHP applications. Digests hashed with phpass have the following sections: + +The format is the following: + +`$P$` + +- $P$ is the prefix used to identify phpass hashes. +- rounds is a single character encoding a 6-bit integer representing the number of rounds used. +- salt is eight characters drawn from [./0-9A-Za-z], providing a 48-bit salt. +- checksum is 22 characters drawn from the same set, encoding the 128-bit checksum with MD5. + +**scrypt_firebase:** The Firebase-specific variant of scrypt. +The value is expected to have 6 segments separated by the $ character and include the following information: + +_hash:_ The actual Base64 hash. This can be retrieved when exporting the user from Firebase. +_salt:_ The salt used to generate the above hash. Again, this is given when exporting the user. +_signer key:_ The base64 encoded signer key. +_salt separator:_ The base64 encoded salt separator. +_rounds:_ The number of rounds the algorithm needs to run. +_memory cost:_ The cost of the algorithm run + +The first 2 (hash and salt) are per user and can be retrieved when exporting the user from Firebase. +The other 4 values (signer key, salt separator, rounds and memory cost) are project-wide settings and can be retrieved from the project's password hash parameters. + +Once you have all these, you can combine it in the following format and send this as the digest in order for Clerk to accept it: + +`$$$$$` + +**scrypt_werkzeug:** The Werkzeug-specific variant of scrypt. + + The value is expected to have 3 segments separated by the $ character and include the following information: + + _algorithm args:_ The algorithm used to generate the hash. + _salt:_ The salt used to generate the above hash. + _hash:_ The actual Base64 hash. + + The algorithm args are the parameters used to generate the hash and are included in the digest. + +**argon2i:** Algorithms in the argon2 family generate digests that encode the following information: + +_version (v):_ The argon version, version 19 is assumed +_memory (m):_ The memory used by the algorithm (in kibibytes) +_iterations (t):_ The number of iterations to perform +_parallelism (p):_ The number of threads to use + +Parts are demarcated by the `$` character, with the first part identifying the algorithm variant. +The middle part is a comma-separated list of the encoding options (memory, iterations, parallelism). +The final part is the actual digest. + +`$argon2i$v=19$m=4096,t=3,p=1$4t6CL3P7YiHBtwESXawI8Hm20zJj4cs7/4/G3c187e0$m7RQFczcKr5bIR0IIxbpO2P0tyrLjf3eUW3M3QSwnLc` + +**argon2id:** See the previous algorithm for an explanation of the formatting. + +For the argon2id case, the value of the algorithm in the first part of the digest is `argon2id`: + +`$argon2id$v=19$m=64,t=4,p=8$Z2liZXJyaXNo$iGXEpMBTDYQ8G/71tF0qGjxRHEmR3gpGULcE93zUJVU` + +**sha256** (insecure): The digest should be a 64-length hex string, e.g.: + +`9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08` + +**sha256_salted** (insecure): The digest should be a 64-length hex string with a salt. + +The format is the following: + `$` + +The value is expected to have 2 segments separated by the $ character and include the following information: + _hash:_ The sha256 hash, a 64-length hex string. + _salt:_ The salt used to generate the above hash. Must be between 1 and 1024 bits. + + +## Values + +| Name | Value | +| ---------------------- | ---------------------- | +| `ARGON2I` | argon2i | +| `ARGON2ID` | argon2id | +| `BCRYPT` | bcrypt | +| `BCRYPT_SHA256_DJANGO` | bcrypt_sha256_django | +| `MD5` | md5 | +| `PBKDF2_SHA256` | pbkdf2_sha256 | +| `PBKDF2_SHA512` | pbkdf2_sha512 | +| `PBKDF2_SHA256_DJANGO` | pbkdf2_sha256_django | +| `PBKDF2_SHA1` | pbkdf2_sha1 | +| `PHPASS` | phpass | +| `SCRYPT_FIREBASE` | scrypt_firebase | +| `SCRYPT_WERKZEUG` | scrypt_werkzeug | +| `SHA256` | sha256 | +| `SHA256_SALTED` | sha256_salted | \ No newline at end of file diff --git a/docs/models/pathparamtemplatetype.md b/docs/models/pathparamtemplatetype.md new file mode 100644 index 0000000..2646b2f --- /dev/null +++ b/docs/models/pathparamtemplatetype.md @@ -0,0 +1,11 @@ +# PathParamTemplateType + +The type of templates to retrieve (email or SMS) + + +## Values + +| Name | Value | +| ------- | ------- | +| `EMAIL` | email | +| `SMS` | sms | \ No newline at end of file diff --git a/docs/models/phonenumber.md b/docs/models/phonenumber.md new file mode 100644 index 0000000..3e2698d --- /dev/null +++ b/docs/models/phonenumber.md @@ -0,0 +1,18 @@ +# PhoneNumber + + +## Fields + +| Field | Type | Required | Description | Example | +| ------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------ | +| `object` | [models.PhoneNumberObject](../models/phonenumberobject.md) | :heavy_check_mark: | String representing the object's type. Objects of the same type share the same value.
| phone_number | +| `phone_number` | *str* | :heavy_check_mark: | N/A | +11234567890 | +| `reserved` | *bool* | :heavy_check_mark: | N/A | false | +| `verification` | [Nullable[models.PhoneNumberVerification]](../models/phonenumberverification.md) | :heavy_check_mark: | N/A | {
"status": "verified",
"strategy": "phone_code",
"attempts": 2,
"expire_at": 1622852400
} | +| `linked_to` | List[[models.IdentificationLink](../models/identificationlink.md)] | :heavy_check_mark: | N/A | [
{
"type": "oauth_google",
"id": "link_id_123"
}
] | +| `created_at` | *int* | :heavy_check_mark: | Unix timestamp of creation
| 1594842023 | +| `updated_at` | *int* | :heavy_check_mark: | Unix timestamp of creation
| 1604842023 | +| `id` | *Optional[str]* | :heavy_minus_sign: | N/A | ph_123456789 | +| `reserved_for_second_factor` | *Optional[bool]* | :heavy_minus_sign: | N/A | false | +| `default_second_factor` | *Optional[bool]* | :heavy_minus_sign: | N/A | true | +| `backup_codes` | List[*str*] | :heavy_minus_sign: | N/A | [
"code1",
"code2",
"code3"
] | \ No newline at end of file diff --git a/docs/models/phonenumberobject.md b/docs/models/phonenumberobject.md new file mode 100644 index 0000000..18fc0c3 --- /dev/null +++ b/docs/models/phonenumberobject.md @@ -0,0 +1,11 @@ +# PhoneNumberObject + +String representing the object's type. Objects of the same type share the same value. + + + +## Values + +| Name | Value | +| -------------- | -------------- | +| `PHONE_NUMBER` | phone_number | \ No newline at end of file diff --git a/docs/models/phonenumberverification.md b/docs/models/phonenumberverification.md new file mode 100644 index 0000000..2bbc67d --- /dev/null +++ b/docs/models/phonenumberverification.md @@ -0,0 +1,17 @@ +# PhoneNumberVerification + + +## Supported Types + +### `models.VerificationOTP` + +```python +value: models.VerificationOTP = /* values here */ +``` + +### `models.VerificationAdmin` + +```python +value: models.VerificationAdmin = /* values here */ +``` + diff --git a/docs/models/previewtemplaterequest.md b/docs/models/previewtemplaterequest.md new file mode 100644 index 0000000..7b1f5f4 --- /dev/null +++ b/docs/models/previewtemplaterequest.md @@ -0,0 +1,10 @@ +# PreviewTemplateRequest + + +## Fields + +| Field | Type | Required | Description | Example | +| -------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | +| `template_type` | *str* | :heavy_check_mark: | The type of template to preview | email | +| `slug` | *str* | :heavy_check_mark: | The slug of the template to preview | welcome-email | +| `request_body` | [Optional[models.PreviewTemplateRequestBody]](../models/previewtemplaterequestbody.md) | :heavy_minus_sign: | Required parameters | | \ No newline at end of file diff --git a/docs/models/previewtemplaterequestbody.md b/docs/models/previewtemplaterequestbody.md new file mode 100644 index 0000000..e2c2fb3 --- /dev/null +++ b/docs/models/previewtemplaterequestbody.md @@ -0,0 +1,13 @@ +# PreviewTemplateRequestBody + +Required parameters + + +## Fields + +| Field | Type | Required | Description | Example | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `subject` | *Optional[Nullable[str]]* | :heavy_minus_sign: | The email subject.
Applicable only to email templates. | Welcome to our service! | +| `body` | *Optional[str]* | :heavy_minus_sign: | The template body before variable interpolation | Hi, thank you for joining our service. | +| `from_email_name` | *Optional[str]* | :heavy_minus_sign: | The local part of the From email address that will be used for emails.
For example, in the address 'hello@example.com', the local part is 'hello'.
Applicable only to email templates. | hello | +| `reply_to_email_name` | *Optional[str]* | :heavy_minus_sign: | The local part of the Reply To email address that will be used for emails.
For example, in the address 'hello@example.com', the local part is 'hello'.
Applicable only to email templates. | support | \ No newline at end of file diff --git a/docs/models/previewtemplateresponsebody.md b/docs/models/previewtemplateresponsebody.md new file mode 100644 index 0000000..b930c48 --- /dev/null +++ b/docs/models/previewtemplateresponsebody.md @@ -0,0 +1,9 @@ +# PreviewTemplateResponseBody + +OK + + +## Fields + +| Field | Type | Required | Description | +| ----------- | ----------- | ----------- | ----------- | \ No newline at end of file diff --git a/docs/models/privatemetadata.md b/docs/models/privatemetadata.md new file mode 100644 index 0000000..133ba7d --- /dev/null +++ b/docs/models/privatemetadata.md @@ -0,0 +1,7 @@ +# PrivateMetadata + + +## Fields + +| Field | Type | Required | Description | +| ----------- | ----------- | ----------- | ----------- | \ No newline at end of file diff --git a/docs/models/provider.md b/docs/models/provider.md new file mode 100644 index 0000000..1bed047 --- /dev/null +++ b/docs/models/provider.md @@ -0,0 +1,13 @@ +# Provider + +The IdP provider of the connection. + + +## Values + +| Name | Value | +| ---------------- | ---------------- | +| `SAML_CUSTOM` | saml_custom | +| `SAML_OKTA` | saml_okta | +| `SAML_GOOGLE` | saml_google | +| `SAML_MICROSOFT` | saml_microsoft | \ No newline at end of file diff --git a/docs/models/proxycheck.md b/docs/models/proxycheck.md new file mode 100644 index 0000000..9147926 --- /dev/null +++ b/docs/models/proxycheck.md @@ -0,0 +1,15 @@ +# ProxyCheck + + +## Fields + +| Field | Type | Required | Description | Example | +| -------------------------------------------------------- | -------------------------------------------------------- | -------------------------------------------------------- | -------------------------------------------------------- | -------------------------------------------------------- | +| `object` | [models.ProxyCheckObject](../models/proxycheckobject.md) | :heavy_check_mark: | N/A | proxy_check | +| `id` | *str* | :heavy_check_mark: | N/A | chk_3498fd | +| `domain_id` | *str* | :heavy_check_mark: | N/A | domain_32hfu3e | +| `last_run_at` | *int* | :heavy_check_mark: | N/A | 1622547600 | +| `proxy_url` | *str* | :heavy_check_mark: | N/A | https://example.com/__clerk | +| `successful` | *bool* | :heavy_check_mark: | N/A | true | +| `created_at` | *int* | :heavy_check_mark: | N/A | 1622547000 | +| `updated_at` | *int* | :heavy_check_mark: | N/A | 1622547700 | \ No newline at end of file diff --git a/docs/models/proxycheckobject.md b/docs/models/proxycheckobject.md new file mode 100644 index 0000000..8f072d3 --- /dev/null +++ b/docs/models/proxycheckobject.md @@ -0,0 +1,8 @@ +# ProxyCheckObject + + +## Values + +| Name | Value | +| ------------- | ------------- | +| `PROXY_CHECK` | proxy_check | \ No newline at end of file diff --git a/docs/models/publicmetadata.md b/docs/models/publicmetadata.md new file mode 100644 index 0000000..b994731 --- /dev/null +++ b/docs/models/publicmetadata.md @@ -0,0 +1,7 @@ +# PublicMetadata + + +## Fields + +| Field | Type | Required | Description | +| ----------- | ----------- | ----------- | ----------- | \ No newline at end of file diff --git a/docs/models/publicuserdata.md b/docs/models/publicuserdata.md new file mode 100644 index 0000000..0b5680a --- /dev/null +++ b/docs/models/publicuserdata.md @@ -0,0 +1,14 @@ +# PublicUserData + + +## Fields + +| Field | Type | Required | Description | Example | +| ----------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- | +| `user_id` | *Optional[str]* | :heavy_minus_sign: | N/A | usr_123456 | +| `first_name` | *Optional[Nullable[str]]* | :heavy_minus_sign: | N/A | John | +| `last_name` | *Optional[Nullable[str]]* | :heavy_minus_sign: | N/A | Doe | +| ~~`profile_image_url`~~ | *Optional[Nullable[str]]* | :heavy_minus_sign: | : warning: ** DEPRECATED **: This will be removed in a future release, please migrate away from it as soon as possible. | https://example.com/profile.jpg | +| `image_url` | *Optional[str]* | :heavy_minus_sign: | N/A | https://example.com/path/to/image.jpg | +| `has_image` | *Optional[bool]* | :heavy_minus_sign: | N/A | true | +| `identifier` | *Optional[Nullable[str]]* | :heavy_minus_sign: | N/A | john.doe@example.com | \ No newline at end of file diff --git a/docs/models/queryparamstatus.md b/docs/models/queryparamstatus.md new file mode 100644 index 0000000..69b7e96 --- /dev/null +++ b/docs/models/queryparamstatus.md @@ -0,0 +1,16 @@ +# QueryParamStatus + +Filter sessions by the provided status + + +## Values + +| Name | Value | +| ----------- | ----------- | +| `ABANDONED` | abandoned | +| `ACTIVE` | active | +| `ENDED` | ended | +| `EXPIRED` | expired | +| `REMOVED` | removed | +| `REPLACED` | replaced | +| `REVOKED` | revoked | \ No newline at end of file diff --git a/docs/models/redirecturl.md b/docs/models/redirecturl.md new file mode 100644 index 0000000..a59f1b4 --- /dev/null +++ b/docs/models/redirecturl.md @@ -0,0 +1,12 @@ +# RedirectURL + + +## Fields + +| Field | Type | Required | Description | Example | +| ---------------------------------------------------------- | ---------------------------------------------------------- | ---------------------------------------------------------- | ---------------------------------------------------------- | ---------------------------------------------------------- | +| `object` | [models.RedirectURLObject](../models/redirecturlobject.md) | :heavy_check_mark: | N/A | redirect_url | +| `id` | *str* | :heavy_check_mark: | N/A | red_12345 | +| `url` | *str* | :heavy_check_mark: | N/A | https://my-app.com/oauth-callback | +| `created_at` | *int* | :heavy_check_mark: | Unix timestamp of creation.
| 1610000000 | +| `updated_at` | *int* | :heavy_check_mark: | Unix timestamp of last update.
| 1620000000 | \ No newline at end of file diff --git a/docs/models/redirecturlobject.md b/docs/models/redirecturlobject.md new file mode 100644 index 0000000..5007ef4 --- /dev/null +++ b/docs/models/redirecturlobject.md @@ -0,0 +1,8 @@ +# RedirectURLObject + + +## Values + +| Name | Value | +| -------------- | -------------- | +| `REDIRECT_URL` | redirect_url | \ No newline at end of file diff --git a/docs/models/requestbody.md b/docs/models/requestbody.md new file mode 100644 index 0000000..be635a1 --- /dev/null +++ b/docs/models/requestbody.md @@ -0,0 +1,13 @@ +# RequestBody + + +## Fields + +| Field | Type | Required | Description | Example | +| ---------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | +| `email_address` | *str* | :heavy_check_mark: | The email address of the new member that is going to be invited to the organization | newmember@example.com | +| `inviter_user_id` | *str* | :heavy_check_mark: | The ID of the user that invites the new member to the organization.
Must be an administrator in the organization. | user_67890 | +| `role` | *str* | :heavy_check_mark: | The role of the new member in the organization. | admin | +| `public_metadata` | [Optional[models.CreateOrganizationInvitationBulkPublicMetadata]](../models/createorganizationinvitationbulkpublicmetadata.md) | :heavy_minus_sign: | Metadata saved on the organization invitation, read-only from the Frontend API and fully accessible (read/write) from the Backend API. | {} | +| `private_metadata` | [Optional[models.CreateOrganizationInvitationBulkPrivateMetadata]](../models/createorganizationinvitationbulkprivatemetadata.md) | :heavy_minus_sign: | Metadata saved on the organization invitation, fully accessible (read/write) from the Backend API but not visible from the Frontend API. | {} | +| `redirect_url` | *Optional[str]* | :heavy_minus_sign: | Optional URL that the invitee will be redirected to once they accept the invitation by clicking the join link in the invitation email. | https://example.com/welcome | \ No newline at end of file diff --git a/docs/models/responsebody.md b/docs/models/responsebody.md new file mode 100644 index 0000000..300ec92 --- /dev/null +++ b/docs/models/responsebody.md @@ -0,0 +1,16 @@ +# ResponseBody + + +## Fields + +| Field | Type | Required | Description | Example | +| ---------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- | +| `object` | *Optional[str]* | :heavy_minus_sign: | N/A | oauth_access_token | +| `external_account_id` | *Optional[str]* | :heavy_minus_sign: | External account ID | external_account_456 | +| `provider_user_id` | *Optional[str]* | :heavy_minus_sign: | The unique ID of the user in the external provider's system | provider_user_789 | +| `token` | *Optional[str]* | :heavy_minus_sign: | The access token | access_token_123 | +| `provider` | *Optional[str]* | :heavy_minus_sign: | The ID of the provider | oauth_google | +| `public_metadata` | [Optional[models.GetOAuthAccessTokenPublicMetadata]](../models/getoauthaccesstokenpublicmetadata.md) | :heavy_minus_sign: | N/A | {} | +| `label` | *Optional[Nullable[str]]* | :heavy_minus_sign: | N/A | Primary account | +| `scopes` | List[*str*] | :heavy_minus_sign: | The list of scopes that the token is valid for.
Only present for OAuth 2.0 tokens. | [
"email",
"profile"
] | +| `token_secret` | *Optional[str]* | :heavy_minus_sign: | The token secret. Only present for OAuth 1.0 tokens. | token_secret_xyz | \ No newline at end of file diff --git a/docs/models/reverttemplatepathparamtemplatetype.md b/docs/models/reverttemplatepathparamtemplatetype.md new file mode 100644 index 0000000..f93ca38 --- /dev/null +++ b/docs/models/reverttemplatepathparamtemplatetype.md @@ -0,0 +1,11 @@ +# RevertTemplatePathParamTemplateType + +The type of template to revert + + +## Values + +| Name | Value | +| ------- | ------- | +| `EMAIL` | email | +| `SMS` | sms | \ No newline at end of file diff --git a/docs/models/reverttemplaterequest.md b/docs/models/reverttemplaterequest.md new file mode 100644 index 0000000..84ae08a --- /dev/null +++ b/docs/models/reverttemplaterequest.md @@ -0,0 +1,9 @@ +# RevertTemplateRequest + + +## Fields + +| Field | Type | Required | Description | Example | +| ---------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- | +| `template_type` | [models.RevertTemplatePathParamTemplateType](../models/reverttemplatepathparamtemplatetype.md) | :heavy_check_mark: | The type of template to revert | email | +| `slug` | *str* | :heavy_check_mark: | The slug of the template to revert | welcome-email | \ No newline at end of file diff --git a/docs/models/revokeactortokenrequest.md b/docs/models/revokeactortokenrequest.md new file mode 100644 index 0000000..397c28c --- /dev/null +++ b/docs/models/revokeactortokenrequest.md @@ -0,0 +1,8 @@ +# RevokeActorTokenRequest + + +## Fields + +| Field | Type | Required | Description | Example | +| ---------------------------------------- | ---------------------------------------- | ---------------------------------------- | ---------------------------------------- | ---------------------------------------- | +| `actor_token_id` | *str* | :heavy_check_mark: | The ID of the actor token to be revoked. | act_tok_abcdefghijk | \ No newline at end of file diff --git a/docs/models/revokeinvitationrequest.md b/docs/models/revokeinvitationrequest.md new file mode 100644 index 0000000..cc9cda1 --- /dev/null +++ b/docs/models/revokeinvitationrequest.md @@ -0,0 +1,8 @@ +# RevokeInvitationRequest + + +## Fields + +| Field | Type | Required | Description | Example | +| -------------------------------------- | -------------------------------------- | -------------------------------------- | -------------------------------------- | -------------------------------------- | +| `invitation_id` | *str* | :heavy_check_mark: | The ID of the invitation to be revoked | inv_123 | \ No newline at end of file diff --git a/docs/models/revokeorganizationinvitationrequest.md b/docs/models/revokeorganizationinvitationrequest.md new file mode 100644 index 0000000..f1dece0 --- /dev/null +++ b/docs/models/revokeorganizationinvitationrequest.md @@ -0,0 +1,10 @@ +# RevokeOrganizationInvitationRequest + + +## Fields + +| Field | Type | Required | Description | Example | +| ------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------ | +| `organization_id` | *str* | :heavy_check_mark: | The organization ID. | org_123456 | +| `invitation_id` | *str* | :heavy_check_mark: | The organization invitation ID. | inv_123456 | +| `request_body` | [models.RevokeOrganizationInvitationRequestBody](../models/revokeorganizationinvitationrequestbody.md) | :heavy_check_mark: | N/A | | \ No newline at end of file diff --git a/docs/models/revokeorganizationinvitationrequestbody.md b/docs/models/revokeorganizationinvitationrequestbody.md new file mode 100644 index 0000000..f4c67c7 --- /dev/null +++ b/docs/models/revokeorganizationinvitationrequestbody.md @@ -0,0 +1,8 @@ +# RevokeOrganizationInvitationRequestBody + + +## Fields + +| Field | Type | Required | Description | Example | +| --------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------- | +| `requesting_user_id` | *str* | :heavy_check_mark: | The ID of the user that revokes the invitation.
Must be an administrator in the organization. | usr_12345 | \ No newline at end of file diff --git a/docs/models/revokesessionrequest.md b/docs/models/revokesessionrequest.md new file mode 100644 index 0000000..b18a5f1 --- /dev/null +++ b/docs/models/revokesessionrequest.md @@ -0,0 +1,8 @@ +# RevokeSessionRequest + + +## Fields + +| Field | Type | Required | Description | Example | +| --------------------- | --------------------- | --------------------- | --------------------- | --------------------- | +| `session_id` | *str* | :heavy_check_mark: | The ID of the session | sess_1234567890abcdef | \ No newline at end of file diff --git a/docs/models/revokesignintokenrequest.md b/docs/models/revokesignintokenrequest.md new file mode 100644 index 0000000..f662579 --- /dev/null +++ b/docs/models/revokesignintokenrequest.md @@ -0,0 +1,8 @@ +# RevokeSignInTokenRequest + + +## Fields + +| Field | Type | Required | Description | Example | +| ----------------------------------------- | ----------------------------------------- | ----------------------------------------- | ----------------------------------------- | ----------------------------------------- | +| `sign_in_token_id` | *str* | :heavy_check_mark: | The ID of the sign-in token to be revoked | tok_test_1234567890 | \ No newline at end of file diff --git a/docs/models/rotateoauthapplicationsecretrequest.md b/docs/models/rotateoauthapplicationsecretrequest.md new file mode 100644 index 0000000..74a37a1 --- /dev/null +++ b/docs/models/rotateoauthapplicationsecretrequest.md @@ -0,0 +1,8 @@ +# RotateOAuthApplicationSecretRequest + + +## Fields + +| Field | Type | Required | Description | Example | +| --------------------------------------------------------------------- | --------------------------------------------------------------------- | --------------------------------------------------------------------- | --------------------------------------------------------------------- | --------------------------------------------------------------------- | +| `oauth_application_id` | *str* | :heavy_check_mark: | The ID of the OAuth application for which to rotate the client secret | oauth_application_12345 | \ No newline at end of file diff --git a/docs/models/saml.md b/docs/models/saml.md new file mode 100644 index 0000000..61bfe33 --- /dev/null +++ b/docs/models/saml.md @@ -0,0 +1,13 @@ +# Saml + + +## Fields + +| Field | Type | Required | Description | Example | +| ------------------------------------------------------------------------------ | ------------------------------------------------------------------------------ | ------------------------------------------------------------------------------ | ------------------------------------------------------------------------------ | ------------------------------------------------------------------------------ | +| `status` | [models.SAMLVerificationStatus](../models/samlverificationstatus.md) | :heavy_check_mark: | N/A | verified | +| `strategy` | [models.SAMLVerificationStrategy](../models/samlverificationstrategy.md) | :heavy_check_mark: | N/A | saml | +| `external_verification_redirect_url` | *Nullable[str]* | :heavy_check_mark: | N/A | https://example.com/saml_callback | +| `expire_at` | *int* | :heavy_check_mark: | N/A | 1622852400 | +| `error` | [Optional[Nullable[models.VerificationError]]](../models/verificationerror.md) | :heavy_minus_sign: | N/A | | +| `attempts` | *Optional[Nullable[int]]* | :heavy_minus_sign: | N/A | | \ No newline at end of file diff --git a/docs/models/samlaccount.md b/docs/models/samlaccount.md new file mode 100644 index 0000000..b6f7b4f --- /dev/null +++ b/docs/models/samlaccount.md @@ -0,0 +1,17 @@ +# SAMLAccount + + +## Fields + +| Field | Type | Required | Description | Example | +| ----------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- | +| `id` | *str* | :heavy_check_mark: | N/A | saml_account_id_123 | +| `object` | [models.SAMLAccountObject](../models/samlaccountobject.md) | :heavy_check_mark: | String representing the object's type. Objects of the same type share the same value.
| saml_account | +| `provider` | *str* | :heavy_check_mark: | N/A | SAML Provider | +| `active` | *bool* | :heavy_check_mark: | N/A | true | +| `email_address` | *str* | :heavy_check_mark: | N/A | user@example.com | +| `verification` | [Nullable[models.SAMLAccountVerification]](../models/samlaccountverification.md) | :heavy_check_mark: | N/A | {
"status": "verified",
"strategy": "saml",
"external_verification_redirect_url": "https://example.com/saml_callback"
} | +| `first_name` | *Optional[Nullable[str]]* | :heavy_minus_sign: | N/A | John | +| `last_name` | *Optional[Nullable[str]]* | :heavy_minus_sign: | N/A | Doe | +| `provider_user_id` | *Optional[Nullable[str]]* | :heavy_minus_sign: | N/A | prov_user_id_123 | +| `public_metadata` | [Optional[models.SAMLAccountPublicMetadata]](../models/samlaccountpublicmetadata.md) | :heavy_minus_sign: | N/A | {
"department": "IT"
} | \ No newline at end of file diff --git a/docs/models/samlaccountobject.md b/docs/models/samlaccountobject.md new file mode 100644 index 0000000..f993007 --- /dev/null +++ b/docs/models/samlaccountobject.md @@ -0,0 +1,11 @@ +# SAMLAccountObject + +String representing the object's type. Objects of the same type share the same value. + + + +## Values + +| Name | Value | +| -------------- | -------------- | +| `SAML_ACCOUNT` | saml_account | \ No newline at end of file diff --git a/docs/models/samlaccountpublicmetadata.md b/docs/models/samlaccountpublicmetadata.md new file mode 100644 index 0000000..9ff4040 --- /dev/null +++ b/docs/models/samlaccountpublicmetadata.md @@ -0,0 +1,7 @@ +# SAMLAccountPublicMetadata + + +## Fields + +| Field | Type | Required | Description | +| ----------- | ----------- | ----------- | ----------- | \ No newline at end of file diff --git a/docs/models/samlaccountverification.md b/docs/models/samlaccountverification.md new file mode 100644 index 0000000..0d5cc92 --- /dev/null +++ b/docs/models/samlaccountverification.md @@ -0,0 +1,17 @@ +# SAMLAccountVerification + + +## Supported Types + +### `models.Saml` + +```python +value: models.Saml = /* values here */ +``` + +### `models.Ticket` + +```python +value: models.Ticket = /* values here */ +``` + diff --git a/docs/models/samlconnection.md b/docs/models/samlconnection.md new file mode 100644 index 0000000..7ca9432 --- /dev/null +++ b/docs/models/samlconnection.md @@ -0,0 +1,28 @@ +# SAMLConnection + + +## Fields + +| Field | Type | Required | Description | Example | +| ------------------------------------------------------------------ | ------------------------------------------------------------------ | ------------------------------------------------------------------ | ------------------------------------------------------------------ | ------------------------------------------------------------------ | +| `object` | [models.SAMLConnectionObject](../models/samlconnectionobject.md) | :heavy_check_mark: | N/A | saml_connection | +| `id` | *str* | :heavy_check_mark: | N/A | sc_1234567890 | +| `name` | *str* | :heavy_check_mark: | N/A | My Company SAML Config | +| `domain` | *str* | :heavy_check_mark: | N/A | mycompany.com | +| `idp_entity_id` | *Nullable[str]* | :heavy_check_mark: | N/A | idp-entity-id | +| `idp_sso_url` | *Nullable[str]* | :heavy_check_mark: | N/A | https://sso.mycompany.com | +| `idp_certificate` | *Nullable[str]* | :heavy_check_mark: | N/A | MIIDdzCCAl+gAwIBAgIJAKcyBaiiz+DT... | +| `acs_url` | *str* | :heavy_check_mark: | N/A | https://mycompany.clerk.com/saml/callback | +| `sp_entity_id` | *str* | :heavy_check_mark: | N/A | sp-entity-id | +| `sp_metadata_url` | *str* | :heavy_check_mark: | N/A | https://mycompany.clerk.com/saml/metadata | +| `active` | *bool* | :heavy_check_mark: | N/A | true | +| `provider` | *str* | :heavy_check_mark: | N/A | saml_custom | +| `user_count` | *int* | :heavy_check_mark: | N/A | 150 | +| `sync_user_attributes` | *bool* | :heavy_check_mark: | N/A | true | +| `created_at` | *int* | :heavy_check_mark: | Unix timestamp of creation.
| 1614768000 | +| `updated_at` | *int* | :heavy_check_mark: | Unix timestamp of last update.
| 1622540800 | +| `idp_metadata_url` | *Optional[Nullable[str]]* | :heavy_minus_sign: | N/A | https://sso.mycompany.com/metadata | +| `idp_metadata` | *Optional[Nullable[str]]* | :heavy_minus_sign: | N/A | | 5 | \ No newline at end of file diff --git a/docs/models/samlerrorclerkerror.md b/docs/models/samlerrorclerkerror.md new file mode 100644 index 0000000..da1c9ee --- /dev/null +++ b/docs/models/samlerrorclerkerror.md @@ -0,0 +1,12 @@ +# SAMLErrorClerkError + + +## Fields + +| Field | Type | Required | Description | Example | +| ------------------------------------------------------------------------ | ------------------------------------------------------------------------ | ------------------------------------------------------------------------ | ------------------------------------------------------------------------ | ------------------------------------------------------------------------ | +| `message` | *str* | :heavy_check_mark: | N/A | Invalid input | +| `long_message` | *str* | :heavy_check_mark: | N/A | The input provided does not meet the requirements. | +| `code` | *str* | :heavy_check_mark: | N/A | 400_bad_request | +| `meta` | [Optional[models.ClerkErrorErrorMeta]](../models/clerkerrorerrormeta.md) | :heavy_minus_sign: | N/A | {} | +| `clerk_trace_id` | *Optional[str]* | :heavy_minus_sign: | N/A | trace_123456789abcd | \ No newline at end of file diff --git a/docs/models/samlverificationstatus.md b/docs/models/samlverificationstatus.md new file mode 100644 index 0000000..64f88a8 --- /dev/null +++ b/docs/models/samlverificationstatus.md @@ -0,0 +1,12 @@ +# SAMLVerificationStatus + + +## Values + +| Name | Value | +| -------------- | -------------- | +| `UNVERIFIED` | unverified | +| `VERIFIED` | verified | +| `FAILED` | failed | +| `EXPIRED` | expired | +| `TRANSFERABLE` | transferable | \ No newline at end of file diff --git a/docs/models/samlverificationstrategy.md b/docs/models/samlverificationstrategy.md new file mode 100644 index 0000000..65978b9 --- /dev/null +++ b/docs/models/samlverificationstrategy.md @@ -0,0 +1,8 @@ +# SAMLVerificationStrategy + + +## Values + +| Name | Value | +| ------ | ------ | +| `SAML` | saml | \ No newline at end of file diff --git a/docs/models/schemaspasskey.md b/docs/models/schemaspasskey.md new file mode 100644 index 0000000..0e4da75 --- /dev/null +++ b/docs/models/schemaspasskey.md @@ -0,0 +1,12 @@ +# SchemasPasskey + + +## Fields + +| Field | Type | Required | Description | Example | +| -------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | +| `object` | [models.SchemasPasskeyObject](../models/schemaspasskeyobject.md) | :heavy_check_mark: | String representing the object's type. Objects of the same type share the same value.
| passkey | +| `name` | *str* | :heavy_check_mark: | N/A | My Passkey | +| `last_used_at` | *int* | :heavy_check_mark: | Unix timestamp of when the passkey was last used.
| 1615852800 | +| `verification` | [Nullable[models.SchemasPasskeyVerification]](../models/schemaspasskeyverification.md) | :heavy_check_mark: | N/A | {
"status": "verified",
"strategy": "passkey",
"nonce": "nonce_value"
} | +| `id` | *Optional[str]* | :heavy_minus_sign: | N/A | passkey_id_123 | \ No newline at end of file diff --git a/docs/models/schemaspasskeyobject.md b/docs/models/schemaspasskeyobject.md new file mode 100644 index 0000000..dba361d --- /dev/null +++ b/docs/models/schemaspasskeyobject.md @@ -0,0 +1,11 @@ +# SchemasPasskeyObject + +String representing the object's type. Objects of the same type share the same value. + + + +## Values + +| Name | Value | +| --------- | --------- | +| `PASSKEY` | passkey | \ No newline at end of file diff --git a/docs/models/schemaspasskeyverification.md b/docs/models/schemaspasskeyverification.md new file mode 100644 index 0000000..eb84e5b --- /dev/null +++ b/docs/models/schemaspasskeyverification.md @@ -0,0 +1,11 @@ +# SchemasPasskeyVerification + + +## Supported Types + +### `models.Passkey` + +```python +value: models.Passkey = /* values here */ +``` + diff --git a/docs/models/security.md b/docs/models/security.md new file mode 100644 index 0000000..f218fa1 --- /dev/null +++ b/docs/models/security.md @@ -0,0 +1,8 @@ +# Security + + +## Fields + +| Field | Type | Required | Description | +| ------------------ | ------------------ | ------------------ | ------------------ | +| `bearer_auth` | *str* | :heavy_check_mark: | N/A | \ No newline at end of file diff --git a/docs/models/session.md b/docs/models/session.md new file mode 100644 index 0000000..9d84a5f --- /dev/null +++ b/docs/models/session.md @@ -0,0 +1,19 @@ +# Session + + +## Fields + +| Field | Type | Required | Description | Example | +| -------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | +| `object` | [models.SessionObject](../models/sessionobject.md) | :heavy_check_mark: | String representing the object's type. Objects of the same type share the same value.
| session | +| `id` | *str* | :heavy_check_mark: | N/A | sess_123456789abcd | +| `user_id` | *str* | :heavy_check_mark: | N/A | user_123456789abcd | +| `client_id` | *str* | :heavy_check_mark: | N/A | client_123456789abcd | +| `status` | [models.Status](../models/status.md) | :heavy_check_mark: | N/A | active | +| `last_active_at` | *int* | :heavy_check_mark: | N/A | 1622471123 | +| `expire_at` | *int* | :heavy_check_mark: | N/A | 1685471123 | +| `abandon_at` | *int* | :heavy_check_mark: | N/A | 1630471123 | +| `updated_at` | *int* | :heavy_check_mark: | Unix timestamp of last update.
| 1622532323 | +| `created_at` | *int* | :heavy_check_mark: | Unix timestamp of creation.
| 1622470000 | +| `actor` | [Optional[Nullable[models.Actor]]](../models/actor.md) | :heavy_minus_sign: | N/A | | +| `last_active_organization_id` | *Optional[Nullable[str]]* | :heavy_minus_sign: | N/A | org_123456789abcd | \ No newline at end of file diff --git a/docs/models/sessionobject.md b/docs/models/sessionobject.md new file mode 100644 index 0000000..ff6d435 --- /dev/null +++ b/docs/models/sessionobject.md @@ -0,0 +1,11 @@ +# SessionObject + +String representing the object's type. Objects of the same type share the same value. + + + +## Values + +| Name | Value | +| --------- | --------- | +| `SESSION` | session | \ No newline at end of file diff --git a/docs/models/setuserprofileimagerequest.md b/docs/models/setuserprofileimagerequest.md new file mode 100644 index 0000000..1461b7d --- /dev/null +++ b/docs/models/setuserprofileimagerequest.md @@ -0,0 +1,9 @@ +# SetUserProfileImageRequest + + +## Fields + +| Field | Type | Required | Description | Example | +| ------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------ | +| `user_id` | *str* | :heavy_check_mark: | The ID of the user to update the profile image for | usr_test123 | +| `request_body` | [models.SetUserProfileImageRequestBody](../models/setuserprofileimagerequestbody.md) | :heavy_check_mark: | N/A | | \ No newline at end of file diff --git a/docs/models/setuserprofileimagerequestbody.md b/docs/models/setuserprofileimagerequestbody.md new file mode 100644 index 0000000..c51ca31 --- /dev/null +++ b/docs/models/setuserprofileimagerequestbody.md @@ -0,0 +1,8 @@ +# SetUserProfileImageRequestBody + + +## Fields + +| Field | Type | Required | Description | +| ------------------------------------------ | ------------------------------------------ | ------------------------------------------ | ------------------------------------------ | +| `file` | [Optional[models.File]](../models/file.md) | :heavy_minus_sign: | N/A | \ No newline at end of file diff --git a/docs/models/signintoken.md b/docs/models/signintoken.md new file mode 100644 index 0000000..e092254 --- /dev/null +++ b/docs/models/signintoken.md @@ -0,0 +1,15 @@ +# SignInToken + + +## Fields + +| Field | Type | Required | Description | Example | +| ---------------------------------------------------------- | ---------------------------------------------------------- | ---------------------------------------------------------- | ---------------------------------------------------------- | ---------------------------------------------------------- | +| `object` | [models.SignInTokenObject](../models/signintokenobject.md) | :heavy_check_mark: | N/A | sign_in_token | +| `id` | *str* | :heavy_check_mark: | N/A | token_12345 | +| `status` | [models.SignInTokenStatus](../models/signintokenstatus.md) | :heavy_check_mark: | N/A | pending | +| `user_id` | *str* | :heavy_check_mark: | N/A | user_12345 | +| `created_at` | *int* | :heavy_check_mark: | Unix timestamp of creation.
| 1609459200 | +| `updated_at` | *int* | :heavy_check_mark: | Unix timestamp of last update.
| 1612137600 | +| `token` | *Optional[str]* | :heavy_minus_sign: | N/A | secret_token | +| `url` | *Optional[Nullable[str]]* | :heavy_minus_sign: | N/A | https://example.com/signin/token | \ No newline at end of file diff --git a/docs/models/signintokenobject.md b/docs/models/signintokenobject.md new file mode 100644 index 0000000..51c2643 --- /dev/null +++ b/docs/models/signintokenobject.md @@ -0,0 +1,8 @@ +# SignInTokenObject + + +## Values + +| Name | Value | +| --------------- | --------------- | +| `SIGN_IN_TOKEN` | sign_in_token | \ No newline at end of file diff --git a/docs/models/signintokenstatus.md b/docs/models/signintokenstatus.md new file mode 100644 index 0000000..d381a77 --- /dev/null +++ b/docs/models/signintokenstatus.md @@ -0,0 +1,10 @@ +# SignInTokenStatus + + +## Values + +| Name | Value | +| ---------- | ---------- | +| `PENDING` | pending | +| `ACCEPTED` | accepted | +| `REVOKED` | revoked | \ No newline at end of file diff --git a/docs/models/signup.md b/docs/models/signup.md new file mode 100644 index 0000000..a948a15 --- /dev/null +++ b/docs/models/signup.md @@ -0,0 +1,30 @@ +# SignUp + + +## Fields + +| Field | Type | Required | Description | Example | +| -------------------------------------------------------------------------- | -------------------------------------------------------------------------- | -------------------------------------------------------------------------- | -------------------------------------------------------------------------- | -------------------------------------------------------------------------- | +| `object` | [models.SignUpObject](../models/signupobject.md) | :heavy_check_mark: | N/A | sign_up_attempt | +| `id` | *str* | :heavy_check_mark: | N/A | signup_1234567890abcdef | +| `status` | [models.SignUpStatus](../models/signupstatus.md) | :heavy_check_mark: | N/A | complete | +| `password_enabled` | *bool* | :heavy_check_mark: | N/A | true | +| `custom_action` | *bool* | :heavy_check_mark: | N/A | false | +| `abandon_at` | *int* | :heavy_check_mark: | N/A | 1609459200 | +| `required_fields` | List[*str*] | :heavy_minus_sign: | N/A | [
"email_address"
] | +| `optional_fields` | List[*str*] | :heavy_minus_sign: | N/A | [
"first_name",
"last_name"
] | +| `missing_fields` | List[*str*] | :heavy_minus_sign: | N/A | [
"phone_number"
] | +| `unverified_fields` | List[*str*] | :heavy_minus_sign: | N/A | [
"email_address"
] | +| `verifications` | [Optional[models.Verifications]](../models/verifications.md) | :heavy_minus_sign: | N/A | | +| `username` | *Optional[Nullable[str]]* | :heavy_minus_sign: | N/A | user_123456 | +| `email_address` | *Optional[Nullable[str]]* | :heavy_minus_sign: | N/A | user@example.com | +| `phone_number` | *Optional[Nullable[str]]* | :heavy_minus_sign: | N/A | +1234567890 | +| `web3_wallet` | *Optional[Nullable[str]]* | :heavy_minus_sign: | N/A | 0x1234567890abcdef1234567890abcdef12345678 | +| `first_name` | *Optional[Nullable[str]]* | :heavy_minus_sign: | N/A | John | +| `last_name` | *Optional[Nullable[str]]* | :heavy_minus_sign: | N/A | Doe | +| `unsafe_metadata` | [Optional[models.SignUpUnsafeMetadata]](../models/signupunsafemetadata.md) | :heavy_minus_sign: | N/A | | +| `public_metadata` | [Optional[models.SignUpPublicMetadata]](../models/signuppublicmetadata.md) | :heavy_minus_sign: | N/A | | +| `external_id` | *Optional[Nullable[str]]* | :heavy_minus_sign: | N/A | ext_id_7890abcdef123456 | +| `created_session_id` | *Optional[Nullable[str]]* | :heavy_minus_sign: | N/A | sess_1234567890abcdef | +| `created_user_id` | *Optional[Nullable[str]]* | :heavy_minus_sign: | N/A | user_1234567890abcdef | +| `external_account` | [Optional[models.ExternalAccount]](../models/externalaccount.md) | :heavy_minus_sign: | N/A | | \ No newline at end of file diff --git a/docs/models/signupobject.md b/docs/models/signupobject.md new file mode 100644 index 0000000..15c2334 --- /dev/null +++ b/docs/models/signupobject.md @@ -0,0 +1,8 @@ +# SignUpObject + + +## Values + +| Name | Value | +| ----------------- | ----------------- | +| `SIGN_UP_ATTEMPT` | sign_up_attempt | \ No newline at end of file diff --git a/docs/models/signuppublicmetadata.md b/docs/models/signuppublicmetadata.md new file mode 100644 index 0000000..7e9e611 --- /dev/null +++ b/docs/models/signuppublicmetadata.md @@ -0,0 +1,7 @@ +# SignUpPublicMetadata + + +## Fields + +| Field | Type | Required | Description | +| ----------- | ----------- | ----------- | ----------- | \ No newline at end of file diff --git a/docs/models/signupstatus.md b/docs/models/signupstatus.md new file mode 100644 index 0000000..17a919b --- /dev/null +++ b/docs/models/signupstatus.md @@ -0,0 +1,10 @@ +# SignUpStatus + + +## Values + +| Name | Value | +| ---------------------- | ---------------------- | +| `MISSING_REQUIREMENTS` | missing_requirements | +| `COMPLETE` | complete | +| `ABANDONED` | abandoned | \ No newline at end of file diff --git a/docs/models/signupunsafemetadata.md b/docs/models/signupunsafemetadata.md new file mode 100644 index 0000000..8a47b7e --- /dev/null +++ b/docs/models/signupunsafemetadata.md @@ -0,0 +1,7 @@ +# SignUpUnsafeMetadata + + +## Fields + +| Field | Type | Required | Description | +| ----------- | ----------- | ----------- | ----------- | \ No newline at end of file diff --git a/docs/models/status.md b/docs/models/status.md new file mode 100644 index 0000000..f8948a2 --- /dev/null +++ b/docs/models/status.md @@ -0,0 +1,14 @@ +# Status + + +## Values + +| Name | Value | +| ----------- | ----------- | +| `ACTIVE` | active | +| `REVOKED` | revoked | +| `ENDED` | ended | +| `EXPIRED` | expired | +| `REMOVED` | removed | +| `ABANDONED` | abandoned | +| `REPLACED` | replaced | \ No newline at end of file diff --git a/docs/models/strategy.md b/docs/models/strategy.md new file mode 100644 index 0000000..c387207 --- /dev/null +++ b/docs/models/strategy.md @@ -0,0 +1,11 @@ +# Strategy + + +## Values + +| Name | Value | +| --------------------------- | --------------------------- | +| `PHONE_CODE` | phone_code | +| `EMAIL_CODE` | email_code | +| `RESET_PASSWORD_EMAIL_CODE` | reset_password_email_code | +| `FROM_OAUTH_DISCORD` | from_oauth_discord | \ No newline at end of file diff --git a/docs/models/svixurl.md b/docs/models/svixurl.md new file mode 100644 index 0000000..b5dcde4 --- /dev/null +++ b/docs/models/svixurl.md @@ -0,0 +1,8 @@ +# SvixURL + + +## Fields + +| Field | Type | Required | Description | Example | +| -------------------------------------- | -------------------------------------- | -------------------------------------- | -------------------------------------- | -------------------------------------- | +| `svix_url` | *str* | :heavy_check_mark: | N/A | https://app.svix.com/your-instance-url | \ No newline at end of file diff --git a/docs/models/template.md b/docs/models/template.md new file mode 100644 index 0000000..2324757 --- /dev/null +++ b/docs/models/template.md @@ -0,0 +1,28 @@ +# Template + + +## Fields + +| Field | Type | Required | Description | Example | +| -------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | +| `id` | *Optional[str]* | :heavy_minus_sign: | N/A | temp_12345 | +| `object` | [Optional[models.TemplateObject]](../models/templateobject.md) | :heavy_minus_sign: | String representing the object's type. Objects of the same type share the same value.
| template | +| `instance_id` | *Optional[Nullable[str]]* | :heavy_minus_sign: | the id of the instance the template belongs to | inst_67890 | +| `resource_type` | *Optional[str]* | :heavy_minus_sign: | whether this is a system (default) or user overridden) template | system | +| `template_type` | *Optional[str]* | :heavy_minus_sign: | whether this is an email or SMS template | email | +| `name` | *Optional[str]* | :heavy_minus_sign: | user-friendly name of the template | Welcome Email | +| `slug` | *Optional[str]* | :heavy_minus_sign: | machine-friendly name of the template | welcome_email | +| `position` | *Optional[int]* | :heavy_minus_sign: | position with the listing of templates | 1 | +| `can_revert` | *Optional[bool]* | :heavy_minus_sign: | whether this template can be reverted to the corresponding system default | false | +| `can_delete` | *Optional[bool]* | :heavy_minus_sign: | whether this template can be deleted | true | +| `can_disable` | *Optional[bool]* | :heavy_minus_sign: | whether this template can be disabled, true only for notification SMS templates | false | +| `subject` | *Optional[Nullable[str]]* | :heavy_minus_sign: | email subject | Welcome to our service! | +| `markup` | *Optional[str]* | :heavy_minus_sign: | the editor markup used to generate the body of the template |

Hello, {{ user.name }}

| +| `body` | *Optional[str]* | :heavy_minus_sign: | the template body before variable interpolation | You are now signed up. Welcome! | +| `available_variables` | List[*str*] | :heavy_minus_sign: | list of variables that are available for use in the template body | [
"user.name",
"user.email"
] | +| `required_variables` | List[*str*] | :heavy_minus_sign: | list of variables that must be contained in the template body | [
"user.name"
] | +| `from_email_name` | *Optional[str]* | :heavy_minus_sign: | N/A | Clerk Support | +| `reply_to_email_name` | *Optional[str]* | :heavy_minus_sign: | N/A | support@clerk.com | +| `delivered_by_clerk` | *Optional[bool]* | :heavy_minus_sign: | N/A | true | +| `updated_at` | *Optional[int]* | :heavy_minus_sign: | Unix timestamp of last update.
| 1610000000 | +| `created_at` | *Optional[int]* | :heavy_minus_sign: | Unix timestamp of creation.
| 1600000000 | \ No newline at end of file diff --git a/docs/models/templateobject.md b/docs/models/templateobject.md new file mode 100644 index 0000000..417d2a6 --- /dev/null +++ b/docs/models/templateobject.md @@ -0,0 +1,11 @@ +# TemplateObject + +String representing the object's type. Objects of the same type share the same value. + + + +## Values + +| Name | Value | +| ---------- | ---------- | +| `TEMPLATE` | template | \ No newline at end of file diff --git a/docs/models/templatetype.md b/docs/models/templatetype.md new file mode 100644 index 0000000..cabd96a --- /dev/null +++ b/docs/models/templatetype.md @@ -0,0 +1,11 @@ +# TemplateType + +The type of templates to list (email or SMS) + + +## Values + +| Name | Value | +| ------- | ------- | +| `EMAIL` | email | +| `SMS` | sms | \ No newline at end of file diff --git a/docs/models/testingtoken.md b/docs/models/testingtoken.md new file mode 100644 index 0000000..6124a0f --- /dev/null +++ b/docs/models/testingtoken.md @@ -0,0 +1,10 @@ +# TestingToken + + +## Fields + +| Field | Type | Required | Description | Example | +| ------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------ | +| `object` | [models.TestingTokenObject](../models/testingtokenobject.md) | :heavy_check_mark: | N/A | testing_token | +| `token` | *str* | :heavy_check_mark: | The actual token. This value is meant to be passed in the `__clerk_testing_token` query parameter with requests to the Frontend API. | 1713877200-c_2J2MvPu9PnXcuhbPZNao0LOXqK9A7YrnBn0HmIWxy | +| `expires_at` | *int* | :heavy_check_mark: | Unix timestamp of the token's expiration time.
| 1713880800 | \ No newline at end of file diff --git a/docs/models/testingtokenobject.md b/docs/models/testingtokenobject.md new file mode 100644 index 0000000..a9dd8c0 --- /dev/null +++ b/docs/models/testingtokenobject.md @@ -0,0 +1,8 @@ +# TestingTokenObject + + +## Values + +| Name | Value | +| --------------- | --------------- | +| `TESTING_TOKEN` | testing_token | \ No newline at end of file diff --git a/docs/models/ticket.md b/docs/models/ticket.md new file mode 100644 index 0000000..80b049b --- /dev/null +++ b/docs/models/ticket.md @@ -0,0 +1,11 @@ +# Ticket + + +## Fields + +| Field | Type | Required | Description | Example | +| ---------------------------------------------------------------------------- | ---------------------------------------------------------------------------- | ---------------------------------------------------------------------------- | ---------------------------------------------------------------------------- | ---------------------------------------------------------------------------- | +| `status` | [models.TicketVerificationStatus](../models/ticketverificationstatus.md) | :heavy_check_mark: | N/A | verified | +| `strategy` | [models.TicketVerificationStrategy](../models/ticketverificationstrategy.md) | :heavy_check_mark: | N/A | ticket | +| `attempts` | *Optional[Nullable[int]]* | :heavy_minus_sign: | N/A | | +| `expire_at` | *Optional[Nullable[int]]* | :heavy_minus_sign: | N/A | | \ No newline at end of file diff --git a/docs/models/ticketverificationstatus.md b/docs/models/ticketverificationstatus.md new file mode 100644 index 0000000..552fb31 --- /dev/null +++ b/docs/models/ticketverificationstatus.md @@ -0,0 +1,10 @@ +# TicketVerificationStatus + + +## Values + +| Name | Value | +| ------------ | ------------ | +| `UNVERIFIED` | unverified | +| `VERIFIED` | verified | +| `EXPIRED` | expired | \ No newline at end of file diff --git a/docs/models/ticketverificationstrategy.md b/docs/models/ticketverificationstrategy.md new file mode 100644 index 0000000..6287be6 --- /dev/null +++ b/docs/models/ticketverificationstrategy.md @@ -0,0 +1,8 @@ +# TicketVerificationStrategy + + +## Values + +| Name | Value | +| -------- | -------- | +| `TICKET` | ticket | \ No newline at end of file diff --git a/docs/models/toggletemplatedeliverypathparamtemplatetype.md b/docs/models/toggletemplatedeliverypathparamtemplatetype.md new file mode 100644 index 0000000..11aebaf --- /dev/null +++ b/docs/models/toggletemplatedeliverypathparamtemplatetype.md @@ -0,0 +1,11 @@ +# ToggleTemplateDeliveryPathParamTemplateType + +The type of template to toggle delivery for + + +## Values + +| Name | Value | +| ------- | ------- | +| `EMAIL` | email | +| `SMS` | sms | \ No newline at end of file diff --git a/docs/models/toggletemplatedeliveryrequest.md b/docs/models/toggletemplatedeliveryrequest.md new file mode 100644 index 0000000..ccc9d09 --- /dev/null +++ b/docs/models/toggletemplatedeliveryrequest.md @@ -0,0 +1,10 @@ +# ToggleTemplateDeliveryRequest + + +## Fields + +| Field | Type | Required | Description | Example | +| -------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------- | +| `template_type` | [models.ToggleTemplateDeliveryPathParamTemplateType](../models/toggletemplatedeliverypathparamtemplatetype.md) | :heavy_check_mark: | The type of template to toggle delivery for | email | +| `slug` | *str* | :heavy_check_mark: | The slug of the template for which to toggle delivery | welcome-email | +| `request_body` | [Optional[models.ToggleTemplateDeliveryRequestBody]](../models/toggletemplatedeliveryrequestbody.md) | :heavy_minus_sign: | N/A | | \ No newline at end of file diff --git a/docs/models/toggletemplatedeliveryrequestbody.md b/docs/models/toggletemplatedeliveryrequestbody.md new file mode 100644 index 0000000..b366173 --- /dev/null +++ b/docs/models/toggletemplatedeliveryrequestbody.md @@ -0,0 +1,8 @@ +# ToggleTemplateDeliveryRequestBody + + +## Fields + +| Field | Type | Required | Description | Example | +| --------------------------------------------------------------------------------- | --------------------------------------------------------------------------------- | --------------------------------------------------------------------------------- | --------------------------------------------------------------------------------- | --------------------------------------------------------------------------------- | +| `delivered_by_clerk` | *Optional[Nullable[bool]]* | :heavy_minus_sign: | Whether Clerk should deliver emails or SMS messages based on the current template | true | \ No newline at end of file diff --git a/docs/models/totalcount.md b/docs/models/totalcount.md new file mode 100644 index 0000000..ef4ba73 --- /dev/null +++ b/docs/models/totalcount.md @@ -0,0 +1,9 @@ +# TotalCount + + +## Fields + +| Field | Type | Required | Description | Example | +| -------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | +| `object` | [models.TotalCountObject](../models/totalcountobject.md) | :heavy_check_mark: | String representing the object's type. Objects of the same type share the same value.
| total_count | +| `total_count` | *int* | :heavy_check_mark: | N/A | 100 | \ No newline at end of file diff --git a/docs/models/totalcountobject.md b/docs/models/totalcountobject.md new file mode 100644 index 0000000..4781d70 --- /dev/null +++ b/docs/models/totalcountobject.md @@ -0,0 +1,11 @@ +# TotalCountObject + +String representing the object's type. Objects of the same type share the same value. + + + +## Values + +| Name | Value | +| ------------- | ------------- | +| `TOTAL_COUNT` | total_count | \ No newline at end of file diff --git a/docs/models/type.md b/docs/models/type.md new file mode 100644 index 0000000..5123c86 --- /dev/null +++ b/docs/models/type.md @@ -0,0 +1,11 @@ +# Type + + +## Values + +| Name | Value | +| --------------- | --------------- | +| `OAUTH_GOOGLE` | oauth_google | +| `OAUTH_MOCK` | oauth_mock | +| `SAML` | saml | +| `OAUTH_DISCORD` | oauth_discord | \ No newline at end of file diff --git a/docs/models/unbanuserrequest.md b/docs/models/unbanuserrequest.md new file mode 100644 index 0000000..533ae48 --- /dev/null +++ b/docs/models/unbanuserrequest.md @@ -0,0 +1,8 @@ +# UnbanUserRequest + + +## Fields + +| Field | Type | Required | Description | Example | +| --------------------------- | --------------------------- | --------------------------- | --------------------------- | --------------------------- | +| `user_id` | *str* | :heavy_check_mark: | The ID of the user to unban | user_12345 | \ No newline at end of file diff --git a/docs/models/unlockuserrequest.md b/docs/models/unlockuserrequest.md new file mode 100644 index 0000000..0505416 --- /dev/null +++ b/docs/models/unlockuserrequest.md @@ -0,0 +1,8 @@ +# UnlockUserRequest + + +## Fields + +| Field | Type | Required | Description | Example | +| ---------------------------- | ---------------------------- | ---------------------------- | ---------------------------- | ---------------------------- | +| `user_id` | *str* | :heavy_check_mark: | The ID of the user to unlock | user_12345 | \ No newline at end of file diff --git a/docs/models/unsafemetadata.md b/docs/models/unsafemetadata.md new file mode 100644 index 0000000..cf94d10 --- /dev/null +++ b/docs/models/unsafemetadata.md @@ -0,0 +1,7 @@ +# UnsafeMetadata + + +## Fields + +| Field | Type | Required | Description | +| ----------- | ----------- | ----------- | ----------- | \ No newline at end of file diff --git a/docs/models/updatedomainrequest.md b/docs/models/updatedomainrequest.md new file mode 100644 index 0000000..fdd4381 --- /dev/null +++ b/docs/models/updatedomainrequest.md @@ -0,0 +1,9 @@ +# UpdateDomainRequest + + +## Fields + +| Field | Type | Required | Description | Example | +| ---------------------------------------------------------------------- | ---------------------------------------------------------------------- | ---------------------------------------------------------------------- | ---------------------------------------------------------------------- | ---------------------------------------------------------------------- | +| `domain_id` | *str* | :heavy_check_mark: | The ID of the domain that will be updated. | domain_12345 | +| `request_body` | [models.UpdateDomainRequestBody](../models/updatedomainrequestbody.md) | :heavy_check_mark: | N/A | | \ No newline at end of file diff --git a/docs/models/updatedomainrequestbody.md b/docs/models/updatedomainrequestbody.md new file mode 100644 index 0000000..33a8601 --- /dev/null +++ b/docs/models/updatedomainrequestbody.md @@ -0,0 +1,9 @@ +# UpdateDomainRequestBody + + +## Fields + +| Field | Type | Required | Description | Example | +| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `name` | *Optional[Nullable[str]]* | :heavy_minus_sign: | The new domain name. For development instances, can contain the port,
i.e `myhostname:3000`. For production instances, must be a valid FQDN,
i.e `mysite.com`. Cannot contain protocol scheme. | example.com | +| `proxy_url` | *Optional[Nullable[str]]* | :heavy_minus_sign: | The full URL of the proxy that will forward requests to Clerk's Frontend API.
Can only be updated for production instances. | http://proxy.example.com | \ No newline at end of file diff --git a/docs/models/updateemailaddressrequest.md b/docs/models/updateemailaddressrequest.md new file mode 100644 index 0000000..0aa8ed5 --- /dev/null +++ b/docs/models/updateemailaddressrequest.md @@ -0,0 +1,9 @@ +# UpdateEmailAddressRequest + + +## Fields + +| Field | Type | Required | Description | Example | +| -------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------- | +| `email_address_id` | *str* | :heavy_check_mark: | The ID of the email address to update | email_address_id_example | +| `request_body` | [Optional[models.UpdateEmailAddressRequestBody]](../models/updateemailaddressrequestbody.md) | :heavy_minus_sign: | N/A | | \ No newline at end of file diff --git a/docs/models/updateemailaddressrequestbody.md b/docs/models/updateemailaddressrequestbody.md new file mode 100644 index 0000000..1d7ca8b --- /dev/null +++ b/docs/models/updateemailaddressrequestbody.md @@ -0,0 +1,9 @@ +# UpdateEmailAddressRequestBody + + +## Fields + +| Field | Type | Required | Description | Example | +| ----------------------------------------------------------------- | ----------------------------------------------------------------- | ----------------------------------------------------------------- | ----------------------------------------------------------------- | ----------------------------------------------------------------- | +| `verified` | *Optional[Nullable[bool]]* | :heavy_minus_sign: | The email address will be marked as verified. | false | +| `primary` | *Optional[Nullable[bool]]* | :heavy_minus_sign: | Set this email address as the primary email address for the user. | true | \ No newline at end of file diff --git a/docs/models/updateinstanceauthconfigrequestbody.md b/docs/models/updateinstanceauthconfigrequestbody.md new file mode 100644 index 0000000..66e03a1 --- /dev/null +++ b/docs/models/updateinstanceauthconfigrequestbody.md @@ -0,0 +1,13 @@ +# UpdateInstanceAuthConfigRequestBody + + +## Fields + +| Field | Type | Required | Description | Example | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `restricted_to_allowlist` | *Optional[Nullable[bool]]* | :heavy_minus_sign: | Whether sign up is restricted to email addresses, phone numbers and usernames that are on the allowlist. | false | +| `from_email_address` | *Optional[Nullable[str]]* | :heavy_minus_sign: | The local part of the email address from which authentication-related emails (e.g. OTP code, magic links) will be sent.
Only alphanumeric values are allowed.
Note that this value should contain only the local part of the address (e.g. `foo` for `foo@example.com`). | noreply | +| `progressive_sign_up` | *Optional[Nullable[bool]]* | :heavy_minus_sign: | Enable the Progressive Sign Up algorithm. Refer to the [docs](https://clerk.com/docs/upgrade-guides/progressive-sign-up) for more info. | true | +| `session_token_template` | *Optional[Nullable[str]]* | :heavy_minus_sign: | The name of the JWT Template used to augment your session tokens. To disable this, pass an empty string. | defaultSessionToken | +| `enhanced_email_deliverability` | *Optional[Nullable[bool]]* | :heavy_minus_sign: | The "enhanced_email_deliverability" feature will send emails from "verifications@clerk.dev" instead of your domain.
This can be helpful if you do not have a high domain reputation. | true | +| `test_mode` | *Optional[Nullable[bool]]* | :heavy_minus_sign: | Toggles test mode for this instance, allowing the use of test email addresses and phone numbers.
Defaults to true for development instances. | true | \ No newline at end of file diff --git a/docs/models/updateinstanceorganizationsettingsrequestbody.md b/docs/models/updateinstanceorganizationsettingsrequestbody.md new file mode 100644 index 0000000..069554f --- /dev/null +++ b/docs/models/updateinstanceorganizationsettingsrequestbody.md @@ -0,0 +1,14 @@ +# UpdateInstanceOrganizationSettingsRequestBody + + +## Fields + +| Field | Type | Required | Description | Example | +| -------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- | +| `enabled` | *Optional[Nullable[bool]]* | :heavy_minus_sign: | N/A | true | +| `max_allowed_memberships` | *Optional[Nullable[int]]* | :heavy_minus_sign: | N/A | 10 | +| `admin_delete_enabled` | *Optional[Nullable[bool]]* | :heavy_minus_sign: | N/A | false | +| `domains_enabled` | *Optional[Nullable[bool]]* | :heavy_minus_sign: | N/A | true | +| `domains_enrollment_modes` | List[*str*] | :heavy_minus_sign: | Specify which enrollment modes to enable for your Organization Domains.
Supported modes are 'automatic_invitation' & 'automatic_suggestion'. | [
"automatic_invitation",
"automatic_suggestion"
] | +| `creator_role_id` | *Optional[str]* | :heavy_minus_sign: | Specify what the default organization role is for an organization creator. | creator_role | +| `domains_default_role_id` | *Optional[str]* | :heavy_minus_sign: | Specify what the default organization role is for the organization domains. | member_role | \ No newline at end of file diff --git a/docs/models/updateinstancerequestbody.md b/docs/models/updateinstancerequestbody.md new file mode 100644 index 0000000..047544a --- /dev/null +++ b/docs/models/updateinstancerequestbody.md @@ -0,0 +1,16 @@ +# UpdateInstanceRequestBody + + +## Fields + +| Field | Type | Required | Description | Example | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `test_mode` | *Optional[Nullable[bool]]* | :heavy_minus_sign: | Toggles test mode for this instance, allowing the use of test email addresses and phone numbers.
Defaults to true for development instances. | true | +| `hibp` | *Optional[Nullable[bool]]* | :heavy_minus_sign: | Whether the instance should be using the HIBP service to check passwords for breaches | false | +| `enhanced_email_deliverability` | *Optional[Nullable[bool]]* | :heavy_minus_sign: | The "enhanced_email_deliverability" feature will send emails from "verifications@clerk.dev" instead of your domain.
This can be helpful if you do not have a high domain reputation. | true | +| `support_email` | *Optional[Nullable[str]]* | :heavy_minus_sign: | N/A | support@example.com | +| `clerk_js_version` | *Optional[Nullable[str]]* | :heavy_minus_sign: | N/A | 2.3.1 | +| `development_origin` | *Optional[Nullable[str]]* | :heavy_minus_sign: | N/A | http://localhost:3000 | +| `allowed_origins` | List[*str*] | :heavy_minus_sign: | For browser-like stacks such as browser extensions, Electron, or Capacitor.js the instance allowed origins need to be updated with the request origin value.
For Chrome extensions popup, background, or service worker pages the origin is chrome-extension://extension_uiid. For Electron apps the default origin is http://localhost:3000. For Capacitor, the origin is capacitor://localhost. | [
"http://localhost:3000",
"chrome-extension://extension_uiid",
"capacitor://localhost"
] | +| ~~`cookieless_dev`~~ | *Optional[bool]* | :heavy_minus_sign: | : warning: ** DEPRECATED **: This will be removed in a future release, please migrate away from it as soon as possible.

Whether the instance should operate in cookieless development mode (i.e. without third-party cookies).
Deprecated: Please use `url_based_session_syncing` instead. | false | +| `url_based_session_syncing` | *Optional[bool]* | :heavy_minus_sign: | Whether the instance should use URL-based session syncing in development mode (i.e. without third-party cookies). | true | \ No newline at end of file diff --git a/docs/models/updateinstancerestrictionsrequestbody.md b/docs/models/updateinstancerestrictionsrequestbody.md new file mode 100644 index 0000000..64366cb --- /dev/null +++ b/docs/models/updateinstancerestrictionsrequestbody.md @@ -0,0 +1,12 @@ +# UpdateInstanceRestrictionsRequestBody + + +## Fields + +| Field | Type | Required | Description | Example | +| --------------------------------- | --------------------------------- | --------------------------------- | --------------------------------- | --------------------------------- | +| `allowlist` | *Optional[Nullable[bool]]* | :heavy_minus_sign: | N/A | false | +| `blocklist` | *Optional[Nullable[bool]]* | :heavy_minus_sign: | N/A | true | +| `block_email_subaddresses` | *Optional[Nullable[bool]]* | :heavy_minus_sign: | N/A | true | +| `block_disposable_email_domains` | *Optional[Nullable[bool]]* | :heavy_minus_sign: | N/A | true | +| `ignore_dots_for_gmail_addresses` | *Optional[Nullable[bool]]* | :heavy_minus_sign: | N/A | false | \ No newline at end of file diff --git a/docs/models/updatejwttemplateclaims.md b/docs/models/updatejwttemplateclaims.md new file mode 100644 index 0000000..554249b --- /dev/null +++ b/docs/models/updatejwttemplateclaims.md @@ -0,0 +1,9 @@ +# UpdateJWTTemplateClaims + +JWT template claims in JSON format + + +## Fields + +| Field | Type | Required | Description | +| ----------- | ----------- | ----------- | ----------- | \ No newline at end of file diff --git a/docs/models/updatejwttemplaterequest.md b/docs/models/updatejwttemplaterequest.md new file mode 100644 index 0000000..3b8f983 --- /dev/null +++ b/docs/models/updatejwttemplaterequest.md @@ -0,0 +1,9 @@ +# UpdateJWTTemplateRequest + + +## Fields + +| Field | Type | Required | Description | +| ------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------ | +| `template_id` | *str* | :heavy_check_mark: | The ID of the JWT template to update | +| `request_body` | [Optional[models.UpdateJWTTemplateRequestBody]](../models/updatejwttemplaterequestbody.md) | :heavy_minus_sign: | N/A | \ No newline at end of file diff --git a/docs/models/updatejwttemplaterequestbody.md b/docs/models/updatejwttemplaterequestbody.md new file mode 100644 index 0000000..4f59987 --- /dev/null +++ b/docs/models/updatejwttemplaterequestbody.md @@ -0,0 +1,14 @@ +# UpdateJWTTemplateRequestBody + + +## Fields + +| Field | Type | Required | Description | +| -------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | +| `name` | *Optional[str]* | :heavy_minus_sign: | JWT template name | +| `claims` | [Optional[models.UpdateJWTTemplateClaims]](../models/updatejwttemplateclaims.md) | :heavy_minus_sign: | JWT template claims in JSON format | +| `lifetime` | *Optional[Nullable[float]]* | :heavy_minus_sign: | JWT token lifetime | +| `allowed_clock_skew` | *Optional[Nullable[float]]* | :heavy_minus_sign: | JWT token allowed clock skew | +| `custom_signing_key` | *Optional[bool]* | :heavy_minus_sign: | Whether a custom signing key/algorithm is also provided for this template | +| `signing_algorithm` | *Optional[Nullable[str]]* | :heavy_minus_sign: | The custom signing algorithm to use when minting JWTs | +| `signing_key` | *Optional[Nullable[str]]* | :heavy_minus_sign: | The custom signing private key to use when minting JWTs | \ No newline at end of file diff --git a/docs/models/updateoauthapplicationrequest.md b/docs/models/updateoauthapplicationrequest.md new file mode 100644 index 0000000..ce63df1 --- /dev/null +++ b/docs/models/updateoauthapplicationrequest.md @@ -0,0 +1,9 @@ +# UpdateOAuthApplicationRequest + + +## Fields + +| Field | Type | Required | Description | Example | +| ------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------ | +| `oauth_application_id` | *str* | :heavy_check_mark: | The ID of the OAuth application to update | oauth_app_67890 | +| `request_body` | [models.UpdateOAuthApplicationRequestBody](../models/updateoauthapplicationrequestbody.md) | :heavy_check_mark: | N/A | | \ No newline at end of file diff --git a/docs/models/updateoauthapplicationrequestbody.md b/docs/models/updateoauthapplicationrequestbody.md new file mode 100644 index 0000000..7e34377 --- /dev/null +++ b/docs/models/updateoauthapplicationrequestbody.md @@ -0,0 +1,10 @@ +# UpdateOAuthApplicationRequestBody + + +## Fields + +| Field | Type | Required | Description | Example | +| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `name` | *Optional[str]* | :heavy_minus_sign: | The new name of the OAuth application | Updated OAuth App Name | +| `callback_url` | *Optional[str]* | :heavy_minus_sign: | The new callback URL of the OAuth application | https://example.com/oauth/callback | +| `scopes` | *Optional[str]* | :heavy_minus_sign: | Define the allowed scopes for the new OAuth applications that dictate the user payload of the OAuth user info endpoint. Available scopes are `profile`, `email`, `public_metadata`, `private_metadata`. Provide the requested scopes as a string, separated by spaces. | profile email public_metadata private_metadata | \ No newline at end of file diff --git a/docs/models/updateorganizationmembershipmetadataprivatemetadata.md b/docs/models/updateorganizationmembershipmetadataprivatemetadata.md new file mode 100644 index 0000000..8fae50e --- /dev/null +++ b/docs/models/updateorganizationmembershipmetadataprivatemetadata.md @@ -0,0 +1,10 @@ +# UpdateOrganizationMembershipMetadataPrivateMetadata + +Metadata saved on the organization membership that is only visible to your backend. +The new object will be merged with the existing value. + + +## Fields + +| Field | Type | Required | Description | +| ----------- | ----------- | ----------- | ----------- | \ No newline at end of file diff --git a/docs/models/updateorganizationmembershipmetadatapublicmetadata.md b/docs/models/updateorganizationmembershipmetadatapublicmetadata.md new file mode 100644 index 0000000..dc1db80 --- /dev/null +++ b/docs/models/updateorganizationmembershipmetadatapublicmetadata.md @@ -0,0 +1,10 @@ +# UpdateOrganizationMembershipMetadataPublicMetadata + +Metadata saved on the organization membership, that is visible to both your frontend and backend. +The new object will be merged with the existing value. + + +## Fields + +| Field | Type | Required | Description | +| ----------- | ----------- | ----------- | ----------- | \ No newline at end of file diff --git a/docs/models/updateorganizationmembershipmetadatarequest.md b/docs/models/updateorganizationmembershipmetadatarequest.md new file mode 100644 index 0000000..15fb489 --- /dev/null +++ b/docs/models/updateorganizationmembershipmetadatarequest.md @@ -0,0 +1,10 @@ +# UpdateOrganizationMembershipMetadataRequest + + +## Fields + +| Field | Type | Required | Description | Example | +| ---------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- | +| `organization_id` | *str* | :heavy_check_mark: | The ID of the organization the membership belongs to | org_123456 | +| `user_id` | *str* | :heavy_check_mark: | The ID of the user that this membership belongs to | user_654321 | +| `request_body` | [models.UpdateOrganizationMembershipMetadataRequestBody](../models/updateorganizationmembershipmetadatarequestbody.md) | :heavy_check_mark: | N/A | | \ No newline at end of file diff --git a/docs/models/updateorganizationmembershipmetadatarequestbody.md b/docs/models/updateorganizationmembershipmetadatarequestbody.md new file mode 100644 index 0000000..6b9221f --- /dev/null +++ b/docs/models/updateorganizationmembershipmetadatarequestbody.md @@ -0,0 +1,9 @@ +# UpdateOrganizationMembershipMetadataRequestBody + + +## Fields + +| Field | Type | Required | Description | Example | +| -------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `public_metadata` | [Optional[models.UpdateOrganizationMembershipMetadataPublicMetadata]](../models/updateorganizationmembershipmetadatapublicmetadata.md) | :heavy_minus_sign: | Metadata saved on the organization membership, that is visible to both your frontend and backend.
The new object will be merged with the existing value. | {} | +| `private_metadata` | [Optional[models.UpdateOrganizationMembershipMetadataPrivateMetadata]](../models/updateorganizationmembershipmetadataprivatemetadata.md) | :heavy_minus_sign: | Metadata saved on the organization membership that is only visible to your backend.
The new object will be merged with the existing value. | {} | \ No newline at end of file diff --git a/docs/models/updateorganizationmembershiprequest.md b/docs/models/updateorganizationmembershiprequest.md new file mode 100644 index 0000000..c3c3189 --- /dev/null +++ b/docs/models/updateorganizationmembershiprequest.md @@ -0,0 +1,10 @@ +# UpdateOrganizationMembershipRequest + + +## Fields + +| Field | Type | Required | Description | Example | +| ------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------ | +| `organization_id` | *str* | :heavy_check_mark: | The ID of the organization the membership belongs to | org_12345 | +| `user_id` | *str* | :heavy_check_mark: | The ID of the user that this membership belongs to | user_67890 | +| `request_body` | [models.UpdateOrganizationMembershipRequestBody](../models/updateorganizationmembershiprequestbody.md) | :heavy_check_mark: | N/A | | \ No newline at end of file diff --git a/docs/models/updateorganizationmembershiprequestbody.md b/docs/models/updateorganizationmembershiprequestbody.md new file mode 100644 index 0000000..6ac7d27 --- /dev/null +++ b/docs/models/updateorganizationmembershiprequestbody.md @@ -0,0 +1,8 @@ +# UpdateOrganizationMembershipRequestBody + + +## Fields + +| Field | Type | Required | Description | Example | +| ------------------------------------- | ------------------------------------- | ------------------------------------- | ------------------------------------- | ------------------------------------- | +| `role` | *str* | :heavy_check_mark: | The new role of the given membership. | admin | \ No newline at end of file diff --git a/docs/models/updateorganizationprivatemetadata.md b/docs/models/updateorganizationprivatemetadata.md new file mode 100644 index 0000000..b095281 --- /dev/null +++ b/docs/models/updateorganizationprivatemetadata.md @@ -0,0 +1,9 @@ +# UpdateOrganizationPrivateMetadata + +Metadata saved on the organization that is only visible to your backend. + + +## Fields + +| Field | Type | Required | Description | +| ----------- | ----------- | ----------- | ----------- | \ No newline at end of file diff --git a/docs/models/updateorganizationpublicmetadata.md b/docs/models/updateorganizationpublicmetadata.md new file mode 100644 index 0000000..a83dfeb --- /dev/null +++ b/docs/models/updateorganizationpublicmetadata.md @@ -0,0 +1,9 @@ +# UpdateOrganizationPublicMetadata + +Metadata saved on the organization, that is visible to both your frontend and backend. + + +## Fields + +| Field | Type | Required | Description | +| ----------- | ----------- | ----------- | ----------- | \ No newline at end of file diff --git a/docs/models/updateorganizationrequest.md b/docs/models/updateorganizationrequest.md new file mode 100644 index 0000000..f305dfb --- /dev/null +++ b/docs/models/updateorganizationrequest.md @@ -0,0 +1,9 @@ +# UpdateOrganizationRequest + + +## Fields + +| Field | Type | Required | Description | Example | +| ---------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- | +| `organization_id` | *str* | :heavy_check_mark: | The ID of the organization to update | org_123_update | +| `request_body` | [models.UpdateOrganizationRequestBody](../models/updateorganizationrequestbody.md) | :heavy_check_mark: | N/A | | \ No newline at end of file diff --git a/docs/models/updateorganizationrequestbody.md b/docs/models/updateorganizationrequestbody.md new file mode 100644 index 0000000..99094b3 --- /dev/null +++ b/docs/models/updateorganizationrequestbody.md @@ -0,0 +1,13 @@ +# UpdateOrganizationRequestBody + + +## Fields + +| Field | Type | Required | Description | Example | +| ---------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- | +| `public_metadata` | [Optional[models.UpdateOrganizationPublicMetadata]](../models/updateorganizationpublicmetadata.md) | :heavy_minus_sign: | Metadata saved on the organization, that is visible to both your frontend and backend. | {} | +| `private_metadata` | [Optional[models.UpdateOrganizationPrivateMetadata]](../models/updateorganizationprivatemetadata.md) | :heavy_minus_sign: | Metadata saved on the organization that is only visible to your backend. | {} | +| `name` | *Optional[Nullable[str]]* | :heavy_minus_sign: | The new name of the organization | New Organization Name | +| `slug` | *Optional[Nullable[str]]* | :heavy_minus_sign: | The new slug of the organization, which needs to be unique in the instance | new-org-slug | +| `max_allowed_memberships` | *Optional[Nullable[int]]* | :heavy_minus_sign: | The maximum number of memberships allowed for this organization | 100 | +| `admin_delete_enabled` | *Optional[Nullable[bool]]* | :heavy_minus_sign: | If true, an admin can delete this organization with the Frontend API. | true | \ No newline at end of file diff --git a/docs/models/updatephonenumberrequest.md b/docs/models/updatephonenumberrequest.md new file mode 100644 index 0000000..47c385c --- /dev/null +++ b/docs/models/updatephonenumberrequest.md @@ -0,0 +1,9 @@ +# UpdatePhoneNumberRequest + + +## Fields + +| Field | Type | Required | Description | Example | +| ------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------ | +| `phone_number_id` | *str* | :heavy_check_mark: | The ID of the phone number to update | phone_12345 | +| `request_body` | [Optional[models.UpdatePhoneNumberRequestBody]](../models/updatephonenumberrequestbody.md) | :heavy_minus_sign: | N/A | | \ No newline at end of file diff --git a/docs/models/updatephonenumberrequestbody.md b/docs/models/updatephonenumberrequestbody.md new file mode 100644 index 0000000..ae267f9 --- /dev/null +++ b/docs/models/updatephonenumberrequestbody.md @@ -0,0 +1,10 @@ +# UpdatePhoneNumberRequestBody + + +## Fields + +| Field | Type | Required | Description | Example | +| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `verified` | *Optional[Nullable[bool]]* | :heavy_minus_sign: | The phone number will be marked as verified. | false | +| `primary` | *Optional[Nullable[bool]]* | :heavy_minus_sign: | Set this phone number as the primary phone number for the user. | true | +| `reserved_for_second_factor` | *Optional[Nullable[bool]]* | :heavy_minus_sign: | Set this phone number as reserved for multi-factor authentication.
The phone number must also be verified.
If there are no other reserved second factors, the phone number will be set as the default second factor. | true | \ No newline at end of file diff --git a/docs/models/updateproductioninstancedomainrequestbody.md b/docs/models/updateproductioninstancedomainrequestbody.md new file mode 100644 index 0000000..3620333 --- /dev/null +++ b/docs/models/updateproductioninstancedomainrequestbody.md @@ -0,0 +1,8 @@ +# UpdateProductionInstanceDomainRequestBody + + +## Fields + +| Field | Type | Required | Description | Example | +| ------------------------------------------------------------------------ | ------------------------------------------------------------------------ | ------------------------------------------------------------------------ | ------------------------------------------------------------------------ | ------------------------------------------------------------------------ | +| `home_url` | *Optional[str]* | :heavy_minus_sign: | The new home URL of the production instance e.g. https://www.example.com | https://www.example.com | \ No newline at end of file diff --git a/docs/models/updatesamlconnectionattributemapping.md b/docs/models/updatesamlconnectionattributemapping.md new file mode 100644 index 0000000..a3ff6eb --- /dev/null +++ b/docs/models/updatesamlconnectionattributemapping.md @@ -0,0 +1,13 @@ +# UpdateSAMLConnectionAttributeMapping + +Define the atrtibute name mapping between Identity Provider and Clerk's user properties + + +## Fields + +| Field | Type | Required | Description | Example | +| ------------------ | ------------------ | ------------------ | ------------------ | ------------------ | +| `user_id` | *Optional[str]* | :heavy_minus_sign: | N/A | id123 | +| `email_address` | *Optional[str]* | :heavy_minus_sign: | N/A | user@example.com | +| `first_name` | *Optional[str]* | :heavy_minus_sign: | N/A | Jane | +| `last_name` | *Optional[str]* | :heavy_minus_sign: | N/A | Doe | \ No newline at end of file diff --git a/docs/models/updatesamlconnectionrequest.md b/docs/models/updatesamlconnectionrequest.md new file mode 100644 index 0000000..c126843 --- /dev/null +++ b/docs/models/updatesamlconnectionrequest.md @@ -0,0 +1,9 @@ +# UpdateSAMLConnectionRequest + + +## Fields + +| Field | Type | Required | Description | Example | +| -------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | +| `saml_connection_id` | *str* | :heavy_check_mark: | The ID of the SAML Connection to update | saml_conn_123_update | +| `request_body` | [models.UpdateSAMLConnectionRequestBody](../models/updatesamlconnectionrequestbody.md) | :heavy_check_mark: | N/A | | \ No newline at end of file diff --git a/docs/models/updatesamlconnectionrequestbody.md b/docs/models/updatesamlconnectionrequestbody.md new file mode 100644 index 0000000..08c0556 --- /dev/null +++ b/docs/models/updatesamlconnectionrequestbody.md @@ -0,0 +1,19 @@ +# UpdateSAMLConnectionRequestBody + + +## Fields + +| Field | Type | Required | Description | Example | +| ----------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | +| `name` | *Optional[Nullable[str]]* | :heavy_minus_sign: | The name of the new SAML Connection | Example SAML Connection | +| `domain` | *Optional[Nullable[str]]* | :heavy_minus_sign: | The domain to use for the new SAML Connection | example.com | +| `idp_entity_id` | *Optional[Nullable[str]]* | :heavy_minus_sign: | The entity id as provided by the IdP | entity_123 | +| `idp_sso_url` | *Optional[Nullable[str]]* | :heavy_minus_sign: | The SSO url as provided by the IdP | https://idp.example.com/sso | +| `idp_certificate` | *Optional[Nullable[str]]* | :heavy_minus_sign: | The x509 certificated as provided by the IdP | MIIDBTCCAe2gAwIBAgIQ... | +| `idp_metadata_url` | *Optional[Nullable[str]]* | :heavy_minus_sign: | The URL which serves the IdP metadata. If present, it takes priority over the corresponding individual properties and replaces them | https://idp.example.com/metadata | +| `idp_metadata` | *Optional[Nullable[str]]* | :heavy_minus_sign: | The XML content of the IdP metadata file. If present, it takes priority over the corresponding individual properties | ... | +| `attribute_mapping` | [Optional[Nullable[models.UpdateSAMLConnectionAttributeMapping]]](../models/updatesamlconnectionattributemapping.md) | :heavy_minus_sign: | Define the atrtibute name mapping between Identity Provider and Clerk's user properties | | +| `active` | *Optional[Nullable[bool]]* | :heavy_minus_sign: | Activate or de-activate the SAML Connection | true | +| `sync_user_attributes` | *Optional[Nullable[bool]]* | :heavy_minus_sign: | Controls whether to update the user's attributes in each sign-in | false | +| `allow_subdomains` | *Optional[Nullable[bool]]* | :heavy_minus_sign: | Allow users with an email address subdomain to use this connection in order to authenticate | true | +| `allow_idp_initiated` | *Optional[Nullable[bool]]* | :heavy_minus_sign: | Enable or deactivate IdP-initiated flows | false | \ No newline at end of file diff --git a/docs/models/updatesignuprequest.md b/docs/models/updatesignuprequest.md new file mode 100644 index 0000000..5d03372 --- /dev/null +++ b/docs/models/updatesignuprequest.md @@ -0,0 +1,9 @@ +# UpdateSignUpRequest + + +## Fields + +| Field | Type | Required | Description | Example | +| -------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | +| `id` | *str* | :heavy_check_mark: | The ID of the sign-up to update | signup_1234567890abcdef | +| `request_body` | [Optional[models.UpdateSignUpRequestBody]](../models/updatesignuprequestbody.md) | :heavy_minus_sign: | N/A | | \ No newline at end of file diff --git a/docs/models/updatesignuprequestbody.md b/docs/models/updatesignuprequestbody.md new file mode 100644 index 0000000..bee28c4 --- /dev/null +++ b/docs/models/updatesignuprequestbody.md @@ -0,0 +1,9 @@ +# UpdateSignUpRequestBody + + +## Fields + +| Field | Type | Required | Description | Example | +| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `custom_action` | *Optional[bool]* | :heavy_minus_sign: | Specifies whether a custom action has run for this sign-up attempt.
This is important when your instance has been configured to require a custom action to run before converting a sign-up into a user.
After executing any external business logic you deem necessary, you can mark the sign-up as ready-to-convert by setting `custom_action` to `true`. | false | +| `external_id` | *Optional[Nullable[str]]* | :heavy_minus_sign: | The ID of the guest attempting to sign up as used in your external systems or your previous authentication solution.
This will be copied to the resulting user when the sign-up is completed. | ext_id_7890abcdef123456 | \ No newline at end of file diff --git a/docs/models/updateusermetadataprivatemetadata.md b/docs/models/updateusermetadataprivatemetadata.md new file mode 100644 index 0000000..628afe0 --- /dev/null +++ b/docs/models/updateusermetadataprivatemetadata.md @@ -0,0 +1,10 @@ +# UpdateUserMetadataPrivateMetadata + +Metadata saved on the user that is only visible to your backend. +The new object will be merged with the existing value. + + +## Fields + +| Field | Type | Required | Description | +| ----------- | ----------- | ----------- | ----------- | \ No newline at end of file diff --git a/docs/models/updateusermetadatarequest.md b/docs/models/updateusermetadatarequest.md new file mode 100644 index 0000000..dd5fc87 --- /dev/null +++ b/docs/models/updateusermetadatarequest.md @@ -0,0 +1,9 @@ +# UpdateUserMetadataRequest + + +## Fields + +| Field | Type | Required | Description | Example | +| -------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------- | +| `user_id` | *str* | :heavy_check_mark: | The ID of the user whose metadata will be updated and merged | user_123456789 | +| `request_body` | [Optional[models.UpdateUserMetadataRequestBody]](../models/updateusermetadatarequestbody.md) | :heavy_minus_sign: | N/A | | \ No newline at end of file diff --git a/docs/models/updateusermetadatarequestbody.md b/docs/models/updateusermetadatarequestbody.md new file mode 100644 index 0000000..95a9208 --- /dev/null +++ b/docs/models/updateusermetadatarequestbody.md @@ -0,0 +1,10 @@ +# UpdateUserMetadataRequestBody + + +## Fields + +| Field | Type | Required | Description | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `public_metadata` | Dict[str, *Any*] | :heavy_minus_sign: | Metadata saved on the user, that is visible to both your frontend and backend.
The new object will be merged with the existing value. | +| `private_metadata` | [Optional[models.UpdateUserMetadataPrivateMetadata]](../models/updateusermetadataprivatemetadata.md) | :heavy_minus_sign: | Metadata saved on the user that is only visible to your backend.
The new object will be merged with the existing value. | +| `unsafe_metadata` | [Optional[models.UpdateUserMetadataUnsafeMetadata]](../models/updateusermetadataunsafemetadata.md) | :heavy_minus_sign: | Metadata saved on the user, that can be updated from both the Frontend and Backend APIs.
The new object will be merged with the existing value.

Note: Since this data can be modified from the frontend, it is not guaranteed to be safe. | \ No newline at end of file diff --git a/docs/models/updateusermetadataunsafemetadata.md b/docs/models/updateusermetadataunsafemetadata.md new file mode 100644 index 0000000..3a59249 --- /dev/null +++ b/docs/models/updateusermetadataunsafemetadata.md @@ -0,0 +1,12 @@ +# UpdateUserMetadataUnsafeMetadata + +Metadata saved on the user, that can be updated from both the Frontend and Backend APIs. +The new object will be merged with the existing value. + +Note: Since this data can be modified from the frontend, it is not guaranteed to be safe. + + +## Fields + +| Field | Type | Required | Description | +| ----------- | ----------- | ----------- | ----------- | \ No newline at end of file diff --git a/docs/models/updateuserpasswordhasher.md b/docs/models/updateuserpasswordhasher.md new file mode 100644 index 0000000..becdfbc --- /dev/null +++ b/docs/models/updateuserpasswordhasher.md @@ -0,0 +1,135 @@ +# UpdateUserPasswordHasher + +The hashing algorithm that was used to generate the password digest. +The algorithms we support at the moment are [bcrypt](https://en.wikipedia.org/wiki/Bcrypt), [bcrypt_sha256_django](https://docs.djangoproject.com/en/4.0/topics/auth/passwords/), +[md5](https://en.wikipedia.org/wiki/MD5), pbkdf2_sha256, pbkdf2_sha512, [pbkdf2_sha256_django](https://docs.djangoproject.com/en/4.0/topics/auth/passwords/), +[phpass](https://www.openwall.com/phpass/), [scrypt_firebase](https://firebaseopensource.com/projects/firebase/scrypt/), +[sha256](https://en.wikipedia.org/wiki/SHA-2), [scrypt_werkzeug](https://werkzeug.palletsprojects.com/en/3.0.x/utils/#werkzeug.security.generate_password_hash) +and the [argon2](https://argon2.online/) variants argon2i and argon2id. + +If you need support for any particular hashing algorithm, [please let us know](https://clerk.com/support). + +Note: for password hashers considered insecure (at this moment MD5 and SHA256), the corresponding user password hashes will be transparently migrated to Bcrypt (a secure hasher) upon the user's first successful password sign in. +Insecure schemes are marked with `(insecure)` in the list below. + +Each of the supported hashers expects the incoming digest to be in a particular format. Specifically: + +**bcrypt:** The digest should be of the following form: + +`$$$` + +**bcrypt_sha256_django:** This is the Django-specific variant of Bcrypt, using SHA256 hashing function. The format should be as follows (as exported from Django): + +`bcrypt_sha256$$$$` + +**md5** (insecure): The digest should follow the regular form e.g.: + +`5f4dcc3b5aa765d61d8327deb882cf99` + +**pbkdf2_sha256:** This is the PBKDF2 algorithm using the SHA256 hashing function. The format should be as follows: + +`pbkdf2_sha256$$$` + +Note: Both the salt and the hash are expected to be base64-encoded. + +**pbkdf2_sha512:** This is the PBKDF2 algorithm using the SHA512 hashing function. The format should be as follows: + +`pbkdf2_sha512$$$` + + _iterations:_ The number of iterations used. Must be an integer less than 420000. + _salt:_ The salt used when generating the hash. Must be less than bytes. + _hash:_ The hex-encoded hash. Must have been generated with a key length less than 1024 bytes. + +**pbkdf2_sha256_django:** This is the Django-specific variant of PBKDF2 and the digest should have the following format (as exported from Django): + +`pbkdf2_sha256$$$` + +Note: The salt is expected to be un-encoded, the hash is expected base64-encoded. + +**pbkdf2_sha1:** This is similar to pkbdf2_sha256_django, but with two differences: +1. uses sha1 instead of sha256 +2. accepts the hash as a hex-encoded string + +The format is the following: + +`pbkdf2_sha1$$$` + +**phpass:** Portable public domain password hashing framework for use in PHP applications. Digests hashed with phpass have the following sections: + +The format is the following: + +`$P$` + +- $P$ is the prefix used to identify phpass hashes. +- rounds is a single character encoding a 6-bit integer representing the number of rounds used. +- salt is eight characters drawn from [./0-9A-Za-z], providing a 48-bit salt. +- checksum is 22 characters drawn from the same set, encoding the 128-bit checksum with MD5. + +**scrypt_firebase:** The Firebase-specific variant of scrypt. +The value is expected to have 6 segments separated by the $ character and include the following information: + +_hash:_ The actual Base64 hash. This can be retrieved when exporting the user from Firebase. +_salt:_ The salt used to generate the above hash. Again, this is given when exporting the user. +_signer key:_ The base64 encoded signer key. +_salt separator:_ The base64 encoded salt separator. +_rounds:_ The number of rounds the algorithm needs to run. +_memory cost:_ The cost of the algorithm run + +The first 2 (hash and salt) are per user and can be retrieved when exporting the user from Firebase. +The other 4 values (signer key, salt separator, rounds and memory cost) are project-wide settings and can be retrieved from the project's password hash parameters. + +Once you have all these, you can combine it in the following format and send this as the digest in order for Clerk to accept it: + +`$$$$$` + +**scrypt_werkzeug:** The Werkzeug-specific variant of scrypt. + +The value is expected to have 3 segments separated by the $ character and include the following information: + +_algorithm args:_ The algorithm used to generate the hash. +_salt:_ The salt used to generate the above hash. +_hash:_ The actual Base64 hash. + +The algorithm args are the parameters used to generate the hash and are included in the digest. + +**argon2i:** Algorithms in the argon2 family generate digests that encode the following information: + +_version (v):_ The argon version, version 19 is assumed +_memory (m):_ The memory used by the algorithm (in kibibytes) +_iterations (t):_ The number of iterations to perform +_parallelism (p):_ The number of threads to use + +Parts are demarcated by the `$` character, with the first part identifying the algorithm variant. +The middle part is a comma-separated list of the encoding options (memory, iterations, parallelism). +The final part is the actual digest. + +`$argon2i$v=19$m=4096,t=3,p=1$4t6CL3P7YiHBtwESXawI8Hm20zJj4cs7/4/G3c187e0$m7RQFczcKr5bIR0IIxbpO2P0tyrLjf3eUW3M3QSwnLc` + +**argon2id:** See the previous algorithm for an explanation of the formatting. + +For the argon2id case, the value of the algorithm in the first part of the digest is `argon2id`: + +`$argon2id$v=19$m=64,t=4,p=8$Z2liZXJyaXNo$iGXEpMBTDYQ8G/71tF0qGjxRHEmR3gpGULcE93zUJVU` + +**sha256** (insecure): The digest should be a 64-length hex string, e.g.: + +`9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08` + + +## Values + +| Name | Value | +| ---------------------- | ---------------------- | +| `ARGON2I` | argon2i | +| `ARGON2ID` | argon2id | +| `BCRYPT` | bcrypt | +| `BCRYPT_SHA256_DJANGO` | bcrypt_sha256_django | +| `MD5` | md5 | +| `PBKDF2_SHA256` | pbkdf2_sha256 | +| `PBKDF2_SHA512` | pbkdf2_sha512 | +| `PBKDF2_SHA256_DJANGO` | pbkdf2_sha256_django | +| `PBKDF2_SHA1` | pbkdf2_sha1 | +| `PHPASS` | phpass | +| `SCRYPT_FIREBASE` | scrypt_firebase | +| `SCRYPT_WERKZEUG` | scrypt_werkzeug | +| `SHA256` | sha256 | \ No newline at end of file diff --git a/docs/models/updateuserprivatemetadata.md b/docs/models/updateuserprivatemetadata.md new file mode 100644 index 0000000..f07e7af --- /dev/null +++ b/docs/models/updateuserprivatemetadata.md @@ -0,0 +1,9 @@ +# UpdateUserPrivateMetadata + +Metadata saved on the user, that is only visible to your Backend API + + +## Fields + +| Field | Type | Required | Description | +| ----------- | ----------- | ----------- | ----------- | \ No newline at end of file diff --git a/docs/models/updateuserpublicmetadata.md b/docs/models/updateuserpublicmetadata.md new file mode 100644 index 0000000..402dcf7 --- /dev/null +++ b/docs/models/updateuserpublicmetadata.md @@ -0,0 +1,9 @@ +# UpdateUserPublicMetadata + +Metadata saved on the user, that is visible to both your Frontend and Backend APIs + + +## Fields + +| Field | Type | Required | Description | +| ----------- | ----------- | ----------- | ----------- | \ No newline at end of file diff --git a/docs/models/updateuserrequest.md b/docs/models/updateuserrequest.md new file mode 100644 index 0000000..d9255b5 --- /dev/null +++ b/docs/models/updateuserrequest.md @@ -0,0 +1,9 @@ +# UpdateUserRequest + + +## Fields + +| Field | Type | Required | Description | Example | +| ------------------------------------------------------------------ | ------------------------------------------------------------------ | ------------------------------------------------------------------ | ------------------------------------------------------------------ | ------------------------------------------------------------------ | +| `user_id` | *str* | :heavy_check_mark: | The ID of the user to update | usr_1 | +| `request_body` | [models.UpdateUserRequestBody](../models/updateuserrequestbody.md) | :heavy_check_mark: | N/A | | \ No newline at end of file diff --git a/docs/models/updateuserrequestbody.md b/docs/models/updateuserrequestbody.md new file mode 100644 index 0000000..4b36c92 --- /dev/null +++ b/docs/models/updateuserrequestbody.md @@ -0,0 +1,29 @@ +# UpdateUserRequestBody + + +## Fields + +| Field | Type | Required | Description | Example | +| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `external_id` | *Optional[Nullable[str]]* | :heavy_minus_sign: | The ID of the user as used in your external systems or your previous authentication solution.
Must be unique across your instance. | ext_123 | +| `first_name` | *Optional[Nullable[str]]* | :heavy_minus_sign: | The first name to assign to the user | Jane | +| `last_name` | *Optional[Nullable[str]]* | :heavy_minus_sign: | The last name to assign to the user | Doe | +| `primary_email_address_id` | *Optional[str]* | :heavy_minus_sign: | The ID of the email address to set as primary.
It must be verified, and present on the current user. | eml_12345 | +| `notify_primary_email_address_changed` | *Optional[bool]* | :heavy_minus_sign: | If set to `true`, the user will be notified that their primary email address has changed.
By default, no notification is sent. | true | +| `primary_phone_number_id` | *Optional[str]* | :heavy_minus_sign: | The ID of the phone number to set as primary.
It must be verified, and present on the current user. | phn_67890 | +| `primary_web3_wallet_id` | *Optional[str]* | :heavy_minus_sign: | The ID of the web3 wallets to set as primary.
It must be verified, and present on the current user. | wlt_123 | +| `username` | *Optional[Nullable[str]]* | :heavy_minus_sign: | The username to give to the user.
It must be unique across your instance. | janedoe | +| `profile_image_id` | *Optional[Nullable[str]]* | :heavy_minus_sign: | The ID of the image to set as the user's profile image | img_789 | +| `password` | *Optional[Nullable[str]]* | :heavy_minus_sign: | The plaintext password to give the user.
Must be at least 8 characters long, and can not be in any list of hacked passwords. | secretPass123! | +| `password_digest` | *Optional[str]* | :heavy_minus_sign: | In case you already have the password digests and not the passwords, you can use them for the newly created user via this property.
The digests should be generated with one of the supported algorithms.
The hashing algorithm can be specified using the `password_hasher` property. | $argon2i$v=19$m=4096,t=3,p=1$4t6CL3P7YiHBtwESXawI8Hm20zJj4cs7/4/G3c187e0$m7RQFczcKr5bIR0IIxbpO2P0tyrLjf3eUW3M3QSwnLc | +| `password_hasher` | [Optional[models.UpdateUserPasswordHasher]](../models/updateuserpasswordhasher.md) | :heavy_minus_sign: | The hashing algorithm that was used to generate the password digest.
The algorithms we support at the moment are [bcrypt](https://en.wikipedia.org/wiki/Bcrypt), [bcrypt_sha256_django](https://docs.djangoproject.com/en/4.0/topics/auth/passwords/),
[md5](https://en.wikipedia.org/wiki/MD5), pbkdf2_sha256, pbkdf2_sha512, [pbkdf2_sha256_django](https://docs.djangoproject.com/en/4.0/topics/auth/passwords/),
[phpass](https://www.openwall.com/phpass/), [scrypt_firebase](https://firebaseopensource.com/projects/firebase/scrypt/),
[sha256](https://en.wikipedia.org/wiki/SHA-2), [scrypt_werkzeug](https://werkzeug.palletsprojects.com/en/3.0.x/utils/#werkzeug.security.generate_password_hash)
and the [argon2](https://argon2.online/) variants argon2i and argon2id.

If you need support for any particular hashing algorithm, [please let us know](https://clerk.com/support).

Note: for password hashers considered insecure (at this moment MD5 and SHA256), the corresponding user password hashes will be transparently migrated to Bcrypt (a secure hasher) upon the user's first successful password sign in.
Insecure schemes are marked with `(insecure)` in the list below.

Each of the supported hashers expects the incoming digest to be in a particular format. Specifically:

**bcrypt:** The digest should be of the following form:

`$$$`

**bcrypt_sha256_django:** This is the Django-specific variant of Bcrypt, using SHA256 hashing function. The format should be as follows (as exported from Django):

`bcrypt_sha256$$$$`

**md5** (insecure): The digest should follow the regular form e.g.:

`5f4dcc3b5aa765d61d8327deb882cf99`

**pbkdf2_sha256:** This is the PBKDF2 algorithm using the SHA256 hashing function. The format should be as follows:

`pbkdf2_sha256$$$`

Note: Both the salt and the hash are expected to be base64-encoded.

**pbkdf2_sha512:** This is the PBKDF2 algorithm using the SHA512 hashing function. The format should be as follows:

`pbkdf2_sha512$$$`

_iterations:_ The number of iterations used. Must be an integer less than 420000.
_salt:_ The salt used when generating the hash. Must be less than bytes.
_hash:_ The hex-encoded hash. Must have been generated with a key length less than 1024 bytes.

**pbkdf2_sha256_django:** This is the Django-specific variant of PBKDF2 and the digest should have the following format (as exported from Django):

`pbkdf2_sha256$$$`

Note: The salt is expected to be un-encoded, the hash is expected base64-encoded.

**pbkdf2_sha1:** This is similar to pkbdf2_sha256_django, but with two differences:
1. uses sha1 instead of sha256
2. accepts the hash as a hex-encoded string

The format is the following:

`pbkdf2_sha1$$$`

**phpass:** Portable public domain password hashing framework for use in PHP applications. Digests hashed with phpass have the following sections:

The format is the following:

`$P$`

- $P$ is the prefix used to identify phpass hashes.
- rounds is a single character encoding a 6-bit integer representing the number of rounds used.
- salt is eight characters drawn from [./0-9A-Za-z], providing a 48-bit salt.
- checksum is 22 characters drawn from the same set, encoding the 128-bit checksum with MD5.

**scrypt_firebase:** The Firebase-specific variant of scrypt.
The value is expected to have 6 segments separated by the $ character and include the following information:

_hash:_ The actual Base64 hash. This can be retrieved when exporting the user from Firebase.
_salt:_ The salt used to generate the above hash. Again, this is given when exporting the user.
_signer key:_ The base64 encoded signer key.
_salt separator:_ The base64 encoded salt separator.
_rounds:_ The number of rounds the algorithm needs to run.
_memory cost:_ The cost of the algorithm run

The first 2 (hash and salt) are per user and can be retrieved when exporting the user from Firebase.
The other 4 values (signer key, salt separator, rounds and memory cost) are project-wide settings and can be retrieved from the project's password hash parameters.

Once you have all these, you can combine it in the following format and send this as the digest in order for Clerk to accept it:

`$$$$$`

**scrypt_werkzeug:** The Werkzeug-specific variant of scrypt.

The value is expected to have 3 segments separated by the $ character and include the following information:

_algorithm args:_ The algorithm used to generate the hash.
_salt:_ The salt used to generate the above hash.
_hash:_ The actual Base64 hash.

The algorithm args are the parameters used to generate the hash and are included in the digest.

**argon2i:** Algorithms in the argon2 family generate digests that encode the following information:

_version (v):_ The argon version, version 19 is assumed
_memory (m):_ The memory used by the algorithm (in kibibytes)
_iterations (t):_ The number of iterations to perform
_parallelism (p):_ The number of threads to use

Parts are demarcated by the `$` character, with the first part identifying the algorithm variant.
The middle part is a comma-separated list of the encoding options (memory, iterations, parallelism).
The final part is the actual digest.

`$argon2i$v=19$m=4096,t=3,p=1$4t6CL3P7YiHBtwESXawI8Hm20zJj4cs7/4/G3c187e0$m7RQFczcKr5bIR0IIxbpO2P0tyrLjf3eUW3M3QSwnLc`

**argon2id:** See the previous algorithm for an explanation of the formatting.

For the argon2id case, the value of the algorithm in the first part of the digest is `argon2id`:

`$argon2id$v=19$m=64,t=4,p=8$Z2liZXJyaXNo$iGXEpMBTDYQ8G/71tF0qGjxRHEmR3gpGULcE93zUJVU`

**sha256** (insecure): The digest should be a 64-length hex string, e.g.:

`9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08` | argon2i | +| `skip_password_checks` | *Optional[Nullable[bool]]* | :heavy_minus_sign: | Set it to `true` if you're updating the user's password and want to skip any password policy settings check. This parameter can only be used when providing a `password`. | false | +| `sign_out_of_other_sessions` | *Optional[Nullable[bool]]* | :heavy_minus_sign: | Set to `true` to sign out the user from all their active sessions once their password is updated. This parameter can only be used when providing a `password`. | true | +| `totp_secret` | *Optional[str]* | :heavy_minus_sign: | In case TOTP is configured on the instance, you can provide the secret to enable it on the specific user without the need to reset it.
Please note that currently the supported options are:
* Period: 30 seconds
* Code length: 6 digits
* Algorithm: SHA1 | ABCD1234EFGH5678 | +| `backup_codes` | List[*str*] | :heavy_minus_sign: | If Backup Codes are configured on the instance, you can provide them to enable it on the specific user without the need to reset them.
You must provide the backup codes in plain format or the corresponding bcrypt digest. | [
"123456",
"654321"
] | +| `public_metadata` | [Optional[models.UpdateUserPublicMetadata]](../models/updateuserpublicmetadata.md) | :heavy_minus_sign: | Metadata saved on the user, that is visible to both your Frontend and Backend APIs | {
"theme": "dark"
} | +| `private_metadata` | [Optional[models.UpdateUserPrivateMetadata]](../models/updateuserprivatemetadata.md) | :heavy_minus_sign: | Metadata saved on the user, that is only visible to your Backend API | {
"vip": true
} | +| `unsafe_metadata` | [Optional[models.UpdateUserUnsafeMetadata]](../models/updateuserunsafemetadata.md) | :heavy_minus_sign: | Metadata saved on the user, that can be updated from both the Frontend and Backend APIs.
Note: Since this data can be modified from the frontend, it is not guaranteed to be safe. | {
"age": 30
} | +| `delete_self_enabled` | *Optional[Nullable[bool]]* | :heavy_minus_sign: | If true, the user can delete themselves with the Frontend API. | true | +| `create_organization_enabled` | *Optional[Nullable[bool]]* | :heavy_minus_sign: | If true, the user can create organizations with the Frontend API. | false | +| `created_at` | *Optional[str]* | :heavy_minus_sign: | A custom date/time denoting _when_ the user signed up to the application, specified in RFC3339 format (e.g. `2012-10-20T07:15:20.902Z`). | 2021-04-05T14:30:00.000Z | \ No newline at end of file diff --git a/docs/models/updateuserunsafemetadata.md b/docs/models/updateuserunsafemetadata.md new file mode 100644 index 0000000..1cc911b --- /dev/null +++ b/docs/models/updateuserunsafemetadata.md @@ -0,0 +1,10 @@ +# UpdateUserUnsafeMetadata + +Metadata saved on the user, that can be updated from both the Frontend and Backend APIs. +Note: Since this data can be modified from the frontend, it is not guaranteed to be safe. + + +## Fields + +| Field | Type | Required | Description | +| ----------- | ----------- | ----------- | ----------- | \ No newline at end of file diff --git a/docs/models/uploadorganizationlogofile.md b/docs/models/uploadorganizationlogofile.md new file mode 100644 index 0000000..561f30a --- /dev/null +++ b/docs/models/uploadorganizationlogofile.md @@ -0,0 +1,10 @@ +# UploadOrganizationLogoFile + + +## Fields + +| Field | Type | Required | Description | +| -------------------------------------------- | -------------------------------------------- | -------------------------------------------- | -------------------------------------------- | +| `file_name` | *str* | :heavy_check_mark: | N/A | +| `content` | *Union[bytes, IO[bytes], io.BufferedReader]* | :heavy_check_mark: | N/A | +| `content_type` | *Optional[str]* | :heavy_minus_sign: | N/A | \ No newline at end of file diff --git a/docs/models/uploadorganizationlogorequest.md b/docs/models/uploadorganizationlogorequest.md new file mode 100644 index 0000000..9880db5 --- /dev/null +++ b/docs/models/uploadorganizationlogorequest.md @@ -0,0 +1,9 @@ +# UploadOrganizationLogoRequest + + +## Fields + +| Field | Type | Required | Description | Example | +| ---------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- | +| `organization_id` | *str* | :heavy_check_mark: | The ID of the organization for which to upload a logo | org_12345 | +| `request_body` | [Optional[models.UploadOrganizationLogoRequestBody]](../models/uploadorganizationlogorequestbody.md) | :heavy_minus_sign: | N/A | | \ No newline at end of file diff --git a/docs/models/uploadorganizationlogorequestbody.md b/docs/models/uploadorganizationlogorequestbody.md new file mode 100644 index 0000000..7c43ad7 --- /dev/null +++ b/docs/models/uploadorganizationlogorequestbody.md @@ -0,0 +1,9 @@ +# UploadOrganizationLogoRequestBody + + +## Fields + +| Field | Type | Required | Description | Example | +| ---------------------------------------------------------------------------- | ---------------------------------------------------------------------------- | ---------------------------------------------------------------------------- | ---------------------------------------------------------------------------- | ---------------------------------------------------------------------------- | +| `uploader_user_id` | *str* | :heavy_check_mark: | The ID of the user that will be credited with the image upload. | user_67890 | +| `file` | [models.UploadOrganizationLogoFile](../models/uploadorganizationlogofile.md) | :heavy_check_mark: | N/A | | \ No newline at end of file diff --git a/docs/models/upserttemplatepathparamtemplatetype.md b/docs/models/upserttemplatepathparamtemplatetype.md new file mode 100644 index 0000000..347c260 --- /dev/null +++ b/docs/models/upserttemplatepathparamtemplatetype.md @@ -0,0 +1,11 @@ +# UpsertTemplatePathParamTemplateType + +The type of template to update + + +## Values + +| Name | Value | +| ------- | ------- | +| `EMAIL` | email | +| `SMS` | sms | \ No newline at end of file diff --git a/docs/models/upserttemplaterequest.md b/docs/models/upserttemplaterequest.md new file mode 100644 index 0000000..a398f6f --- /dev/null +++ b/docs/models/upserttemplaterequest.md @@ -0,0 +1,10 @@ +# UpsertTemplateRequest + + +## Fields + +| Field | Type | Required | Description | Example | +| ---------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- | +| `template_type` | [models.UpsertTemplatePathParamTemplateType](../models/upserttemplatepathparamtemplatetype.md) | :heavy_check_mark: | The type of template to update | sms | +| `slug` | *str* | :heavy_check_mark: | The slug of the template to update | verification-code | +| `request_body` | [Optional[models.UpsertTemplateRequestBody]](../models/upserttemplaterequestbody.md) | :heavy_minus_sign: | N/A | | \ No newline at end of file diff --git a/docs/models/upserttemplaterequestbody.md b/docs/models/upserttemplaterequestbody.md new file mode 100644 index 0000000..1650082 --- /dev/null +++ b/docs/models/upserttemplaterequestbody.md @@ -0,0 +1,14 @@ +# UpsertTemplateRequestBody + + +## Fields + +| Field | Type | Required | Description | Example | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `name` | *Optional[str]* | :heavy_minus_sign: | The user-friendly name of the template | Verification Code | +| `subject` | *Optional[Nullable[str]]* | :heavy_minus_sign: | The email subject.
Applicable only to email templates. | Your Verification Code | +| `markup` | *Optional[Nullable[str]]* | :heavy_minus_sign: | The editor markup used to generate the body of the template |

Your code: {{code}}

| +| `body` | *Optional[str]* | :heavy_minus_sign: | The template body before variable interpolation | Use this code to verify your email: {{code}} | +| `delivered_by_clerk` | *Optional[Nullable[bool]]* | :heavy_minus_sign: | Whether Clerk should deliver emails or SMS messages based on the current template | true | +| `from_email_name` | *Optional[str]* | :heavy_minus_sign: | The local part of the From email address that will be used for emails.
For example, in the address 'hello@example.com', the local part is 'hello'.
Applicable only to email templates. | hello | +| `reply_to_email_name` | *Optional[str]* | :heavy_minus_sign: | The local part of the Reply To email address that will be used for emails.
For example, in the address 'hello@example.com', the local part is 'hello'.
Applicable only to email templates. | support | \ No newline at end of file diff --git a/docs/models/user.md b/docs/models/user.md new file mode 100644 index 0000000..10d0218 --- /dev/null +++ b/docs/models/user.md @@ -0,0 +1,44 @@ +# User + + +## Fields + +| Field | Type | Required | Description | Example | +| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `id` | *Optional[str]* | :heavy_minus_sign: | N/A | user_id_123 | +| `object` | [Optional[models.UserObject]](../models/userobject.md) | :heavy_minus_sign: | String representing the object's type. Objects of the same type share the same value.
| user | +| `external_id` | *Optional[Nullable[str]]* | :heavy_minus_sign: | N/A | external_user_id_123 | +| `primary_email_address_id` | *Optional[Nullable[str]]* | :heavy_minus_sign: | N/A | email_id_123 | +| `primary_phone_number_id` | *Optional[Nullable[str]]* | :heavy_minus_sign: | N/A | phone_id_123 | +| `primary_web3_wallet_id` | *Optional[Nullable[str]]* | :heavy_minus_sign: | N/A | wallet_id_123 | +| `username` | *Optional[Nullable[str]]* | :heavy_minus_sign: | N/A | john_doe | +| `first_name` | *Optional[Nullable[str]]* | :heavy_minus_sign: | N/A | John | +| `last_name` | *Optional[Nullable[str]]* | :heavy_minus_sign: | N/A | Doe | +| ~~`profile_image_url`~~ | *Optional[str]* | :heavy_minus_sign: | : warning: ** DEPRECATED **: This will be removed in a future release, please migrate away from it as soon as possible. | https://example.com/profile.jpg | +| `image_url` | *Optional[str]* | :heavy_minus_sign: | N/A | https://example.com/new-profile.jpg | +| `has_image` | *Optional[bool]* | :heavy_minus_sign: | N/A | true | +| `public_metadata` | [Optional[models.PublicMetadata]](../models/publicmetadata.md) | :heavy_minus_sign: | N/A | {
"role": "admin"
} | +| `private_metadata` | [Optional[Nullable[models.PrivateMetadata]]](../models/privatemetadata.md) | :heavy_minus_sign: | N/A | {
"ssn": "123-45-6789"
} | +| `unsafe_metadata` | [Optional[models.UnsafeMetadata]](../models/unsafemetadata.md) | :heavy_minus_sign: | N/A | {
"theme": "dark"
} | +| `email_addresses` | List[[models.EmailAddress](../models/emailaddress.md)] | :heavy_minus_sign: | N/A | [
{
"id": "email_id_123",
"object": "email_address",
"email_address": "john.doe@example.com",
"verification": {
"status": "verified",
"strategy": "email_code"
},
"created_at": 1609459200,
"updated_at": 1609459200
}
] | +| `phone_numbers` | List[[models.PhoneNumber](../models/phonenumber.md)] | :heavy_minus_sign: | N/A | [
{
"id": "phone_id_123",
"object": "phone_number",
"phone_number": "+12345678901",
"verification": {
"status": "verified",
"strategy": "phone_code"
},
"created_at": 1609459200,
"updated_at": 1609459200
}
] | +| `web3_wallets` | List[[models.Web3Wallet](../models/web3wallet.md)] | :heavy_minus_sign: | N/A | [
{
"id": "wallet_id_123",
"object": "web3_wallet",
"web3_wallet": "0x123456789abcdef",
"verification": {
"status": "verified",
"strategy": "web3_metamask_signature"
},
"created_at": 1609459200,
"updated_at": 1609459200
}
] | +| `passkeys` | List[[models.SchemasPasskey](../models/schemaspasskey.md)] | :heavy_minus_sign: | N/A | [
{
"id": "passkey_id_123",
"object": "passkey",
"name": "My Passkey",
"last_used_at": 1615852800,
"verification": {
"status": "verified",
"strategy": "passkey"
}
}
] | +| `password_enabled` | *Optional[bool]* | :heavy_minus_sign: | N/A | true | +| `two_factor_enabled` | *Optional[bool]* | :heavy_minus_sign: | N/A | true | +| `totp_enabled` | *Optional[bool]* | :heavy_minus_sign: | N/A | true | +| `backup_code_enabled` | *Optional[bool]* | :heavy_minus_sign: | N/A | true | +| `mfa_enabled_at` | *Optional[Nullable[int]]* | :heavy_minus_sign: | Unix timestamp of when MFA was last enabled for this user. It should be noted that this field is not nullified if MFA is disabled.
| 1615852800 | +| `mfa_disabled_at` | *Optional[Nullable[int]]* | :heavy_minus_sign: | Unix timestamp of when MFA was last disabled for this user. It should be noted that this field is not nullified if MFA is enabled again.
| | +| `external_accounts` | List[[models.ExternalAccounts](../models/externalaccounts.md)] | :heavy_minus_sign: | N/A | [
{
"id": "ext_account_id_123",
"provider": "Facebook",
"user_id": "user_id_at_provider"
}
] | +| `saml_accounts` | List[[models.SAMLAccount](../models/samlaccount.md)] | :heavy_minus_sign: | N/A | [
{
"id": "saml_account_id_123",
"object": "saml_account",
"provider": "SAML Provider",
"active": true,
"email_address": "user@example.com",
"public_metadata": {
"department": "IT"
},
"verification": {
"status": "verified",
"strategy": "saml"
}
}
] | +| `last_sign_in_at` | *Optional[Nullable[int]]* | :heavy_minus_sign: | Unix timestamp of last sign-in.
| 1622852400 | +| `banned` | *Optional[bool]* | :heavy_minus_sign: | Flag to denote whether user is banned or not.
| false | +| `locked` | *Optional[bool]* | :heavy_minus_sign: | Flag to denote whether user is currently locked, i.e. restricted from signing in or not.
| false | +| `lockout_expires_in_seconds` | *Optional[Nullable[int]]* | :heavy_minus_sign: | The number of seconds remaining until the lockout period expires for a locked user. A null value for a locked user indicates that lockout never expires.
| | +| `verification_attempts_remaining` | *Optional[Nullable[int]]* | :heavy_minus_sign: | The number of verification attempts remaining until the user is locked. Null if account lockout is not enabled. Note: if a user is locked explicitly via the Backend API, they may still have verification attempts remaining.
| 5 | +| `updated_at` | *Optional[int]* | :heavy_minus_sign: | Unix timestamp of last update.
| 1622852400 | +| `created_at` | *Optional[int]* | :heavy_minus_sign: | Unix timestamp of creation.
| 1609459200 | +| `delete_self_enabled` | *Optional[bool]* | :heavy_minus_sign: | If enabled, user can delete themselves via FAPI.
| true | +| `create_organization_enabled` | *Optional[bool]* | :heavy_minus_sign: | If enabled, user can create organizations via FAPI.
| true | +| `last_active_at` | *Optional[Nullable[int]]* | :heavy_minus_sign: | Unix timestamp of the latest session activity, with day precision.
| 1700690400000 | \ No newline at end of file diff --git a/docs/models/userobject.md b/docs/models/userobject.md new file mode 100644 index 0000000..5ebea17 --- /dev/null +++ b/docs/models/userobject.md @@ -0,0 +1,11 @@ +# UserObject + +String representing the object's type. Objects of the same type share the same value. + + + +## Values + +| Name | Value | +| ------ | ------ | +| `USER` | user | \ No newline at end of file diff --git a/docs/models/usersgetorganizationmembershipsrequest.md b/docs/models/usersgetorganizationmembershipsrequest.md new file mode 100644 index 0000000..8a44c86 --- /dev/null +++ b/docs/models/usersgetorganizationmembershipsrequest.md @@ -0,0 +1,10 @@ +# UsersGetOrganizationMembershipsRequest + + +## Fields + +| Field | Type | Required | Description | Example | +| ----------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | +| `user_id` | *str* | :heavy_check_mark: | The ID of the user whose organization memberships we want to retrieve | usr_1234567890 | +| `limit` | *Optional[float]* | :heavy_minus_sign: | Applies a limit to the number of results returned.
Can be used for paginating the results together with `offset`. | 20 | +| `offset` | *Optional[float]* | :heavy_minus_sign: | Skip the first `offset` results when paginating.
Needs to be an integer greater or equal to zero.
To be used in conjunction with `limit`. | 10 | \ No newline at end of file diff --git a/docs/models/usersgetorganizationmembershipsresponse.md b/docs/models/usersgetorganizationmembershipsresponse.md new file mode 100644 index 0000000..7d98c9f --- /dev/null +++ b/docs/models/usersgetorganizationmembershipsresponse.md @@ -0,0 +1,8 @@ +# UsersGetOrganizationMembershipsResponse + + +## Fields + +| Field | Type | Required | Description | +| ---------------------------------------------------------------------- | ---------------------------------------------------------------------- | ---------------------------------------------------------------------- | ---------------------------------------------------------------------- | +| `result` | [models.OrganizationMemberships](../models/organizationmemberships.md) | :heavy_check_mark: | N/A | \ No newline at end of file diff --git a/docs/models/utils/retryconfig.md b/docs/models/utils/retryconfig.md new file mode 100644 index 0000000..69dd549 --- /dev/null +++ b/docs/models/utils/retryconfig.md @@ -0,0 +1,24 @@ +# RetryConfig + +Allows customizing the default retry configuration. Only usable with methods that mention they support retries. + +## Fields + +| Name | Type | Description | Example | +| ------------------------- | ----------------------------------- | --------------------------------------- | --------- | +| `strategy` | `*str*` | The retry strategy to use. | `backoff` | +| `backoff` | [BackoffStrategy](#backoffstrategy) | Configuration for the backoff strategy. | | +| `retry_connection_errors` | `*bool*` | Whether to retry on connection errors. | `true` | + +## BackoffStrategy + +The backoff strategy allows retrying a request with an exponential backoff between each retry. + +### Fields + +| Name | Type | Description | Example | +| ------------------ | --------- | ----------------------------------------- | -------- | +| `initial_interval` | `*int*` | The initial interval in milliseconds. | `500` | +| `max_interval` | `*int*` | The maximum interval in milliseconds. | `60000` | +| `exponent` | `*float*` | The exponent to use for the backoff. | `1.5` | +| `max_elapsed_time` | `*int*` | The maximum elapsed time in milliseconds. | `300000` | \ No newline at end of file diff --git a/docs/models/verification.md b/docs/models/verification.md new file mode 100644 index 0000000..ec67038 --- /dev/null +++ b/docs/models/verification.md @@ -0,0 +1,23 @@ +# Verification + + +## Supported Types + +### `models.Otp` + +```python +value: models.Otp = /* values here */ +``` + +### `models.Admin` + +```python +value: models.Admin = /* values here */ +``` + +### `models.Oauth` + +```python +value: models.Oauth = /* values here */ +``` + diff --git a/docs/models/verificationadmin.md b/docs/models/verificationadmin.md new file mode 100644 index 0000000..2ce4afc --- /dev/null +++ b/docs/models/verificationadmin.md @@ -0,0 +1,11 @@ +# VerificationAdmin + + +## Fields + +| Field | Type | Required | Description | Example | +| -------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------- | +| `status` | [models.AdminVerificationPhoneNumberStatus](../models/adminverificationphonenumberstatus.md) | :heavy_check_mark: | N/A | verified | +| `strategy` | [models.AdminVerificationStrategy](../models/adminverificationstrategy.md) | :heavy_check_mark: | N/A | admin | +| `attempts` | *Optional[Nullable[int]]* | :heavy_minus_sign: | N/A | 0 | +| `expire_at` | *Optional[Nullable[int]]* | :heavy_minus_sign: | N/A | 1620000000 | \ No newline at end of file diff --git a/docs/models/verificationerror.md b/docs/models/verificationerror.md new file mode 100644 index 0000000..3a524ec --- /dev/null +++ b/docs/models/verificationerror.md @@ -0,0 +1,11 @@ +# VerificationError + + +## Supported Types + +### `models.SAMLErrorClerkError` + +```python +value: models.SAMLErrorClerkError = /* values here */ +``` + diff --git a/docs/models/verificationnonce.md b/docs/models/verificationnonce.md new file mode 100644 index 0000000..87cd5b9 --- /dev/null +++ b/docs/models/verificationnonce.md @@ -0,0 +1,8 @@ +# VerificationNonce + + +## Values + +| Name | Value | +| ------- | ------- | +| `NONCE` | nonce | \ No newline at end of file diff --git a/docs/models/verificationotp.md b/docs/models/verificationotp.md new file mode 100644 index 0000000..bcb3975 --- /dev/null +++ b/docs/models/verificationotp.md @@ -0,0 +1,11 @@ +# VerificationOTP + + +## Fields + +| Field | Type | Required | Description | Example | +| ---------------------------------------------------------------------- | ---------------------------------------------------------------------- | ---------------------------------------------------------------------- | ---------------------------------------------------------------------- | ---------------------------------------------------------------------- | +| `status` | [models.OTPVerificationStatus](../models/otpverificationstatus.md) | :heavy_check_mark: | N/A | verified | +| `strategy` | [models.OTPVerificationStrategy](../models/otpverificationstrategy.md) | :heavy_check_mark: | N/A | email_code | +| `attempts` | *Nullable[int]* | :heavy_check_mark: | N/A | 1 | +| `expire_at` | *Nullable[int]* | :heavy_check_mark: | N/A | 1615462399 | \ No newline at end of file diff --git a/docs/models/verifications.md b/docs/models/verifications.md new file mode 100644 index 0000000..9822e8c --- /dev/null +++ b/docs/models/verifications.md @@ -0,0 +1,7 @@ +# Verifications + + +## Fields + +| Field | Type | Required | Description | +| ----------- | ----------- | ----------- | ----------- | \ No newline at end of file diff --git a/docs/models/verificationstatus.md b/docs/models/verificationstatus.md new file mode 100644 index 0000000..7da7c68 --- /dev/null +++ b/docs/models/verificationstatus.md @@ -0,0 +1,11 @@ +# VerificationStatus + + +## Values + +| Name | Value | +| ------------ | ------------ | +| `UNVERIFIED` | unverified | +| `VERIFIED` | verified | +| `FAILED` | failed | +| `EXPIRED` | expired | \ No newline at end of file diff --git a/docs/models/verificationstrategy.md b/docs/models/verificationstrategy.md new file mode 100644 index 0000000..5e58032 --- /dev/null +++ b/docs/models/verificationstrategy.md @@ -0,0 +1,9 @@ +# VerificationStrategy + + +## Values + +| Name | Value | +| -------------------- | -------------------- | +| `ADMIN` | admin | +| `FROM_OAUTH_DISCORD` | from_oauth_discord | \ No newline at end of file diff --git a/docs/models/verifyclientrequestbody.md b/docs/models/verifyclientrequestbody.md new file mode 100644 index 0000000..5bcdafe --- /dev/null +++ b/docs/models/verifyclientrequestbody.md @@ -0,0 +1,10 @@ +# VerifyClientRequestBody + +Parameters. + + +## Fields + +| Field | Type | Required | Description | Example | +| ---------------------------------------------- | ---------------------------------------------- | ---------------------------------------------- | ---------------------------------------------- | ---------------------------------------------- | +| `token` | *Optional[str]* | :heavy_minus_sign: | A JWT Token that represents the active client. | jwt_token_example | \ No newline at end of file diff --git a/docs/models/verifydomainproxyrequestbody.md b/docs/models/verifydomainproxyrequestbody.md new file mode 100644 index 0000000..b55fd4a --- /dev/null +++ b/docs/models/verifydomainproxyrequestbody.md @@ -0,0 +1,9 @@ +# VerifyDomainProxyRequestBody + + +## Fields + +| Field | Type | Required | Description | Example | +| --------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- | +| `domain_id` | *Optional[str]* | :heavy_minus_sign: | The ID of the domain that will be updated. | domain_32hfu3e | +| `proxy_url` | *Optional[str]* | :heavy_minus_sign: | The full URL of the proxy which will forward requests to the Clerk Frontend API for this domain. e.g. https://example.com/__clerk | https://example.com/__clerk | \ No newline at end of file diff --git a/docs/models/verifypasswordrequest.md b/docs/models/verifypasswordrequest.md new file mode 100644 index 0000000..17801cd --- /dev/null +++ b/docs/models/verifypasswordrequest.md @@ -0,0 +1,9 @@ +# VerifyPasswordRequest + + +## Fields + +| Field | Type | Required | Description | Example | +| ------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------ | +| `user_id` | *str* | :heavy_check_mark: | The ID of the user for whom to verify the password | user_123 | +| `request_body` | [Optional[models.VerifyPasswordRequestBody]](../models/verifypasswordrequestbody.md) | :heavy_minus_sign: | N/A | | \ No newline at end of file diff --git a/docs/models/verifypasswordrequestbody.md b/docs/models/verifypasswordrequestbody.md new file mode 100644 index 0000000..9f9d599 --- /dev/null +++ b/docs/models/verifypasswordrequestbody.md @@ -0,0 +1,8 @@ +# VerifyPasswordRequestBody + + +## Fields + +| Field | Type | Required | Description | Example | +| --------------------------- | --------------------------- | --------------------------- | --------------------------- | --------------------------- | +| `password` | *str* | :heavy_check_mark: | The user password to verify | securepassword123 | \ No newline at end of file diff --git a/docs/models/verifypasswordresponsebody.md b/docs/models/verifypasswordresponsebody.md new file mode 100644 index 0000000..f53673e --- /dev/null +++ b/docs/models/verifypasswordresponsebody.md @@ -0,0 +1,10 @@ +# VerifyPasswordResponseBody + +The provided password was correct. + + +## Fields + +| Field | Type | Required | Description | Example | +| ------------------ | ------------------ | ------------------ | ------------------ | ------------------ | +| `verified` | *Optional[bool]* | :heavy_minus_sign: | N/A | true | \ No newline at end of file diff --git a/docs/models/verifysessionrequest.md b/docs/models/verifysessionrequest.md new file mode 100644 index 0000000..78d2919 --- /dev/null +++ b/docs/models/verifysessionrequest.md @@ -0,0 +1,9 @@ +# VerifySessionRequest + + +## Fields + +| Field | Type | Required | Description | Example | +| ---------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- | +| `session_id` | *str* | :heavy_check_mark: | The ID of the session | sess_w8q4g9s60j28fghv00f3 | +| `request_body` | [Optional[models.VerifySessionRequestBody]](../models/verifysessionrequestbody.md) | :heavy_minus_sign: | Parameters. | | \ No newline at end of file diff --git a/docs/models/verifysessionrequestbody.md b/docs/models/verifysessionrequestbody.md new file mode 100644 index 0000000..cccf441 --- /dev/null +++ b/docs/models/verifysessionrequestbody.md @@ -0,0 +1,10 @@ +# VerifySessionRequestBody + +Parameters. + + +## Fields + +| Field | Type | Required | Description | Example | +| ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `token` | *Optional[str]* | :heavy_minus_sign: | The JWT that is sent via the `__session` cookie from your frontend.
Note: this JWT must be associated with the supplied session ID. | eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzZXNzaW9uX2lkIjoic2Vzc193OHF4ZzZzNm9qMjhmZ2h2MDBmMyIsImlhdCI6MTU4MjY0OTg2Mn0.J4KP2L6bEZ6YccHFW4E2vKbOLw_mmO0gF_GNRw-wtLM | \ No newline at end of file diff --git a/docs/models/verifytotprequest.md b/docs/models/verifytotprequest.md new file mode 100644 index 0000000..e63e932 --- /dev/null +++ b/docs/models/verifytotprequest.md @@ -0,0 +1,9 @@ +# VerifyTOTPRequest + + +## Fields + +| Field | Type | Required | Description | Example | +| ---------------------------------------------------------------------------- | ---------------------------------------------------------------------------- | ---------------------------------------------------------------------------- | ---------------------------------------------------------------------------- | ---------------------------------------------------------------------------- | +| `user_id` | *str* | :heavy_check_mark: | The ID of the user for whom to verify the TOTP | usr_1a2b3c | +| `request_body` | [Optional[models.VerifyTOTPRequestBody]](../models/verifytotprequestbody.md) | :heavy_minus_sign: | N/A | | \ No newline at end of file diff --git a/docs/models/verifytotprequestbody.md b/docs/models/verifytotprequestbody.md new file mode 100644 index 0000000..d08e41a --- /dev/null +++ b/docs/models/verifytotprequestbody.md @@ -0,0 +1,8 @@ +# VerifyTOTPRequestBody + + +## Fields + +| Field | Type | Required | Description | Example | +| --------------------------------- | --------------------------------- | --------------------------------- | --------------------------------- | --------------------------------- | +| `code` | *str* | :heavy_check_mark: | The TOTP or backup code to verify | 123456 | \ No newline at end of file diff --git a/docs/models/verifytotpresponsebody.md b/docs/models/verifytotpresponsebody.md new file mode 100644 index 0000000..a2ad1d5 --- /dev/null +++ b/docs/models/verifytotpresponsebody.md @@ -0,0 +1,11 @@ +# VerifyTOTPResponseBody + +The provided TOTP or backup code was correct. + + +## Fields + +| Field | Type | Required | Description | Example | +| -------------------------------------------------- | -------------------------------------------------- | -------------------------------------------------- | -------------------------------------------------- | -------------------------------------------------- | +| `verified` | *Optional[bool]* | :heavy_minus_sign: | N/A | true | +| `code_type` | [Optional[models.CodeType]](../models/codetype.md) | :heavy_minus_sign: | N/A | totp | \ No newline at end of file diff --git a/docs/models/web3signature.md b/docs/models/web3signature.md new file mode 100644 index 0000000..bc7aef8 --- /dev/null +++ b/docs/models/web3signature.md @@ -0,0 +1,12 @@ +# Web3Signature + + +## Fields + +| Field | Type | Required | Description | Example | +| ------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------ | +| `status` | [models.Web3SignatureVerificationStatus](../models/web3signatureverificationstatus.md) | :heavy_check_mark: | N/A | verified | +| `strategy` | [models.Web3SignatureVerificationStrategy](../models/web3signatureverificationstrategy.md) | :heavy_check_mark: | N/A | web3_metamask_signature | +| `nonce` | [models.Nonce](../models/nonce.md) | :heavy_check_mark: | N/A | nonce_value | +| `attempts` | *Optional[Nullable[int]]* | :heavy_minus_sign: | N/A | | +| `expire_at` | *Optional[Nullable[int]]* | :heavy_minus_sign: | N/A | | \ No newline at end of file diff --git a/docs/models/web3signatureverificationstatus.md b/docs/models/web3signatureverificationstatus.md new file mode 100644 index 0000000..357fd05 --- /dev/null +++ b/docs/models/web3signatureverificationstatus.md @@ -0,0 +1,8 @@ +# Web3SignatureVerificationStatus + + +## Values + +| Name | Value | +| ---------- | ---------- | +| `VERIFIED` | verified | \ No newline at end of file diff --git a/docs/models/web3signatureverificationstrategy.md b/docs/models/web3signatureverificationstrategy.md new file mode 100644 index 0000000..0a4e6bd --- /dev/null +++ b/docs/models/web3signatureverificationstrategy.md @@ -0,0 +1,8 @@ +# Web3SignatureVerificationStrategy + + +## Values + +| Name | Value | +| ------------------------- | ------------------------- | +| `WEB3_METAMASK_SIGNATURE` | web3_metamask_signature | \ No newline at end of file diff --git a/docs/models/web3wallet.md b/docs/models/web3wallet.md new file mode 100644 index 0000000..d39b424 --- /dev/null +++ b/docs/models/web3wallet.md @@ -0,0 +1,13 @@ +# Web3Wallet + + +## Fields + +| Field | Type | Required | Description | Example | +| --------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------- | +| `object` | [models.Web3WalletObject](../models/web3walletobject.md) | :heavy_check_mark: | String representing the object's type. Objects of the same type share the same value.
| web3_wallet | +| `web3_wallet` | *str* | :heavy_check_mark: | N/A | 0x123456789abcdef | +| `verification` | [Nullable[models.Web3WalletVerification]](../models/web3walletverification.md) | :heavy_check_mark: | N/A | {
"status": "verified",
"strategy": "web3_metamask_signature",
"nonce": "nonce_value"
} | +| `created_at` | *int* | :heavy_check_mark: | Unix timestamp of creation
| 1609459200 | +| `updated_at` | *int* | :heavy_check_mark: | Unix timestamp of creation
| 1609459200 | +| `id` | *Optional[str]* | :heavy_minus_sign: | N/A | wallet_id_123 | \ No newline at end of file diff --git a/docs/models/web3walletobject.md b/docs/models/web3walletobject.md new file mode 100644 index 0000000..e5f7458 --- /dev/null +++ b/docs/models/web3walletobject.md @@ -0,0 +1,11 @@ +# Web3WalletObject + +String representing the object's type. Objects of the same type share the same value. + + + +## Values + +| Name | Value | +| ------------- | ------------- | +| `WEB3_WALLET` | web3_wallet | \ No newline at end of file diff --git a/docs/models/web3walletverification.md b/docs/models/web3walletverification.md new file mode 100644 index 0000000..539d0ac --- /dev/null +++ b/docs/models/web3walletverification.md @@ -0,0 +1,17 @@ +# Web3WalletVerification + + +## Supported Types + +### `models.Web3Signature` + +```python +value: models.Web3Signature = /* values here */ +``` + +### `models.Web3WalletVerificationAdmin` + +```python +value: models.Web3WalletVerificationAdmin = /* values here */ +``` + diff --git a/docs/models/web3walletverificationadmin.md b/docs/models/web3walletverificationadmin.md new file mode 100644 index 0000000..1baa9e8 --- /dev/null +++ b/docs/models/web3walletverificationadmin.md @@ -0,0 +1,11 @@ +# Web3WalletVerificationAdmin + + +## Fields + +| Field | Type | Required | Description | Example | +| ---------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- | +| `status` | [models.AdminVerificationWeb3WalletStatus](../models/adminverificationweb3walletstatus.md) | :heavy_check_mark: | N/A | verified | +| `strategy` | [models.AdminVerificationWeb3WalletStrategy](../models/adminverificationweb3walletstrategy.md) | :heavy_check_mark: | N/A | admin | +| `attempts` | *Optional[Nullable[int]]* | :heavy_minus_sign: | N/A | 0 | +| `expire_at` | *Optional[Nullable[int]]* | :heavy_minus_sign: | N/A | 1620000000 | \ No newline at end of file diff --git a/docs/sdks/actortokens/README.md b/docs/sdks/actortokens/README.md new file mode 100644 index 0000000..a8b3150 --- /dev/null +++ b/docs/sdks/actortokens/README.md @@ -0,0 +1,95 @@ +# ActorTokens +(*actor_tokens*) + +### Available Operations + +* [create](#create) - Create actor token +* [revoke](#revoke) - Revoke actor token + +## create + +Create an actor token that can be used to impersonate the given user. +The `actor` parameter needs to include at least a "sub" key whose value is the ID of the actor (impersonating) user. + +### Example Usage + +```python +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +res = s.actor_tokens.create(user_id="user_1a2b3c", actor={ + "sub": "user_2OEpKhcCN1Lat9NQ0G6puh7q5Rb", +}, expires_in_seconds=3600, session_max_duration_in_seconds=1800) + +if res is not None: + # handle response + pass + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `user_id` | *str* | :heavy_check_mark: | The ID of the user that can use the newly created sign in token. | user_1a2b3c | +| `actor` | Dict[str, *Any*] | :heavy_check_mark: | The actor payload. It needs to include a sub property which should contain the ID of the actor.
This whole payload will be also included in the JWT session token. | {
"sub": "user_2OEpKhcCN1Lat9NQ0G6puh7q5Rb"
} | +| `expires_in_seconds` | *Optional[int]* | :heavy_minus_sign: | Optional parameter to specify the life duration of the actor token in seconds.
By default, the duration is 1 hour. | 3600 | +| `session_max_duration_in_seconds` | *Optional[int]* | :heavy_minus_sign: | The maximum duration that the session which will be created by the generated actor token should last.
By default, the duration of a session created via an actor token, lasts 30 minutes. | 1800 | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + + +### Response + +**[models.ActorToken](../../models/actortoken.md)** +### Errors + +| Error Object | Status Code | Content Type | +| ------------------ | ------------------ | ------------------ | +| models.ClerkErrors | 400,402,422 | application/json | +| models.SDKError | 4xx-5xx | */* | + +## revoke + +Revokes a pending actor token. + +### Example Usage + +```python +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +res = s.actor_tokens.revoke(actor_token_id="act_tok_abcdefghijk") + +if res is not None: + # handle response + pass + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | +| `actor_token_id` | *str* | :heavy_check_mark: | The ID of the actor token to be revoked. | act_tok_abcdefghijk | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + + +### Response + +**[models.ActorToken](../../models/actortoken.md)** +### Errors + +| Error Object | Status Code | Content Type | +| ------------------ | ------------------ | ------------------ | +| models.ClerkErrors | 400,404 | application/json | +| models.SDKError | 4xx-5xx | */* | diff --git a/docs/sdks/allowlistidentifiers/README.md b/docs/sdks/allowlistidentifiers/README.md new file mode 100644 index 0000000..7cdb914 --- /dev/null +++ b/docs/sdks/allowlistidentifiers/README.md @@ -0,0 +1,131 @@ +# AllowlistIdentifiers +(*allowlist_identifiers*) + +### Available Operations + +* [list](#list) - List all identifiers on the allow-list +* [create](#create) - Add identifier to the allow-list +* [delete](#delete) - Delete identifier from allow-list + +## list + +Get a list of all identifiers allowed to sign up to an instance + +### Example Usage + +```python +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +res = s.allowlist_identifiers.list() + +if res is not None: + # handle response + pass + +``` + +### Parameters + +| Parameter | Type | Required | Description | +| ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | + + +### Response + +**[List[models.AllowlistIdentifier]](../../models/.md)** +### Errors + +| Error Object | Status Code | Content Type | +| ------------------ | ------------------ | ------------------ | +| models.ClerkErrors | 401,402 | application/json | +| models.SDKError | 4xx-5xx | */* | + +## create + +Create an identifier allowed to sign up to an instance + +### Example Usage + +```python +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +res = s.allowlist_identifiers.create(identifier="user@example.com", notify=True) + +if res is not None: + # handle response + pass + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `identifier` | *str* | :heavy_check_mark: | The identifier to be added in the allow-list.
This can be an email address, a phone number or a web3 wallet. | user@example.com | +| `notify` | *Optional[bool]* | :heavy_minus_sign: | This flag denotes whether the given identifier will receive an invitation to join the application.
Note that this only works for email address and phone number identifiers. | true | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + + +### Response + +**[models.AllowlistIdentifier](../../models/allowlistidentifier.md)** +### Errors + +| Error Object | Status Code | Content Type | +| ------------------ | ------------------ | ------------------ | +| models.ClerkErrors | 400,402,422 | application/json | +| models.SDKError | 4xx-5xx | */* | + +## delete + +Delete an identifier from the instance allow-list + +### Example Usage + +```python +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +res = s.allowlist_identifiers.delete(identifier_id="example_identifier_id") + +if res is not None: + # handle response + pass + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | +| `identifier_id` | *str* | :heavy_check_mark: | The ID of the identifier to delete from the allow-list | example_identifier_id | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + + +### Response + +**[models.DeletedObject](../../models/deletedobject.md)** +### Errors + +| Error Object | Status Code | Content Type | +| ------------------ | ------------------ | ------------------ | +| models.ClerkErrors | 402,404 | application/json | +| models.SDKError | 4xx-5xx | */* | diff --git a/docs/sdks/betafeatures/README.md b/docs/sdks/betafeatures/README.md new file mode 100644 index 0000000..a7b5ba5 --- /dev/null +++ b/docs/sdks/betafeatures/README.md @@ -0,0 +1,134 @@ +# BetaFeatures +(*beta_features*) + +### Available Operations + +* [update_instance_auth_config](#update_instance_auth_config) - Update instance settings +* [~~update_production_instance_domain~~](#update_production_instance_domain) - Update production instance domain :warning: **Deprecated** +* [change_production_instance_domain](#change_production_instance_domain) - Update production instance domain + +## update_instance_auth_config + +Updates the settings of an instance + +### Example Usage + +```python +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +res = s.beta_features.update_instance_auth_config(restricted_to_allowlist=False, from_email_address="noreply", progressive_sign_up=True, session_token_template="defaultSessionToken", enhanced_email_deliverability=True, test_mode=True) + +if res is not None: + # handle response + pass + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `restricted_to_allowlist` | *Optional[Nullable[bool]]* | :heavy_minus_sign: | Whether sign up is restricted to email addresses, phone numbers and usernames that are on the allowlist. | false | +| `from_email_address` | *Optional[Nullable[str]]* | :heavy_minus_sign: | The local part of the email address from which authentication-related emails (e.g. OTP code, magic links) will be sent.
Only alphanumeric values are allowed.
Note that this value should contain only the local part of the address (e.g. `foo` for `foo@example.com`). | noreply | +| `progressive_sign_up` | *Optional[Nullable[bool]]* | :heavy_minus_sign: | Enable the Progressive Sign Up algorithm. Refer to the [docs](https://clerk.com/docs/upgrade-guides/progressive-sign-up) for more info. | true | +| `session_token_template` | *Optional[Nullable[str]]* | :heavy_minus_sign: | The name of the JWT Template used to augment your session tokens. To disable this, pass an empty string. | defaultSessionToken | +| `enhanced_email_deliverability` | *Optional[Nullable[bool]]* | :heavy_minus_sign: | The "enhanced_email_deliverability" feature will send emails from "verifications@clerk.dev" instead of your domain.
This can be helpful if you do not have a high domain reputation. | true | +| `test_mode` | *Optional[Nullable[bool]]* | :heavy_minus_sign: | Toggles test mode for this instance, allowing the use of test email addresses and phone numbers.
Defaults to true for development instances. | true | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + + +### Response + +**[models.InstanceSettings](../../models/instancesettings.md)** +### Errors + +| Error Object | Status Code | Content Type | +| ------------------ | ------------------ | ------------------ | +| models.ClerkErrors | 402,422 | application/json | +| models.SDKError | 4xx-5xx | */* | + +## ~~update_production_instance_domain~~ + +Change the domain of a production instance. + +Changing the domain requires updating the [DNS records](https://clerk.com/docs/deployments/overview#dns-records) accordingly, deploying new [SSL certificates](https://clerk.com/docs/deployments/overview#deploy), updating your Social Connection's redirect URLs and setting the new keys in your code. + +WARNING: Changing your domain will invalidate all current user sessions (i.e. users will be logged out). Also, while your application is being deployed, a small downtime is expected to occur. + +> :warning: **DEPRECATED**: This will be removed in a future release, please migrate away from it as soon as possible. + +### Example Usage + +```python +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +s.beta_features.update_production_instance_domain(home_url="https://www.example.com") + +# Use the SDK ... + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| ------------------------------------------------------------------------ | ------------------------------------------------------------------------ | ------------------------------------------------------------------------ | ------------------------------------------------------------------------ | ------------------------------------------------------------------------ | +| `home_url` | *Optional[str]* | :heavy_minus_sign: | The new home URL of the production instance e.g. https://www.example.com | https://www.example.com | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + +### Errors + +| Error Object | Status Code | Content Type | +| ------------------ | ------------------ | ------------------ | +| models.ClerkErrors | 400,422 | application/json | +| models.SDKError | 4xx-5xx | */* | + +## change_production_instance_domain + +Change the domain of a production instance. + +Changing the domain requires updating the [DNS records](https://clerk.com/docs/deployments/overview#dns-records) accordingly, deploying new [SSL certificates](https://clerk.com/docs/deployments/overview#deploy), updating your Social Connection's redirect URLs and setting the new keys in your code. + +WARNING: Changing your domain will invalidate all current user sessions (i.e. users will be logged out). Also, while your application is being deployed, a small downtime is expected to occur. + +### Example Usage + +```python +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +s.beta_features.change_production_instance_domain(home_url="https://www.newdomain.com") + +# Use the SDK ... + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| ------------------------------------------------------------------------ | ------------------------------------------------------------------------ | ------------------------------------------------------------------------ | ------------------------------------------------------------------------ | ------------------------------------------------------------------------ | +| `home_url` | *Optional[str]* | :heavy_minus_sign: | The new home URL of the production instance e.g. https://www.example.com | https://www.newdomain.com | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + +### Errors + +| Error Object | Status Code | Content Type | +| ------------------ | ------------------ | ------------------ | +| models.ClerkErrors | 400,422 | application/json | +| models.SDKError | 4xx-5xx | */* | diff --git a/docs/sdks/blocklistidentifierssdk/README.md b/docs/sdks/blocklistidentifierssdk/README.md new file mode 100644 index 0000000..71ab738 --- /dev/null +++ b/docs/sdks/blocklistidentifierssdk/README.md @@ -0,0 +1,130 @@ +# BlocklistIdentifiersSDK +(*blocklist_identifiers*) + +### Available Operations + +* [list](#list) - List all identifiers on the block-list +* [create](#create) - Add identifier to the block-list +* [delete](#delete) - Delete identifier from block-list + +## list + +Get a list of all identifiers which are not allowed to access an instance + +### Example Usage + +```python +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +res = s.blocklist_identifiers.list() + +if res is not None: + # handle response + pass + +``` + +### Parameters + +| Parameter | Type | Required | Description | +| ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | + + +### Response + +**[models.BlocklistIdentifiers](../../models/blocklistidentifiers.md)** +### Errors + +| Error Object | Status Code | Content Type | +| ------------------ | ------------------ | ------------------ | +| models.ClerkErrors | 401,402 | application/json | +| models.SDKError | 4xx-5xx | */* | + +## create + +Create an identifier that is blocked from accessing an instance + +### Example Usage + +```python +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +res = s.blocklist_identifiers.create(identifier="example@example.com") + +if res is not None: + # handle response + pass + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| ------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------ | +| `identifier` | *str* | :heavy_check_mark: | The identifier to be added in the block-list.
This can be an email address, a phone number or a web3 wallet. | example@example.com | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + + +### Response + +**[models.BlocklistIdentifier](../../models/blocklistidentifier.md)** +### Errors + +| Error Object | Status Code | Content Type | +| ------------------ | ------------------ | ------------------ | +| models.ClerkErrors | 400,402,422 | application/json | +| models.SDKError | 4xx-5xx | */* | + +## delete + +Delete an identifier from the instance block-list + +### Example Usage + +```python +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +res = s.blocklist_identifiers.delete(identifier_id="identifier123") + +if res is not None: + # handle response + pass + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | +| `identifier_id` | *str* | :heavy_check_mark: | The ID of the identifier to delete from the block-list | identifier123 | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + + +### Response + +**[models.DeletedObject](../../models/deletedobject.md)** +### Errors + +| Error Object | Status Code | Content Type | +| ------------------ | ------------------ | ------------------ | +| models.ClerkErrors | 402,404 | application/json | +| models.SDKError | 4xx-5xx | */* | diff --git a/docs/sdks/clerk/README.md b/docs/sdks/clerk/README.md new file mode 100644 index 0000000..7571e84 --- /dev/null +++ b/docs/sdks/clerk/README.md @@ -0,0 +1,19 @@ +# Clerk SDK + + +## Overview + +Clerk Backend API: The Clerk REST Backend API, meant to be accessed by backend +servers. + +### Versions + +When the API changes in a way that isn't compatible with older versions, a new version is released. +Each version is identified by its release date, e.g. `2021-02-05`. For more information, please see [Clerk API Versions](https://clerk.com/docs/backend-requests/versioning/overview). + + +Please see https://clerk.com/docs for more information. + + +### Available Operations + diff --git a/docs/sdks/clients/README.md b/docs/sdks/clients/README.md new file mode 100644 index 0000000..7082ec4 --- /dev/null +++ b/docs/sdks/clients/README.md @@ -0,0 +1,141 @@ +# Clients +(*clients*) + +### Available Operations + +* [~~list~~](#list) - List all clients :warning: **Deprecated** +* [verify](#verify) - Verify a client +* [get](#get) - Get a client + +## ~~list~~ + +Returns a list of all clients. The clients are returned sorted by creation date, +with the newest clients appearing first. +Warning: the endpoint is being deprecated and will be removed in future versions. + +> :warning: **DEPRECATED**: This will be removed in a future release, please migrate away from it as soon as possible. + +### Example Usage + +```python +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +res = s.clients.list(limit=20, offset=10) + +if res is not None: + while True: + # handle items + + res = res.Next() + if res is None: + break + + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| ----------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | +| `limit` | *Optional[float]* | :heavy_minus_sign: | Applies a limit to the number of results returned.
Can be used for paginating the results together with `offset`. | 20 | +| `offset` | *Optional[float]* | :heavy_minus_sign: | Skip the first `offset` results when paginating.
Needs to be an integer greater or equal to zero.
To be used in conjunction with `limit`. | 10 | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + + +### Response + +**[models.GetClientListResponse](../../models/getclientlistresponse.md)** +### Errors + +| Error Object | Status Code | Content Type | +| ------------------ | ------------------ | ------------------ | +| models.ClerkErrors | 400,401,410,422 | application/json | +| models.SDKError | 4xx-5xx | */* | + +## verify + +Verifies the client in the provided token + +### Example Usage + +```python +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +res = s.clients.verify(token="jwt_token_example") + +if res is not None: + # handle response + pass + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | +| `token` | *Optional[str]* | :heavy_minus_sign: | A JWT Token that represents the active client. | jwt_token_example | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + + +### Response + +**[models.Client](../../models/client.md)** +### Errors + +| Error Object | Status Code | Content Type | +| ------------------ | ------------------ | ------------------ | +| models.ClerkErrors | 400,401,404 | application/json | +| models.SDKError | 4xx-5xx | */* | + +## get + +Returns the details of a client. + +### Example Usage + +```python +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +res = s.clients.get(client_id="cli_123456789") + +if res is not None: + # handle response + pass + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | +| `client_id` | *str* | :heavy_check_mark: | Client ID. | cli_123456789 | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + + +### Response + +**[models.Client](../../models/client.md)** +### Errors + +| Error Object | Status Code | Content Type | +| ------------------ | ------------------ | ------------------ | +| models.ClerkErrors | 400,401,404 | application/json | +| models.SDKError | 4xx-5xx | */* | diff --git a/docs/sdks/domainssdk/README.md b/docs/sdks/domainssdk/README.md new file mode 100644 index 0000000..052dd2d --- /dev/null +++ b/docs/sdks/domainssdk/README.md @@ -0,0 +1,188 @@ +# DomainsSDK +(*domains*) + +### Available Operations + +* [list](#list) - List all instance domains +* [add](#add) - Add a domain +* [delete](#delete) - Delete a satellite domain +* [update](#update) - Update a domain + +## list + +Use this endpoint to get a list of all domains for an instance. +The response will contain the primary domain for the instance and any satellite domains. Each domain in the response contains information about the URLs where Clerk operates and the required CNAME targets. + +### Example Usage + +```python +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +res = s.domains.list() + +if res is not None: + # handle response + pass + +``` + +### Parameters + +| Parameter | Type | Required | Description | +| ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | + + +### Response + +**[models.Domains](../../models/domains.md)** +### Errors + +| Error Object | Status Code | Content Type | +| --------------- | --------------- | --------------- | +| models.SDKError | 4xx-5xx | */* | + +## add + +Add a new domain for your instance. +Useful in the case of multi-domain instances, allows adding satellite domains to an instance. +The new domain must have a `name`. The domain name can contain the port for development instances, like `localhost:3000`. +At the moment, instances can have only one primary domain, so the `is_satellite` parameter must be set to `true`. +If you're planning to configure the new satellite domain to run behind a proxy, pass the `proxy_url` parameter accordingly. + +### Example Usage + +```python +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +res = s.domains.add(name="example.com", is_satellite=True, proxy_url="https://proxy.example.com") + +if res is not None: + # handle response + pass + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| ----------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | +| `name` | *str* | :heavy_check_mark: | The new domain name. Can contain the port for development instances. | example.com | +| `is_satellite` | *bool* | :heavy_check_mark: | Marks the new domain as satellite. Only `true` is accepted at the moment. | true | +| `proxy_url` | *Optional[str]* | :heavy_minus_sign: | The full URL of the proxy which will forward requests to the Clerk Frontend API for this domain. Applicable only to production instances. | https://proxy.example.com | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + + +### Response + +**[models.Domain](../../models/domain.md)** +### Errors + +| Error Object | Status Code | Content Type | +| ------------------ | ------------------ | ------------------ | +| models.ClerkErrors | 400,402,422 | application/json | +| models.SDKError | 4xx-5xx | */* | + +## delete + +Deletes a satellite domain for the instance. +It is currently not possible to delete the instance's primary domain. + +### Example Usage + +```python +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +res = s.domains.delete(domain_id="domain_12345") + +if res is not None: + # handle response + pass + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| ---------------------------------------------------------------------- | ---------------------------------------------------------------------- | ---------------------------------------------------------------------- | ---------------------------------------------------------------------- | ---------------------------------------------------------------------- | +| `domain_id` | *str* | :heavy_check_mark: | The ID of the domain that will be deleted. Must be a satellite domain. | domain_12345 | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + + +### Response + +**[models.DeletedObject](../../models/deletedobject.md)** +### Errors + +| Error Object | Status Code | Content Type | +| ------------------ | ------------------ | ------------------ | +| models.ClerkErrors | 403,404 | application/json | +| models.SDKError | 4xx-5xx | */* | + +## update + +The `proxy_url` can be updated only for production instances. +Update one of the instance's domains. Both primary and satellite domains can be updated. +If you choose to use Clerk via proxy, use this endpoint to specify the `proxy_url`. +Whenever you decide you'd rather switch to DNS setup for Clerk, simply set `proxy_url` +to `null` for the domain. When you update a production instance's primary domain name, +you have to make sure that you've completed all the necessary setup steps for DNS and +emails to work. Expect downtime otherwise. Updating a primary domain's name will also +update the instance's home origin, affecting the default application paths. + +### Example Usage + +```python +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +res = s.domains.update(domain_id="domain_12345", name="example.com", proxy_url="http://proxy.example.com") + +if res is not None: + # handle response + pass + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `domain_id` | *str* | :heavy_check_mark: | The ID of the domain that will be updated. | domain_12345 | +| `name` | *Optional[Nullable[str]]* | :heavy_minus_sign: | The new domain name. For development instances, can contain the port,
i.e `myhostname:3000`. For production instances, must be a valid FQDN,
i.e `mysite.com`. Cannot contain protocol scheme. | example.com | +| `proxy_url` | *Optional[Nullable[str]]* | :heavy_minus_sign: | The full URL of the proxy that will forward requests to Clerk's Frontend API.
Can only be updated for production instances. | http://proxy.example.com | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + + +### Response + +**[models.Domain](../../models/domain.md)** +### Errors + +| Error Object | Status Code | Content Type | +| ------------------ | ------------------ | ------------------ | +| models.ClerkErrors | 400,404,422 | application/json | +| models.SDKError | 4xx-5xx | */* | diff --git a/docs/sdks/emailaddresses/README.md b/docs/sdks/emailaddresses/README.md new file mode 100644 index 0000000..41e9e52 --- /dev/null +++ b/docs/sdks/emailaddresses/README.md @@ -0,0 +1,178 @@ +# EmailAddresses +(*email_addresses*) + +### Available Operations + +* [create](#create) - Create an email address +* [get](#get) - Retrieve an email address +* [delete](#delete) - Delete an email address +* [update](#update) - Update an email address + +## create + +Create a new email address + +### Example Usage + +```python +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +res = s.email_addresses.create(user_id="user_12345", email_address="example@clerk.com", verified=False, primary=True) + +if res is not None: + # handle response + pass + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| -------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- | +| `user_id` | *Optional[str]* | :heavy_minus_sign: | The ID representing the user | user_12345 | +| `email_address` | *Optional[str]* | :heavy_minus_sign: | The new email address. Must adhere to the RFC 5322 specification for email address format. | example@clerk.com | +| `verified` | *Optional[Nullable[bool]]* | :heavy_minus_sign: | When created, the email address will be marked as verified. | false | +| `primary` | *Optional[Nullable[bool]]* | :heavy_minus_sign: | Create this email address as the primary email address for the user.
Default: false, unless it is the first email address. | true | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + + +### Response + +**[models.EmailAddress](../../models/emailaddress.md)** +### Errors + +| Error Object | Status Code | Content Type | +| ------------------- | ------------------- | ------------------- | +| models.ClerkErrors | 400,401,403,404,422 | application/json | +| models.SDKError | 4xx-5xx | */* | + +## get + +Returns the details of an email address. + +### Example Usage + +```python +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +res = s.email_addresses.get(email_address_id="email_address_id_example") + +if res is not None: + # handle response + pass + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | +| `email_address_id` | *str* | :heavy_check_mark: | The ID of the email address to retrieve | email_address_id_example | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + + +### Response + +**[models.EmailAddress](../../models/emailaddress.md)** +### Errors + +| Error Object | Status Code | Content Type | +| ------------------ | ------------------ | ------------------ | +| models.ClerkErrors | 400,401,403,404 | application/json | +| models.SDKError | 4xx-5xx | */* | + +## delete + +Delete the email address with the given ID + +### Example Usage + +```python +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +res = s.email_addresses.delete(email_address_id="email_address_id_example") + +if res is not None: + # handle response + pass + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | +| `email_address_id` | *str* | :heavy_check_mark: | The ID of the email address to delete | email_address_id_example | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + + +### Response + +**[models.DeletedObject](../../models/deletedobject.md)** +### Errors + +| Error Object | Status Code | Content Type | +| ------------------ | ------------------ | ------------------ | +| models.ClerkErrors | 400,401,403,404 | application/json | +| models.SDKError | 4xx-5xx | */* | + +## update + +Updates an email address. + +### Example Usage + +```python +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +res = s.email_addresses.update(email_address_id="email_address_id_example", verified=False, primary=True) + +if res is not None: + # handle response + pass + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | +| `email_address_id` | *str* | :heavy_check_mark: | The ID of the email address to update | email_address_id_example | +| `verified` | *Optional[Nullable[bool]]* | :heavy_minus_sign: | The email address will be marked as verified. | false | +| `primary` | *Optional[Nullable[bool]]* | :heavy_minus_sign: | Set this email address as the primary email address for the user. | true | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + + +### Response + +**[models.EmailAddress](../../models/emailaddress.md)** +### Errors + +| Error Object | Status Code | Content Type | +| ------------------ | ------------------ | ------------------ | +| models.ClerkErrors | 400,401,403,404 | application/json | +| models.SDKError | 4xx-5xx | */* | diff --git a/docs/sdks/instancesettingssdk/README.md b/docs/sdks/instancesettingssdk/README.md new file mode 100644 index 0000000..8f5debf --- /dev/null +++ b/docs/sdks/instancesettingssdk/README.md @@ -0,0 +1,150 @@ +# InstanceSettingsSDK +(*instance_settings*) + +### Available Operations + +* [update](#update) - Update instance settings +* [update_restrictions](#update_restrictions) - Update instance restrictions +* [update_organization_settings](#update_organization_settings) - Update instance organization settings + +## update + +Updates the settings of an instance + +### Example Usage + +```python +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +s.instance_settings.update(test_mode=True, hibp=False, enhanced_email_deliverability=True, support_email="support@example.com", clerk_js_version="2.3.1", development_origin="http://localhost:3000", allowed_origins=[ + "http://localhost:3000", + "chrome-extension://extension_uiid", + "capacitor://localhost", +], cookieless_dev=False, url_based_session_syncing=True) + +# Use the SDK ... + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `test_mode` | *Optional[Nullable[bool]]* | :heavy_minus_sign: | Toggles test mode for this instance, allowing the use of test email addresses and phone numbers.
Defaults to true for development instances. | true | +| `hibp` | *Optional[Nullable[bool]]* | :heavy_minus_sign: | Whether the instance should be using the HIBP service to check passwords for breaches | false | +| `enhanced_email_deliverability` | *Optional[Nullable[bool]]* | :heavy_minus_sign: | The "enhanced_email_deliverability" feature will send emails from "verifications@clerk.dev" instead of your domain.
This can be helpful if you do not have a high domain reputation. | true | +| `support_email` | *Optional[Nullable[str]]* | :heavy_minus_sign: | N/A | support@example.com | +| `clerk_js_version` | *Optional[Nullable[str]]* | :heavy_minus_sign: | N/A | 2.3.1 | +| `development_origin` | *Optional[Nullable[str]]* | :heavy_minus_sign: | N/A | http://localhost:3000 | +| `allowed_origins` | List[*str*] | :heavy_minus_sign: | For browser-like stacks such as browser extensions, Electron, or Capacitor.js the instance allowed origins need to be updated with the request origin value.
For Chrome extensions popup, background, or service worker pages the origin is chrome-extension://extension_uiid. For Electron apps the default origin is http://localhost:3000. For Capacitor, the origin is capacitor://localhost. | [
"http://localhost:3000",
"chrome-extension://extension_uiid",
"capacitor://localhost"
] | +| `cookieless_dev` | *Optional[bool]* | :heavy_minus_sign: | : warning: ** DEPRECATED **: This will be removed in a future release, please migrate away from it as soon as possible.

Whether the instance should operate in cookieless development mode (i.e. without third-party cookies).
Deprecated: Please use `url_based_session_syncing` instead. | false | +| `url_based_session_syncing` | *Optional[bool]* | :heavy_minus_sign: | Whether the instance should use URL-based session syncing in development mode (i.e. without third-party cookies). | true | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + +### Errors + +| Error Object | Status Code | Content Type | +| ------------------ | ------------------ | ------------------ | +| models.ClerkErrors | 422 | application/json | +| models.SDKError | 4xx-5xx | */* | + +## update_restrictions + +Updates the restriction settings of an instance + +### Example Usage + +```python +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +res = s.instance_settings.update_restrictions(allowlist=False, blocklist=True, block_email_subaddresses=True, block_disposable_email_domains=True, ignore_dots_for_gmail_addresses=False) + +if res is not None: + # handle response + pass + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | +| `allowlist` | *Optional[Nullable[bool]]* | :heavy_minus_sign: | N/A | false | +| `blocklist` | *Optional[Nullable[bool]]* | :heavy_minus_sign: | N/A | true | +| `block_email_subaddresses` | *Optional[Nullable[bool]]* | :heavy_minus_sign: | N/A | true | +| `block_disposable_email_domains` | *Optional[Nullable[bool]]* | :heavy_minus_sign: | N/A | true | +| `ignore_dots_for_gmail_addresses` | *Optional[Nullable[bool]]* | :heavy_minus_sign: | N/A | false | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + + +### Response + +**[models.InstanceRestrictions](../../models/instancerestrictions.md)** +### Errors + +| Error Object | Status Code | Content Type | +| ------------------ | ------------------ | ------------------ | +| models.ClerkErrors | 402,422 | application/json | +| models.SDKError | 4xx-5xx | */* | + +## update_organization_settings + +Updates the organization settings of the instance + +### Example Usage + +```python +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +res = s.instance_settings.update_organization_settings(enabled=True, max_allowed_memberships=10, admin_delete_enabled=False, domains_enabled=True, domains_enrollment_modes=[ + "automatic_invitation", + "automatic_suggestion", +], creator_role_id="creator_role", domains_default_role_id="member_role") + +if res is not None: + # handle response + pass + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| -------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- | +| `enabled` | *Optional[Nullable[bool]]* | :heavy_minus_sign: | N/A | true | +| `max_allowed_memberships` | *Optional[Nullable[int]]* | :heavy_minus_sign: | N/A | 10 | +| `admin_delete_enabled` | *Optional[Nullable[bool]]* | :heavy_minus_sign: | N/A | false | +| `domains_enabled` | *Optional[Nullable[bool]]* | :heavy_minus_sign: | N/A | true | +| `domains_enrollment_modes` | List[*str*] | :heavy_minus_sign: | Specify which enrollment modes to enable for your Organization Domains.
Supported modes are 'automatic_invitation' & 'automatic_suggestion'. | [
"automatic_invitation",
"automatic_suggestion"
] | +| `creator_role_id` | *Optional[str]* | :heavy_minus_sign: | Specify what the default organization role is for an organization creator. | creator_role | +| `domains_default_role_id` | *Optional[str]* | :heavy_minus_sign: | Specify what the default organization role is for the organization domains. | member_role | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + + +### Response + +**[models.OrganizationSettings](../../models/organizationsettings.md)** +### Errors + +| Error Object | Status Code | Content Type | +| ------------------ | ------------------ | ------------------ | +| models.ClerkErrors | 402,404,422 | application/json | +| models.SDKError | 4xx-5xx | */* | diff --git a/docs/sdks/invitations/README.md b/docs/sdks/invitations/README.md new file mode 100644 index 0000000..a796b6f --- /dev/null +++ b/docs/sdks/invitations/README.md @@ -0,0 +1,147 @@ +# Invitations +(*invitations*) + +### Available Operations + +* [create](#create) - Create an invitation +* [list](#list) - List all invitations +* [revoke](#revoke) - Revokes an invitation + +## create + +Creates a new invitation for the given email address and sends the invitation email. +Keep in mind that you cannot create an invitation if there is already one for the given email address. +Also, trying to create an invitation for an email address that already exists in your application will result to an error. + +### Example Usage + +```python +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +res = s.invitations.create(email_address="user@example.com", public_metadata={}, redirect_url="https://example.com/welcome", notify=True, ignore_existing=True) + +if res is not None: + # handle response + pass + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `email_address` | *str* | :heavy_check_mark: | The email address the invitation will be sent to | user@example.com | +| `public_metadata` | [Optional[models.CreateInvitationPublicMetadata]](../../models/createinvitationpublicmetadata.md) | :heavy_minus_sign: | Metadata that will be attached to the newly created invitation.
The value of this property should be a well-formed JSON object.
Once the user accepts the invitation and signs up, these metadata will end up in the user's public metadata. | {} | +| `redirect_url` | *Optional[str]* | :heavy_minus_sign: | Optional URL which specifies where to redirect the user once they click the invitation link.
This is only required if you have implemented a [custom flow](https://clerk.com/docs/authentication/invitations#custom-flow) and you're not using Clerk Hosted Pages or Clerk Components. | https://example.com/welcome | +| `notify` | *Optional[Nullable[bool]]* | :heavy_minus_sign: | Optional flag which denotes whether an email invitation should be sent to the given email address.
Defaults to true. | true | +| `ignore_existing` | *Optional[Nullable[bool]]* | :heavy_minus_sign: | Whether an invitation should be created if there is already an existing invitation for this email address, or it's claimed by another user. | ​false | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + + +### Response + +**[models.Invitation](../../models/invitation.md)** +### Errors + +| Error Object | Status Code | Content Type | +| ------------------ | ------------------ | ------------------ | +| models.ClerkErrors | 400,422 | application/json | +| models.SDKError | 4xx-5xx | */* | + +## list + +Returns all non-revoked invitations for your application, sorted by creation date + +### Example Usage + +```python +import clerk +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +res = s.invitations.list(limit=20, offset=10, status=clerk.ListInvitationsQueryParamStatus.PENDING) + +if res is not None: + while True: + # handle items + + res = res.Next() + if res is None: + break + + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| ----------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | +| `limit` | *Optional[float]* | :heavy_minus_sign: | Applies a limit to the number of results returned.
Can be used for paginating the results together with `offset`. | 20 | +| `offset` | *Optional[float]* | :heavy_minus_sign: | Skip the first `offset` results when paginating.
Needs to be an integer greater or equal to zero.
To be used in conjunction with `limit`. | 10 | +| `status` | [Optional[models.ListInvitationsQueryParamStatus]](../../models/listinvitationsqueryparamstatus.md) | :heavy_minus_sign: | Filter invitations based on their status | pending | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + + +### Response + +**[models.ListInvitationsResponse](../../models/listinvitationsresponse.md)** +### Errors + +| Error Object | Status Code | Content Type | +| --------------- | --------------- | --------------- | +| models.SDKError | 4xx-5xx | */* | + +## revoke + +Revokes the given invitation. +Revoking an invitation will prevent the user from using the invitation link that was sent to them. +However, it doesn't prevent the user from signing up if they follow the sign up flow. +Only active (i.e. non-revoked) invitations can be revoked. + +### Example Usage + +```python +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +res = s.invitations.revoke(invitation_id="inv_123") + +if res is not None: + # handle response + pass + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | +| `invitation_id` | *str* | :heavy_check_mark: | The ID of the invitation to be revoked | inv_123 | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + + +### Response + +**[models.InvitationRevoked](../../models/invitationrevoked.md)** +### Errors + +| Error Object | Status Code | Content Type | +| ------------------ | ------------------ | ------------------ | +| models.ClerkErrors | 400,404 | application/json | +| models.SDKError | 4xx-5xx | */* | diff --git a/docs/sdks/jwks/README.md b/docs/sdks/jwks/README.md new file mode 100644 index 0000000..9dd18d6 --- /dev/null +++ b/docs/sdks/jwks/README.md @@ -0,0 +1,39 @@ +# Jwks +(*jwks*) + +### Available Operations + +* [get](#get) - Retrieve the JSON Web Key Set of the instance + +## get + +Retrieve the JSON Web Key Set of the instance + +### Example Usage + +```python +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +s.jwks.get() + +# Use the SDK ... + +``` + +### Parameters + +| Parameter | Type | Required | Description | +| ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | + +### Errors + +| Error Object | Status Code | Content Type | +| --------------- | --------------- | --------------- | +| models.SDKError | 4xx-5xx | */* | diff --git a/docs/sdks/jwttemplates/README.md b/docs/sdks/jwttemplates/README.md new file mode 100644 index 0000000..0cf45c7 --- /dev/null +++ b/docs/sdks/jwttemplates/README.md @@ -0,0 +1,226 @@ +# JwtTemplates +(*jwt_templates*) + +### Available Operations + +* [list](#list) - List all templates +* [create](#create) - Create a JWT template +* [get](#get) - Retrieve a template +* [update](#update) - Update a JWT template +* [delete](#delete) - Delete a Template + +## list + +List all templates + +### Example Usage + +```python +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +res = s.jwt_templates.list() + +if res is not None: + # handle response + pass + +``` + +### Parameters + +| Parameter | Type | Required | Description | +| ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | + + +### Response + +**[List[models.JWTTemplate]](../../models/.md)** +### Errors + +| Error Object | Status Code | Content Type | +| --------------- | --------------- | --------------- | +| models.SDKError | 4xx-5xx | */* | + +## create + +Create a new JWT template + +### Example Usage + +```python +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +res = s.jwt_templates.create(name="Example Template", claims={}, lifetime=3600, allowed_clock_skew=5, custom_signing_key=False, signing_algorithm="RS256", signing_key="PRIVATE_KEY_PLACEHOLDER") + +if res is not None: + # handle response + pass + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| ----------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- | +| `name` | *Optional[str]* | :heavy_minus_sign: | JWT template name | Example Template | +| `claims` | [Optional[models.CreateJWTTemplateClaims]](../../models/createjwttemplateclaims.md) | :heavy_minus_sign: | JWT template claims in JSON format | {} | +| `lifetime` | *Optional[Nullable[float]]* | :heavy_minus_sign: | JWT token lifetime | 3600 | +| `allowed_clock_skew` | *Optional[Nullable[float]]* | :heavy_minus_sign: | JWT token allowed clock skew | 5 | +| `custom_signing_key` | *Optional[bool]* | :heavy_minus_sign: | Whether a custom signing key/algorithm is also provided for this template | false | +| `signing_algorithm` | *Optional[Nullable[str]]* | :heavy_minus_sign: | The custom signing algorithm to use when minting JWTs | RS256 | +| `signing_key` | *Optional[Nullable[str]]* | :heavy_minus_sign: | The custom signing private key to use when minting JWTs | PRIVATE_KEY_PLACEHOLDER | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + + +### Response + +**[models.JWTTemplate](../../models/jwttemplate.md)** +### Errors + +| Error Object | Status Code | Content Type | +| ------------------ | ------------------ | ------------------ | +| models.ClerkErrors | 400,402,422 | application/json | +| models.SDKError | 4xx-5xx | */* | + +## get + +Retrieve the details of a given JWT template + +### Example Usage + +```python +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +res = s.jwt_templates.get(template_id="template_123") + +if res is not None: + # handle response + pass + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | +| `template_id` | *str* | :heavy_check_mark: | JWT Template ID | template_123 | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + + +### Response + +**[models.JWTTemplate](../../models/jwttemplate.md)** +### Errors + +| Error Object | Status Code | Content Type | +| ------------------ | ------------------ | ------------------ | +| models.ClerkErrors | 404 | application/json | +| models.SDKError | 4xx-5xx | */* | + +## update + +Updates an existing JWT template + +### Example Usage + +```python +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +res = s.jwt_templates.update(template_id="", name="", claims={}, lifetime=8574.78, allowed_clock_skew=245.55, custom_signing_key=False, signing_algorithm="", signing_key="") + +if res is not None: + # handle response + pass + +``` + +### Parameters + +| Parameter | Type | Required | Description | +| ----------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- | +| `template_id` | *str* | :heavy_check_mark: | The ID of the JWT template to update | +| `name` | *Optional[str]* | :heavy_minus_sign: | JWT template name | +| `claims` | [Optional[models.UpdateJWTTemplateClaims]](../../models/updatejwttemplateclaims.md) | :heavy_minus_sign: | JWT template claims in JSON format | +| `lifetime` | *Optional[Nullable[float]]* | :heavy_minus_sign: | JWT token lifetime | +| `allowed_clock_skew` | *Optional[Nullable[float]]* | :heavy_minus_sign: | JWT token allowed clock skew | +| `custom_signing_key` | *Optional[bool]* | :heavy_minus_sign: | Whether a custom signing key/algorithm is also provided for this template | +| `signing_algorithm` | *Optional[Nullable[str]]* | :heavy_minus_sign: | The custom signing algorithm to use when minting JWTs | +| `signing_key` | *Optional[Nullable[str]]* | :heavy_minus_sign: | The custom signing private key to use when minting JWTs | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | + + +### Response + +**[models.JWTTemplate](../../models/jwttemplate.md)** +### Errors + +| Error Object | Status Code | Content Type | +| ------------------ | ------------------ | ------------------ | +| models.ClerkErrors | 400,402,422 | application/json | +| models.SDKError | 4xx-5xx | */* | + +## delete + +Delete a Template + +### Example Usage + +```python +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +res = s.jwt_templates.delete(template_id="") + +if res is not None: + # handle response + pass + +``` + +### Parameters + +| Parameter | Type | Required | Description | +| ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | +| `template_id` | *str* | :heavy_check_mark: | JWT Template ID | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | + + +### Response + +**[models.DeletedObject](../../models/deletedobject.md)** +### Errors + +| Error Object | Status Code | Content Type | +| ------------------ | ------------------ | ------------------ | +| models.ClerkErrors | 403,404 | application/json | +| models.SDKError | 4xx-5xx | */* | diff --git a/docs/sdks/misc/README.md b/docs/sdks/misc/README.md new file mode 100644 index 0000000..5e3e972 --- /dev/null +++ b/docs/sdks/misc/README.md @@ -0,0 +1,39 @@ +# Misc +(*misc*) + +### Available Operations + +* [get_public_interstitial](#get_public_interstitial) - Returns the markup for the interstitial page + +## get_public_interstitial + +The Clerk interstitial endpoint serves an html page that loads clerk.js in order to check the user's authentication state. +It is used by Clerk SDKs when the user's authentication state cannot be immediately determined. + +### Example Usage + +```python +from clerk import Clerk + +s = Clerk() + + +s.misc.get_public_interstitial(frontend_api="frontend-api_1a2b3c4d", publishable_key="pub_1a2b3c4d") + +# Use the SDK ... + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | +| `frontend_api` | *Optional[str]* | :heavy_minus_sign: | The Frontend API key of your instance | frontend-api_1a2b3c4d | +| `publishable_key` | *Optional[str]* | :heavy_minus_sign: | The publishable key of your instance | pub_1a2b3c4d | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + +### Errors + +| Error Object | Status Code | Content Type | +| --------------- | --------------- | --------------- | +| models.SDKError | 4xx-5xx | */* | diff --git a/docs/sdks/oauthapplicationssdk/README.md b/docs/sdks/oauthapplicationssdk/README.md new file mode 100644 index 0000000..b47a67b --- /dev/null +++ b/docs/sdks/oauthapplicationssdk/README.md @@ -0,0 +1,276 @@ +# OAuthApplicationsSDK +(*o_auth_applications*) + +### Available Operations + +* [list](#list) - Get a list of OAuth applications for an instance +* [create](#create) - Create an OAuth application +* [get](#get) - Retrieve an OAuth application by ID +* [update](#update) - Update an OAuth application +* [delete](#delete) - Delete an OAuth application +* [rotate_secret](#rotate_secret) - Rotate the client secret of the given OAuth application + +## list + +This request returns the list of OAuth applications for an instance. +Results can be paginated using the optional `limit` and `offset` query parameters. +The OAuth applications are ordered by descending creation date. +Most recent OAuth applications will be returned first. + +### Example Usage + +```python +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +res = s.o_auth_applications.list(limit=20, offset=10) + +if res is not None: + while True: + # handle items + + res = res.Next() + if res is None: + break + + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| ----------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | +| `limit` | *Optional[float]* | :heavy_minus_sign: | Applies a limit to the number of results returned.
Can be used for paginating the results together with `offset`. | 20 | +| `offset` | *Optional[float]* | :heavy_minus_sign: | Skip the first `offset` results when paginating.
Needs to be an integer greater or equal to zero.
To be used in conjunction with `limit`. | 10 | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + + +### Response + +**[models.ListOAuthApplicationsResponse](../../models/listoauthapplicationsresponse.md)** +### Errors + +| Error Object | Status Code | Content Type | +| ------------------ | ------------------ | ------------------ | +| models.ClerkErrors | 400,403,422 | application/json | +| models.SDKError | 4xx-5xx | */* | + +## create + +Creates a new OAuth application with the given name and callback URL for an instance. +The callback URL must be a valid url. +All URL schemes are allowed such as `http://`, `https://`, `myapp://`, etc... + +### Example Usage + +```python +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +res = s.o_auth_applications.create(name="Example App", callback_url="https://example.com/oauth/callback", scopes="profile email public_metadata", public=True) + +if res is not None: + # handle response + pass + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `name` | *str* | :heavy_check_mark: | The name of the new OAuth application | Example App | +| `callback_url` | *str* | :heavy_check_mark: | The callback URL of the new OAuth application | https://example.com/oauth/callback | +| `scopes` | *Optional[str]* | :heavy_minus_sign: | Define the allowed scopes for the new OAuth applications that dictate the user payload of the OAuth user info endpoint. Available scopes are `profile`, `email`, `public_metadata`, `private_metadata`. Provide the requested scopes as a string, separated by spaces. | profile email public_metadata | +| `public` | *Optional[bool]* | :heavy_minus_sign: | If true, this client is public and cannot securely store a client secret.
Only the authorization code flow with proof key for code exchange (PKCE) may be used.
Public clients cannot be updated to be confidential clients, and vice versa. | true | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + + +### Response + +**[models.OAuthApplicationWithSecret](../../models/oauthapplicationwithsecret.md)** +### Errors + +| Error Object | Status Code | Content Type | +| ------------------ | ------------------ | ------------------ | +| models.ClerkErrors | 400,403,422 | application/json | +| models.SDKError | 4xx-5xx | */* | + +## get + +Fetches the OAuth application whose ID matches the provided `id` in the path. + +### Example Usage + +```python +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +res = s.o_auth_applications.get(oauth_application_id="oauth_app_12345") + +if res is not None: + # handle response + pass + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | +| `oauth_application_id` | *str* | :heavy_check_mark: | The ID of the OAuth application | oauth_app_12345 | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + + +### Response + +**[models.OAuthApplication](../../models/oauthapplication.md)** +### Errors + +| Error Object | Status Code | Content Type | +| ------------------ | ------------------ | ------------------ | +| models.ClerkErrors | 403,404 | application/json | +| models.SDKError | 4xx-5xx | */* | + +## update + +Updates an existing OAuth application + +### Example Usage + +```python +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +res = s.o_auth_applications.update(oauth_application_id="oauth_app_67890", name="Updated OAuth App Name", callback_url="https://example.com/oauth/callback", scopes="profile email public_metadata private_metadata") + +if res is not None: + # handle response + pass + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `oauth_application_id` | *str* | :heavy_check_mark: | The ID of the OAuth application to update | oauth_app_67890 | +| `name` | *Optional[str]* | :heavy_minus_sign: | The new name of the OAuth application | Updated OAuth App Name | +| `callback_url` | *Optional[str]* | :heavy_minus_sign: | The new callback URL of the OAuth application | https://example.com/oauth/callback | +| `scopes` | *Optional[str]* | :heavy_minus_sign: | Define the allowed scopes for the new OAuth applications that dictate the user payload of the OAuth user info endpoint. Available scopes are `profile`, `email`, `public_metadata`, `private_metadata`. Provide the requested scopes as a string, separated by spaces. | profile email public_metadata private_metadata | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + + +### Response + +**[models.OAuthApplication](../../models/oauthapplication.md)** +### Errors + +| Error Object | Status Code | Content Type | +| ------------------ | ------------------ | ------------------ | +| models.ClerkErrors | 403,404,422 | application/json | +| models.SDKError | 4xx-5xx | */* | + +## delete + +Deletes the given OAuth application. +This is not reversible. + +### Example Usage + +```python +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +res = s.o_auth_applications.delete(oauth_application_id="oauth_app_09876") + +if res is not None: + # handle response + pass + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | +| `oauth_application_id` | *str* | :heavy_check_mark: | The ID of the OAuth application to delete | oauth_app_09876 | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + + +### Response + +**[models.DeletedObject](../../models/deletedobject.md)** +### Errors + +| Error Object | Status Code | Content Type | +| ------------------ | ------------------ | ------------------ | +| models.ClerkErrors | 403,404 | application/json | +| models.SDKError | 4xx-5xx | */* | + +## rotate_secret + +Rotates the OAuth application's client secret. +When the client secret is rotated, make sure to update it in authorized OAuth clients. + +### Example Usage + +```python +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +res = s.o_auth_applications.rotate_secret(oauth_application_id="oauth_application_12345") + +if res is not None: + # handle response + pass + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| --------------------------------------------------------------------- | --------------------------------------------------------------------- | --------------------------------------------------------------------- | --------------------------------------------------------------------- | --------------------------------------------------------------------- | +| `oauth_application_id` | *str* | :heavy_check_mark: | The ID of the OAuth application for which to rotate the client secret | oauth_application_12345 | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + + +### Response + +**[models.OAuthApplicationWithSecret](../../models/oauthapplicationwithsecret.md)** +### Errors + +| Error Object | Status Code | Content Type | +| ------------------ | ------------------ | ------------------ | +| models.ClerkErrors | 403,404 | application/json | +| models.SDKError | 4xx-5xx | */* | diff --git a/docs/sdks/organizationinvitationssdk/README.md b/docs/sdks/organizationinvitationssdk/README.md new file mode 100644 index 0000000..965a6ee --- /dev/null +++ b/docs/sdks/organizationinvitationssdk/README.md @@ -0,0 +1,335 @@ +# OrganizationInvitationsSDK +(*organization_invitations*) + +### Available Operations + +* [create](#create) - Create and send an organization invitation +* [list](#list) - Get a list of organization invitations +* [create_bulk](#create_bulk) - Bulk create and send organization invitations +* [~~list_pending~~](#list_pending) - Get a list of pending organization invitations :warning: **Deprecated** +* [get](#get) - Retrieve an organization invitation by ID +* [revoke](#revoke) - Revoke a pending organization invitation + +## create + +Creates a new organization invitation and sends an email to the provided `email_address` with a link to accept the invitation and join the organization. +You can specify the `role` for the invited organization member. + +New organization invitations get a "pending" status until they are revoked by an organization administrator or accepted by the invitee. + +The request body supports passing an optional `redirect_url` parameter. +When the invited user clicks the link to accept the invitation, they will be redirected to the URL provided. +Use this parameter to implement a custom invitation acceptance flow. + +You must specify the ID of the user that will send the invitation with the `inviter_user_id` parameter. +That user must be a member with administrator privileges in the organization. +Only "admin" members can create organization invitations. + +You can optionally provide public and private metadata for the organization invitation. +The public metadata are visible by both the Frontend and the Backend whereas the private ones only by the Backend. +When the organization invitation is accepted, the metadata will be transferred to the newly created organization membership. + +### Example Usage + +```python +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +res = s.organization_invitations.create(organization_id="org_12345", email_address="user@example.com", inviter_user_id="user_67890", role="admin", public_metadata={}, private_metadata={}, redirect_url="https://example.com/welcome") + +if res is not None: + # handle response + pass + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| ---------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | +| `organization_id` | *str* | :heavy_check_mark: | The ID of the organization for which to send the invitation | org_12345 | +| `email_address` | *str* | :heavy_check_mark: | The email address of the new member that is going to be invited to the organization | user@example.com | +| `inviter_user_id` | *str* | :heavy_check_mark: | The ID of the user that invites the new member to the organization.
Must be an administrator in the organization. | user_67890 | +| `role` | *str* | :heavy_check_mark: | The role of the new member in the organization | admin | +| `public_metadata` | [Optional[models.CreateOrganizationInvitationPublicMetadata]](../../models/createorganizationinvitationpublicmetadata.md) | :heavy_minus_sign: | Metadata saved on the organization invitation, read-only from the Frontend API and fully accessible (read/write) from the Backend API. | {
"key": "value"
} | +| `private_metadata` | [Optional[models.CreateOrganizationInvitationPrivateMetadata]](../../models/createorganizationinvitationprivatemetadata.md) | :heavy_minus_sign: | Metadata saved on the organization invitation, fully accessible (read/write) from the Backend API but not visible from the Frontend API. | {
"private_key": "secret_value"
} | +| `redirect_url` | *Optional[str]* | :heavy_minus_sign: | Optional URL that the invitee will be redirected to once they accept the invitation by clicking the join link in the invitation email. | https://example.com/welcome | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + + +### Response + +**[models.OrganizationInvitation](../../models/organizationinvitation.md)** +### Errors + +| Error Object | Status Code | Content Type | +| ------------------ | ------------------ | ------------------ | +| models.ClerkErrors | 400,403,404,422 | application/json | +| models.SDKError | 4xx-5xx | */* | + +## list + +This request returns the list of organization invitations. +Results can be paginated using the optional `limit` and `offset` query parameters. +You can filter them by providing the 'status' query parameter, that accepts multiple values. +The organization invitations are ordered by descending creation date. +Most recent invitations will be returned first. +Any invitations created as a result of an Organization Domain are not included in the results. + +### Example Usage + +```python +import clerk +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +res = s.organization_invitations.list(organization_id="org_12345", limit=20, offset=10, status=clerk.ListOrganizationInvitationsQueryParamStatus.PENDING) + +if res is not None: + while True: + # handle items + + res = res.Next() + if res is None: + break + + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| ----------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | +| `organization_id` | *str* | :heavy_check_mark: | The organization ID. | org_12345 | +| `limit` | *Optional[float]* | :heavy_minus_sign: | Applies a limit to the number of results returned.
Can be used for paginating the results together with `offset`. | 20 | +| `offset` | *Optional[float]* | :heavy_minus_sign: | Skip the first `offset` results when paginating.
Needs to be an integer greater or equal to zero.
To be used in conjunction with `limit`. | 10 | +| `status` | [Optional[models.ListOrganizationInvitationsQueryParamStatus]](../../models/listorganizationinvitationsqueryparamstatus.md) | :heavy_minus_sign: | Filter organization invitations based on their status | pending | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + + +### Response + +**[models.ListOrganizationInvitationsResponse](../../models/listorganizationinvitationsresponse.md)** +### Errors + +| Error Object | Status Code | Content Type | +| ------------------ | ------------------ | ------------------ | +| models.ClerkErrors | 400,404 | application/json | +| models.SDKError | 4xx-5xx | */* | + +## create_bulk + +Creates new organization invitations in bulk and sends out emails to the provided email addresses with a link to accept the invitation and join the organization. +You can specify a different `role` for each invited organization member. +New organization invitations get a "pending" status until they are revoked by an organization administrator or accepted by the invitee. +The request body supports passing an optional `redirect_url` parameter for each invitation. +When the invited user clicks the link to accept the invitation, they will be redirected to the provided URL. +Use this parameter to implement a custom invitation acceptance flow. +You must specify the ID of the user that will send the invitation with the `inviter_user_id` parameter. Each invitation +can have a different inviter user. +Inviter users must be members with administrator privileges in the organization. +Only "admin" members can create organization invitations. +You can optionally provide public and private metadata for each organization invitation. The public metadata are visible +by both the Frontend and the Backend, whereas the private metadata are only visible by the Backend. +When the organization invitation is accepted, the metadata will be transferred to the newly created organization membership. + +### Example Usage + +```python +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +res = s.organization_invitations.create_bulk(organization_id="org_12345", request_body=[ + { + "email_address": "newmember@example.com", + "inviter_user_id": "user_67890", + "role": "admin", + "public_metadata": {}, + "private_metadata": {}, + "redirect_url": "https://example.com/welcome", + }, +]) + +if res is not None: + # handle response + pass + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | +| `organization_id` | *str* | :heavy_check_mark: | The organization ID. | org_12345 | +| `request_body` | List[[models.RequestBody](../../models/requestbody.md)] | :heavy_check_mark: | N/A | | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + + +### Response + +**[models.OrganizationInvitations](../../models/organizationinvitations.md)** +### Errors + +| Error Object | Status Code | Content Type | +| ------------------ | ------------------ | ------------------ | +| models.ClerkErrors | 400,403,404,422 | application/json | +| models.SDKError | 4xx-5xx | */* | + +## ~~list_pending~~ + +This request returns the list of organization invitations with "pending" status. +These are the organization invitations that can still be used to join the organization, but have not been accepted by the invited user yet. +Results can be paginated using the optional `limit` and `offset` query parameters. +The organization invitations are ordered by descending creation date. +Most recent invitations will be returned first. +Any invitations created as a result of an Organization Domain are not included in the results. + +> :warning: **DEPRECATED**: This will be removed in a future release, please migrate away from it as soon as possible. + +### Example Usage + +```python +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +res = s.organization_invitations.list_pending(organization_id="org_12345", limit=20, offset=10) + +if res is not None: + while True: + # handle items + + res = res.Next() + if res is None: + break + + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| ----------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | +| `organization_id` | *str* | :heavy_check_mark: | The organization ID. | org_12345 | +| `limit` | *Optional[float]* | :heavy_minus_sign: | Applies a limit to the number of results returned.
Can be used for paginating the results together with `offset`. | 20 | +| `offset` | *Optional[float]* | :heavy_minus_sign: | Skip the first `offset` results when paginating.
Needs to be an integer greater or equal to zero.
To be used in conjunction with `limit`. | 10 | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + + +### Response + +**[models.ListPendingOrganizationInvitationsResponse](../../models/listpendingorganizationinvitationsresponse.md)** +### Errors + +| Error Object | Status Code | Content Type | +| ------------------ | ------------------ | ------------------ | +| models.ClerkErrors | 400,404 | application/json | +| models.SDKError | 4xx-5xx | */* | + +## get + +Use this request to get an existing organization invitation by ID. + +### Example Usage + +```python +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +res = s.organization_invitations.get(organization_id="org_123456789", invitation_id="inv_987654321") + +if res is not None: + # handle response + pass + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | +| `organization_id` | *str* | :heavy_check_mark: | The organization ID. | org_123456789 | +| `invitation_id` | *str* | :heavy_check_mark: | The organization invitation ID. | inv_987654321 | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + + +### Response + +**[models.OrganizationInvitation](../../models/organizationinvitation.md)** +### Errors + +| Error Object | Status Code | Content Type | +| ------------------ | ------------------ | ------------------ | +| models.ClerkErrors | 400,403,404 | application/json | +| models.SDKError | 4xx-5xx | */* | + +## revoke + +Use this request to revoke a previously issued organization invitation. +Revoking an organization invitation makes it invalid; the invited user will no longer be able to join the organization with the revoked invitation. +Only organization invitations with "pending" status can be revoked. +The request needs the `requesting_user_id` parameter to specify the user which revokes the invitation. +Only users with "admin" role can revoke invitations. + +### Example Usage + +```python +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +res = s.organization_invitations.revoke(organization_id="org_123456", invitation_id="inv_123456", requesting_user_id="usr_12345") + +if res is not None: + # handle response + pass + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| --------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------- | +| `organization_id` | *str* | :heavy_check_mark: | The organization ID. | org_123456 | +| `invitation_id` | *str* | :heavy_check_mark: | The organization invitation ID. | inv_123456 | +| `requesting_user_id` | *str* | :heavy_check_mark: | The ID of the user that revokes the invitation.
Must be an administrator in the organization. | usr_12345 | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + + +### Response + +**[models.OrganizationInvitation](../../models/organizationinvitation.md)** +### Errors + +| Error Object | Status Code | Content Type | +| ------------------ | ------------------ | ------------------ | +| models.ClerkErrors | 400,403,404 | application/json | +| models.SDKError | 4xx-5xx | */* | diff --git a/docs/sdks/organizationmembershipssdk/README.md b/docs/sdks/organizationmembershipssdk/README.md new file mode 100644 index 0000000..c6e7877 --- /dev/null +++ b/docs/sdks/organizationmembershipssdk/README.md @@ -0,0 +1,233 @@ +# OrganizationMembershipsSDK +(*organization_memberships*) + +### Available Operations + +* [create](#create) - Create a new organization membership +* [list](#list) - Get a list of all members of an organization +* [update](#update) - Update an organization membership +* [delete](#delete) - Remove a member from an organization +* [update_metadata](#update_metadata) - Merge and update organization membership metadata + +## create + +Adds a user as a member to the given organization. + +### Example Usage + +```python +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +res = s.organization_memberships.create(organization_id="org_123", user_id="user_456", role="admin") + +if res is not None: + # handle response + pass + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| ---------------------------------------------------------------------- | ---------------------------------------------------------------------- | ---------------------------------------------------------------------- | ---------------------------------------------------------------------- | ---------------------------------------------------------------------- | +| `organization_id` | *str* | :heavy_check_mark: | The ID of the organization where the new membership will be created | org_123 | +| `user_id` | *str* | :heavy_check_mark: | The ID of the user that will be added as a member in the organization. | user_456 | +| `role` | *str* | :heavy_check_mark: | The role that the new member will have in the organization. | admin | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + + +### Response + +**[models.OrganizationMembership](../../models/organizationmembership.md)** +### Errors + +| Error Object | Status Code | Content Type | +| ------------------ | ------------------ | ------------------ | +| models.ClerkErrors | 400,403,404,422 | application/json | +| models.SDKError | 4xx-5xx | */* | + +## list + +Retrieves all user memberships for the given organization + +### Example Usage + +```python +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +res = s.organization_memberships.list(organization_id="org_789", limit=20, offset=10, order_by="+created_at") + +if res is not None: + while True: + # handle items + + res = res.Next() + if res is None: + break + + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `organization_id` | *str* | :heavy_check_mark: | The organization ID. | org_789 | +| `limit` | *Optional[float]* | :heavy_minus_sign: | Applies a limit to the number of results returned.
Can be used for paginating the results together with `offset`. | 20 | +| `offset` | *Optional[float]* | :heavy_minus_sign: | Skip the first `offset` results when paginating.
Needs to be an integer greater or equal to zero.
To be used in conjunction with `limit`. | 10 | +| `order_by` | *Optional[str]* | :heavy_minus_sign: | Sorts organizations memberships by phone_number, email_address, created_at, first_name, last_name or username.
By prepending one of those values with + or -,
we can choose to sort in ascending (ASC) or descending (DESC) order." | +created_at | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + + +### Response + +**[models.ListOrganizationMembershipsResponse](../../models/listorganizationmembershipsresponse.md)** +### Errors + +| Error Object | Status Code | Content Type | +| ------------------ | ------------------ | ------------------ | +| models.ClerkErrors | 401,422 | application/json | +| models.SDKError | 4xx-5xx | */* | + +## update + +Updates the properties of an existing organization membership + +### Example Usage + +```python +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +res = s.organization_memberships.update(organization_id="org_12345", user_id="user_67890", role="admin") + +if res is not None: + # handle response + pass + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | +| `organization_id` | *str* | :heavy_check_mark: | The ID of the organization the membership belongs to | org_12345 | +| `user_id` | *str* | :heavy_check_mark: | The ID of the user that this membership belongs to | user_67890 | +| `role` | *str* | :heavy_check_mark: | The new role of the given membership. | admin | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + + +### Response + +**[models.OrganizationMembership](../../models/organizationmembership.md)** +### Errors + +| Error Object | Status Code | Content Type | +| ------------------ | ------------------ | ------------------ | +| models.ClerkErrors | 400,404,422 | application/json | +| models.SDKError | 4xx-5xx | */* | + +## delete + +Removes the given membership from the organization + +### Example Usage + +```python +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +res = s.organization_memberships.delete(organization_id="org_12345", user_id="user_67890") + +if res is not None: + # handle response + pass + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | +| `organization_id` | *str* | :heavy_check_mark: | The ID of the organization the membership belongs to | org_12345 | +| `user_id` | *str* | :heavy_check_mark: | The ID of the user that this membership belongs to | user_67890 | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + + +### Response + +**[models.OrganizationMembership](../../models/organizationmembership.md)** +### Errors + +| Error Object | Status Code | Content Type | +| ------------------ | ------------------ | ------------------ | +| models.ClerkErrors | 400,401,404 | application/json | +| models.SDKError | 4xx-5xx | */* | + +## update_metadata + +Update an organization membership's metadata attributes by merging existing values with the provided parameters. +Metadata values will be updated via a deep merge. Deep means that any nested JSON objects will be merged as well. +You can remove metadata keys at any level by setting their value to `null`. + +### Example Usage + +```python +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +res = s.organization_memberships.update_metadata(organization_id="org_123456", user_id="user_654321", public_metadata={}, private_metadata={}) + +if res is not None: + # handle response + pass + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| -------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `organization_id` | *str* | :heavy_check_mark: | The ID of the organization the membership belongs to | org_123456 | +| `user_id` | *str* | :heavy_check_mark: | The ID of the user that this membership belongs to | user_654321 | +| `public_metadata` | [Optional[models.UpdateOrganizationMembershipMetadataPublicMetadata]](../../models/updateorganizationmembershipmetadatapublicmetadata.md) | :heavy_minus_sign: | Metadata saved on the organization membership, that is visible to both your frontend and backend.
The new object will be merged with the existing value. | {} | +| `private_metadata` | [Optional[models.UpdateOrganizationMembershipMetadataPrivateMetadata]](../../models/updateorganizationmembershipmetadataprivatemetadata.md) | :heavy_minus_sign: | Metadata saved on the organization membership that is only visible to your backend.
The new object will be merged with the existing value. | {} | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + + +### Response + +**[models.OrganizationMembership](../../models/organizationmembership.md)** +### Errors + +| Error Object | Status Code | Content Type | +| ------------------ | ------------------ | ------------------ | +| models.ClerkErrors | 400,404,422 | application/json | +| models.SDKError | 4xx-5xx | */* | diff --git a/docs/sdks/organizationssdk/README.md b/docs/sdks/organizationssdk/README.md new file mode 100644 index 0000000..5ab8a24 --- /dev/null +++ b/docs/sdks/organizationssdk/README.md @@ -0,0 +1,383 @@ +# OrganizationsSDK +(*organizations*) + +### Available Operations + +* [list](#list) - Get a list of organizations for an instance +* [create](#create) - Create an organization +* [get](#get) - Retrieve an organization by ID or slug +* [update](#update) - Update an organization +* [delete](#delete) - Delete an organization +* [merge_metadata](#merge_metadata) - Merge and update metadata for an organization +* [upload_logo](#upload_logo) - Upload a logo for the organization +* [delete_logo](#delete_logo) - Delete the organization's logo. + +## list + +This request returns the list of organizations for an instance. +Results can be paginated using the optional `limit` and `offset` query parameters. +The organizations are ordered by descending creation date. +Most recent organizations will be returned first. + +### Example Usage + +```python +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +res = s.organizations.list(limit=20, offset=10, include_members_count=False, query="clerk", order_by="-name") + +if res is not None: + # handle response + pass + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `limit` | *Optional[float]* | :heavy_minus_sign: | Applies a limit to the number of results returned.
Can be used for paginating the results together with `offset`. | 20 | +| `offset` | *Optional[float]* | :heavy_minus_sign: | Skip the first `offset` results when paginating.
Needs to be an integer greater or equal to zero.
To be used in conjunction with `limit`. | 10 | +| `include_members_count` | *Optional[bool]* | :heavy_minus_sign: | Flag to denote whether the member counts of each organization should be included in the response or not. | false | +| `query` | *Optional[str]* | :heavy_minus_sign: | Returns organizations with ID, name, or slug that match the given query.
Uses exact match for organization ID and partial match for name and slug. | clerk | +| `order_by` | *Optional[str]* | :heavy_minus_sign: | Allows to return organizations in a particular order.
At the moment, you can order the returned organizations either by their `name`, `created_at` or `members_count`.
In order to specify the direction, you can use the `+/-` symbols prepended in the property to order by.
For example, if you want organizations to be returned in descending order according to their `created_at` property, you can use `-created_at`.
If you don't use `+` or `-`, then `+` is implied.
Defaults to `-created_at`. | -name | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + + +### Response + +**[models.Organizations](../../models/organizations.md)** +### Errors + +| Error Object | Status Code | Content Type | +| ------------------ | ------------------ | ------------------ | +| models.ClerkErrors | 400,403,422 | application/json | +| models.SDKError | 4xx-5xx | */* | + +## create + +Creates a new organization with the given name for an instance. +In order to successfully create an organization you need to provide the ID of the User who will become the organization administrator. +You can specify an optional slug for the new organization. +If provided, the organization slug can contain only lowercase alphanumeric characters (letters and digits) and the dash "-". +Organization slugs must be unique for the instance. +You can provide additional metadata for the organization and set any custom attribute you want. +Organizations support private and public metadata. +Private metadata can only be accessed from the Backend API. +Public metadata can be accessed from the Backend API, and are read-only from the Frontend API. + +### Example Usage + +```python +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +res = s.organizations.create(name="NewOrg", created_by="user_123", private_metadata={}, public_metadata={}, slug="neworg", max_allowed_memberships=100) + +if res is not None: + # handle response + pass + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| -------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- | +| `name` | *str* | :heavy_check_mark: | The name of the new organization | NewOrg | +| `created_by` | *str* | :heavy_check_mark: | The ID of the User who will become the administrator for the new organization | user_123 | +| `private_metadata` | [Optional[models.CreateOrganizationPrivateMetadata]](../../models/createorganizationprivatemetadata.md) | :heavy_minus_sign: | Metadata saved on the organization, accessible only from the Backend API | {
"internal_code": "ABC123"
} | +| `public_metadata` | [Optional[models.CreateOrganizationPublicMetadata]](../../models/createorganizationpublicmetadata.md) | :heavy_minus_sign: | Metadata saved on the organization, read-only from the Frontend API and fully accessible (read/write) from the Backend API | {
"public_event": "Annual Summit"
} | +| `slug` | *Optional[str]* | :heavy_minus_sign: | A slug for the new organization.
Can contain only lowercase alphanumeric characters and the dash "-".
Must be unique for the instance. | neworg | +| `max_allowed_memberships` | *Optional[int]* | :heavy_minus_sign: | The maximum number of memberships allowed for this organization | 100 | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + + +### Response + +**[models.Organization](../../models/organization.md)** +### Errors + +| Error Object | Status Code | Content Type | +| ------------------ | ------------------ | ------------------ | +| models.ClerkErrors | 400,403,422 | application/json | +| models.SDKError | 4xx-5xx | */* | + +## get + +Fetches the organization whose ID or slug matches the provided `id_or_slug` URL query parameter. + +### Example Usage + +```python +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +res = s.organizations.get(organization_id="org_123") + +if res is not None: + # handle response + pass + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | +| `organization_id` | *str* | :heavy_check_mark: | The ID or slug of the organization | org_123 | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + + +### Response + +**[models.Organization](../../models/organization.md)** +### Errors + +| Error Object | Status Code | Content Type | +| ------------------ | ------------------ | ------------------ | +| models.ClerkErrors | 403,404 | application/json | +| models.SDKError | 4xx-5xx | */* | + +## update + +Updates an existing organization + +### Example Usage + +```python +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +res = s.organizations.update(organization_id="org_123_update", public_metadata={}, private_metadata={}, name="New Organization Name", slug="new-org-slug", max_allowed_memberships=100, admin_delete_enabled=True) + +if res is not None: + # handle response + pass + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| ------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- | +| `organization_id` | *str* | :heavy_check_mark: | The ID of the organization to update | org_123_update | +| `public_metadata` | [Optional[models.UpdateOrganizationPublicMetadata]](../../models/updateorganizationpublicmetadata.md) | :heavy_minus_sign: | Metadata saved on the organization, that is visible to both your frontend and backend. | {} | +| `private_metadata` | [Optional[models.UpdateOrganizationPrivateMetadata]](../../models/updateorganizationprivatemetadata.md) | :heavy_minus_sign: | Metadata saved on the organization that is only visible to your backend. | {} | +| `name` | *Optional[Nullable[str]]* | :heavy_minus_sign: | The new name of the organization | New Organization Name | +| `slug` | *Optional[Nullable[str]]* | :heavy_minus_sign: | The new slug of the organization, which needs to be unique in the instance | new-org-slug | +| `max_allowed_memberships` | *Optional[Nullable[int]]* | :heavy_minus_sign: | The maximum number of memberships allowed for this organization | 100 | +| `admin_delete_enabled` | *Optional[Nullable[bool]]* | :heavy_minus_sign: | If true, an admin can delete this organization with the Frontend API. | true | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + + +### Response + +**[models.Organization](../../models/organization.md)** +### Errors + +| Error Object | Status Code | Content Type | +| ------------------ | ------------------ | ------------------ | +| models.ClerkErrors | 402,404,422 | application/json | +| models.SDKError | 4xx-5xx | */* | + +## delete + +Deletes the given organization. +Please note that deleting an organization will also delete all memberships and invitations. +This is not reversible. + +### Example Usage + +```python +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +res = s.organizations.delete(organization_id="org_321_delete") + +if res is not None: + # handle response + pass + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | +| `organization_id` | *str* | :heavy_check_mark: | The ID of the organization to delete | org_321_delete | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + + +### Response + +**[models.DeletedObject](../../models/deletedobject.md)** +### Errors + +| Error Object | Status Code | Content Type | +| ------------------ | ------------------ | ------------------ | +| models.ClerkErrors | 404 | application/json | +| models.SDKError | 4xx-5xx | */* | + +## merge_metadata + +Update organization metadata attributes by merging existing values with the provided parameters. +Metadata values will be updated via a deep merge. +Deep meaning that any nested JSON objects will be merged as well. +You can remove metadata keys at any level by setting their value to `null`. + +### Example Usage + +```python +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +res = s.organizations.merge_metadata(organization_id="org_12345", public_metadata={}, private_metadata={}) + +if res is not None: + # handle response + pass + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| --------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | +| `organization_id` | *str* | :heavy_check_mark: | The ID of the organization for which metadata will be merged or updated | org_12345 | +| `public_metadata` | [Optional[models.MergeOrganizationMetadataPublicMetadata]](../../models/mergeorganizationmetadatapublicmetadata.md) | :heavy_minus_sign: | Metadata saved on the organization, that is visible to both your frontend and backend.
The new object will be merged with the existing value. | {
"announcement": "We are opening a new office!"
} | +| `private_metadata` | [Optional[models.MergeOrganizationMetadataPrivateMetadata]](../../models/mergeorganizationmetadataprivatemetadata.md) | :heavy_minus_sign: | Metadata saved on the organization that is only visible to your backend.
The new object will be merged with the existing value. | {
"internal_use_only": "Future plans discussion."
} | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + + +### Response + +**[models.Organization](../../models/organization.md)** +### Errors + +| Error Object | Status Code | Content Type | +| ------------------ | ------------------ | ------------------ | +| models.ClerkErrors | 400,401,404,422 | application/json | +| models.SDKError | 4xx-5xx | */* | + +## upload_logo + +Set or replace an organization's logo, by uploading an image file. +This endpoint uses the `multipart/form-data` request content type and accepts a file of image type. +The file size cannot exceed 10MB. +Only the following file content types are supported: `image/jpeg`, `image/png`, `image/gif`, `image/webp`, `image/x-icon`, `image/vnd.microsoft.icon`. + +### Example Usage + +```python +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +res = s.organizations.upload_logo(organization_id="org_12345", uploader_user_id="user_67890", file={ + "file_name": "your_file_here", + "content": open("", "rb"), + "content_type": "", +}) + +if res is not None: + # handle response + pass + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| ------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | +| `organization_id` | *str* | :heavy_check_mark: | The ID of the organization for which to upload a logo | org_12345 | +| `uploader_user_id` | *str* | :heavy_check_mark: | The ID of the user that will be credited with the image upload. | user_67890 | +| `file` | [models.UploadOrganizationLogoFile](../../models/uploadorganizationlogofile.md) | :heavy_check_mark: | N/A | | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + + +### Response + +**[models.OrganizationWithLogo](../../models/organizationwithlogo.md)** +### Errors + +| Error Object | Status Code | Content Type | +| ------------------ | ------------------ | ------------------ | +| models.ClerkErrors | 400,403,404,413 | application/json | +| models.SDKError | 4xx-5xx | */* | + +## delete_logo + +Delete the organization's logo. + +### Example Usage + +```python +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +res = s.organizations.delete_logo(organization_id="org_12345") + +if res is not None: + # handle response + pass + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | +| `organization_id` | *str* | :heavy_check_mark: | The ID of the organization for which the logo will be deleted. | org_12345 | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + + +### Response + +**[models.Organization](../../models/organization.md)** +### Errors + +| Error Object | Status Code | Content Type | +| ------------------ | ------------------ | ------------------ | +| models.ClerkErrors | 404 | application/json | +| models.SDKError | 4xx-5xx | */* | diff --git a/docs/sdks/phonenumbers/README.md b/docs/sdks/phonenumbers/README.md new file mode 100644 index 0000000..a0cc7a1 --- /dev/null +++ b/docs/sdks/phonenumbers/README.md @@ -0,0 +1,180 @@ +# PhoneNumbers +(*phone_numbers*) + +### Available Operations + +* [create](#create) - Create a phone number +* [get](#get) - Retrieve a phone number +* [delete](#delete) - Delete a phone number +* [update](#update) - Update a phone number + +## create + +Create a new phone number + +### Example Usage + +```python +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +res = s.phone_numbers.create(user_id="usr_12345", phone_number="+11234567890", verified=True, primary=False, reserved_for_second_factor=False) + +if res is not None: + # handle response + pass + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `user_id` | *Optional[str]* | :heavy_minus_sign: | The ID representing the user | usr_12345 | +| `phone_number` | *Optional[str]* | :heavy_minus_sign: | The new phone number. Must adhere to the E.164 standard for phone number format. | +11234567890 | +| `verified` | *Optional[Nullable[bool]]* | :heavy_minus_sign: | When created, the phone number will be marked as verified. | true | +| `primary` | *Optional[Nullable[bool]]* | :heavy_minus_sign: | Create this phone number as the primary phone number for the user.
Default: false, unless it is the first phone number. | false | +| `reserved_for_second_factor` | *Optional[Nullable[bool]]* | :heavy_minus_sign: | Create this phone number as reserved for multi-factor authentication.
The phone number must also be verified.
If there are no other reserved second factors, the phone number will be set as the default second factor. | false | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + + +### Response + +**[models.PhoneNumber](../../models/phonenumber.md)** +### Errors + +| Error Object | Status Code | Content Type | +| ------------------- | ------------------- | ------------------- | +| models.ClerkErrors | 400,401,403,404,422 | application/json | +| models.SDKError | 4xx-5xx | */* | + +## get + +Returns the details of a phone number + +### Example Usage + +```python +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +res = s.phone_numbers.get(phone_number_id="phone_12345") + +if res is not None: + # handle response + pass + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | +| `phone_number_id` | *str* | :heavy_check_mark: | The ID of the phone number to retrieve | phone_12345 | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + + +### Response + +**[models.PhoneNumber](../../models/phonenumber.md)** +### Errors + +| Error Object | Status Code | Content Type | +| ------------------ | ------------------ | ------------------ | +| models.ClerkErrors | 400,401,403,404 | application/json | +| models.SDKError | 4xx-5xx | */* | + +## delete + +Delete the phone number with the given ID + +### Example Usage + +```python +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +res = s.phone_numbers.delete(phone_number_id="phone_12345") + +if res is not None: + # handle response + pass + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | +| `phone_number_id` | *str* | :heavy_check_mark: | The ID of the phone number to delete | phone_12345 | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + + +### Response + +**[models.DeletedObject](../../models/deletedobject.md)** +### Errors + +| Error Object | Status Code | Content Type | +| ------------------ | ------------------ | ------------------ | +| models.ClerkErrors | 400,401,403,404 | application/json | +| models.SDKError | 4xx-5xx | */* | + +## update + +Updates a phone number + +### Example Usage + +```python +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +res = s.phone_numbers.update(phone_number_id="phone_12345", verified=False, primary=True, reserved_for_second_factor=True) + +if res is not None: + # handle response + pass + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `phone_number_id` | *str* | :heavy_check_mark: | The ID of the phone number to update | phone_12345 | +| `verified` | *Optional[Nullable[bool]]* | :heavy_minus_sign: | The phone number will be marked as verified. | false | +| `primary` | *Optional[Nullable[bool]]* | :heavy_minus_sign: | Set this phone number as the primary phone number for the user. | true | +| `reserved_for_second_factor` | *Optional[Nullable[bool]]* | :heavy_minus_sign: | Set this phone number as reserved for multi-factor authentication.
The phone number must also be verified.
If there are no other reserved second factors, the phone number will be set as the default second factor. | true | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + + +### Response + +**[models.PhoneNumber](../../models/phonenumber.md)** +### Errors + +| Error Object | Status Code | Content Type | +| ------------------ | ------------------ | ------------------ | +| models.ClerkErrors | 400,401,403,404 | application/json | +| models.SDKError | 4xx-5xx | */* | diff --git a/docs/sdks/proxychecks/README.md b/docs/sdks/proxychecks/README.md new file mode 100644 index 0000000..6484114 --- /dev/null +++ b/docs/sdks/proxychecks/README.md @@ -0,0 +1,55 @@ +# ProxyChecks +(*proxy_checks*) + +### Available Operations + +* [verify](#verify) - Verify the proxy configuration for your domain + +## verify + +This endpoint can be used to validate that a proxy-enabled domain is operational. +It tries to verify that the proxy URL provided in the parameters maps to a functional proxy that can reach the Clerk Frontend API. + +You can use this endpoint before you set a proxy URL for a domain. This way you can ensure that switching to proxy-based +configuration will not lead to downtime for your instance. + +The `proxy_url` parameter allows for testing proxy configurations for domains that don't have a proxy URL yet, or operate on +a different proxy URL than the one provided. It can also be used to re-validate a domain that is already configured to work with a proxy. + +### Example Usage + +```python +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +res = s.proxy_checks.verify(domain_id="domain_32hfu3e", proxy_url="https://example.com/__clerk") + +if res is not None: + # handle response + pass + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| --------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- | +| `domain_id` | *Optional[str]* | :heavy_minus_sign: | The ID of the domain that will be updated. | domain_32hfu3e | +| `proxy_url` | *Optional[str]* | :heavy_minus_sign: | The full URL of the proxy which will forward requests to the Clerk Frontend API for this domain. e.g. https://example.com/__clerk | https://example.com/__clerk | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + + +### Response + +**[models.ProxyCheck](../../models/proxycheck.md)** +### Errors + +| Error Object | Status Code | Content Type | +| ------------------ | ------------------ | ------------------ | +| models.ClerkErrors | 400,422 | application/json | +| models.SDKError | 4xx-5xx | */* | diff --git a/docs/sdks/redirecturls/README.md b/docs/sdks/redirecturls/README.md new file mode 100644 index 0000000..bae9ee0 --- /dev/null +++ b/docs/sdks/redirecturls/README.md @@ -0,0 +1,171 @@ +# RedirectUrls +(*redirect_urls*) + +### Available Operations + +* [list](#list) - List all redirect URLs +* [create](#create) - Create a redirect URL +* [get](#get) - Retrieve a redirect URL +* [delete](#delete) - Delete a redirect URL + +## list + +Lists all whitelisted redirect_urls for the instance + +### Example Usage + +```python +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +res = s.redirect_urls.list() + +if res is not None: + # handle response + pass + +``` + +### Parameters + +| Parameter | Type | Required | Description | +| ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | + + +### Response + +**[List[models.RedirectURL]](../../models/.md)** +### Errors + +| Error Object | Status Code | Content Type | +| --------------- | --------------- | --------------- | +| models.SDKError | 4xx-5xx | */* | + +## create + +Create a redirect URL + +### Example Usage + +```python +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +res = s.redirect_urls.create(url="https://my-app.com/oauth-callback") + +if res is not None: + # handle response + pass + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| ---------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | +| `url` | *Optional[str]* | :heavy_minus_sign: | The full url value prefixed with `https://` or a custom scheme e.g. `"https://my-app.com/oauth-callback"` or `"my-app://oauth-callback"` | https://my-app.com/oauth-callback | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + + +### Response + +**[models.RedirectURL](../../models/redirecturl.md)** +### Errors + +| Error Object | Status Code | Content Type | +| ------------------ | ------------------ | ------------------ | +| models.ClerkErrors | 400,422 | application/json | +| models.SDKError | 4xx-5xx | */* | + +## get + +Retrieve the details of the redirect URL with the given ID + +### Example Usage + +```python +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +res = s.redirect_urls.get(id="redir_01FG4K9G5NWSQ4ZPT4TQE4Z7G3") + +if res is not None: + # handle response + pass + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | +| `id` | *str* | :heavy_check_mark: | The ID of the redirect URL | redir_01FG4K9G5NWSQ4ZPT4TQE4Z7G3 | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + + +### Response + +**[models.RedirectURL](../../models/redirecturl.md)** +### Errors + +| Error Object | Status Code | Content Type | +| ------------------ | ------------------ | ------------------ | +| models.ClerkErrors | 404 | application/json | +| models.SDKError | 4xx-5xx | */* | + +## delete + +Remove the selected redirect URL from the whitelist of the instance + +### Example Usage + +```python +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +res = s.redirect_urls.delete(id="redir_01FG4K9G5NWSQ4ZPT4TQE4Z7G3") + +if res is not None: + # handle response + pass + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | +| `id` | *str* | :heavy_check_mark: | The ID of the redirect URL | redir_01FG4K9G5NWSQ4ZPT4TQE4Z7G3 | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + + +### Response + +**[models.DeletedObject](../../models/deletedobject.md)** +### Errors + +| Error Object | Status Code | Content Type | +| ------------------ | ------------------ | ------------------ | +| models.ClerkErrors | 404 | application/json | +| models.SDKError | 4xx-5xx | */* | diff --git a/docs/sdks/samlconnectionssdk/README.md b/docs/sdks/samlconnectionssdk/README.md new file mode 100644 index 0000000..a00646c --- /dev/null +++ b/docs/sdks/samlconnectionssdk/README.md @@ -0,0 +1,254 @@ +# SamlConnectionsSDK +(*saml_connections*) + +### Available Operations + +* [list](#list) - Get a list of SAML Connections for an instance +* [create](#create) - Create a SAML Connection +* [get](#get) - Retrieve a SAML Connection by ID +* [update](#update) - Update a SAML Connection +* [delete](#delete) - Delete a SAML Connection + +## list + +Returns the list of SAML Connections for an instance. +Results can be paginated using the optional `limit` and `offset` query parameters. +The SAML Connections are ordered by descending creation date and the most recent will be returned first. + +### Example Usage + +```python +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +res = s.saml_connections.list(limit=20, offset=10) + +if res is not None: + while True: + # handle items + + res = res.Next() + if res is None: + break + + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| ----------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | +| `limit` | *Optional[float]* | :heavy_minus_sign: | Applies a limit to the number of results returned.
Can be used for paginating the results together with `offset`. | 20 | +| `offset` | *Optional[float]* | :heavy_minus_sign: | Skip the first `offset` results when paginating.
Needs to be an integer greater or equal to zero.
To be used in conjunction with `limit`. | 10 | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + + +### Response + +**[models.ListSAMLConnectionsResponse](../../models/listsamlconnectionsresponse.md)** +### Errors + +| Error Object | Status Code | Content Type | +| ------------------ | ------------------ | ------------------ | +| models.ClerkErrors | 402,403,422 | application/json | +| models.SDKError | 4xx-5xx | */* | + +## create + +Create a new SAML Connection. + +### Example Usage + +```python +import clerk +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +res = s.saml_connections.create(name="My SAML Connection", domain="example.org", provider=clerk.Provider.SAML_CUSTOM, idp_entity_id="http://idp.example.org/", idp_sso_url="http://idp.example.org/sso", idp_certificate="MIIDdzCCAl+gAwIBAgIJAKcyBaiiz+DT...", idp_metadata_url="http://idp.example.org/metadata.xml", idp_metadata="... | +| `attribute_mapping` | [Optional[Nullable[models.UpdateSAMLConnectionAttributeMapping]]](../../models/updatesamlconnectionattributemapping.md) | :heavy_minus_sign: | Define the atrtibute name mapping between Identity Provider and Clerk's user properties | | +| `active` | *Optional[Nullable[bool]]* | :heavy_minus_sign: | Activate or de-activate the SAML Connection | true | +| `sync_user_attributes` | *Optional[Nullable[bool]]* | :heavy_minus_sign: | Controls whether to update the user's attributes in each sign-in | false | +| `allow_subdomains` | *Optional[Nullable[bool]]* | :heavy_minus_sign: | Allow users with an email address subdomain to use this connection in order to authenticate | true | +| `allow_idp_initiated` | *Optional[Nullable[bool]]* | :heavy_minus_sign: | Enable or deactivate IdP-initiated flows | false | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + + +### Response + +**[models.SAMLConnection](../../models/samlconnection.md)** +### Errors + +| Error Object | Status Code | Content Type | +| ------------------ | ------------------ | ------------------ | +| models.ClerkErrors | 402,403,404,422 | application/json | +| models.SDKError | 4xx-5xx | */* | + +## delete + +Deletes the SAML Connection whose ID matches the provided `id` in the path. + +### Example Usage + +```python +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +res = s.saml_connections.delete(saml_connection_id="saml_conn_123_delete") + +if res is not None: + # handle response + pass + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | +| `saml_connection_id` | *str* | :heavy_check_mark: | The ID of the SAML Connection to delete | saml_conn_123_delete | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + + +### Response + +**[models.DeletedObject](../../models/deletedobject.md)** +### Errors + +| Error Object | Status Code | Content Type | +| ------------------ | ------------------ | ------------------ | +| models.ClerkErrors | 402,403,404 | application/json | +| models.SDKError | 4xx-5xx | */* | diff --git a/docs/sdks/sessions/README.md b/docs/sdks/sessions/README.md new file mode 100644 index 0000000..161f3d6 --- /dev/null +++ b/docs/sdks/sessions/README.md @@ -0,0 +1,231 @@ +# Sessions +(*sessions*) + +### Available Operations + +* [list](#list) - List all sessions +* [get](#get) - Retrieve a session +* [revoke](#revoke) - Revoke a session +* [~~verify~~](#verify) - Verify a session :warning: **Deprecated** +* [create_token_from_template](#create_token_from_template) - Create a session token from a jwt template + +## list + +Returns a list of all sessions. +The sessions are returned sorted by creation date, with the newest sessions appearing first. +**Deprecation Notice (2024-01-01):** All parameters were initially considered optional, however +moving forward at least one of `client_id` or `user_id` parameters should be provided. + +### Example Usage + +```python +import clerk +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +res = s.sessions.list(client_id="client_123", user_id="user_456", status=clerk.QueryParamStatus.ACTIVE, limit=20, offset=10) + +if res is not None: + # handle response + pass + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| ----------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | +| `client_id` | *Optional[str]* | :heavy_minus_sign: | List sessions for the given client | client_123 | +| `user_id` | *Optional[str]* | :heavy_minus_sign: | List sessions for the given user | user_456 | +| `status` | [Optional[models.QueryParamStatus]](../../models/queryparamstatus.md) | :heavy_minus_sign: | Filter sessions by the provided status | active | +| `limit` | *Optional[float]* | :heavy_minus_sign: | Applies a limit to the number of results returned.
Can be used for paginating the results together with `offset`. | 20 | +| `offset` | *Optional[float]* | :heavy_minus_sign: | Skip the first `offset` results when paginating.
Needs to be an integer greater or equal to zero.
To be used in conjunction with `limit`. | 10 | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + + +### Response + +**[List[models.Session]](../../models/.md)** +### Errors + +| Error Object | Status Code | Content Type | +| ------------------ | ------------------ | ------------------ | +| models.ClerkErrors | 400,401,422 | application/json | +| models.SDKError | 4xx-5xx | */* | + +## get + +Retrieve the details of a session + +### Example Usage + +```python +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +res = s.sessions.get(session_id="sess_1234567890abcdef") + +if res is not None: + # handle response + pass + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | +| `session_id` | *str* | :heavy_check_mark: | The ID of the session | sess_1234567890abcdef | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + + +### Response + +**[models.Session](../../models/session.md)** +### Errors + +| Error Object | Status Code | Content Type | +| ------------------ | ------------------ | ------------------ | +| models.ClerkErrors | 400,401,404 | application/json | +| models.SDKError | 4xx-5xx | */* | + +## revoke + +Sets the status of a session as "revoked", which is an unauthenticated state. +In multi-session mode, a revoked session will still be returned along with its client object, however the user will need to sign in again. + +### Example Usage + +```python +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +res = s.sessions.revoke(session_id="sess_1234567890abcdef") + +if res is not None: + # handle response + pass + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | +| `session_id` | *str* | :heavy_check_mark: | The ID of the session | sess_1234567890abcdef | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + + +### Response + +**[models.Session](../../models/session.md)** +### Errors + +| Error Object | Status Code | Content Type | +| ------------------ | ------------------ | ------------------ | +| models.ClerkErrors | 400,401,404 | application/json | +| models.SDKError | 4xx-5xx | */* | + +## ~~verify~~ + +Returns the session if it is authenticated, otherwise returns an error. +WARNING: This endpoint is deprecated and will be removed in future versions. We strongly recommend switching to networkless verification using short-lived session tokens, + which is implemented transparently in all recent SDK versions (e.g. [NodeJS SDK](https://clerk.com/docs/backend-requests/handling/nodejs#clerk-express-require-auth)). + For more details on how networkless verification works, refer to our [Session Tokens documentation](https://clerk.com/docs/backend-requests/resources/session-tokens). + +> :warning: **DEPRECATED**: This will be removed in a future release, please migrate away from it as soon as possible. + +### Example Usage + +```python +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +res = s.sessions.verify(session_id="sess_w8q4g9s60j28fghv00f3", token="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzZXNzaW9uX2lkIjoic2Vzc193OHF4ZzZzNm9qMjhmZ2h2MDBmMyIsImlhdCI6MTU4MjY0OTg2Mn0.J4KP2L6bEZ6YccHFW4E2vKbOLw_mmO0gF_GNRw-wtLM") + +if res is not None: + # handle response + pass + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `session_id` | *str* | :heavy_check_mark: | The ID of the session | sess_w8q4g9s60j28fghv00f3 | +| `token` | *Optional[str]* | :heavy_minus_sign: | The JWT that is sent via the `__session` cookie from your frontend.
Note: this JWT must be associated with the supplied session ID. | eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzZXNzaW9uX2lkIjoic2Vzc193OHF4ZzZzNm9qMjhmZ2h2MDBmMyIsImlhdCI6MTU4MjY0OTg2Mn0.J4KP2L6bEZ6YccHFW4E2vKbOLw_mmO0gF_GNRw-wtLM | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + + +### Response + +**[models.Session](../../models/session.md)** +### Errors + +| Error Object | Status Code | Content Type | +| ------------------ | ------------------ | ------------------ | +| models.ClerkErrors | 400,401,404,410 | application/json | +| models.SDKError | 4xx-5xx | */* | + +## create_token_from_template + +Creates a JSON Web Token(JWT) based on a session and a JWT Template name defined for your instance + +### Example Usage + +```python +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +res = s.sessions.create_token_from_template(session_id="ses_123abcd4567", template_name="custom_hasura") + +if res is not None: + # handle response + pass + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| ----------------------------------------------------------------------------- | ----------------------------------------------------------------------------- | ----------------------------------------------------------------------------- | ----------------------------------------------------------------------------- | ----------------------------------------------------------------------------- | +| `session_id` | *str* | :heavy_check_mark: | The ID of the session | ses_123abcd4567 | +| `template_name` | *str* | :heavy_check_mark: | The name of the JWT Template defined in your instance (e.g. `custom_hasura`). | custom_hasura | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + + +### Response + +**[models.CreateSessionTokenFromTemplateResponseBody](../../models/createsessiontokenfromtemplateresponsebody.md)** +### Errors + +| Error Object | Status Code | Content Type | +| ------------------ | ------------------ | ------------------ | +| models.ClerkErrors | 401,404 | application/json | +| models.SDKError | 4xx-5xx | */* | diff --git a/docs/sdks/signintokens/README.md b/docs/sdks/signintokens/README.md new file mode 100644 index 0000000..872de84 --- /dev/null +++ b/docs/sdks/signintokens/README.md @@ -0,0 +1,92 @@ +# SignInTokens +(*sign_in_tokens*) + +### Available Operations + +* [create](#create) - Create sign-in token +* [revoke](#revoke) - Revoke the given sign-in token + +## create + +Creates a new sign-in token and associates it with the given user. +By default, sign-in tokens expire in 30 days. +You can optionally supply a different duration in seconds using the `expires_in_seconds` property. + +### Example Usage + +```python +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +res = s.sign_in_tokens.create(user_id="user_12345", expires_in_seconds=2592000) + +if res is not None: + # handle response + pass + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| --------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | +| `user_id` | *Optional[str]* | :heavy_minus_sign: | The ID of the user that can use the newly created sign in token | user_12345 | +| `expires_in_seconds` | *Optional[int]* | :heavy_minus_sign: | Optional parameter to specify the life duration of the sign in token in seconds.
By default, the duration is 30 days. | 2592000 | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + + +### Response + +**[models.SignInToken](../../models/signintoken.md)** +### Errors + +| Error Object | Status Code | Content Type | +| ------------------ | ------------------ | ------------------ | +| models.ClerkErrors | 404,422 | application/json | +| models.SDKError | 4xx-5xx | */* | + +## revoke + +Revokes a pending sign-in token + +### Example Usage + +```python +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +res = s.sign_in_tokens.revoke(sign_in_token_id="tok_test_1234567890") + +if res is not None: + # handle response + pass + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | +| `sign_in_token_id` | *str* | :heavy_check_mark: | The ID of the sign-in token to be revoked | tok_test_1234567890 | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + + +### Response + +**[models.SignInToken](../../models/signintoken.md)** +### Errors + +| Error Object | Status Code | Content Type | +| ------------------ | ------------------ | ------------------ | +| models.ClerkErrors | 400,404 | application/json | +| models.SDKError | 4xx-5xx | */* | diff --git a/docs/sdks/signups/README.md b/docs/sdks/signups/README.md new file mode 100644 index 0000000..a625e6b --- /dev/null +++ b/docs/sdks/signups/README.md @@ -0,0 +1,49 @@ +# SignUps +(*sign_ups*) + +### Available Operations + +* [update](#update) - Update a sign-up + +## update + +Update the sign-up with the given ID + +### Example Usage + +```python +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +res = s.sign_ups.update(id="signup_1234567890abcdef", custom_action=False, external_id="ext_id_7890abcdef123456") + +if res is not None: + # handle response + pass + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `id` | *str* | :heavy_check_mark: | The ID of the sign-up to update | signup_1234567890abcdef | +| `custom_action` | *Optional[bool]* | :heavy_minus_sign: | Specifies whether a custom action has run for this sign-up attempt.
This is important when your instance has been configured to require a custom action to run before converting a sign-up into a user.
After executing any external business logic you deem necessary, you can mark the sign-up as ready-to-convert by setting `custom_action` to `true`. | false | +| `external_id` | *Optional[Nullable[str]]* | :heavy_minus_sign: | The ID of the guest attempting to sign up as used in your external systems or your previous authentication solution.
This will be copied to the resulting user when the sign-up is completed. | ext_id_7890abcdef123456 | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + + +### Response + +**[models.SignUp](../../models/signup.md)** +### Errors + +| Error Object | Status Code | Content Type | +| ------------------ | ------------------ | ------------------ | +| models.ClerkErrors | 403 | application/json | +| models.SDKError | 4xx-5xx | */* | diff --git a/docs/sdks/templates/README.md b/docs/sdks/templates/README.md new file mode 100644 index 0000000..cc7ea09 --- /dev/null +++ b/docs/sdks/templates/README.md @@ -0,0 +1,282 @@ +# Templates +(*templates*) + +### Available Operations + +* [list](#list) - List all templates +* [get](#get) - Retrieve a template +* [upsert](#upsert) - Update a template for a given type and slug +* [revert](#revert) - Revert a template +* [preview](#preview) - Preview changes to a template +* [toggle_delivery](#toggle_delivery) - Toggle the delivery by Clerk for a template of a given type and slug + +## list + +Returns a list of all templates. +The templates are returned sorted by position. + +### Example Usage + +```python +import clerk +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +res = s.templates.list(template_type=clerk.TemplateType.EMAIL) + +if res is not None: + # handle response + pass + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | +| `template_type` | [models.TemplateType](../../models/templatetype.md) | :heavy_check_mark: | The type of templates to list (email or SMS) | email | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + + +### Response + +**[List[models.Template]](../../models/.md)** +### Errors + +| Error Object | Status Code | Content Type | +| ------------------ | ------------------ | ------------------ | +| models.ClerkErrors | 400,401,422 | application/json | +| models.SDKError | 4xx-5xx | */* | + +## get + +Returns the details of a template + +### Example Usage + +```python +import clerk +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +res = s.templates.get(template_type=clerk.PathParamTemplateType.EMAIL, slug="welcome-email") + +if res is not None: + # handle response + pass + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| --------------------------------------------------------------------- | --------------------------------------------------------------------- | --------------------------------------------------------------------- | --------------------------------------------------------------------- | --------------------------------------------------------------------- | +| `template_type` | [models.PathParamTemplateType](../../models/pathparamtemplatetype.md) | :heavy_check_mark: | The type of templates to retrieve (email or SMS) | email | +| `slug` | *str* | :heavy_check_mark: | The slug (i.e. machine-friendly name) of the template to retrieve | welcome-email | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + + +### Response + +**[models.Template](../../models/template.md)** +### Errors + +| Error Object | Status Code | Content Type | +| ------------------ | ------------------ | ------------------ | +| models.ClerkErrors | 400,401,404 | application/json | +| models.SDKError | 4xx-5xx | */* | + +## upsert + +Updates the existing template of the given type and slug + +### Example Usage + +```python +import clerk +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +res = s.templates.upsert(template_type=clerk.UpsertTemplatePathParamTemplateType.SMS, slug="verification-code", name="Verification Code", subject="Your Verification Code", markup="

Your code: {{code}}

", body="Use this code to verify your email: {{code}}", delivered_by_clerk=True, from_email_name="hello", reply_to_email_name="support") + +if res is not None: + # handle response + pass + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `template_type` | [models.UpsertTemplatePathParamTemplateType](../../models/upserttemplatepathparamtemplatetype.md) | :heavy_check_mark: | The type of template to update | sms | +| `slug` | *str* | :heavy_check_mark: | The slug of the template to update | verification-code | +| `name` | *Optional[str]* | :heavy_minus_sign: | The user-friendly name of the template | Verification Code | +| `subject` | *Optional[Nullable[str]]* | :heavy_minus_sign: | The email subject.
Applicable only to email templates. | Your Verification Code | +| `markup` | *Optional[Nullable[str]]* | :heavy_minus_sign: | The editor markup used to generate the body of the template |

Your code: {{code}}

| +| `body` | *Optional[str]* | :heavy_minus_sign: | The template body before variable interpolation | Use this code to verify your email: {{code}} | +| `delivered_by_clerk` | *Optional[Nullable[bool]]* | :heavy_minus_sign: | Whether Clerk should deliver emails or SMS messages based on the current template | true | +| `from_email_name` | *Optional[str]* | :heavy_minus_sign: | The local part of the From email address that will be used for emails.
For example, in the address 'hello@example.com', the local part is 'hello'.
Applicable only to email templates. | hello | +| `reply_to_email_name` | *Optional[str]* | :heavy_minus_sign: | The local part of the Reply To email address that will be used for emails.
For example, in the address 'hello@example.com', the local part is 'hello'.
Applicable only to email templates. | support | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + + +### Response + +**[models.Template](../../models/template.md)** +### Errors + +| Error Object | Status Code | Content Type | +| ----------------------- | ----------------------- | ----------------------- | +| models.ClerkErrors | 400,401,402,403,404,422 | application/json | +| models.SDKError | 4xx-5xx | */* | + +## revert + +Reverts an updated template to its default state + +### Example Usage + +```python +import clerk +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +res = s.templates.revert(template_type=clerk.RevertTemplatePathParamTemplateType.EMAIL, slug="welcome-email") + +if res is not None: + # handle response + pass + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| ------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------- | +| `template_type` | [models.RevertTemplatePathParamTemplateType](../../models/reverttemplatepathparamtemplatetype.md) | :heavy_check_mark: | The type of template to revert | email | +| `slug` | *str* | :heavy_check_mark: | The slug of the template to revert | welcome-email | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + + +### Response + +**[models.Template](../../models/template.md)** +### Errors + +| Error Object | Status Code | Content Type | +| ------------------ | ------------------ | ------------------ | +| models.ClerkErrors | 400,401,402,404 | application/json | +| models.SDKError | 4xx-5xx | */* | + +## preview + +Returns a preview of a template for a given template_type, slug and body + +### Example Usage + +```python +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +res = s.templates.preview(template_type="email", slug="welcome-email", subject="Welcome to our service!", body="Hi, thank you for joining our service.", from_email_name="hello", reply_to_email_name="support") + +if res is not None: + # handle response + pass + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `template_type` | *str* | :heavy_check_mark: | The type of template to preview | email | +| `slug` | *str* | :heavy_check_mark: | The slug of the template to preview | welcome-email | +| `subject` | *Optional[Nullable[str]]* | :heavy_minus_sign: | The email subject.
Applicable only to email templates. | Welcome to our service! | +| `body` | *Optional[str]* | :heavy_minus_sign: | The template body before variable interpolation | Hi, thank you for joining our service. | +| `from_email_name` | *Optional[str]* | :heavy_minus_sign: | The local part of the From email address that will be used for emails.
For example, in the address 'hello@example.com', the local part is 'hello'.
Applicable only to email templates. | hello | +| `reply_to_email_name` | *Optional[str]* | :heavy_minus_sign: | The local part of the Reply To email address that will be used for emails.
For example, in the address 'hello@example.com', the local part is 'hello'.
Applicable only to email templates. | support | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + + +### Response + +**[models.PreviewTemplateResponseBody](../../models/previewtemplateresponsebody.md)** +### Errors + +| Error Object | Status Code | Content Type | +| ------------------ | ------------------ | ------------------ | +| models.ClerkErrors | 400,401,404,422 | application/json | +| models.SDKError | 4xx-5xx | */* | + +## toggle_delivery + +Toggles the delivery by Clerk for a template of a given type and slug. +If disabled, Clerk will not deliver the resulting email or SMS. +The app developer will need to listen to the `email.created` or `sms.created` webhooks in order to handle delivery themselves. + +### Example Usage + +```python +import clerk +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +res = s.templates.toggle_delivery(template_type=clerk.ToggleTemplateDeliveryPathParamTemplateType.EMAIL, slug="welcome-email", delivered_by_clerk=True) + +if res is not None: + # handle response + pass + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| ----------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- | +| `template_type` | [models.ToggleTemplateDeliveryPathParamTemplateType](../../models/toggletemplatedeliverypathparamtemplatetype.md) | :heavy_check_mark: | The type of template to toggle delivery for | email | +| `slug` | *str* | :heavy_check_mark: | The slug of the template for which to toggle delivery | welcome-email | +| `delivered_by_clerk` | *Optional[Nullable[bool]]* | :heavy_minus_sign: | Whether Clerk should deliver emails or SMS messages based on the current template | true | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + + +### Response + +**[models.Template](../../models/template.md)** +### Errors + +| Error Object | Status Code | Content Type | +| ------------------ | ------------------ | ------------------ | +| models.ClerkErrors | 400,401,404 | application/json | +| models.SDKError | 4xx-5xx | */* | diff --git a/docs/sdks/testingtokens/README.md b/docs/sdks/testingtokens/README.md new file mode 100644 index 0000000..fd4f53d --- /dev/null +++ b/docs/sdks/testingtokens/README.md @@ -0,0 +1,45 @@ +# TestingTokens +(*testing_tokens*) + +### Available Operations + +* [create](#create) - Retrieve a new testing token + +## create + +Retrieve a new testing token. Only available for development instances. + +### Example Usage + +```python +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +res = s.testing_tokens.create() + +if res is not None: + # handle response + pass + +``` + +### Parameters + +| Parameter | Type | Required | Description | +| ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | + + +### Response + +**[models.TestingToken](../../models/testingtoken.md)** +### Errors + +| Error Object | Status Code | Content Type | +| --------------- | --------------- | --------------- | +| models.SDKError | 4xx-5xx | */* | diff --git a/docs/sdks/users/README.md b/docs/sdks/users/README.md new file mode 100644 index 0000000..3e55f3d --- /dev/null +++ b/docs/sdks/users/README.md @@ -0,0 +1,908 @@ +# Users +(*users*) + +### Available Operations + +* [list](#list) - List all users +* [create](#create) - Create a new user +* [count](#count) - Count users +* [get](#get) - Retrieve a user +* [update](#update) - Update a user +* [delete](#delete) - Delete a user +* [ban](#ban) - Ban a user +* [unban](#unban) - Unban a user +* [lock](#lock) - Lock a user +* [unlock](#unlock) - Unlock a user +* [set_profile_image](#set_profile_image) - Set user profile image +* [delete_profile_image](#delete_profile_image) - Delete user profile image +* [update_metadata](#update_metadata) - Merge and update a user's metadata +* [get_o_auth_access_token](#get_o_auth_access_token) - Retrieve the OAuth access token of a user +* [get_organization_memberships](#get_organization_memberships) - Retrieve all memberships for a user +* [verify_password](#verify_password) - Verify the password of a user +* [verify_totp](#verify_totp) - Verify a TOTP or backup code for a user +* [disable_mfa](#disable_mfa) - Disable a user's MFA methods + +## list + +Returns a list of all users. +The users are returned sorted by creation date, with the newest users appearing first. + +### Example Usage + +```python +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +res = s.users.list(email_address=[ + "test@example.com", +], phone_number=[ + "+12345678901", +], external_id=[ + "external-id-123", +], username=[ + "user123", +], web3_wallet=[ + "0x123456789abcdef0x123456789abcdef", +], user_id=[ + "user-id-123", +], organization_id=[ + "org-id-123", +], query="John", last_active_at_since=1700690400000, limit=20, offset=10, order_by="-created_at") + +if res is not None: + # handle response + pass + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `email_address` | List[*str*] | :heavy_minus_sign: | Returns users with the specified email addresses.
Accepts up to 100 email addresses.
Any email addresses not found are ignored. | [
"test@example.com"
] | +| `phone_number` | List[*str*] | :heavy_minus_sign: | Returns users with the specified phone numbers.
Accepts up to 100 phone numbers.
Any phone numbers not found are ignored. | [
"+12345678901"
] | +| `external_id` | List[*str*] | :heavy_minus_sign: | Returns users with the specified external ids.
For each external id, the `+` and `-` can be
prepended to the id, which denote whether the
respective external id should be included or
excluded from the result set.
Accepts up to 100 external ids.
Any external ids not found are ignored. | [
"external-id-123"
] | +| `username` | List[*str*] | :heavy_minus_sign: | Returns users with the specified usernames.
Accepts up to 100 usernames.
Any usernames not found are ignored. | [
"user123"
] | +| `web3_wallet` | List[*str*] | :heavy_minus_sign: | Returns users with the specified web3 wallet addresses.
Accepts up to 100 web3 wallet addresses.
Any web3 wallet addressed not found are ignored. | [
"0x123456789abcdef0x123456789abcdef"
] | +| `user_id` | List[*str*] | :heavy_minus_sign: | Returns users with the user ids specified.
For each user id, the `+` and `-` can be
prepended to the id, which denote whether the
respective user id should be included or
excluded from the result set.
Accepts up to 100 user ids.
Any user ids not found are ignored. | [
"user-id-123"
] | +| `organization_id` | List[*str*] | :heavy_minus_sign: | Returns users that have memberships to the
given organizations.
For each organization id, the `+` and `-` can be
prepended to the id, which denote whether the
respective organization should be included or
excluded from the result set.
Accepts up to 100 organization ids. | [
"org-id-123"
] | +| `query` | *Optional[str]* | :heavy_minus_sign: | Returns users that match the given query.
For possible matches, we check the email addresses, phone numbers, usernames, web3 wallets, user ids, first and last names.
The query value doesn't need to match the exact value you are looking for, it is capable of partial matches as well. | John | +| `last_active_at_since` | *Optional[int]* | :heavy_minus_sign: | Returns users that had session activity since the given date, with day precision.
Providing a value with higher precision than day will result in an error.
Example: use 1700690400000 to retrieve users that had session activity from 2023-11-23 until the current day. | 1700690400000 | +| `limit` | *Optional[float]* | :heavy_minus_sign: | Applies a limit to the number of results returned.
Can be used for paginating the results together with `offset`. | 20 | +| `offset` | *Optional[float]* | :heavy_minus_sign: | Skip the first `offset` results when paginating.
Needs to be an integer greater or equal to zero.
To be used in conjunction with `limit`. | 10 | +| `order_by` | *Optional[str]* | :heavy_minus_sign: | Allows to return users in a particular order.
At the moment, you can order the returned users by their `created_at`,`updated_at`,`email_address`,`web3wallet`,`first_name`,`last_name`,`phone_number`,`username`,`last_active_at`,`last_sign_in_at`.
In order to specify the direction, you can use the `+/-` symbols prepended in the property to order by.
For example, if you want users to be returned in descending order according to their `created_at` property, you can use `-created_at`.
If you don't use `+` or `-`, then `+` is implied. We only support one `order_by` parameter, and if multiple `order_by` parameters are provided, we will only keep the first one. For example,
if you pass `order_by=username&order_by=created_at`, we will consider only the first `order_by` parameter, which is `username`. The `created_at` parameter will be ignored in this case. | | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + + +### Response + +**[List[models.User]](../../models/.md)** +### Errors + +| Error Object | Status Code | Content Type | +| ------------------ | ------------------ | ------------------ | +| models.ClerkErrors | 400,401,422 | application/json | +| models.SDKError | 4xx-5xx | */* | + +## create + +Creates a new user. Your user management settings determine how you should setup your user model. + +Any email address and phone number created using this method will be marked as verified. + +Note: If you are performing a migration, check out our guide on [zero downtime migrations](https://clerk.com/docs/deployments/migrate-overview). + +A rate limit rule of 20 requests per 10 seconds is applied to this endpoint. + +### Example Usage + +```python +import clerk +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +res = s.users.create(external_id="ext-id-001", first_name="John", last_name="Doe", email_address=[ + "john.doe@example.com", +], phone_number=[ + "+12345678901", +], web3_wallet=[ + "0x123456789abcdef0x123456789abcdef", +], username="johndoe123", password="Secure*Pass4", password_digest="$argon2i$v=19$m=4096,t=3,p=1$4t6CL3P7YiHBtwESXawI8Hm20zJj4cs7/4/G3c187e0$m7RQFczcKr5bIR0IIxbpO2P0tyrLjf3eUW3M3QSwnLc", password_hasher=clerk.PasswordHasher.ARGON2I, skip_password_checks=False, skip_password_requirement=False, totp_secret="base32totpsecretkey", backup_codes=[ + "123456", + "654321", +], public_metadata={}, private_metadata={}, unsafe_metadata={}, created_at="2023-03-15T07:15:20.902Z") + +if res is not None: + # handle response + pass + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `external_id` | *Optional[Nullable[str]]* | :heavy_minus_sign: | The ID of the user as used in your external systems or your previous authentication solution.
Must be unique across your instance. | ext-id-001 | +| `first_name` | *Optional[Nullable[str]]* | :heavy_minus_sign: | The first name to assign to the user | John | +| `last_name` | *Optional[Nullable[str]]* | :heavy_minus_sign: | The last name to assign to the user | Doe | +| `email_address` | List[*str*] | :heavy_minus_sign: | Email addresses to add to the user.
Must be unique across your instance.
The first email address will be set as the user's primary email address. | | +| `phone_number` | List[*str*] | :heavy_minus_sign: | Phone numbers to add to the user.
Must be unique across your instance.
The first phone number will be set as the user's primary phone number. | | +| `web3_wallet` | List[*str*] | :heavy_minus_sign: | Web3 wallets to add to the user.
Must be unique across your instance.
The first wallet will be set as the user's primary wallet. | | +| `username` | *Optional[Nullable[str]]* | :heavy_minus_sign: | The username to give to the user.
It must be unique across your instance. | johndoe123 | +| `password` | *Optional[Nullable[str]]* | :heavy_minus_sign: | The plaintext password to give the user.
Must be at least 8 characters long, and can not be in any list of hacked passwords. | Secure*Pass4 | +| `password_digest` | *Optional[str]* | :heavy_minus_sign: | In case you already have the password digests and not the passwords, you can use them for the newly created user via this property.
The digests should be generated with one of the supported algorithms.
The hashing algorithm can be specified using the `password_hasher` property. | $argon2i$v=19$m=4096,t=3,p=1$4t6CL3P7YiHBtwESXawI8Hm20zJj4cs7/4/G3c187e0$m7RQFczcKr5bIR0IIxbpO2P0tyrLjf3eUW3M3QSwnLc | +| `password_hasher` | [Optional[models.PasswordHasher]](../../models/passwordhasher.md) | :heavy_minus_sign: | The hashing algorithm that was used to generate the password digest.
The algorithms we support at the moment are [bcrypt](https://en.wikipedia.org/wiki/Bcrypt), [bcrypt_sha256_django](https://docs.djangoproject.com/en/4.0/topics/auth/passwords/),
[md5](https://en.wikipedia.org/wiki/MD5), pbkdf2_sha256, pbkdf2_sha512, [pbkdf2_sha256_django](https://docs.djangoproject.com/en/4.0/topics/auth/passwords/),
[phpass](https://www.openwall.com/phpass/), [scrypt_firebase](https://firebaseopensource.com/projects/firebase/scrypt/),
[scrypt_werkzeug](https://werkzeug.palletsprojects.com/en/3.0.x/utils/#werkzeug.security.generate_password_hash), [sha256](https://en.wikipedia.org/wiki/SHA-2)
and the [argon2](https://argon2.online/) variants argon2i and argon2id.

If you need support for any particular hashing algorithm, [please let us know](https://clerk.com/support).

Note: for password hashers considered insecure (at this moment MD5 and SHA256), the corresponding user password hashes will be transparently migrated to Bcrypt (a secure hasher) upon the user's first successful password sign in.
Insecure schemes are marked with `(insecure)` in the list below.

Each of the supported hashers expects the incoming digest to be in a particular format. Specifically:

**bcrypt:** The digest should be of the following form:

`$$$`

**bcrypt_sha256_django:** This is the Django-specific variant of Bcrypt, using SHA256 hashing function. The format should be as follows (as exported from Django):

`bcrypt_sha256$$$$`

**md5** (insecure): The digest should follow the regular form e.g.:

`5f4dcc3b5aa765d61d8327deb882cf99`

**pbkdf2_sha256:** This is the PBKDF2 algorithm using the SHA256 hashing function. The format should be as follows:

`pbkdf2_sha256$$$`

Note: Both the salt and the hash are expected to be base64-encoded.

**pbkdf2_sha512:** This is the PBKDF2 algorithm using the SHA512 hashing function. The format should be as follows:

`pbkdf2_sha512$$$`

_iterations:_ The number of iterations used. Must be an integer less than 420000.
_salt:_ The salt used when generating the hash. Must be less than 1024 bytes.
_hash:_ The hex-encoded hash. Must have been generated with a key length less than 1024 bytes.

**pbkdf2_sha256_django:** This is the Django-specific variant of PBKDF2 and the digest should have the following format (as exported from Django):

`pbkdf2_sha256$$$`

Note: The salt is expected to be un-encoded, the hash is expected base64-encoded.

**pbkdf2_sha1:** This is similar to pkbdf2_sha256_django, but with two differences:
1. uses sha1 instead of sha256
2. accepts the hash as a hex-encoded string

The format is the following:

`pbkdf2_sha1$$$`

**phpass:** Portable public domain password hashing framework for use in PHP applications. Digests hashed with phpass have the following sections:

The format is the following:

`$P$`

- $P$ is the prefix used to identify phpass hashes.
- rounds is a single character encoding a 6-bit integer representing the number of rounds used.
- salt is eight characters drawn from [./0-9A-Za-z], providing a 48-bit salt.
- checksum is 22 characters drawn from the same set, encoding the 128-bit checksum with MD5.

**scrypt_firebase:** The Firebase-specific variant of scrypt.
The value is expected to have 6 segments separated by the $ character and include the following information:

_hash:_ The actual Base64 hash. This can be retrieved when exporting the user from Firebase.
_salt:_ The salt used to generate the above hash. Again, this is given when exporting the user.
_signer key:_ The base64 encoded signer key.
_salt separator:_ The base64 encoded salt separator.
_rounds:_ The number of rounds the algorithm needs to run.
_memory cost:_ The cost of the algorithm run

The first 2 (hash and salt) are per user and can be retrieved when exporting the user from Firebase.
The other 4 values (signer key, salt separator, rounds and memory cost) are project-wide settings and can be retrieved from the project's password hash parameters.

Once you have all these, you can combine it in the following format and send this as the digest in order for Clerk to accept it:

`$$$$$`

**scrypt_werkzeug:** The Werkzeug-specific variant of scrypt.

The value is expected to have 3 segments separated by the $ character and include the following information:

_algorithm args:_ The algorithm used to generate the hash.
_salt:_ The salt used to generate the above hash.
_hash:_ The actual Base64 hash.

The algorithm args are the parameters used to generate the hash and are included in the digest.

**argon2i:** Algorithms in the argon2 family generate digests that encode the following information:

_version (v):_ The argon version, version 19 is assumed
_memory (m):_ The memory used by the algorithm (in kibibytes)
_iterations (t):_ The number of iterations to perform
_parallelism (p):_ The number of threads to use

Parts are demarcated by the `$` character, with the first part identifying the algorithm variant.
The middle part is a comma-separated list of the encoding options (memory, iterations, parallelism).
The final part is the actual digest.

`$argon2i$v=19$m=4096,t=3,p=1$4t6CL3P7YiHBtwESXawI8Hm20zJj4cs7/4/G3c187e0$m7RQFczcKr5bIR0IIxbpO2P0tyrLjf3eUW3M3QSwnLc`

**argon2id:** See the previous algorithm for an explanation of the formatting.

For the argon2id case, the value of the algorithm in the first part of the digest is `argon2id`:

`$argon2id$v=19$m=64,t=4,p=8$Z2liZXJyaXNo$iGXEpMBTDYQ8G/71tF0qGjxRHEmR3gpGULcE93zUJVU`

**sha256** (insecure): The digest should be a 64-length hex string, e.g.:

`9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08`

**sha256_salted** (insecure): The digest should be a 64-length hex string with a salt.

The format is the following:
`$`

The value is expected to have 2 segments separated by the $ character and include the following information:
_hash:_ The sha256 hash, a 64-length hex string.
_salt:_ The salt used to generate the above hash. Must be between 1 and 1024 bits. | argon2i | +| `skip_password_checks` | *Optional[bool]* | :heavy_minus_sign: | When set to `true` all password checks are skipped.
It is recommended to use this method only when migrating plaintext passwords to Clerk.
Upon migration the user base should be prompted to pick stronger password. | false | +| `skip_password_requirement` | *Optional[bool]* | :heavy_minus_sign: | When set to `true`, `password` is not required anymore when creating the user and can be omitted.
This is useful when you are trying to create a user that doesn't have a password, in an instance that is using passwords.
Please note that you cannot use this flag if password is the only way for a user to sign into your instance. | false | +| `totp_secret` | *Optional[str]* | :heavy_minus_sign: | In case TOTP is configured on the instance, you can provide the secret to enable it on the newly created user without the need to reset it.
Please note that currently the supported options are:
* Period: 30 seconds
* Code length: 6 digits
* Algorithm: SHA1 | base32totpsecretkey | +| `backup_codes` | List[*str*] | :heavy_minus_sign: | If Backup Codes are configured on the instance, you can provide them to enable it on the newly created user without the need to reset them.
You must provide the backup codes in plain format or the corresponding bcrypt digest. | [
"123456",
"654321"
] | +| `public_metadata` | [Optional[models.CreateUserPublicMetadata]](../../models/createuserpublicmetadata.md) | :heavy_minus_sign: | Metadata saved on the user, that is visible to both your Frontend and Backend APIs | {
"role": "user"
} | +| `private_metadata` | [Optional[models.CreateUserPrivateMetadata]](../../models/createuserprivatemetadata.md) | :heavy_minus_sign: | Metadata saved on the user, that is only visible to your Backend API | {
"internal_id": "789"
} | +| `unsafe_metadata` | [Optional[models.CreateUserUnsafeMetadata]](../../models/createuserunsafemetadata.md) | :heavy_minus_sign: | Metadata saved on the user, that can be updated from both the Frontend and Backend APIs.
Note: Since this data can be modified from the frontend, it is not guaranteed to be safe. | {
"preferences": {
"theme": "dark"
}
} | +| `created_at` | *Optional[str]* | :heavy_minus_sign: | A custom date/time denoting _when_ the user signed up to the application, specified in RFC3339 format (e.g. `2012-10-20T07:15:20.902Z`). | 2023-03-15T07:15:20.902Z | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + + +### Response + +**[models.User](../../models/user.md)** +### Errors + +| Error Object | Status Code | Content Type | +| ------------------ | ------------------ | ------------------ | +| models.ClerkErrors | 400,401,403,422 | application/json | +| models.SDKError | 4xx-5xx | */* | + +## count + +Returns a total count of all users that match the given filtering criteria. + +### Example Usage + +```python +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +res = s.users.count(email_address=[ + "user@example.com", +], phone_number=[ + "+1234567890", +], external_id=[ + "external-id-123", +], username=[ + "username123", +], web3_wallet=[ + "0x123456789abcdef", +], user_id=[ + "user-id-123", +], query="John Doe") + +if res is not None: + # handle response + pass + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `email_address` | List[*str*] | :heavy_minus_sign: | Counts users with the specified email addresses.
Accepts up to 100 email addresses.
Any email addresses not found are ignored. | [
"user@example.com"
] | +| `phone_number` | List[*str*] | :heavy_minus_sign: | Counts users with the specified phone numbers.
Accepts up to 100 phone numbers.
Any phone numbers not found are ignored. | [
"+1234567890"
] | +| `external_id` | List[*str*] | :heavy_minus_sign: | Counts users with the specified external ids.
Accepts up to 100 external ids.
Any external ids not found are ignored. | [
"external-id-123"
] | +| `username` | List[*str*] | :heavy_minus_sign: | Counts users with the specified usernames.
Accepts up to 100 usernames.
Any usernames not found are ignored. | [
"username123"
] | +| `web3_wallet` | List[*str*] | :heavy_minus_sign: | Counts users with the specified web3 wallet addresses.
Accepts up to 100 web3 wallet addresses.
Any web3 wallet addressed not found are ignored. | [
"0x123456789abcdef"
] | +| `user_id` | List[*str*] | :heavy_minus_sign: | Counts users with the user ids specified.
Accepts up to 100 user ids.
Any user ids not found are ignored. | [
"user-id-123"
] | +| `query` | *Optional[str]* | :heavy_minus_sign: | Counts users that match the given query.
For possible matches, we check the email addresses, phone numbers, usernames, web3 wallets, user ids, first and last names.
The query value doesn't need to match the exact value you are looking for, it is capable of partial matches as well. | John Doe | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + + +### Response + +**[models.TotalCount](../../models/totalcount.md)** +### Errors + +| Error Object | Status Code | Content Type | +| ------------------ | ------------------ | ------------------ | +| models.ClerkErrors | 422 | application/json | +| models.SDKError | 4xx-5xx | */* | + +## get + +Retrieve the details of a user + +### Example Usage + +```python +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +res = s.users.get(user_id="usr_1") + +if res is not None: + # handle response + pass + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | +| `user_id` | *str* | :heavy_check_mark: | The ID of the user to retrieve | usr_1 | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + + +### Response + +**[models.User](../../models/user.md)** +### Errors + +| Error Object | Status Code | Content Type | +| ------------------ | ------------------ | ------------------ | +| models.ClerkErrors | 400,401,404 | application/json | +| models.SDKError | 4xx-5xx | */* | + +## update + +Update a user's attributes. + +You can set the user's primary contact identifiers (email address and phone numbers) by updating the `primary_email_address_id` and `primary_phone_number_id` attributes respectively. +Both IDs should correspond to verified identifications that belong to the user. + +You can remove a user's username by setting the username attribute to null or the blank string "". +This is a destructive action; the identification will be deleted forever. +Usernames can be removed only if they are optional in your instance settings and there's at least one other identifier which can be used for authentication. + +This endpoint allows changing a user's password. When passing the `password` parameter directly you have two further options. +You can ignore the password policy checks for your instance by setting the `skip_password_checks` parameter to `true`. +You can also choose to sign the user out of all their active sessions on any device once the password is updated. Just set `sign_out_of_other_sessions` to `true`. + +### Example Usage + +```python +import clerk +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +res = s.users.update(user_id="usr_1", external_id="ext_123", first_name="Jane", last_name="Doe", primary_email_address_id="eml_12345", notify_primary_email_address_changed=True, primary_phone_number_id="phn_67890", primary_web3_wallet_id="wlt_123", username="janedoe", profile_image_id="img_789", password="secretPass123!", password_digest="$argon2i$v=19$m=4096,t=3,p=1$4t6CL3P7YiHBtwESXawI8Hm20zJj4cs7/4/G3c187e0$m7RQFczcKr5bIR0IIxbpO2P0tyrLjf3eUW3M3QSwnLc", password_hasher=clerk.UpdateUserPasswordHasher.ARGON2I, skip_password_checks=False, sign_out_of_other_sessions=True, totp_secret="ABCD1234EFGH5678", backup_codes=[ + "123456", + "654321", +], public_metadata={}, private_metadata={}, unsafe_metadata={}, delete_self_enabled=True, create_organization_enabled=False, created_at="2021-04-05T14:30:00.000Z") + +if res is not None: + # handle response + pass + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `user_id` | *str* | :heavy_check_mark: | The ID of the user to update | usr_1 | +| `external_id` | *Optional[Nullable[str]]* | :heavy_minus_sign: | The ID of the user as used in your external systems or your previous authentication solution.
Must be unique across your instance. | ext_123 | +| `first_name` | *Optional[Nullable[str]]* | :heavy_minus_sign: | The first name to assign to the user | Jane | +| `last_name` | *Optional[Nullable[str]]* | :heavy_minus_sign: | The last name to assign to the user | Doe | +| `primary_email_address_id` | *Optional[str]* | :heavy_minus_sign: | The ID of the email address to set as primary.
It must be verified, and present on the current user. | eml_12345 | +| `notify_primary_email_address_changed` | *Optional[bool]* | :heavy_minus_sign: | If set to `true`, the user will be notified that their primary email address has changed.
By default, no notification is sent. | true | +| `primary_phone_number_id` | *Optional[str]* | :heavy_minus_sign: | The ID of the phone number to set as primary.
It must be verified, and present on the current user. | phn_67890 | +| `primary_web3_wallet_id` | *Optional[str]* | :heavy_minus_sign: | The ID of the web3 wallets to set as primary.
It must be verified, and present on the current user. | wlt_123 | +| `username` | *Optional[Nullable[str]]* | :heavy_minus_sign: | The username to give to the user.
It must be unique across your instance. | janedoe | +| `profile_image_id` | *Optional[Nullable[str]]* | :heavy_minus_sign: | The ID of the image to set as the user's profile image | img_789 | +| `password` | *Optional[Nullable[str]]* | :heavy_minus_sign: | The plaintext password to give the user.
Must be at least 8 characters long, and can not be in any list of hacked passwords. | secretPass123! | +| `password_digest` | *Optional[str]* | :heavy_minus_sign: | In case you already have the password digests and not the passwords, you can use them for the newly created user via this property.
The digests should be generated with one of the supported algorithms.
The hashing algorithm can be specified using the `password_hasher` property. | $argon2i$v=19$m=4096,t=3,p=1$4t6CL3P7YiHBtwESXawI8Hm20zJj4cs7/4/G3c187e0$m7RQFczcKr5bIR0IIxbpO2P0tyrLjf3eUW3M3QSwnLc | +| `password_hasher` | [Optional[models.UpdateUserPasswordHasher]](../../models/updateuserpasswordhasher.md) | :heavy_minus_sign: | The hashing algorithm that was used to generate the password digest.
The algorithms we support at the moment are [bcrypt](https://en.wikipedia.org/wiki/Bcrypt), [bcrypt_sha256_django](https://docs.djangoproject.com/en/4.0/topics/auth/passwords/),
[md5](https://en.wikipedia.org/wiki/MD5), pbkdf2_sha256, pbkdf2_sha512, [pbkdf2_sha256_django](https://docs.djangoproject.com/en/4.0/topics/auth/passwords/),
[phpass](https://www.openwall.com/phpass/), [scrypt_firebase](https://firebaseopensource.com/projects/firebase/scrypt/),
[sha256](https://en.wikipedia.org/wiki/SHA-2), [scrypt_werkzeug](https://werkzeug.palletsprojects.com/en/3.0.x/utils/#werkzeug.security.generate_password_hash)
and the [argon2](https://argon2.online/) variants argon2i and argon2id.

If you need support for any particular hashing algorithm, [please let us know](https://clerk.com/support).

Note: for password hashers considered insecure (at this moment MD5 and SHA256), the corresponding user password hashes will be transparently migrated to Bcrypt (a secure hasher) upon the user's first successful password sign in.
Insecure schemes are marked with `(insecure)` in the list below.

Each of the supported hashers expects the incoming digest to be in a particular format. Specifically:

**bcrypt:** The digest should be of the following form:

`$$$`

**bcrypt_sha256_django:** This is the Django-specific variant of Bcrypt, using SHA256 hashing function. The format should be as follows (as exported from Django):

`bcrypt_sha256$$$$`

**md5** (insecure): The digest should follow the regular form e.g.:

`5f4dcc3b5aa765d61d8327deb882cf99`

**pbkdf2_sha256:** This is the PBKDF2 algorithm using the SHA256 hashing function. The format should be as follows:

`pbkdf2_sha256$$$`

Note: Both the salt and the hash are expected to be base64-encoded.

**pbkdf2_sha512:** This is the PBKDF2 algorithm using the SHA512 hashing function. The format should be as follows:

`pbkdf2_sha512$$$`

_iterations:_ The number of iterations used. Must be an integer less than 420000.
_salt:_ The salt used when generating the hash. Must be less than bytes.
_hash:_ The hex-encoded hash. Must have been generated with a key length less than 1024 bytes.

**pbkdf2_sha256_django:** This is the Django-specific variant of PBKDF2 and the digest should have the following format (as exported from Django):

`pbkdf2_sha256$$$`

Note: The salt is expected to be un-encoded, the hash is expected base64-encoded.

**pbkdf2_sha1:** This is similar to pkbdf2_sha256_django, but with two differences:
1. uses sha1 instead of sha256
2. accepts the hash as a hex-encoded string

The format is the following:

`pbkdf2_sha1$$$`

**phpass:** Portable public domain password hashing framework for use in PHP applications. Digests hashed with phpass have the following sections:

The format is the following:

`$P$`

- $P$ is the prefix used to identify phpass hashes.
- rounds is a single character encoding a 6-bit integer representing the number of rounds used.
- salt is eight characters drawn from [./0-9A-Za-z], providing a 48-bit salt.
- checksum is 22 characters drawn from the same set, encoding the 128-bit checksum with MD5.

**scrypt_firebase:** The Firebase-specific variant of scrypt.
The value is expected to have 6 segments separated by the $ character and include the following information:

_hash:_ The actual Base64 hash. This can be retrieved when exporting the user from Firebase.
_salt:_ The salt used to generate the above hash. Again, this is given when exporting the user.
_signer key:_ The base64 encoded signer key.
_salt separator:_ The base64 encoded salt separator.
_rounds:_ The number of rounds the algorithm needs to run.
_memory cost:_ The cost of the algorithm run

The first 2 (hash and salt) are per user and can be retrieved when exporting the user from Firebase.
The other 4 values (signer key, salt separator, rounds and memory cost) are project-wide settings and can be retrieved from the project's password hash parameters.

Once you have all these, you can combine it in the following format and send this as the digest in order for Clerk to accept it:

`$$$$$`

**scrypt_werkzeug:** The Werkzeug-specific variant of scrypt.

The value is expected to have 3 segments separated by the $ character and include the following information:

_algorithm args:_ The algorithm used to generate the hash.
_salt:_ The salt used to generate the above hash.
_hash:_ The actual Base64 hash.

The algorithm args are the parameters used to generate the hash and are included in the digest.

**argon2i:** Algorithms in the argon2 family generate digests that encode the following information:

_version (v):_ The argon version, version 19 is assumed
_memory (m):_ The memory used by the algorithm (in kibibytes)
_iterations (t):_ The number of iterations to perform
_parallelism (p):_ The number of threads to use

Parts are demarcated by the `$` character, with the first part identifying the algorithm variant.
The middle part is a comma-separated list of the encoding options (memory, iterations, parallelism).
The final part is the actual digest.

`$argon2i$v=19$m=4096,t=3,p=1$4t6CL3P7YiHBtwESXawI8Hm20zJj4cs7/4/G3c187e0$m7RQFczcKr5bIR0IIxbpO2P0tyrLjf3eUW3M3QSwnLc`

**argon2id:** See the previous algorithm for an explanation of the formatting.

For the argon2id case, the value of the algorithm in the first part of the digest is `argon2id`:

`$argon2id$v=19$m=64,t=4,p=8$Z2liZXJyaXNo$iGXEpMBTDYQ8G/71tF0qGjxRHEmR3gpGULcE93zUJVU`

**sha256** (insecure): The digest should be a 64-length hex string, e.g.:

`9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08` | argon2i | +| `skip_password_checks` | *Optional[Nullable[bool]]* | :heavy_minus_sign: | Set it to `true` if you're updating the user's password and want to skip any password policy settings check. This parameter can only be used when providing a `password`. | false | +| `sign_out_of_other_sessions` | *Optional[Nullable[bool]]* | :heavy_minus_sign: | Set to `true` to sign out the user from all their active sessions once their password is updated. This parameter can only be used when providing a `password`. | true | +| `totp_secret` | *Optional[str]* | :heavy_minus_sign: | In case TOTP is configured on the instance, you can provide the secret to enable it on the specific user without the need to reset it.
Please note that currently the supported options are:
* Period: 30 seconds
* Code length: 6 digits
* Algorithm: SHA1 | ABCD1234EFGH5678 | +| `backup_codes` | List[*str*] | :heavy_minus_sign: | If Backup Codes are configured on the instance, you can provide them to enable it on the specific user without the need to reset them.
You must provide the backup codes in plain format or the corresponding bcrypt digest. | [
"123456",
"654321"
] | +| `public_metadata` | [Optional[models.UpdateUserPublicMetadata]](../../models/updateuserpublicmetadata.md) | :heavy_minus_sign: | Metadata saved on the user, that is visible to both your Frontend and Backend APIs | {
"theme": "dark"
} | +| `private_metadata` | [Optional[models.UpdateUserPrivateMetadata]](../../models/updateuserprivatemetadata.md) | :heavy_minus_sign: | Metadata saved on the user, that is only visible to your Backend API | {
"vip": true
} | +| `unsafe_metadata` | [Optional[models.UpdateUserUnsafeMetadata]](../../models/updateuserunsafemetadata.md) | :heavy_minus_sign: | Metadata saved on the user, that can be updated from both the Frontend and Backend APIs.
Note: Since this data can be modified from the frontend, it is not guaranteed to be safe. | {
"age": 30
} | +| `delete_self_enabled` | *Optional[Nullable[bool]]* | :heavy_minus_sign: | If true, the user can delete themselves with the Frontend API. | true | +| `create_organization_enabled` | *Optional[Nullable[bool]]* | :heavy_minus_sign: | If true, the user can create organizations with the Frontend API. | false | +| `created_at` | *Optional[str]* | :heavy_minus_sign: | A custom date/time denoting _when_ the user signed up to the application, specified in RFC3339 format (e.g. `2012-10-20T07:15:20.902Z`). | 2021-04-05T14:30:00.000Z | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + + +### Response + +**[models.User](../../models/user.md)** +### Errors + +| Error Object | Status Code | Content Type | +| ------------------ | ------------------ | ------------------ | +| models.ClerkErrors | 400,401,404,422 | application/json | +| models.SDKError | 4xx-5xx | */* | + +## delete + +Delete the specified user + +### Example Usage + +```python +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +res = s.users.delete(user_id="usr_1") + +if res is not None: + # handle response + pass + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | +| `user_id` | *str* | :heavy_check_mark: | The ID of the user to delete | usr_1 | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + + +### Response + +**[models.DeletedObject](../../models/deletedobject.md)** +### Errors + +| Error Object | Status Code | Content Type | +| ------------------ | ------------------ | ------------------ | +| models.ClerkErrors | 400,401,404 | application/json | +| models.SDKError | 4xx-5xx | */* | + +## ban + +Marks the given user as banned, which means that all their sessions are revoked and they are not allowed to sign in again. + +### Example Usage + +```python +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +res = s.users.ban(user_id="user_12345") + +if res is not None: + # handle response + pass + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | +| `user_id` | *str* | :heavy_check_mark: | The ID of the user to ban | user_12345 | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + + +### Response + +**[models.User](../../models/user.md)** +### Errors + +| Error Object | Status Code | Content Type | +| ------------------ | ------------------ | ------------------ | +| models.ClerkErrors | 402 | application/json | +| models.SDKError | 4xx-5xx | */* | + +## unban + +Removes the ban mark from the given user. + +### Example Usage + +```python +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +res = s.users.unban(user_id="user_12345") + +if res is not None: + # handle response + pass + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | +| `user_id` | *str* | :heavy_check_mark: | The ID of the user to unban | user_12345 | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + + +### Response + +**[models.User](../../models/user.md)** +### Errors + +| Error Object | Status Code | Content Type | +| ------------------ | ------------------ | ------------------ | +| models.ClerkErrors | 402 | application/json | +| models.SDKError | 4xx-5xx | */* | + +## lock + +Marks the given user as locked, which means they are not allowed to sign in again until the lock expires. +Lock duration can be configured in the instance's restrictions settings. + +### Example Usage + +```python +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +res = s.users.lock(user_id="user_123456789") + +if res is not None: + # handle response + pass + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | +| `user_id` | *str* | :heavy_check_mark: | The ID of the user to lock | user_123456789 | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + + +### Response + +**[models.User](../../models/user.md)** +### Errors + +| Error Object | Status Code | Content Type | +| ------------------ | ------------------ | ------------------ | +| models.ClerkErrors | 403 | application/json | +| models.SDKError | 4xx-5xx | */* | + +## unlock + +Removes the lock from the given user. + +### Example Usage + +```python +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +res = s.users.unlock(user_id="user_12345") + +if res is not None: + # handle response + pass + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | +| `user_id` | *str* | :heavy_check_mark: | The ID of the user to unlock | user_12345 | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + + +### Response + +**[models.User](../../models/user.md)** +### Errors + +| Error Object | Status Code | Content Type | +| ------------------ | ------------------ | ------------------ | +| models.ClerkErrors | 403 | application/json | +| models.SDKError | 4xx-5xx | */* | + +## set_profile_image + +Update a user's profile image + +### Example Usage + +```python +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +res = s.users.set_profile_image(user_id="usr_test123", file={ + "file_name": "your_file_here", + "content": open("", "rb"), + "content_type": "", +}) + +if res is not None: + # handle response + pass + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | +| `user_id` | *str* | :heavy_check_mark: | The ID of the user to update the profile image for | usr_test123 | +| `file` | [Optional[models.File]](../../models/file.md) | :heavy_minus_sign: | N/A | | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + + +### Response + +**[models.User](../../models/user.md)** +### Errors + +| Error Object | Status Code | Content Type | +| ------------------ | ------------------ | ------------------ | +| models.ClerkErrors | 400,401,404 | application/json | +| models.SDKError | 4xx-5xx | */* | + +## delete_profile_image + +Delete a user's profile image + +### Example Usage + +```python +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +res = s.users.delete_profile_image(user_id="usr_test123") + +if res is not None: + # handle response + pass + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | +| `user_id` | *str* | :heavy_check_mark: | The ID of the user to delete the profile image for | usr_test123 | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + + +### Response + +**[models.User](../../models/user.md)** +### Errors + +| Error Object | Status Code | Content Type | +| ------------------ | ------------------ | ------------------ | +| models.ClerkErrors | 404 | application/json | +| models.SDKError | 4xx-5xx | */* | + +## update_metadata + +Update a user's metadata attributes by merging existing values with the provided parameters. + +This endpoint behaves differently than the *Update a user* endpoint. +Metadata values will not be replaced entirely. +Instead, a deep merge will be performed. +Deep means that any nested JSON objects will be merged as well. + +You can remove metadata keys at any level by setting their value to `null`. + +### Example Usage + +```python +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +res = s.users.update_metadata(user_id="user_123456789", public_metadata={ + "key": "", +}, private_metadata={}, unsafe_metadata={}) + +if res is not None: + # handle response + pass + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `user_id` | *str* | :heavy_check_mark: | The ID of the user whose metadata will be updated and merged | user_123456789 | +| `public_metadata` | Dict[str, *Any*] | :heavy_minus_sign: | Metadata saved on the user, that is visible to both your frontend and backend.
The new object will be merged with the existing value. | | +| `private_metadata` | [Optional[models.UpdateUserMetadataPrivateMetadata]](../../models/updateusermetadataprivatemetadata.md) | :heavy_minus_sign: | Metadata saved on the user that is only visible to your backend.
The new object will be merged with the existing value. | | +| `unsafe_metadata` | [Optional[models.UpdateUserMetadataUnsafeMetadata]](../../models/updateusermetadataunsafemetadata.md) | :heavy_minus_sign: | Metadata saved on the user, that can be updated from both the Frontend and Backend APIs.
The new object will be merged with the existing value.

Note: Since this data can be modified from the frontend, it is not guaranteed to be safe. | | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + + +### Response + +**[models.User](../../models/user.md)** +### Errors + +| Error Object | Status Code | Content Type | +| ------------------ | ------------------ | ------------------ | +| models.ClerkErrors | 400,401,404,422 | application/json | +| models.SDKError | 4xx-5xx | */* | + +## get_o_auth_access_token + +Fetch the corresponding OAuth access token for a user that has previously authenticated with a particular OAuth provider. +For OAuth 2.0, if the access token has expired and we have a corresponding refresh token, the access token will be refreshed transparently the new one will be returned. + +### Example Usage + +```python +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +res = s.users.get_o_auth_access_token(user_id="user_123", provider="oauth_google") + +if res is not None: + # handle response + pass + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | +| `user_id` | *str* | :heavy_check_mark: | The ID of the user for which to retrieve the OAuth access token | user_123 | +| `provider` | *str* | :heavy_check_mark: | The ID of the OAuth provider (e.g. `oauth_google`) | oauth_google | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + + +### Response + +**[List[models.ResponseBody]](../../models/.md)** +### Errors + +| Error Object | Status Code | Content Type | +| ------------------ | ------------------ | ------------------ | +| models.ClerkErrors | 422 | application/json | +| models.SDKError | 4xx-5xx | */* | + +## get_organization_memberships + +Retrieve a paginated list of the user's organization memberships + +### Example Usage + +```python +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +res = s.users.get_organization_memberships(user_id="usr_1234567890", limit=20, offset=10) + +if res is not None: + while True: + # handle items + + res = res.Next() + if res is None: + break + + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| ----------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | +| `user_id` | *str* | :heavy_check_mark: | The ID of the user whose organization memberships we want to retrieve | usr_1234567890 | +| `limit` | *Optional[float]* | :heavy_minus_sign: | Applies a limit to the number of results returned.
Can be used for paginating the results together with `offset`. | 20 | +| `offset` | *Optional[float]* | :heavy_minus_sign: | Skip the first `offset` results when paginating.
Needs to be an integer greater or equal to zero.
To be used in conjunction with `limit`. | 10 | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + + +### Response + +**[models.UsersGetOrganizationMembershipsResponse](../../models/usersgetorganizationmembershipsresponse.md)** +### Errors + +| Error Object | Status Code | Content Type | +| ------------------ | ------------------ | ------------------ | +| models.ClerkErrors | 403 | application/json | +| models.SDKError | 4xx-5xx | */* | + +## verify_password + +Check that the user's password matches the supplied input. +Useful for custom auth flows and re-verification. + +### Example Usage + +```python +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +res = s.users.verify_password(user_id="user_123", password="securepassword123") + +if res is not None: + # handle response + pass + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | +| `user_id` | *str* | :heavy_check_mark: | The ID of the user for whom to verify the password | user_123 | +| `password` | *str* | :heavy_check_mark: | The user password to verify | securepassword123 | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + + +### Response + +**[models.VerifyPasswordResponseBody](../../models/verifypasswordresponsebody.md)** +### Errors + +| Error Object | Status Code | Content Type | +| ------------------ | ------------------ | ------------------ | +| models.ClerkErrors | 500 | application/json | +| models.SDKError | 4xx-5xx | */* | + +## verify_totp + +Verify that the provided TOTP or backup code is valid for the user. +Verifying a backup code will result it in being consumed (i.e. it will +become invalid). +Useful for custom auth flows and re-verification. + +### Example Usage + +```python +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +res = s.users.verify_totp(user_id="usr_1a2b3c", code="123456") + +if res is not None: + # handle response + pass + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | +| `user_id` | *str* | :heavy_check_mark: | The ID of the user for whom to verify the TOTP | usr_1a2b3c | +| `code` | *str* | :heavy_check_mark: | The TOTP or backup code to verify | 123456 | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + + +### Response + +**[models.VerifyTOTPResponseBody](../../models/verifytotpresponsebody.md)** +### Errors + +| Error Object | Status Code | Content Type | +| ------------------ | ------------------ | ------------------ | +| models.ClerkErrors | 500 | application/json | +| models.SDKError | 4xx-5xx | */* | + +## disable_mfa + +Disable all of a user's MFA methods (e.g. OTP sent via SMS, TOTP on their authenticator app) at once. + +### Example Usage + +```python +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +res = s.users.disable_mfa(user_id="user_123456") + +if res is not None: + # handle response + pass + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | +| `user_id` | *str* | :heavy_check_mark: | The ID of the user whose MFA methods are to be disabled | user_123456 | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + + +### Response + +**[models.DisableMFAResponseBody](../../models/disablemfaresponsebody.md)** +### Errors + +| Error Object | Status Code | Content Type | +| ------------------ | ------------------ | ------------------ | +| models.ClerkErrors | 404,500 | application/json | +| models.SDKError | 4xx-5xx | */* | diff --git a/docs/sdks/webhooks/README.md b/docs/sdks/webhooks/README.md new file mode 100644 index 0000000..9ac6b0d --- /dev/null +++ b/docs/sdks/webhooks/README.md @@ -0,0 +1,122 @@ +# Webhooks +(*webhooks*) + +### Available Operations + +* [create_svix_app](#create_svix_app) - Create a Svix app +* [delete_svix_app](#delete_svix_app) - Delete a Svix app +* [generate_svix_auth_url](#generate_svix_auth_url) - Create a Svix Dashboard URL + +## create_svix_app + +Create a Svix app and associate it with the current instance + +### Example Usage + +```python +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +res = s.webhooks.create_svix_app() + +if res is not None: + # handle response + pass + +``` + +### Parameters + +| Parameter | Type | Required | Description | +| ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | + + +### Response + +**[models.SvixURL](../../models/svixurl.md)** +### Errors + +| Error Object | Status Code | Content Type | +| ------------------ | ------------------ | ------------------ | +| models.ClerkErrors | 400 | application/json | +| models.SDKError | 4xx-5xx | */* | + +## delete_svix_app + +Delete a Svix app and disassociate it from the current instance + +### Example Usage + +```python +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +s.webhooks.delete_svix_app() + +# Use the SDK ... + +``` + +### Parameters + +| Parameter | Type | Required | Description | +| ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | + +### Errors + +| Error Object | Status Code | Content Type | +| ------------------ | ------------------ | ------------------ | +| models.ClerkErrors | 400 | application/json | +| models.SDKError | 4xx-5xx | */* | + +## generate_svix_auth_url + +Generate a new url for accessing the Svix's management dashboard for that particular instance + +### Example Usage + +```python +from clerk import Clerk +import os + +s = Clerk( + bearer_auth=os.getenv("BEARER_AUTH", ""), +) + + +res = s.webhooks.generate_svix_auth_url() + +if res is not None: + # handle response + pass + +``` + +### Parameters + +| Parameter | Type | Required | Description | +| ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | + + +### Response + +**[models.SvixURL](../../models/svixurl.md)** +### Errors + +| Error Object | Status Code | Content Type | +| ------------------ | ------------------ | ------------------ | +| models.ClerkErrors | 400 | application/json | +| models.SDKError | 4xx-5xx | */* | diff --git a/.speakeasy/examples.yaml b/examples.yaml similarity index 100% rename from .speakeasy/examples.yaml rename to examples.yaml diff --git a/.speakeasy/fixes.yaml b/fixes.yaml similarity index 100% rename from .speakeasy/fixes.yaml rename to fixes.yaml diff --git a/py.typed b/py.typed new file mode 100644 index 0000000..3e38f1a --- /dev/null +++ b/py.typed @@ -0,0 +1 @@ +# Marker file for PEP 561. The package enables type hints. diff --git a/pylintrc b/pylintrc new file mode 100644 index 0000000..224b0d5 --- /dev/null +++ b/pylintrc @@ -0,0 +1,659 @@ +[MAIN] + +# Analyse import fallback blocks. This can be used to support both Python 2 and +# 3 compatible code, which means that the block might have code that exists +# only in one or another interpreter, leading to false positives when analysed. +analyse-fallback-blocks=no + +# Clear in-memory caches upon conclusion of linting. Useful if running pylint +# in a server-like mode. +clear-cache-post-run=no + +# Load and enable all available extensions. Use --list-extensions to see a list +# all available extensions. +#enable-all-extensions= + +# In error mode, messages with a category besides ERROR or FATAL are +# suppressed, and no reports are done by default. Error mode is compatible with +# disabling specific errors. +#errors-only= + +# Always return a 0 (non-error) status code, even if lint errors are found. +# This is primarily useful in continuous integration scripts. +#exit-zero= + +# A comma-separated list of package or module names from where C extensions may +# be loaded. Extensions are loading into the active Python interpreter and may +# run arbitrary code. +extension-pkg-allow-list= + +# A comma-separated list of package or module names from where C extensions may +# be loaded. Extensions are loading into the active Python interpreter and may +# run arbitrary code. (This is an alternative name to extension-pkg-allow-list +# for backward compatibility.) +extension-pkg-whitelist= + +# Return non-zero exit code if any of these messages/categories are detected, +# even if score is above --fail-under value. Syntax same as enable. Messages +# specified are enabled, while categories only check already-enabled messages. +fail-on= + +# Specify a score threshold under which the program will exit with error. +fail-under=10 + +# Interpret the stdin as a python script, whose filename needs to be passed as +# the module_or_package argument. +#from-stdin= + +# Files or directories to be skipped. They should be base names, not paths. +ignore=CVS + +# Add files or directories matching the regular expressions patterns to the +# ignore-list. The regex matches against paths and can be in Posix or Windows +# format. Because '\\' represents the directory delimiter on Windows systems, +# it can't be used as an escape character. +ignore-paths= + +# Files or directories matching the regular expression patterns are skipped. +# The regex matches against base names, not paths. The default value ignores +# Emacs file locks +ignore-patterns=^\.# + +# List of module names for which member attributes should not be checked and +# will not be imported (useful for modules/projects where namespaces are +# manipulated during runtime and thus existing member attributes cannot be +# deduced by static analysis). It supports qualified module names, as well as +# Unix pattern matching. +ignored-modules= + +# Python code to execute, usually for sys.path manipulation such as +# pygtk.require(). +#init-hook= + +# Use multiple processes to speed up Pylint. Specifying 0 will auto-detect the +# number of processors available to use, and will cap the count on Windows to +# avoid hangs. +jobs=1 + +# Control the amount of potential inferred values when inferring a single +# object. This can help the performance when dealing with large functions or +# complex, nested conditions. +limit-inference-results=100 + +# List of plugins (as comma separated values of python module names) to load, +# usually to register additional checkers. +load-plugins= + +# Pickle collected data for later comparisons. +persistent=yes + +# Minimum Python version to use for version dependent checks. Will default to +# the version used to run pylint. +py-version=3.8 + +# Discover python modules and packages in the file system subtree. +recursive=no + +# Add paths to the list of the source roots. Supports globbing patterns. The +# source root is an absolute path or a path relative to the current working +# directory used to determine a package namespace for modules located under the +# source root. +source-roots=src + +# When enabled, pylint would attempt to guess common misconfiguration and emit +# user-friendly hints instead of false-positive error messages. +suggestion-mode=yes + +# Allow loading of arbitrary C extensions. Extensions are imported into the +# active Python interpreter and may run arbitrary code. +unsafe-load-any-extension=no + +# In verbose mode, extra non-checker-related info will be displayed. +#verbose= + + +[BASIC] + +# Naming style matching correct argument names. +argument-naming-style=snake_case + +# Regular expression matching correct argument names. Overrides argument- +# naming-style. If left empty, argument names will be checked with the set +# naming style. +#argument-rgx= + +# Naming style matching correct attribute names. +#attr-naming-style=snake_case + +# Regular expression matching correct attribute names. Overrides attr-naming- +# style. If left empty, attribute names will be checked with the set naming +# style. +attr-rgx=[^\W\d][^\W]*|__.*__$ + +# Bad variable names which should always be refused, separated by a comma. +bad-names= + +# Bad variable names regexes, separated by a comma. If names match any regex, +# they will always be refused +bad-names-rgxs= + +# Naming style matching correct class attribute names. +class-attribute-naming-style=any + +# Regular expression matching correct class attribute names. Overrides class- +# attribute-naming-style. If left empty, class attribute names will be checked +# with the set naming style. +#class-attribute-rgx= + +# Naming style matching correct class constant names. +class-const-naming-style=UPPER_CASE + +# Regular expression matching correct class constant names. Overrides class- +# const-naming-style. If left empty, class constant names will be checked with +# the set naming style. +#class-const-rgx= + +# Naming style matching correct class names. +class-naming-style=PascalCase + +# Regular expression matching correct class names. Overrides class-naming- +# style. If left empty, class names will be checked with the set naming style. +#class-rgx= + +# Naming style matching correct constant names. +const-naming-style=UPPER_CASE + +# Regular expression matching correct constant names. Overrides const-naming- +# style. If left empty, constant names will be checked with the set naming +# style. +#const-rgx= + +# Minimum line length for functions/classes that require docstrings, shorter +# ones are exempt. +docstring-min-length=-1 + +# Naming style matching correct function names. +function-naming-style=snake_case + +# Regular expression matching correct function names. Overrides function- +# naming-style. If left empty, function names will be checked with the set +# naming style. +#function-rgx= + +# Good variable names which should always be accepted, separated by a comma. +good-names=i, + j, + k, + ex, + Run, + _, + e, + id + +# Good variable names regexes, separated by a comma. If names match any regex, +# they will always be accepted +good-names-rgxs= + +# Include a hint for the correct naming format with invalid-name. +include-naming-hint=no + +# Naming style matching correct inline iteration names. +inlinevar-naming-style=any + +# Regular expression matching correct inline iteration names. Overrides +# inlinevar-naming-style. If left empty, inline iteration names will be checked +# with the set naming style. +#inlinevar-rgx= + +# Naming style matching correct method names. +method-naming-style=snake_case + +# Regular expression matching correct method names. Overrides method-naming- +# style. If left empty, method names will be checked with the set naming style. +#method-rgx= + +# Naming style matching correct module names. +module-naming-style=snake_case + +# Regular expression matching correct module names. Overrides module-naming- +# style. If left empty, module names will be checked with the set naming style. +#module-rgx= + +# Colon-delimited sets of names that determine each other's naming style when +# the name regexes allow several styles. +name-group= + +# Regular expression which should only match function or class names that do +# not require a docstring. +no-docstring-rgx=^_ + +# List of decorators that produce properties, such as abc.abstractproperty. Add +# to this list to register other decorators that produce valid properties. +# These decorators are taken in consideration only for invalid-name. +property-classes=abc.abstractproperty + +# Regular expression matching correct type alias names. If left empty, type +# alias names will be checked with the set naming style. +typealias-rgx=.* + +# Regular expression matching correct type variable names. If left empty, type +# variable names will be checked with the set naming style. +#typevar-rgx= + +# Naming style matching correct variable names. +variable-naming-style=snake_case + +# Regular expression matching correct variable names. Overrides variable- +# naming-style. If left empty, variable names will be checked with the set +# naming style. +#variable-rgx= + + +[CLASSES] + +# Warn about protected attribute access inside special methods +check-protected-access-in-special-methods=no + +# List of method names used to declare (i.e. assign) instance attributes. +defining-attr-methods=__init__, + __new__, + setUp, + asyncSetUp, + __post_init__ + +# List of member names, which should be excluded from the protected access +# warning. +exclude-protected=_asdict,_fields,_replace,_source,_make,os._exit + +# List of valid names for the first argument in a class method. +valid-classmethod-first-arg=cls + +# List of valid names for the first argument in a metaclass class method. +valid-metaclass-classmethod-first-arg=mcs + + +[DESIGN] + +# List of regular expressions of class ancestor names to ignore when counting +# public methods (see R0903) +exclude-too-few-public-methods= + +# List of qualified class names to ignore when counting class parents (see +# R0901) +ignored-parents= + +# Maximum number of arguments for function / method. +max-args=5 + +# Maximum number of attributes for a class (see R0902). +max-attributes=7 + +# Maximum number of boolean expressions in an if statement (see R0916). +max-bool-expr=5 + +# Maximum number of branch for function / method body. +max-branches=12 + +# Maximum number of locals for function / method body. +max-locals=15 + +# Maximum number of parents for a class (see R0901). +max-parents=7 + +# Maximum number of public methods for a class (see R0904). +max-public-methods=25 + +# Maximum number of return / yield for function / method body. +max-returns=6 + +# Maximum number of statements in function / method body. +max-statements=50 + +# Minimum number of public methods for a class (see R0903). +min-public-methods=2 + + +[EXCEPTIONS] + +# Exceptions that will emit a warning when caught. +overgeneral-exceptions=builtins.BaseException,builtins.Exception + + +[FORMAT] + +# Expected format of line ending, e.g. empty (any line ending), LF or CRLF. +expected-line-ending-format= + +# Regexp for a line that is allowed to be longer than the limit. +ignore-long-lines=^\s*(# )??$ + +# Number of spaces of indent required inside a hanging or continued line. +indent-after-paren=4 + +# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1 +# tab). +indent-string=' ' + +# Maximum number of characters on a single line. +max-line-length=100 + +# Maximum number of lines in a module. +max-module-lines=1000 + +# Allow the body of a class to be on the same line as the declaration if body +# contains single statement. +single-line-class-stmt=no + +# Allow the body of an if to be on the same line as the test if there is no +# else. +single-line-if-stmt=no + + +[IMPORTS] + +# List of modules that can be imported at any level, not just the top level +# one. +allow-any-import-level= + +# Allow explicit reexports by alias from a package __init__. +allow-reexport-from-package=no + +# Allow wildcard imports from modules that define __all__. +allow-wildcard-with-all=no + +# Deprecated modules which should not be used, separated by a comma. +deprecated-modules= + +# Output a graph (.gv or any supported image format) of external dependencies +# to the given file (report RP0402 must not be disabled). +ext-import-graph= + +# Output a graph (.gv or any supported image format) of all (i.e. internal and +# external) dependencies to the given file (report RP0402 must not be +# disabled). +import-graph= + +# Output a graph (.gv or any supported image format) of internal dependencies +# to the given file (report RP0402 must not be disabled). +int-import-graph= + +# Force import order to recognize a module as part of the standard +# compatibility libraries. +known-standard-library= + +# Force import order to recognize a module as part of a third party library. +known-third-party=enchant + +# Couples of modules and preferred modules, separated by a comma. +preferred-modules= + + +[LOGGING] + +# The type of string formatting that logging methods do. `old` means using % +# formatting, `new` is for `{}` formatting. +logging-format-style=old + +# Logging modules to check that the string format arguments are in logging +# function parameter format. +logging-modules=logging + + +[MESSAGES CONTROL] + +# Only show warnings with the listed confidence levels. Leave empty to show +# all. Valid levels: HIGH, CONTROL_FLOW, INFERENCE, INFERENCE_FAILURE, +# UNDEFINED. +confidence=HIGH, + CONTROL_FLOW, + INFERENCE, + INFERENCE_FAILURE, + UNDEFINED + +# Disable the message, report, category or checker with the given id(s). You +# can either give multiple identifiers separated by comma (,) or put this +# option multiple times (only on the command line, not in the configuration +# file where it should appear only once). You can also use "--disable=all" to +# disable everything first and then re-enable specific checks. For example, if +# you want to run only the similarities checker, you can use "--disable=all +# --enable=similarities". If you want to run only the classes checker, but have +# no Warning level messages displayed, use "--disable=all --enable=classes +# --disable=W". +disable=raw-checker-failed, + bad-inline-option, + locally-disabled, + file-ignored, + suppressed-message, + useless-suppression, + deprecated-pragma, + use-implicit-booleaness-not-comparison-to-string, + use-implicit-booleaness-not-comparison-to-zero, + use-symbolic-message-instead, + trailing-whitespace, + line-too-long, + missing-class-docstring, + missing-module-docstring, + missing-function-docstring, + too-many-instance-attributes, + wrong-import-order, + too-many-arguments, + broad-exception-raised, + too-few-public-methods, + too-many-branches, + chained-comparison, + duplicate-code, + trailing-newlines, + too-many-public-methods, + too-many-locals, + too-many-lines, + using-constant-test, + too-many-statements, + cyclic-import, + too-many-nested-blocks, + too-many-boolean-expressions, + no-else-raise, + bare-except, + broad-exception-caught, + fixme, + consider-using-from-import + +# Enable the message, report, category or checker with the given id(s). You can +# either give multiple identifier separated by comma (,) or put this option +# multiple time (only on the command line, not in the configuration file where +# it should appear only once). See also the "--disable" option for examples. +enable= + + +[METHOD_ARGS] + +# List of qualified names (i.e., library.method) which require a timeout +# parameter e.g. 'requests.api.get,requests.api.post' +timeout-methods=requests.api.delete,requests.api.get,requests.api.head,requests.api.options,requests.api.patch,requests.api.post,requests.api.put,requests.api.request + + +[MISCELLANEOUS] + +# List of note tags to take in consideration, separated by a comma. +notes=FIXME, + XXX, + TODO + +# Regular expression of note tags to take in consideration. +notes-rgx= + + +[REFACTORING] + +# Maximum number of nested blocks for function / method body +max-nested-blocks=5 + +# Complete name of functions that never returns. When checking for +# inconsistent-return-statements if a never returning function is called then +# it will be considered as an explicit return statement and no message will be +# printed. +never-returning-functions=sys.exit,argparse.parse_error + + +[REPORTS] + +# Python expression which should return a score less than or equal to 10. You +# have access to the variables 'fatal', 'error', 'warning', 'refactor', +# 'convention', and 'info' which contain the number of messages in each +# category, as well as 'statement' which is the total number of statements +# analyzed. This score is used by the global evaluation report (RP0004). +evaluation=max(0, 0 if fatal else 10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10)) + +# Template used to display messages. This is a python new-style format string +# used to format the message information. See doc for all details. +msg-template= + +# Set the output format. Available formats are: text, parseable, colorized, +# json2 (improved json format), json (old json format) and msvs (visual +# studio). You can also give a reporter class, e.g. +# mypackage.mymodule.MyReporterClass. +#output-format= + +# Tells whether to display a full report or only the messages. +reports=no + +# Activate the evaluation score. +score=yes + + +[SIMILARITIES] + +# Comments are removed from the similarity computation +ignore-comments=yes + +# Docstrings are removed from the similarity computation +ignore-docstrings=yes + +# Imports are removed from the similarity computation +ignore-imports=yes + +# Signatures are removed from the similarity computation +ignore-signatures=yes + +# Minimum lines number of a similarity. +min-similarity-lines=4 + + +[SPELLING] + +# Limits count of emitted suggestions for spelling mistakes. +max-spelling-suggestions=4 + +# Spelling dictionary name. No available dictionaries : You need to install +# both the python package and the system dependency for enchant to work. +spelling-dict= + +# List of comma separated words that should be considered directives if they +# appear at the beginning of a comment and should not be checked. +spelling-ignore-comment-directives=fmt: on,fmt: off,noqa:,noqa,nosec,isort:skip,mypy: + +# List of comma separated words that should not be checked. +spelling-ignore-words= + +# A path to a file that contains the private dictionary; one word per line. +spelling-private-dict-file= + +# Tells whether to store unknown words to the private dictionary (see the +# --spelling-private-dict-file option) instead of raising a message. +spelling-store-unknown-words=no + + +[STRING] + +# This flag controls whether inconsistent-quotes generates a warning when the +# character used as a quote delimiter is used inconsistently within a module. +check-quote-consistency=no + +# This flag controls whether the implicit-str-concat should generate a warning +# on implicit string concatenation in sequences defined over several lines. +check-str-concat-over-line-jumps=no + + +[TYPECHECK] + +# List of decorators that produce context managers, such as +# contextlib.contextmanager. Add to this list to register other decorators that +# produce valid context managers. +contextmanager-decorators=contextlib.contextmanager + +# List of members which are set dynamically and missed by pylint inference +# system, and so shouldn't trigger E1101 when accessed. Python regular +# expressions are accepted. +generated-members= + +# Tells whether to warn about missing members when the owner of the attribute +# is inferred to be None. +ignore-none=yes + +# This flag controls whether pylint should warn about no-member and similar +# checks whenever an opaque object is returned when inferring. The inference +# can return multiple potential results while evaluating a Python object, but +# some branches might not be evaluated, which results in partial inference. In +# that case, it might be useful to still emit no-member and other checks for +# the rest of the inferred objects. +ignore-on-opaque-inference=yes + +# List of symbolic message names to ignore for Mixin members. +ignored-checks-for-mixins=no-member, + not-async-context-manager, + not-context-manager, + attribute-defined-outside-init + +# List of class names for which member attributes should not be checked (useful +# for classes with dynamically set attributes). This supports the use of +# qualified names. +ignored-classes=optparse.Values,thread._local,_thread._local,argparse.Namespace + +# Show a hint with possible names when a member name was not found. The aspect +# of finding the hint is based on edit distance. +missing-member-hint=yes + +# The minimum edit distance a name should have in order to be considered a +# similar match for a missing member name. +missing-member-hint-distance=1 + +# The total number of similar names that should be taken in consideration when +# showing a hint for a missing member. +missing-member-max-choices=1 + +# Regex pattern to define which classes are considered mixins. +mixin-class-rgx=.*[Mm]ixin + +# List of decorators that change the signature of a decorated function. +signature-mutators= + + +[VARIABLES] + +# List of additional names supposed to be defined in builtins. Remember that +# you should avoid defining new builtins when possible. +additional-builtins= + +# Tells whether unused global variables should be treated as a violation. +allow-global-unused-variables=yes + +# List of names allowed to shadow builtins +allowed-redefined-builtins=id,object + +# List of strings which can identify a callback function by name. A callback +# name must start or end with one of those strings. +callbacks=cb_, + _cb + +# A regular expression matching the name of dummy variables (i.e. expected to +# not be used). +dummy-variables-rgx=_+$|(_[a-zA-Z0-9_]*[a-zA-Z0-9]+?$)|dummy|^ignored_|^unused_ + +# Argument names that match this expression will be ignored. +ignored-argument-names=_.*|^ignored_|^unused_ + +# Tells whether we should check for unused import in __init__ files. +init-import=no + +# List of qualified module names which can have objects that can redefine +# builtins. +redefining-builtins-modules=six.moves,past.builtins,future.builtins,builtins,io diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..b7f13e9 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,28 @@ +[tool.poetry] +name = "clerk" +version = "0.5.0-alpha.5" +description = "Python Client SDK for clerk.dev" +authors = ["Clerk",] +readme = "README.md" +packages = [ + { include = "clerk", from = "src" } +] +include = ["py.typed"] + +[tool.poetry.dependencies] +python = "^3.8" +httpx = "^0.27.0" +jsonpath-python = "^1.0.6" +pydantic = "~2.8.2" +python-dateutil = "^2.9.0.post0" +typing-inspect = "^0.9.0" + +[tool.poetry.group.dev.dependencies] +pylint = "==3.2.3" + +[build-system] +requires = ["poetry-core"] +build-backend = "poetry.core.masonry.api" + +[tool.pytest.ini_options] +pythonpath = ["src"] diff --git a/scripts/publish.sh b/scripts/publish.sh new file mode 100755 index 0000000..6392f41 --- /dev/null +++ b/scripts/publish.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash + +export POETRY_PYPI_TOKEN_PYPI=${PYPI_TOKEN} + +poetry publish --build diff --git a/src/clerk/__init__.py b/src/clerk/__init__.py new file mode 100644 index 0000000..6b8c2d8 --- /dev/null +++ b/src/clerk/__init__.py @@ -0,0 +1,5 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from .sdk import * +from .sdkconfiguration import * +from .models import * diff --git a/src/clerk/_hooks/__init__.py b/src/clerk/_hooks/__init__.py new file mode 100644 index 0000000..5fd985a --- /dev/null +++ b/src/clerk/_hooks/__init__.py @@ -0,0 +1,5 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from .sdkhooks import * +from .types import * +from .registration import * diff --git a/src/clerk/_hooks/registration.py b/src/clerk/_hooks/registration.py new file mode 100644 index 0000000..1db6a52 --- /dev/null +++ b/src/clerk/_hooks/registration.py @@ -0,0 +1,13 @@ +from .types import Hooks + + +# This file is only ever generated once on the first generation and then is free to be modified. +# Any hooks you wish to add should be registered in the init_hooks function. Feel free to define them +# in this file or in separate files in the hooks folder. + + +def init_hooks(hooks: Hooks): + # pylint: disable=unused-argument + """Add hooks by calling hooks.register{sdk_init/before_request/after_success/after_error}Hook + with an instance of a hook that implements that specific Hook interface + Hooks are registered per SDK instance, and are valid for the lifetime of the SDK instance""" diff --git a/src/clerk/_hooks/sdkhooks.py b/src/clerk/_hooks/sdkhooks.py new file mode 100644 index 0000000..f950e6b --- /dev/null +++ b/src/clerk/_hooks/sdkhooks.py @@ -0,0 +1,57 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +import httpx +from .types import SDKInitHook, BeforeRequestContext, BeforeRequestHook, AfterSuccessContext, AfterSuccessHook, AfterErrorContext, AfterErrorHook, Hooks +from .registration import init_hooks +from typing import List, Optional, Tuple +from clerk.httpclient import HttpClient + +class SDKHooks(Hooks): + def __init__(self): + self.sdk_init_hooks: List[SDKInitHook] = [] + self.before_request_hooks: List[BeforeRequestHook] = [] + self.after_success_hooks: List[AfterSuccessHook] = [] + self.after_error_hooks: List[AfterErrorHook] = [] + init_hooks(self) + + def register_sdk_init_hook(self, hook: SDKInitHook) -> None: + self.sdk_init_hooks.append(hook) + + def register_before_request_hook(self, hook: BeforeRequestHook) -> None: + self.before_request_hooks.append(hook) + + def register_after_success_hook(self, hook: AfterSuccessHook) -> None: + self.after_success_hooks.append(hook) + + def register_after_error_hook(self, hook: AfterErrorHook) -> None: + self.after_error_hooks.append(hook) + + def sdk_init(self, base_url: str, client: HttpClient) -> Tuple[str, HttpClient]: + for hook in self.sdk_init_hooks: + base_url, client = hook.sdk_init(base_url, client) + return base_url, client + + def before_request(self, hook_ctx: BeforeRequestContext, request: httpx.Request) -> httpx.Request: + for hook in self.before_request_hooks: + out = hook.before_request(hook_ctx, request) + if isinstance(out, Exception): + raise out + request = out + + return request + + def after_success(self, hook_ctx: AfterSuccessContext, response: httpx.Response) -> httpx.Response: + for hook in self.after_success_hooks: + out = hook.after_success(hook_ctx, response) + if isinstance(out, Exception): + raise out + response = out + return response + + def after_error(self, hook_ctx: AfterErrorContext, response: Optional[httpx.Response], error: Optional[Exception]) -> Tuple[Optional[httpx.Response], Optional[Exception]]: + for hook in self.after_error_hooks: + result = hook.after_error(hook_ctx, response, error) + if isinstance(result, Exception): + raise result + response, error = result + return response, error diff --git a/src/clerk/_hooks/types.py b/src/clerk/_hooks/types.py new file mode 100644 index 0000000..4cf1f8a --- /dev/null +++ b/src/clerk/_hooks/types.py @@ -0,0 +1,76 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + + +from abc import ABC, abstractmethod +from clerk.httpclient import HttpClient +import httpx +from typing import Any, Callable, List, Optional, Tuple, Union + + +class HookContext: + operation_id: str + oauth2_scopes: Optional[List[str]] = None + security_source: Optional[Union[Any, Callable[[], Any]]] = None + + def __init__(self, operation_id: str, oauth2_scopes: Optional[List[str]], security_source: Optional[Union[Any, Callable[[], Any]]]): + self.operation_id = operation_id + self.oauth2_scopes = oauth2_scopes + self.security_source = security_source + + +class BeforeRequestContext(HookContext): + def __init__(self, hook_ctx: HookContext): + super().__init__(hook_ctx.operation_id, hook_ctx.oauth2_scopes, hook_ctx.security_source) + + +class AfterSuccessContext(HookContext): + def __init__(self, hook_ctx: HookContext): + super().__init__(hook_ctx.operation_id, hook_ctx.oauth2_scopes, hook_ctx.security_source) + + + +class AfterErrorContext(HookContext): + def __init__(self, hook_ctx: HookContext): + super().__init__(hook_ctx.operation_id, hook_ctx.oauth2_scopes, hook_ctx.security_source) + + +class SDKInitHook(ABC): + @abstractmethod + def sdk_init(self, base_url: str, client: HttpClient) -> Tuple[str, HttpClient]: + pass + + +class BeforeRequestHook(ABC): + @abstractmethod + def before_request(self, hook_ctx: BeforeRequestContext, request: httpx.Request) -> Union[httpx.Request, Exception]: + pass + + +class AfterSuccessHook(ABC): + @abstractmethod + def after_success(self, hook_ctx: AfterSuccessContext, response: httpx.Response) -> Union[httpx.Response, Exception]: + pass + + +class AfterErrorHook(ABC): + @abstractmethod + def after_error(self, hook_ctx: AfterErrorContext, response: Optional[httpx.Response], error: Optional[Exception]) -> Union[Tuple[Optional[httpx.Response], Optional[Exception]], Exception]: + pass + + +class Hooks(ABC): + @abstractmethod + def register_sdk_init_hook(self, hook: SDKInitHook): + pass + + @abstractmethod + def register_before_request_hook(self, hook: BeforeRequestHook): + pass + + @abstractmethod + def register_after_success_hook(self, hook: AfterSuccessHook): + pass + + @abstractmethod + def register_after_error_hook(self, hook: AfterErrorHook): + pass diff --git a/src/clerk/actortokens.py b/src/clerk/actortokens.py new file mode 100644 index 0000000..2295d12 --- /dev/null +++ b/src/clerk/actortokens.py @@ -0,0 +1,341 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from .basesdk import BaseSDK +from clerk import models +from clerk._hooks import HookContext +from clerk.types import Nullable, UNSET +import clerk.utils as utils +from typing import Any, Dict, Optional + +class ActorTokens(BaseSDK): + + + def create( + self, *, + user_id: str, + actor: Dict[str, Any], + expires_in_seconds: Optional[int] = None, + session_max_duration_in_seconds: Optional[int] = None, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.ActorToken: + r"""Create actor token + + Create an actor token that can be used to impersonate the given user. + The `actor` parameter needs to include at least a \"sub\" key whose value is the ID of the actor (impersonating) user. + + :param user_id: The ID of the user that can use the newly created sign in token. + :param actor: The actor payload. It needs to include a sub property which should contain the ID of the actor. This whole payload will be also included in the JWT session token. + :param expires_in_seconds: Optional parameter to specify the life duration of the actor token in seconds. By default, the duration is 1 hour. + :param session_max_duration_in_seconds: The maximum duration that the session which will be created by the generated actor token should last. By default, the duration of a session created via an actor token, lasts 30 minutes. + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.CreateActorTokenRequestBody( + user_id=user_id, + actor=actor, + expires_in_seconds=expires_in_seconds, + session_max_duration_in_seconds=session_max_duration_in_seconds, + ) + + req = self.build_request( + method="POST", + path="/actor_tokens", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=False, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + get_serialized_body=lambda: utils.serialize_request_body(request, False, True, "json", Optional[models.CreateActorTokenRequestBody]), + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="CreateActorToken", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","402","422","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.ActorToken]) + if utils.match_response(http_res, ["400","402","422"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + async def create_async( + self, *, + user_id: str, + actor: Dict[str, Any], + expires_in_seconds: Optional[int] = None, + session_max_duration_in_seconds: Optional[int] = None, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.ActorToken: + r"""Create actor token + + Create an actor token that can be used to impersonate the given user. + The `actor` parameter needs to include at least a \"sub\" key whose value is the ID of the actor (impersonating) user. + + :param user_id: The ID of the user that can use the newly created sign in token. + :param actor: The actor payload. It needs to include a sub property which should contain the ID of the actor. This whole payload will be also included in the JWT session token. + :param expires_in_seconds: Optional parameter to specify the life duration of the actor token in seconds. By default, the duration is 1 hour. + :param session_max_duration_in_seconds: The maximum duration that the session which will be created by the generated actor token should last. By default, the duration of a session created via an actor token, lasts 30 minutes. + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.CreateActorTokenRequestBody( + user_id=user_id, + actor=actor, + expires_in_seconds=expires_in_seconds, + session_max_duration_in_seconds=session_max_duration_in_seconds, + ) + + req = self.build_request( + method="POST", + path="/actor_tokens", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=False, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + get_serialized_body=lambda: utils.serialize_request_body(request, False, True, "json", Optional[models.CreateActorTokenRequestBody]), + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="CreateActorToken", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","402","422","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.ActorToken]) + if utils.match_response(http_res, ["400","402","422"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + def revoke( + self, *, + actor_token_id: str, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.ActorToken: + r"""Revoke actor token + + Revokes a pending actor token. + + :param actor_token_id: The ID of the actor token to be revoked. + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.RevokeActorTokenRequest( + actor_token_id=actor_token_id, + ) + + req = self.build_request( + method="POST", + path="/actor_tokens/{actor_token_id}/revoke", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="RevokeActorToken", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","404","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.ActorToken]) + if utils.match_response(http_res, ["400","404"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + async def revoke_async( + self, *, + actor_token_id: str, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.ActorToken: + r"""Revoke actor token + + Revokes a pending actor token. + + :param actor_token_id: The ID of the actor token to be revoked. + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.RevokeActorTokenRequest( + actor_token_id=actor_token_id, + ) + + req = self.build_request( + method="POST", + path="/actor_tokens/{actor_token_id}/revoke", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="RevokeActorToken", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","404","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.ActorToken]) + if utils.match_response(http_res, ["400","404"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + diff --git a/src/clerk/allowlistidentifiers.py b/src/clerk/allowlistidentifiers.py new file mode 100644 index 0000000..b892666 --- /dev/null +++ b/src/clerk/allowlistidentifiers.py @@ -0,0 +1,467 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from .basesdk import BaseSDK +from clerk import models +from clerk._hooks import HookContext +from clerk.types import Nullable, UNSET +import clerk.utils as utils +from typing import List, Optional + +class AllowlistIdentifiers(BaseSDK): + + + def list( + self, *, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> List[models.AllowlistIdentifier]: + r"""List all identifiers on the allow-list + + Get a list of all identifiers allowed to sign up to an instance + + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + req = self.build_request( + method="GET", + path="/allowlist_identifiers", + base_url=base_url, + url_variables=url_variables, + request=None, + request_body_required=False, + request_has_path_params=False, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="ListAllowlistIdentifiers", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["401","402","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[List[models.AllowlistIdentifier]]) + if utils.match_response(http_res, ["401","402"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + async def list_async( + self, *, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> List[models.AllowlistIdentifier]: + r"""List all identifiers on the allow-list + + Get a list of all identifiers allowed to sign up to an instance + + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + req = self.build_request( + method="GET", + path="/allowlist_identifiers", + base_url=base_url, + url_variables=url_variables, + request=None, + request_body_required=False, + request_has_path_params=False, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="ListAllowlistIdentifiers", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["401","402","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[List[models.AllowlistIdentifier]]) + if utils.match_response(http_res, ["401","402"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + def create( + self, *, + identifier: str, + notify: Optional[bool] = None, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.AllowlistIdentifier: + r"""Add identifier to the allow-list + + Create an identifier allowed to sign up to an instance + + :param identifier: The identifier to be added in the allow-list. This can be an email address, a phone number or a web3 wallet. + :param notify: This flag denotes whether the given identifier will receive an invitation to join the application. Note that this only works for email address and phone number identifiers. + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.CreateAllowlistIdentifierRequestBody( + identifier=identifier, + notify=notify, + ) + + req = self.build_request( + method="POST", + path="/allowlist_identifiers", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=False, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + get_serialized_body=lambda: utils.serialize_request_body(request, False, True, "json", Optional[models.CreateAllowlistIdentifierRequestBody]), + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="CreateAllowlistIdentifier", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","402","422","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.AllowlistIdentifier]) + if utils.match_response(http_res, ["400","402","422"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + async def create_async( + self, *, + identifier: str, + notify: Optional[bool] = None, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.AllowlistIdentifier: + r"""Add identifier to the allow-list + + Create an identifier allowed to sign up to an instance + + :param identifier: The identifier to be added in the allow-list. This can be an email address, a phone number or a web3 wallet. + :param notify: This flag denotes whether the given identifier will receive an invitation to join the application. Note that this only works for email address and phone number identifiers. + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.CreateAllowlistIdentifierRequestBody( + identifier=identifier, + notify=notify, + ) + + req = self.build_request( + method="POST", + path="/allowlist_identifiers", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=False, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + get_serialized_body=lambda: utils.serialize_request_body(request, False, True, "json", Optional[models.CreateAllowlistIdentifierRequestBody]), + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="CreateAllowlistIdentifier", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","402","422","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.AllowlistIdentifier]) + if utils.match_response(http_res, ["400","402","422"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + def delete( + self, *, + identifier_id: str, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.DeletedObject: + r"""Delete identifier from allow-list + + Delete an identifier from the instance allow-list + + :param identifier_id: The ID of the identifier to delete from the allow-list + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.DeleteAllowlistIdentifierRequest( + identifier_id=identifier_id, + ) + + req = self.build_request( + method="DELETE", + path="/allowlist_identifiers/{identifier_id}", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="DeleteAllowlistIdentifier", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["402","404","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.DeletedObject]) + if utils.match_response(http_res, ["402","404"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + async def delete_async( + self, *, + identifier_id: str, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.DeletedObject: + r"""Delete identifier from allow-list + + Delete an identifier from the instance allow-list + + :param identifier_id: The ID of the identifier to delete from the allow-list + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.DeleteAllowlistIdentifierRequest( + identifier_id=identifier_id, + ) + + req = self.build_request( + method="DELETE", + path="/allowlist_identifiers/{identifier_id}", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="DeleteAllowlistIdentifier", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["402","404","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.DeletedObject]) + if utils.match_response(http_res, ["402","404"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + diff --git a/src/clerk/basesdk.py b/src/clerk/basesdk.py new file mode 100644 index 0000000..f7e9fbf --- /dev/null +++ b/src/clerk/basesdk.py @@ -0,0 +1,213 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from .sdkconfiguration import SDKConfiguration +from clerk import models +from clerk._hooks import AfterErrorContext, AfterSuccessContext, BeforeRequestContext +import clerk.utils as utils +from clerk.utils import RetryConfig, SerializedRequestBody +import httpx +from typing import Callable, List, Optional, Tuple + +class BaseSDK: + sdk_configuration: SDKConfiguration + + def __init__(self, sdk_config: SDKConfiguration) -> None: + self.sdk_configuration = sdk_config + + def get_url(self, base_url, url_variables): + sdk_url, sdk_variables = self.sdk_configuration.get_server_details() + + if base_url is None: + base_url = sdk_url + + if url_variables is None: + url_variables = sdk_variables + + return utils.template_url(base_url, url_variables) + + def build_request( + self, + method, + path, + base_url, + url_variables, + request, + request_body_required, + request_has_path_params, + request_has_query_params, + user_agent_header, + accept_header_value, + _globals=None, + security=None, + timeout_config: Optional[int] = None, + get_serialized_body: Optional[ + Callable[[], Optional[SerializedRequestBody]] + ] = None, + url_override: Optional[str] = None, + ) -> httpx.Request: + client = self.sdk_configuration.client + + query_params = {} + + url = url_override + if url is None: + url = utils.generate_url( + self.get_url(base_url, url_variables), + path, + request if request_has_path_params else None, + _globals if request_has_path_params else None, + ) + + query_params = utils.get_query_params( + request if request_has_query_params else None, + _globals if request_has_query_params else None, + ) + + headers = utils.get_headers(request, _globals) + headers["Accept"] = accept_header_value + headers[user_agent_header] = self.sdk_configuration.user_agent + + if security is not None: + if callable(security): + security = security() + + if security is not None: + security_headers, security_query_params = utils.get_security(security) + headers = {**headers, **security_headers} + query_params = {**query_params, **security_query_params} + + serialized_request_body = SerializedRequestBody("application/octet-stream") + if get_serialized_body is not None: + rb = get_serialized_body() + if request_body_required and rb is None: + raise ValueError("request body is required") + + if rb is not None: + serialized_request_body = rb + + if ( + serialized_request_body.media_type is not None + and serialized_request_body.media_type + not in ( + "multipart/form-data", + "multipart/mixed", + ) + ): + headers["content-type"] = serialized_request_body.media_type + + timeout = timeout_config / 1000 if timeout_config is not None else None + + return client.build_request( + method, + url, + params=query_params, + content=serialized_request_body.content, + data=serialized_request_body.data, + files=serialized_request_body.files, + headers=headers, + timeout=timeout, + ) + + def do_request( + self, + hook_ctx, + request, + error_status_codes, + retry_config: Optional[Tuple[RetryConfig, List[str]]] = None, + ) -> httpx.Response: + client = self.sdk_configuration.client + + def do(): + http_res = None + try: + req = self.sdk_configuration.get_hooks().before_request( + BeforeRequestContext(hook_ctx), request + ) + http_res = client.send(req) + except Exception as e: + _, e = self.sdk_configuration.get_hooks().after_error( + AfterErrorContext(hook_ctx), None, e + ) + if e is not None: + raise e + + if http_res is None: + raise models.SDKError("No response received") + + if utils.match_status_codes(error_status_codes, http_res.status_code): + result, e = self.sdk_configuration.get_hooks().after_error( + AfterErrorContext(hook_ctx), http_res, None + ) + if e is not None: + raise e + if result is not None: + http_res = result + else: + raise models.SDKError("Unexpected error occurred") + + return http_res + + if retry_config is not None: + http_res = utils.retry(do, utils.Retries(retry_config[0], retry_config[1])) + else: + http_res = do() + + if not utils.match_status_codes(error_status_codes, http_res.status_code): + http_res = self.sdk_configuration.get_hooks().after_success( + AfterSuccessContext(hook_ctx), http_res + ) + + return http_res + + async def do_request_async( + self, + hook_ctx, + request, + error_status_codes, + retry_config: Optional[Tuple[RetryConfig, List[str]]] = None, + ) -> httpx.Response: + client = self.sdk_configuration.async_client + + async def do(): + http_res = None + try: + req = self.sdk_configuration.get_hooks().before_request( + BeforeRequestContext(hook_ctx), request + ) + http_res = await client.send(req) + except Exception as e: + _, e = self.sdk_configuration.get_hooks().after_error( + AfterErrorContext(hook_ctx), None, e + ) + if e is not None: + raise e + + if http_res is None: + raise models.SDKError("No response received") + + if utils.match_status_codes(error_status_codes, http_res.status_code): + result, e = self.sdk_configuration.get_hooks().after_error( + AfterErrorContext(hook_ctx), http_res, None + ) + if e is not None: + raise e + if result is not None: + http_res = result + else: + raise models.SDKError("Unexpected error occurred") + + return http_res + + if retry_config is not None: + http_res = await utils.retry_async( + do, utils.Retries(retry_config[0], retry_config[1]) + ) + else: + http_res = await do() + + if not utils.match_status_codes(error_status_codes, http_res.status_code): + http_res = self.sdk_configuration.get_hooks().after_success( + AfterSuccessContext(hook_ctx), http_res + ) + + return http_res diff --git a/src/clerk/betafeatures.py b/src/clerk/betafeatures.py new file mode 100644 index 0000000..35af196 --- /dev/null +++ b/src/clerk/betafeatures.py @@ -0,0 +1,528 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from .basesdk import BaseSDK +from clerk import models +from clerk._hooks import HookContext +from clerk.types import Nullable, UNSET +import clerk.utils as utils +from typing import Optional +from typing_extensions import deprecated + +class BetaFeatures(BaseSDK): + + + def update_instance_auth_config( + self, *, + restricted_to_allowlist: Optional[Nullable[bool]] = None, + from_email_address: Optional[Nullable[str]] = None, + progressive_sign_up: Optional[Nullable[bool]] = None, + session_token_template: Optional[Nullable[str]] = None, + enhanced_email_deliverability: Optional[Nullable[bool]] = None, + test_mode: Optional[Nullable[bool]] = None, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.InstanceSettings: + r"""Update instance settings + + Updates the settings of an instance + + :param restricted_to_allowlist: Whether sign up is restricted to email addresses, phone numbers and usernames that are on the allowlist. + :param from_email_address: The local part of the email address from which authentication-related emails (e.g. OTP code, magic links) will be sent. Only alphanumeric values are allowed. Note that this value should contain only the local part of the address (e.g. `foo` for `foo@example.com`). + :param progressive_sign_up: Enable the Progressive Sign Up algorithm. Refer to the [docs](https://clerk.com/docs/upgrade-guides/progressive-sign-up) for more info. + :param session_token_template: The name of the JWT Template used to augment your session tokens. To disable this, pass an empty string. + :param enhanced_email_deliverability: The \"enhanced_email_deliverability\" feature will send emails from \"verifications@clerk.dev\" instead of your domain. This can be helpful if you do not have a high domain reputation. + :param test_mode: Toggles test mode for this instance, allowing the use of test email addresses and phone numbers. Defaults to true for development instances. + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.UpdateInstanceAuthConfigRequestBody( + restricted_to_allowlist=restricted_to_allowlist, + from_email_address=from_email_address, + progressive_sign_up=progressive_sign_up, + session_token_template=session_token_template, + enhanced_email_deliverability=enhanced_email_deliverability, + test_mode=test_mode, + ) + + req = self.build_request( + method="PATCH", + path="/beta_features/instance_settings", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=False, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + get_serialized_body=lambda: utils.serialize_request_body(request, False, True, "json", Optional[models.UpdateInstanceAuthConfigRequestBody]), + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="UpdateInstanceAuthConfig", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["402","422","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.InstanceSettings]) + if utils.match_response(http_res, ["402","422"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + async def update_instance_auth_config_async( + self, *, + restricted_to_allowlist: Optional[Nullable[bool]] = None, + from_email_address: Optional[Nullable[str]] = None, + progressive_sign_up: Optional[Nullable[bool]] = None, + session_token_template: Optional[Nullable[str]] = None, + enhanced_email_deliverability: Optional[Nullable[bool]] = None, + test_mode: Optional[Nullable[bool]] = None, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.InstanceSettings: + r"""Update instance settings + + Updates the settings of an instance + + :param restricted_to_allowlist: Whether sign up is restricted to email addresses, phone numbers and usernames that are on the allowlist. + :param from_email_address: The local part of the email address from which authentication-related emails (e.g. OTP code, magic links) will be sent. Only alphanumeric values are allowed. Note that this value should contain only the local part of the address (e.g. `foo` for `foo@example.com`). + :param progressive_sign_up: Enable the Progressive Sign Up algorithm. Refer to the [docs](https://clerk.com/docs/upgrade-guides/progressive-sign-up) for more info. + :param session_token_template: The name of the JWT Template used to augment your session tokens. To disable this, pass an empty string. + :param enhanced_email_deliverability: The \"enhanced_email_deliverability\" feature will send emails from \"verifications@clerk.dev\" instead of your domain. This can be helpful if you do not have a high domain reputation. + :param test_mode: Toggles test mode for this instance, allowing the use of test email addresses and phone numbers. Defaults to true for development instances. + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.UpdateInstanceAuthConfigRequestBody( + restricted_to_allowlist=restricted_to_allowlist, + from_email_address=from_email_address, + progressive_sign_up=progressive_sign_up, + session_token_template=session_token_template, + enhanced_email_deliverability=enhanced_email_deliverability, + test_mode=test_mode, + ) + + req = self.build_request( + method="PATCH", + path="/beta_features/instance_settings", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=False, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + get_serialized_body=lambda: utils.serialize_request_body(request, False, True, "json", Optional[models.UpdateInstanceAuthConfigRequestBody]), + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="UpdateInstanceAuthConfig", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["402","422","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.InstanceSettings]) + if utils.match_response(http_res, ["402","422"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + @deprecated("warning: ** DEPRECATED ** - This will be removed in a future release, please migrate away from it as soon as possible.") + def update_production_instance_domain( + self, *, + home_url: Optional[str] = None, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ): + r"""Update production instance domain + + Change the domain of a production instance. + + Changing the domain requires updating the [DNS records](https://clerk.com/docs/deployments/overview#dns-records) accordingly, deploying new [SSL certificates](https://clerk.com/docs/deployments/overview#deploy), updating your Social Connection's redirect URLs and setting the new keys in your code. + + WARNING: Changing your domain will invalidate all current user sessions (i.e. users will be logged out). Also, while your application is being deployed, a small downtime is expected to occur. + + :param home_url: The new home URL of the production instance e.g. https://www.example.com + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.UpdateProductionInstanceDomainRequestBody( + home_url=home_url, + ) + + req = self.build_request( + method="PUT", + path="/beta_features/domain", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=False, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + get_serialized_body=lambda: utils.serialize_request_body(request, False, True, "json", Optional[models.UpdateProductionInstanceDomainRequestBody]), + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="UpdateProductionInstanceDomain", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","422","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "202", "*"): + return + if utils.match_response(http_res, ["400","422"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + @deprecated("warning: ** DEPRECATED ** - This will be removed in a future release, please migrate away from it as soon as possible.") + async def update_production_instance_domain_async( + self, *, + home_url: Optional[str] = None, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ): + r"""Update production instance domain + + Change the domain of a production instance. + + Changing the domain requires updating the [DNS records](https://clerk.com/docs/deployments/overview#dns-records) accordingly, deploying new [SSL certificates](https://clerk.com/docs/deployments/overview#deploy), updating your Social Connection's redirect URLs and setting the new keys in your code. + + WARNING: Changing your domain will invalidate all current user sessions (i.e. users will be logged out). Also, while your application is being deployed, a small downtime is expected to occur. + + :param home_url: The new home URL of the production instance e.g. https://www.example.com + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.UpdateProductionInstanceDomainRequestBody( + home_url=home_url, + ) + + req = self.build_request( + method="PUT", + path="/beta_features/domain", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=False, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + get_serialized_body=lambda: utils.serialize_request_body(request, False, True, "json", Optional[models.UpdateProductionInstanceDomainRequestBody]), + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="UpdateProductionInstanceDomain", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","422","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "202", "*"): + return + if utils.match_response(http_res, ["400","422"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + def change_production_instance_domain( + self, *, + home_url: Optional[str] = None, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ): + r"""Update production instance domain + + Change the domain of a production instance. + + Changing the domain requires updating the [DNS records](https://clerk.com/docs/deployments/overview#dns-records) accordingly, deploying new [SSL certificates](https://clerk.com/docs/deployments/overview#deploy), updating your Social Connection's redirect URLs and setting the new keys in your code. + + WARNING: Changing your domain will invalidate all current user sessions (i.e. users will be logged out). Also, while your application is being deployed, a small downtime is expected to occur. + + :param home_url: The new home URL of the production instance e.g. https://www.example.com + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.ChangeProductionInstanceDomainRequestBody( + home_url=home_url, + ) + + req = self.build_request( + method="POST", + path="/instance/change_domain", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=False, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + get_serialized_body=lambda: utils.serialize_request_body(request, False, True, "json", Optional[models.ChangeProductionInstanceDomainRequestBody]), + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="ChangeProductionInstanceDomain", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","422","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "202", "*"): + return + if utils.match_response(http_res, ["400","422"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + async def change_production_instance_domain_async( + self, *, + home_url: Optional[str] = None, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ): + r"""Update production instance domain + + Change the domain of a production instance. + + Changing the domain requires updating the [DNS records](https://clerk.com/docs/deployments/overview#dns-records) accordingly, deploying new [SSL certificates](https://clerk.com/docs/deployments/overview#deploy), updating your Social Connection's redirect URLs and setting the new keys in your code. + + WARNING: Changing your domain will invalidate all current user sessions (i.e. users will be logged out). Also, while your application is being deployed, a small downtime is expected to occur. + + :param home_url: The new home URL of the production instance e.g. https://www.example.com + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.ChangeProductionInstanceDomainRequestBody( + home_url=home_url, + ) + + req = self.build_request( + method="POST", + path="/instance/change_domain", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=False, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + get_serialized_body=lambda: utils.serialize_request_body(request, False, True, "json", Optional[models.ChangeProductionInstanceDomainRequestBody]), + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="ChangeProductionInstanceDomain", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","422","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "202", "*"): + return + if utils.match_response(http_res, ["400","422"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + diff --git a/src/clerk/blocklistidentifiers_sdk.py b/src/clerk/blocklistidentifiers_sdk.py new file mode 100644 index 0000000..0536136 --- /dev/null +++ b/src/clerk/blocklistidentifiers_sdk.py @@ -0,0 +1,461 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from .basesdk import BaseSDK +from clerk import models +from clerk._hooks import HookContext +from clerk.types import Nullable, UNSET +import clerk.utils as utils +from typing import Optional + +class BlocklistIdentifiersSDK(BaseSDK): + + + def list( + self, *, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.BlocklistIdentifiers: + r"""List all identifiers on the block-list + + Get a list of all identifiers which are not allowed to access an instance + + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + req = self.build_request( + method="GET", + path="/blocklist_identifiers", + base_url=base_url, + url_variables=url_variables, + request=None, + request_body_required=False, + request_has_path_params=False, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="ListBlocklistIdentifiers", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["401","402","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.BlocklistIdentifiers]) + if utils.match_response(http_res, ["401","402"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + async def list_async( + self, *, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.BlocklistIdentifiers: + r"""List all identifiers on the block-list + + Get a list of all identifiers which are not allowed to access an instance + + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + req = self.build_request( + method="GET", + path="/blocklist_identifiers", + base_url=base_url, + url_variables=url_variables, + request=None, + request_body_required=False, + request_has_path_params=False, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="ListBlocklistIdentifiers", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["401","402","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.BlocklistIdentifiers]) + if utils.match_response(http_res, ["401","402"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + def create( + self, *, + identifier: str, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.BlocklistIdentifier: + r"""Add identifier to the block-list + + Create an identifier that is blocked from accessing an instance + + :param identifier: The identifier to be added in the block-list. This can be an email address, a phone number or a web3 wallet. + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.CreateBlocklistIdentifierRequestBody( + identifier=identifier, + ) + + req = self.build_request( + method="POST", + path="/blocklist_identifiers", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=False, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + get_serialized_body=lambda: utils.serialize_request_body(request, False, True, "json", Optional[models.CreateBlocklistIdentifierRequestBody]), + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="CreateBlocklistIdentifier", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","402","422","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.BlocklistIdentifier]) + if utils.match_response(http_res, ["400","402","422"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + async def create_async( + self, *, + identifier: str, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.BlocklistIdentifier: + r"""Add identifier to the block-list + + Create an identifier that is blocked from accessing an instance + + :param identifier: The identifier to be added in the block-list. This can be an email address, a phone number or a web3 wallet. + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.CreateBlocklistIdentifierRequestBody( + identifier=identifier, + ) + + req = self.build_request( + method="POST", + path="/blocklist_identifiers", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=False, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + get_serialized_body=lambda: utils.serialize_request_body(request, False, True, "json", Optional[models.CreateBlocklistIdentifierRequestBody]), + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="CreateBlocklistIdentifier", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","402","422","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.BlocklistIdentifier]) + if utils.match_response(http_res, ["400","402","422"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + def delete( + self, *, + identifier_id: str, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.DeletedObject: + r"""Delete identifier from block-list + + Delete an identifier from the instance block-list + + :param identifier_id: The ID of the identifier to delete from the block-list + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.DeleteBlocklistIdentifierRequest( + identifier_id=identifier_id, + ) + + req = self.build_request( + method="DELETE", + path="/blocklist_identifiers/{identifier_id}", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="DeleteBlocklistIdentifier", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["402","404","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.DeletedObject]) + if utils.match_response(http_res, ["402","404"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + async def delete_async( + self, *, + identifier_id: str, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.DeletedObject: + r"""Delete identifier from block-list + + Delete an identifier from the instance block-list + + :param identifier_id: The ID of the identifier to delete from the block-list + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.DeleteBlocklistIdentifierRequest( + identifier_id=identifier_id, + ) + + req = self.build_request( + method="DELETE", + path="/blocklist_identifiers/{identifier_id}", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="DeleteBlocklistIdentifier", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["402","404","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.DeletedObject]) + if utils.match_response(http_res, ["402","404"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + diff --git a/src/clerk/clients.py b/src/clerk/clients.py new file mode 100644 index 0000000..9965629 --- /dev/null +++ b/src/clerk/clients.py @@ -0,0 +1,535 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from .basesdk import BaseSDK +from clerk import models +from clerk._hooks import HookContext +from clerk.types import Nullable, UNSET +import clerk.utils as utils +from jsonpath import JSONPath +from typing import Any, Dict, List, Optional +from typing_extensions import deprecated + +class Clients(BaseSDK): + + + @deprecated("warning: ** DEPRECATED ** - This will be removed in a future release, please migrate away from it as soon as possible.") + def list( + self, *, + limit: Optional[float] = None, + offset: Optional[float] = None, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.GetClientListResponse: + r"""List all clients + + Returns a list of all clients. The clients are returned sorted by creation date, + with the newest clients appearing first. + Warning: the endpoint is being deprecated and will be removed in future versions. + + :param limit: Applies a limit to the number of results returned. Can be used for paginating the results together with `offset`. + :param offset: Skip the first `offset` results when paginating. Needs to be an integer greater or equal to zero. To be used in conjunction with `limit`. + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.GetClientListRequest( + limit=limit, + offset=offset, + ) + + req = self.build_request( + method="GET", + path="/clients", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=False, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="GetClientList", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","401","410","422","4XX","5XX"], + retry_config=retry_config + ) + + def next_func() -> Optional[models.GetClientListResponse]: + body = utils.unmarshal_json(http_res.text, Dict[Any, Any]) + offset = request.offset if not request.offset is None else 0 + + if not http_res.text: + return None + results = JSONPath("$").parse(body) + if len(results) == 0 or len(results[0]) == 0: + return None + limit = request.limit if not request.limit is None else 0 + if len(results[0]) < limit: + return None + next_offset = offset + len(results[0]) + + return self.list( + limit=limit, + offset=next_offset, + retries=retries, + ) + + res = models.GetClientListResponse(result=None, next=next_func) + + if utils.match_response(http_res, "200", "application/json"): + res.result = utils.unmarshal_json(http_res.text, Optional[List[models.Client]]) + elif utils.match_response(http_res, ["400","401","410","422"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + elif utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + else: + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + return res + + + @deprecated("warning: ** DEPRECATED ** - This will be removed in a future release, please migrate away from it as soon as possible.") + async def list_async( + self, *, + limit: Optional[float] = None, + offset: Optional[float] = None, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.GetClientListResponse: + r"""List all clients + + Returns a list of all clients. The clients are returned sorted by creation date, + with the newest clients appearing first. + Warning: the endpoint is being deprecated and will be removed in future versions. + + :param limit: Applies a limit to the number of results returned. Can be used for paginating the results together with `offset`. + :param offset: Skip the first `offset` results when paginating. Needs to be an integer greater or equal to zero. To be used in conjunction with `limit`. + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.GetClientListRequest( + limit=limit, + offset=offset, + ) + + req = self.build_request( + method="GET", + path="/clients", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=False, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="GetClientList", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","401","410","422","4XX","5XX"], + retry_config=retry_config + ) + + def next_func() -> Optional[models.GetClientListResponse]: + body = utils.unmarshal_json(http_res.text, Dict[Any, Any]) + offset = request.offset if not request.offset is None else 0 + + if not http_res.text: + return None + results = JSONPath("$").parse(body) + if len(results) == 0 or len(results[0]) == 0: + return None + limit = request.limit if not request.limit is None else 0 + if len(results[0]) < limit: + return None + next_offset = offset + len(results[0]) + + return self.list( + limit=limit, + offset=next_offset, + retries=retries, + ) + + res = models.GetClientListResponse(result=None, next=next_func) + + if utils.match_response(http_res, "200", "application/json"): + res.result = utils.unmarshal_json(http_res.text, Optional[List[models.Client]]) + elif utils.match_response(http_res, ["400","401","410","422"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + elif utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + else: + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + return res + + + def verify( + self, *, + token: Optional[str] = None, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.Client: + r"""Verify a client + + Verifies the client in the provided token + + :param token: A JWT Token that represents the active client. + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.VerifyClientRequestBody( + token=token, + ) + + req = self.build_request( + method="POST", + path="/clients/verify", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=False, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + get_serialized_body=lambda: utils.serialize_request_body(request, False, True, "json", Optional[models.VerifyClientRequestBody]), + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="VerifyClient", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","401","404","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.Client]) + if utils.match_response(http_res, ["400","401","404"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + async def verify_async( + self, *, + token: Optional[str] = None, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.Client: + r"""Verify a client + + Verifies the client in the provided token + + :param token: A JWT Token that represents the active client. + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.VerifyClientRequestBody( + token=token, + ) + + req = self.build_request( + method="POST", + path="/clients/verify", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=False, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + get_serialized_body=lambda: utils.serialize_request_body(request, False, True, "json", Optional[models.VerifyClientRequestBody]), + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="VerifyClient", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","401","404","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.Client]) + if utils.match_response(http_res, ["400","401","404"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + def get( + self, *, + client_id: str, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.Client: + r"""Get a client + + Returns the details of a client. + + :param client_id: Client ID. + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.GetClientRequest( + client_id=client_id, + ) + + req = self.build_request( + method="GET", + path="/clients/{client_id}", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="GetClient", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","401","404","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.Client]) + if utils.match_response(http_res, ["400","401","404"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + async def get_async( + self, *, + client_id: str, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.Client: + r"""Get a client + + Returns the details of a client. + + :param client_id: Client ID. + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.GetClientRequest( + client_id=client_id, + ) + + req = self.build_request( + method="GET", + path="/clients/{client_id}", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="GetClient", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","401","404","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.Client]) + if utils.match_response(http_res, ["400","401","404"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + diff --git a/src/clerk/domains_sdk.py b/src/clerk/domains_sdk.py new file mode 100644 index 0000000..39bd164 --- /dev/null +++ b/src/clerk/domains_sdk.py @@ -0,0 +1,665 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from .basesdk import BaseSDK +from clerk import models +from clerk._hooks import HookContext +from clerk.types import Nullable, UNSET +import clerk.utils as utils +from typing import Optional + +class DomainsSDK(BaseSDK): + + + def list( + self, *, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.Domains: + r"""List all instance domains + + Use this endpoint to get a list of all domains for an instance. + The response will contain the primary domain for the instance and any satellite domains. Each domain in the response contains information about the URLs where Clerk operates and the required CNAME targets. + + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + req = self.build_request( + method="GET", + path="/domains", + base_url=base_url, + url_variables=url_variables, + request=None, + request_body_required=False, + request_has_path_params=False, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="ListDomains", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.Domains]) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + async def list_async( + self, *, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.Domains: + r"""List all instance domains + + Use this endpoint to get a list of all domains for an instance. + The response will contain the primary domain for the instance and any satellite domains. Each domain in the response contains information about the URLs where Clerk operates and the required CNAME targets. + + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + req = self.build_request( + method="GET", + path="/domains", + base_url=base_url, + url_variables=url_variables, + request=None, + request_body_required=False, + request_has_path_params=False, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="ListDomains", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.Domains]) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + def add( + self, *, + name: str, + is_satellite: bool, + proxy_url: Optional[str] = None, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.Domain: + r"""Add a domain + + Add a new domain for your instance. + Useful in the case of multi-domain instances, allows adding satellite domains to an instance. + The new domain must have a `name`. The domain name can contain the port for development instances, like `localhost:3000`. + At the moment, instances can have only one primary domain, so the `is_satellite` parameter must be set to `true`. + If you're planning to configure the new satellite domain to run behind a proxy, pass the `proxy_url` parameter accordingly. + + :param name: The new domain name. Can contain the port for development instances. + :param is_satellite: Marks the new domain as satellite. Only `true` is accepted at the moment. + :param proxy_url: The full URL of the proxy which will forward requests to the Clerk Frontend API for this domain. Applicable only to production instances. + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.AddDomainRequestBody( + name=name, + is_satellite=is_satellite, + proxy_url=proxy_url, + ) + + req = self.build_request( + method="POST", + path="/domains", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=False, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + get_serialized_body=lambda: utils.serialize_request_body(request, False, True, "json", Optional[models.AddDomainRequestBody]), + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="AddDomain", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","402","422","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.Domain]) + if utils.match_response(http_res, ["400","402","422"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + async def add_async( + self, *, + name: str, + is_satellite: bool, + proxy_url: Optional[str] = None, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.Domain: + r"""Add a domain + + Add a new domain for your instance. + Useful in the case of multi-domain instances, allows adding satellite domains to an instance. + The new domain must have a `name`. The domain name can contain the port for development instances, like `localhost:3000`. + At the moment, instances can have only one primary domain, so the `is_satellite` parameter must be set to `true`. + If you're planning to configure the new satellite domain to run behind a proxy, pass the `proxy_url` parameter accordingly. + + :param name: The new domain name. Can contain the port for development instances. + :param is_satellite: Marks the new domain as satellite. Only `true` is accepted at the moment. + :param proxy_url: The full URL of the proxy which will forward requests to the Clerk Frontend API for this domain. Applicable only to production instances. + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.AddDomainRequestBody( + name=name, + is_satellite=is_satellite, + proxy_url=proxy_url, + ) + + req = self.build_request( + method="POST", + path="/domains", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=False, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + get_serialized_body=lambda: utils.serialize_request_body(request, False, True, "json", Optional[models.AddDomainRequestBody]), + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="AddDomain", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","402","422","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.Domain]) + if utils.match_response(http_res, ["400","402","422"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + def delete( + self, *, + domain_id: str, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.DeletedObject: + r"""Delete a satellite domain + + Deletes a satellite domain for the instance. + It is currently not possible to delete the instance's primary domain. + + :param domain_id: The ID of the domain that will be deleted. Must be a satellite domain. + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.DeleteDomainRequest( + domain_id=domain_id, + ) + + req = self.build_request( + method="DELETE", + path="/domains/{domain_id}", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="DeleteDomain", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["403","404","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.DeletedObject]) + if utils.match_response(http_res, ["403","404"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + async def delete_async( + self, *, + domain_id: str, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.DeletedObject: + r"""Delete a satellite domain + + Deletes a satellite domain for the instance. + It is currently not possible to delete the instance's primary domain. + + :param domain_id: The ID of the domain that will be deleted. Must be a satellite domain. + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.DeleteDomainRequest( + domain_id=domain_id, + ) + + req = self.build_request( + method="DELETE", + path="/domains/{domain_id}", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="DeleteDomain", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["403","404","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.DeletedObject]) + if utils.match_response(http_res, ["403","404"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + def update( + self, *, + domain_id: str, + name: Optional[Nullable[str]] = None, + proxy_url: Optional[Nullable[str]] = None, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.Domain: + r"""Update a domain + + The `proxy_url` can be updated only for production instances. + Update one of the instance's domains. Both primary and satellite domains can be updated. + If you choose to use Clerk via proxy, use this endpoint to specify the `proxy_url`. + Whenever you decide you'd rather switch to DNS setup for Clerk, simply set `proxy_url` + to `null` for the domain. When you update a production instance's primary domain name, + you have to make sure that you've completed all the necessary setup steps for DNS and + emails to work. Expect downtime otherwise. Updating a primary domain's name will also + update the instance's home origin, affecting the default application paths. + + :param domain_id: The ID of the domain that will be updated. + :param name: The new domain name. For development instances, can contain the port, i.e `myhostname:3000`. For production instances, must be a valid FQDN, i.e `mysite.com`. Cannot contain protocol scheme. + :param proxy_url: The full URL of the proxy that will forward requests to Clerk's Frontend API. Can only be updated for production instances. + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.UpdateDomainRequest( + domain_id=domain_id, + request_body=models.UpdateDomainRequestBody( + name=name, + proxy_url=proxy_url, + ), + ) + + req = self.build_request( + method="PATCH", + path="/domains/{domain_id}", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=True, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + get_serialized_body=lambda: utils.serialize_request_body(request.request_body, False, False, "json", models.UpdateDomainRequestBody), + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="UpdateDomain", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","404","422","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.Domain]) + if utils.match_response(http_res, ["400","404","422"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + async def update_async( + self, *, + domain_id: str, + name: Optional[Nullable[str]] = None, + proxy_url: Optional[Nullable[str]] = None, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.Domain: + r"""Update a domain + + The `proxy_url` can be updated only for production instances. + Update one of the instance's domains. Both primary and satellite domains can be updated. + If you choose to use Clerk via proxy, use this endpoint to specify the `proxy_url`. + Whenever you decide you'd rather switch to DNS setup for Clerk, simply set `proxy_url` + to `null` for the domain. When you update a production instance's primary domain name, + you have to make sure that you've completed all the necessary setup steps for DNS and + emails to work. Expect downtime otherwise. Updating a primary domain's name will also + update the instance's home origin, affecting the default application paths. + + :param domain_id: The ID of the domain that will be updated. + :param name: The new domain name. For development instances, can contain the port, i.e `myhostname:3000`. For production instances, must be a valid FQDN, i.e `mysite.com`. Cannot contain protocol scheme. + :param proxy_url: The full URL of the proxy that will forward requests to Clerk's Frontend API. Can only be updated for production instances. + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.UpdateDomainRequest( + domain_id=domain_id, + request_body=models.UpdateDomainRequestBody( + name=name, + proxy_url=proxy_url, + ), + ) + + req = self.build_request( + method="PATCH", + path="/domains/{domain_id}", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=True, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + get_serialized_body=lambda: utils.serialize_request_body(request.request_body, False, False, "json", models.UpdateDomainRequestBody), + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="UpdateDomain", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","404","422","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.Domain]) + if utils.match_response(http_res, ["400","404","422"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + diff --git a/src/clerk/emailaddresses.py b/src/clerk/emailaddresses.py new file mode 100644 index 0000000..fcd1025 --- /dev/null +++ b/src/clerk/emailaddresses.py @@ -0,0 +1,665 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from .basesdk import BaseSDK +from clerk import models +from clerk._hooks import HookContext +from clerk.types import Nullable, UNSET +import clerk.utils as utils +from typing import Optional + +class EmailAddresses(BaseSDK): + + + def create( + self, *, + user_id: Optional[str] = None, + email_address: Optional[str] = None, + verified: Optional[Nullable[bool]] = None, + primary: Optional[Nullable[bool]] = None, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.EmailAddress: + r"""Create an email address + + Create a new email address + + :param user_id: The ID representing the user + :param email_address: The new email address. Must adhere to the RFC 5322 specification for email address format. + :param verified: When created, the email address will be marked as verified. + :param primary: Create this email address as the primary email address for the user. Default: false, unless it is the first email address. + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.CreateEmailAddressRequestBody( + user_id=user_id, + email_address=email_address, + verified=verified, + primary=primary, + ) + + req = self.build_request( + method="POST", + path="/email_addresses", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=False, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + get_serialized_body=lambda: utils.serialize_request_body(request, False, True, "json", Optional[models.CreateEmailAddressRequestBody]), + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="CreateEmailAddress", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","401","403","404","422","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.EmailAddress]) + if utils.match_response(http_res, ["400","401","403","404","422"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + async def create_async( + self, *, + user_id: Optional[str] = None, + email_address: Optional[str] = None, + verified: Optional[Nullable[bool]] = None, + primary: Optional[Nullable[bool]] = None, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.EmailAddress: + r"""Create an email address + + Create a new email address + + :param user_id: The ID representing the user + :param email_address: The new email address. Must adhere to the RFC 5322 specification for email address format. + :param verified: When created, the email address will be marked as verified. + :param primary: Create this email address as the primary email address for the user. Default: false, unless it is the first email address. + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.CreateEmailAddressRequestBody( + user_id=user_id, + email_address=email_address, + verified=verified, + primary=primary, + ) + + req = self.build_request( + method="POST", + path="/email_addresses", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=False, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + get_serialized_body=lambda: utils.serialize_request_body(request, False, True, "json", Optional[models.CreateEmailAddressRequestBody]), + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="CreateEmailAddress", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","401","403","404","422","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.EmailAddress]) + if utils.match_response(http_res, ["400","401","403","404","422"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + def get( + self, *, + email_address_id: str, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.EmailAddress: + r"""Retrieve an email address + + Returns the details of an email address. + + :param email_address_id: The ID of the email address to retrieve + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.GetEmailAddressRequest( + email_address_id=email_address_id, + ) + + req = self.build_request( + method="GET", + path="/email_addresses/{email_address_id}", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="GetEmailAddress", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","401","403","404","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.EmailAddress]) + if utils.match_response(http_res, ["400","401","403","404"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + async def get_async( + self, *, + email_address_id: str, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.EmailAddress: + r"""Retrieve an email address + + Returns the details of an email address. + + :param email_address_id: The ID of the email address to retrieve + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.GetEmailAddressRequest( + email_address_id=email_address_id, + ) + + req = self.build_request( + method="GET", + path="/email_addresses/{email_address_id}", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="GetEmailAddress", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","401","403","404","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.EmailAddress]) + if utils.match_response(http_res, ["400","401","403","404"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + def delete( + self, *, + email_address_id: str, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.DeletedObject: + r"""Delete an email address + + Delete the email address with the given ID + + :param email_address_id: The ID of the email address to delete + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.DeleteEmailAddressRequest( + email_address_id=email_address_id, + ) + + req = self.build_request( + method="DELETE", + path="/email_addresses/{email_address_id}", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="DeleteEmailAddress", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","401","403","404","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.DeletedObject]) + if utils.match_response(http_res, ["400","401","403","404"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + async def delete_async( + self, *, + email_address_id: str, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.DeletedObject: + r"""Delete an email address + + Delete the email address with the given ID + + :param email_address_id: The ID of the email address to delete + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.DeleteEmailAddressRequest( + email_address_id=email_address_id, + ) + + req = self.build_request( + method="DELETE", + path="/email_addresses/{email_address_id}", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="DeleteEmailAddress", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","401","403","404","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.DeletedObject]) + if utils.match_response(http_res, ["400","401","403","404"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + def update( + self, *, + email_address_id: str, + verified: Optional[Nullable[bool]] = None, + primary: Optional[Nullable[bool]] = None, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.EmailAddress: + r"""Update an email address + + Updates an email address. + + :param email_address_id: The ID of the email address to update + :param verified: The email address will be marked as verified. + :param primary: Set this email address as the primary email address for the user. + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.UpdateEmailAddressRequest( + email_address_id=email_address_id, + request_body=models.UpdateEmailAddressRequestBody( + verified=verified, + primary=primary, + ), + ) + + req = self.build_request( + method="PATCH", + path="/email_addresses/{email_address_id}", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + get_serialized_body=lambda: utils.serialize_request_body(request.request_body, False, True, "json", Optional[models.UpdateEmailAddressRequestBody]), + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="UpdateEmailAddress", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","401","403","404","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.EmailAddress]) + if utils.match_response(http_res, ["400","401","403","404"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + async def update_async( + self, *, + email_address_id: str, + verified: Optional[Nullable[bool]] = None, + primary: Optional[Nullable[bool]] = None, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.EmailAddress: + r"""Update an email address + + Updates an email address. + + :param email_address_id: The ID of the email address to update + :param verified: The email address will be marked as verified. + :param primary: Set this email address as the primary email address for the user. + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.UpdateEmailAddressRequest( + email_address_id=email_address_id, + request_body=models.UpdateEmailAddressRequestBody( + verified=verified, + primary=primary, + ), + ) + + req = self.build_request( + method="PATCH", + path="/email_addresses/{email_address_id}", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + get_serialized_body=lambda: utils.serialize_request_body(request.request_body, False, True, "json", Optional[models.UpdateEmailAddressRequestBody]), + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="UpdateEmailAddress", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","401","403","404","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.EmailAddress]) + if utils.match_response(http_res, ["400","401","403","404"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + diff --git a/src/clerk/httpclient.py b/src/clerk/httpclient.py new file mode 100644 index 0000000..985e31c --- /dev/null +++ b/src/clerk/httpclient.py @@ -0,0 +1,78 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +# pyright: reportReturnType = false +from typing_extensions import Protocol, runtime_checkable +import httpx +from typing import Any, Optional, Union + + +@runtime_checkable +class HttpClient(Protocol): + def send( + self, + request: httpx.Request, + *, + stream: bool = False, + auth: Union[ + httpx._types.AuthTypes, httpx._client.UseClientDefault, None + ] = httpx.USE_CLIENT_DEFAULT, + follow_redirects: Union[ + bool, httpx._client.UseClientDefault + ] = httpx.USE_CLIENT_DEFAULT, + ) -> httpx.Response: + pass + + def build_request( + self, + method: str, + url: httpx._types.URLTypes, + *, + content: Optional[httpx._types.RequestContent] = None, + data: Optional[httpx._types.RequestData] = None, + files: Optional[httpx._types.RequestFiles] = None, + json: Optional[Any] = None, + params: Optional[httpx._types.QueryParamTypes] = None, + headers: Optional[httpx._types.HeaderTypes] = None, + cookies: Optional[httpx._types.CookieTypes] = None, + timeout: Union[ + httpx._types.TimeoutTypes, httpx._client.UseClientDefault + ] = httpx.USE_CLIENT_DEFAULT, + extensions: Optional[httpx._types.RequestExtensions] = None, + ) -> httpx.Request: + pass + + +@runtime_checkable +class AsyncHttpClient(Protocol): + async def send( + self, + request: httpx.Request, + *, + stream: bool = False, + auth: Union[ + httpx._types.AuthTypes, httpx._client.UseClientDefault, None + ] = httpx.USE_CLIENT_DEFAULT, + follow_redirects: Union[ + bool, httpx._client.UseClientDefault + ] = httpx.USE_CLIENT_DEFAULT, + ) -> httpx.Response: + pass + + def build_request( + self, + method: str, + url: httpx._types.URLTypes, + *, + content: Optional[httpx._types.RequestContent] = None, + data: Optional[httpx._types.RequestData] = None, + files: Optional[httpx._types.RequestFiles] = None, + json: Optional[Any] = None, + params: Optional[httpx._types.QueryParamTypes] = None, + headers: Optional[httpx._types.HeaderTypes] = None, + cookies: Optional[httpx._types.CookieTypes] = None, + timeout: Union[ + httpx._types.TimeoutTypes, httpx._client.UseClientDefault + ] = httpx.USE_CLIENT_DEFAULT, + extensions: Optional[httpx._types.RequestExtensions] = None, + ) -> httpx.Request: + pass diff --git a/src/clerk/instancesettings_sdk.py b/src/clerk/instancesettings_sdk.py new file mode 100644 index 0000000..4331f5c --- /dev/null +++ b/src/clerk/instancesettings_sdk.py @@ -0,0 +1,587 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from .basesdk import BaseSDK +from clerk import models +from clerk._hooks import HookContext +from clerk.types import Nullable, UNSET +import clerk.utils as utils +from typing import List, Optional + +class InstanceSettingsSDK(BaseSDK): + + + def update( + self, *, + test_mode: Optional[Nullable[bool]] = None, + hibp: Optional[Nullable[bool]] = None, + enhanced_email_deliverability: Optional[Nullable[bool]] = None, + support_email: Optional[Nullable[str]] = None, + clerk_js_version: Optional[Nullable[str]] = None, + development_origin: Optional[Nullable[str]] = None, + allowed_origins: Optional[List[str]] = None, + cookieless_dev: Optional[bool] = None, + url_based_session_syncing: Optional[bool] = None, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ): + r"""Update instance settings + + Updates the settings of an instance + + :param test_mode: Toggles test mode for this instance, allowing the use of test email addresses and phone numbers. Defaults to true for development instances. + :param hibp: Whether the instance should be using the HIBP service to check passwords for breaches + :param enhanced_email_deliverability: The \"enhanced_email_deliverability\" feature will send emails from \"verifications@clerk.dev\" instead of your domain. This can be helpful if you do not have a high domain reputation. + :param support_email: + :param clerk_js_version: + :param development_origin: + :param allowed_origins: For browser-like stacks such as browser extensions, Electron, or Capacitor.js the instance allowed origins need to be updated with the request origin value. For Chrome extensions popup, background, or service worker pages the origin is chrome-extension://extension_uiid. For Electron apps the default origin is http://localhost:3000. For Capacitor, the origin is capacitor://localhost. + :param cookieless_dev: Whether the instance should operate in cookieless development mode (i.e. without third-party cookies). Deprecated: Please use `url_based_session_syncing` instead. + :param url_based_session_syncing: Whether the instance should use URL-based session syncing in development mode (i.e. without third-party cookies). + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.UpdateInstanceRequestBody( + test_mode=test_mode, + hibp=hibp, + enhanced_email_deliverability=enhanced_email_deliverability, + support_email=support_email, + clerk_js_version=clerk_js_version, + development_origin=development_origin, + allowed_origins=allowed_origins, + cookieless_dev=cookieless_dev, + url_based_session_syncing=url_based_session_syncing, + ) + + req = self.build_request( + method="PATCH", + path="/instance", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=False, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + get_serialized_body=lambda: utils.serialize_request_body(request, False, True, "json", Optional[models.UpdateInstanceRequestBody]), + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="UpdateInstance", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["422","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "204", "*"): + return + if utils.match_response(http_res, "422", "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + async def update_async( + self, *, + test_mode: Optional[Nullable[bool]] = None, + hibp: Optional[Nullable[bool]] = None, + enhanced_email_deliverability: Optional[Nullable[bool]] = None, + support_email: Optional[Nullable[str]] = None, + clerk_js_version: Optional[Nullable[str]] = None, + development_origin: Optional[Nullable[str]] = None, + allowed_origins: Optional[List[str]] = None, + cookieless_dev: Optional[bool] = None, + url_based_session_syncing: Optional[bool] = None, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ): + r"""Update instance settings + + Updates the settings of an instance + + :param test_mode: Toggles test mode for this instance, allowing the use of test email addresses and phone numbers. Defaults to true for development instances. + :param hibp: Whether the instance should be using the HIBP service to check passwords for breaches + :param enhanced_email_deliverability: The \"enhanced_email_deliverability\" feature will send emails from \"verifications@clerk.dev\" instead of your domain. This can be helpful if you do not have a high domain reputation. + :param support_email: + :param clerk_js_version: + :param development_origin: + :param allowed_origins: For browser-like stacks such as browser extensions, Electron, or Capacitor.js the instance allowed origins need to be updated with the request origin value. For Chrome extensions popup, background, or service worker pages the origin is chrome-extension://extension_uiid. For Electron apps the default origin is http://localhost:3000. For Capacitor, the origin is capacitor://localhost. + :param cookieless_dev: Whether the instance should operate in cookieless development mode (i.e. without third-party cookies). Deprecated: Please use `url_based_session_syncing` instead. + :param url_based_session_syncing: Whether the instance should use URL-based session syncing in development mode (i.e. without third-party cookies). + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.UpdateInstanceRequestBody( + test_mode=test_mode, + hibp=hibp, + enhanced_email_deliverability=enhanced_email_deliverability, + support_email=support_email, + clerk_js_version=clerk_js_version, + development_origin=development_origin, + allowed_origins=allowed_origins, + cookieless_dev=cookieless_dev, + url_based_session_syncing=url_based_session_syncing, + ) + + req = self.build_request( + method="PATCH", + path="/instance", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=False, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + get_serialized_body=lambda: utils.serialize_request_body(request, False, True, "json", Optional[models.UpdateInstanceRequestBody]), + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="UpdateInstance", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["422","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "204", "*"): + return + if utils.match_response(http_res, "422", "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + def update_restrictions( + self, *, + allowlist: Optional[Nullable[bool]] = None, + blocklist: Optional[Nullable[bool]] = None, + block_email_subaddresses: Optional[Nullable[bool]] = None, + block_disposable_email_domains: Optional[Nullable[bool]] = None, + ignore_dots_for_gmail_addresses: Optional[Nullable[bool]] = None, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.InstanceRestrictions: + r"""Update instance restrictions + + Updates the restriction settings of an instance + + :param allowlist: + :param blocklist: + :param block_email_subaddresses: + :param block_disposable_email_domains: + :param ignore_dots_for_gmail_addresses: + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.UpdateInstanceRestrictionsRequestBody( + allowlist=allowlist, + blocklist=blocklist, + block_email_subaddresses=block_email_subaddresses, + block_disposable_email_domains=block_disposable_email_domains, + ignore_dots_for_gmail_addresses=ignore_dots_for_gmail_addresses, + ) + + req = self.build_request( + method="PATCH", + path="/instance/restrictions", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=False, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + get_serialized_body=lambda: utils.serialize_request_body(request, False, True, "json", Optional[models.UpdateInstanceRestrictionsRequestBody]), + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="UpdateInstanceRestrictions", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["402","422","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.InstanceRestrictions]) + if utils.match_response(http_res, ["402","422"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + async def update_restrictions_async( + self, *, + allowlist: Optional[Nullable[bool]] = None, + blocklist: Optional[Nullable[bool]] = None, + block_email_subaddresses: Optional[Nullable[bool]] = None, + block_disposable_email_domains: Optional[Nullable[bool]] = None, + ignore_dots_for_gmail_addresses: Optional[Nullable[bool]] = None, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.InstanceRestrictions: + r"""Update instance restrictions + + Updates the restriction settings of an instance + + :param allowlist: + :param blocklist: + :param block_email_subaddresses: + :param block_disposable_email_domains: + :param ignore_dots_for_gmail_addresses: + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.UpdateInstanceRestrictionsRequestBody( + allowlist=allowlist, + blocklist=blocklist, + block_email_subaddresses=block_email_subaddresses, + block_disposable_email_domains=block_disposable_email_domains, + ignore_dots_for_gmail_addresses=ignore_dots_for_gmail_addresses, + ) + + req = self.build_request( + method="PATCH", + path="/instance/restrictions", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=False, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + get_serialized_body=lambda: utils.serialize_request_body(request, False, True, "json", Optional[models.UpdateInstanceRestrictionsRequestBody]), + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="UpdateInstanceRestrictions", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["402","422","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.InstanceRestrictions]) + if utils.match_response(http_res, ["402","422"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + def update_organization_settings( + self, *, + enabled: Optional[Nullable[bool]] = None, + max_allowed_memberships: Optional[Nullable[int]] = None, + admin_delete_enabled: Optional[Nullable[bool]] = None, + domains_enabled: Optional[Nullable[bool]] = None, + domains_enrollment_modes: Optional[List[str]] = None, + creator_role_id: Optional[str] = None, + domains_default_role_id: Optional[str] = None, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.OrganizationSettings: + r"""Update instance organization settings + + Updates the organization settings of the instance + + :param enabled: + :param max_allowed_memberships: + :param admin_delete_enabled: + :param domains_enabled: + :param domains_enrollment_modes: Specify which enrollment modes to enable for your Organization Domains. Supported modes are 'automatic_invitation' & 'automatic_suggestion'. + :param creator_role_id: Specify what the default organization role is for an organization creator. + :param domains_default_role_id: Specify what the default organization role is for the organization domains. + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.UpdateInstanceOrganizationSettingsRequestBody( + enabled=enabled, + max_allowed_memberships=max_allowed_memberships, + admin_delete_enabled=admin_delete_enabled, + domains_enabled=domains_enabled, + domains_enrollment_modes=domains_enrollment_modes, + creator_role_id=creator_role_id, + domains_default_role_id=domains_default_role_id, + ) + + req = self.build_request( + method="PATCH", + path="/instance/organization_settings", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=False, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + get_serialized_body=lambda: utils.serialize_request_body(request, False, True, "json", Optional[models.UpdateInstanceOrganizationSettingsRequestBody]), + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="UpdateInstanceOrganizationSettings", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["402","404","422","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.OrganizationSettings]) + if utils.match_response(http_res, ["402","404","422"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + async def update_organization_settings_async( + self, *, + enabled: Optional[Nullable[bool]] = None, + max_allowed_memberships: Optional[Nullable[int]] = None, + admin_delete_enabled: Optional[Nullable[bool]] = None, + domains_enabled: Optional[Nullable[bool]] = None, + domains_enrollment_modes: Optional[List[str]] = None, + creator_role_id: Optional[str] = None, + domains_default_role_id: Optional[str] = None, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.OrganizationSettings: + r"""Update instance organization settings + + Updates the organization settings of the instance + + :param enabled: + :param max_allowed_memberships: + :param admin_delete_enabled: + :param domains_enabled: + :param domains_enrollment_modes: Specify which enrollment modes to enable for your Organization Domains. Supported modes are 'automatic_invitation' & 'automatic_suggestion'. + :param creator_role_id: Specify what the default organization role is for an organization creator. + :param domains_default_role_id: Specify what the default organization role is for the organization domains. + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.UpdateInstanceOrganizationSettingsRequestBody( + enabled=enabled, + max_allowed_memberships=max_allowed_memberships, + admin_delete_enabled=admin_delete_enabled, + domains_enabled=domains_enabled, + domains_enrollment_modes=domains_enrollment_modes, + creator_role_id=creator_role_id, + domains_default_role_id=domains_default_role_id, + ) + + req = self.build_request( + method="PATCH", + path="/instance/organization_settings", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=False, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + get_serialized_body=lambda: utils.serialize_request_body(request, False, True, "json", Optional[models.UpdateInstanceOrganizationSettingsRequestBody]), + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="UpdateInstanceOrganizationSettings", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["402","404","422","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.OrganizationSettings]) + if utils.match_response(http_res, ["402","404","422"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + diff --git a/src/clerk/invitations.py b/src/clerk/invitations.py new file mode 100644 index 0000000..f42e94a --- /dev/null +++ b/src/clerk/invitations.py @@ -0,0 +1,564 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from .basesdk import BaseSDK +from clerk import models +from clerk._hooks import HookContext +from clerk.types import BaseModel, Nullable, UNSET +import clerk.utils as utils +from jsonpath import JSONPath +from typing import Any, Dict, List, Optional, Union + +class Invitations(BaseSDK): + + + def create( + self, *, + email_address: str, + public_metadata: Optional[Union[models.CreateInvitationPublicMetadata, models.CreateInvitationPublicMetadataTypedDict]] = None, + redirect_url: Optional[str] = None, + notify: Optional[Nullable[bool]] = None, + ignore_existing: Optional[Nullable[bool]] = None, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.Invitation: + r"""Create an invitation + + Creates a new invitation for the given email address and sends the invitation email. + Keep in mind that you cannot create an invitation if there is already one for the given email address. + Also, trying to create an invitation for an email address that already exists in your application will result to an error. + + :param email_address: The email address the invitation will be sent to + :param public_metadata: Metadata that will be attached to the newly created invitation. The value of this property should be a well-formed JSON object. Once the user accepts the invitation and signs up, these metadata will end up in the user's public metadata. + :param redirect_url: Optional URL which specifies where to redirect the user once they click the invitation link. This is only required if you have implemented a [custom flow](https://clerk.com/docs/authentication/invitations#custom-flow) and you're not using Clerk Hosted Pages or Clerk Components. + :param notify: Optional flag which denotes whether an email invitation should be sent to the given email address. Defaults to true. + :param ignore_existing: Whether an invitation should be created if there is already an existing invitation for this email address, or it's claimed by another user. + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.CreateInvitationRequestBody( + email_address=email_address, + public_metadata=utils.unmarshal(public_metadata, models.CreateInvitationPublicMetadata) if not isinstance(public_metadata, BaseModel) and public_metadata is not None else public_metadata, + redirect_url=redirect_url, + notify=notify, + ignore_existing=ignore_existing, + ) + + req = self.build_request( + method="POST", + path="/invitations", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=False, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + get_serialized_body=lambda: utils.serialize_request_body(request, False, True, "json", Optional[models.CreateInvitationRequestBody]), + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="CreateInvitation", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","422","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.Invitation]) + if utils.match_response(http_res, ["400","422"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + async def create_async( + self, *, + email_address: str, + public_metadata: Optional[Union[models.CreateInvitationPublicMetadata, models.CreateInvitationPublicMetadataTypedDict]] = None, + redirect_url: Optional[str] = None, + notify: Optional[Nullable[bool]] = None, + ignore_existing: Optional[Nullable[bool]] = None, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.Invitation: + r"""Create an invitation + + Creates a new invitation for the given email address and sends the invitation email. + Keep in mind that you cannot create an invitation if there is already one for the given email address. + Also, trying to create an invitation for an email address that already exists in your application will result to an error. + + :param email_address: The email address the invitation will be sent to + :param public_metadata: Metadata that will be attached to the newly created invitation. The value of this property should be a well-formed JSON object. Once the user accepts the invitation and signs up, these metadata will end up in the user's public metadata. + :param redirect_url: Optional URL which specifies where to redirect the user once they click the invitation link. This is only required if you have implemented a [custom flow](https://clerk.com/docs/authentication/invitations#custom-flow) and you're not using Clerk Hosted Pages or Clerk Components. + :param notify: Optional flag which denotes whether an email invitation should be sent to the given email address. Defaults to true. + :param ignore_existing: Whether an invitation should be created if there is already an existing invitation for this email address, or it's claimed by another user. + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.CreateInvitationRequestBody( + email_address=email_address, + public_metadata=utils.unmarshal(public_metadata, models.CreateInvitationPublicMetadata) if not isinstance(public_metadata, BaseModel) and public_metadata is not None else public_metadata, + redirect_url=redirect_url, + notify=notify, + ignore_existing=ignore_existing, + ) + + req = self.build_request( + method="POST", + path="/invitations", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=False, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + get_serialized_body=lambda: utils.serialize_request_body(request, False, True, "json", Optional[models.CreateInvitationRequestBody]), + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="CreateInvitation", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","422","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.Invitation]) + if utils.match_response(http_res, ["400","422"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + def list( + self, *, + limit: Optional[float] = None, + offset: Optional[float] = None, + status: Optional[models.ListInvitationsQueryParamStatus] = None, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.ListInvitationsResponse: + r"""List all invitations + + Returns all non-revoked invitations for your application, sorted by creation date + + :param limit: Applies a limit to the number of results returned. Can be used for paginating the results together with `offset`. + :param offset: Skip the first `offset` results when paginating. Needs to be an integer greater or equal to zero. To be used in conjunction with `limit`. + :param status: Filter invitations based on their status + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.ListInvitationsRequest( + limit=limit, + offset=offset, + status=status, + ) + + req = self.build_request( + method="GET", + path="/invitations", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=False, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="ListInvitations", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["4XX","5XX"], + retry_config=retry_config + ) + + def next_func() -> Optional[models.ListInvitationsResponse]: + body = utils.unmarshal_json(http_res.text, Dict[Any, Any]) + offset = request.offset if not request.offset is None else 0 + + if not http_res.text: + return None + results = JSONPath("$").parse(body) + if len(results) == 0 or len(results[0]) == 0: + return None + limit = request.limit if not request.limit is None else 0 + if len(results[0]) < limit: + return None + next_offset = offset + len(results[0]) + + return self.list( + limit=limit, + offset=next_offset, + status=status, + retries=retries, + ) + + res = models.ListInvitationsResponse(result=None, next=next_func) + + if utils.match_response(http_res, "200", "application/json"): + res.result = utils.unmarshal_json(http_res.text, Optional[List[models.Invitation]]) + elif utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + else: + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + return res + + + async def list_async( + self, *, + limit: Optional[float] = None, + offset: Optional[float] = None, + status: Optional[models.ListInvitationsQueryParamStatus] = None, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.ListInvitationsResponse: + r"""List all invitations + + Returns all non-revoked invitations for your application, sorted by creation date + + :param limit: Applies a limit to the number of results returned. Can be used for paginating the results together with `offset`. + :param offset: Skip the first `offset` results when paginating. Needs to be an integer greater or equal to zero. To be used in conjunction with `limit`. + :param status: Filter invitations based on their status + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.ListInvitationsRequest( + limit=limit, + offset=offset, + status=status, + ) + + req = self.build_request( + method="GET", + path="/invitations", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=False, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="ListInvitations", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["4XX","5XX"], + retry_config=retry_config + ) + + def next_func() -> Optional[models.ListInvitationsResponse]: + body = utils.unmarshal_json(http_res.text, Dict[Any, Any]) + offset = request.offset if not request.offset is None else 0 + + if not http_res.text: + return None + results = JSONPath("$").parse(body) + if len(results) == 0 or len(results[0]) == 0: + return None + limit = request.limit if not request.limit is None else 0 + if len(results[0]) < limit: + return None + next_offset = offset + len(results[0]) + + return self.list( + limit=limit, + offset=next_offset, + status=status, + retries=retries, + ) + + res = models.ListInvitationsResponse(result=None, next=next_func) + + if utils.match_response(http_res, "200", "application/json"): + res.result = utils.unmarshal_json(http_res.text, Optional[List[models.Invitation]]) + elif utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + else: + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + return res + + + def revoke( + self, *, + invitation_id: str, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.InvitationRevoked: + r"""Revokes an invitation + + Revokes the given invitation. + Revoking an invitation will prevent the user from using the invitation link that was sent to them. + However, it doesn't prevent the user from signing up if they follow the sign up flow. + Only active (i.e. non-revoked) invitations can be revoked. + + :param invitation_id: The ID of the invitation to be revoked + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.RevokeInvitationRequest( + invitation_id=invitation_id, + ) + + req = self.build_request( + method="POST", + path="/invitations/{invitation_id}/revoke", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="RevokeInvitation", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","404","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.InvitationRevoked]) + if utils.match_response(http_res, ["400","404"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + async def revoke_async( + self, *, + invitation_id: str, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.InvitationRevoked: + r"""Revokes an invitation + + Revokes the given invitation. + Revoking an invitation will prevent the user from using the invitation link that was sent to them. + However, it doesn't prevent the user from signing up if they follow the sign up flow. + Only active (i.e. non-revoked) invitations can be revoked. + + :param invitation_id: The ID of the invitation to be revoked + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.RevokeInvitationRequest( + invitation_id=invitation_id, + ) + + req = self.build_request( + method="POST", + path="/invitations/{invitation_id}/revoke", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="RevokeInvitation", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","404","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.InvitationRevoked]) + if utils.match_response(http_res, ["400","404"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + diff --git a/src/clerk/jwks.py b/src/clerk/jwks.py new file mode 100644 index 0000000..7474ca1 --- /dev/null +++ b/src/clerk/jwks.py @@ -0,0 +1,145 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from .basesdk import BaseSDK +from clerk import models +from clerk._hooks import HookContext +from clerk.types import Nullable, UNSET +import clerk.utils as utils +from typing import Optional + +class Jwks(BaseSDK): + + + def get( + self, *, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ): + r"""Retrieve the JSON Web Key Set of the instance + + Retrieve the JSON Web Key Set of the instance + + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + req = self.build_request( + method="GET", + path="/jwks", + base_url=base_url, + url_variables=url_variables, + request=None, + request_body_required=False, + request_has_path_params=False, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="*/*", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="GetJWKS", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "*"): + return + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + async def get_async( + self, *, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ): + r"""Retrieve the JSON Web Key Set of the instance + + Retrieve the JSON Web Key Set of the instance + + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + req = self.build_request( + method="GET", + path="/jwks", + base_url=base_url, + url_variables=url_variables, + request=None, + request_body_required=False, + request_has_path_params=False, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="*/*", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="GetJWKS", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "*"): + return + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + diff --git a/src/clerk/jwttemplates.py b/src/clerk/jwttemplates.py new file mode 100644 index 0000000..2822865 --- /dev/null +++ b/src/clerk/jwttemplates.py @@ -0,0 +1,839 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from .basesdk import BaseSDK +from clerk import models +from clerk._hooks import HookContext +from clerk.types import BaseModel, Nullable, UNSET +import clerk.utils as utils +from typing import List, Optional, Union + +class JwtTemplates(BaseSDK): + + + def list( + self, *, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> List[models.JWTTemplate]: + r"""List all templates + + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + req = self.build_request( + method="GET", + path="/jwt_templates", + base_url=base_url, + url_variables=url_variables, + request=None, + request_body_required=False, + request_has_path_params=False, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="ListJWTTemplates", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[List[models.JWTTemplate]]) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + async def list_async( + self, *, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> List[models.JWTTemplate]: + r"""List all templates + + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + req = self.build_request( + method="GET", + path="/jwt_templates", + base_url=base_url, + url_variables=url_variables, + request=None, + request_body_required=False, + request_has_path_params=False, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="ListJWTTemplates", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[List[models.JWTTemplate]]) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + def create( + self, *, + name: Optional[str] = None, + claims: Optional[Union[models.CreateJWTTemplateClaims, models.CreateJWTTemplateClaimsTypedDict]] = None, + lifetime: Optional[Nullable[float]] = None, + allowed_clock_skew: Optional[Nullable[float]] = None, + custom_signing_key: Optional[bool] = None, + signing_algorithm: Optional[Nullable[str]] = None, + signing_key: Optional[Nullable[str]] = None, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.JWTTemplate: + r"""Create a JWT template + + Create a new JWT template + + :param name: JWT template name + :param claims: JWT template claims in JSON format + :param lifetime: JWT token lifetime + :param allowed_clock_skew: JWT token allowed clock skew + :param custom_signing_key: Whether a custom signing key/algorithm is also provided for this template + :param signing_algorithm: The custom signing algorithm to use when minting JWTs + :param signing_key: The custom signing private key to use when minting JWTs + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.CreateJWTTemplateRequestBody( + name=name, + claims=utils.unmarshal(claims, models.CreateJWTTemplateClaims) if not isinstance(claims, BaseModel) and claims is not None else claims, + lifetime=lifetime, + allowed_clock_skew=allowed_clock_skew, + custom_signing_key=custom_signing_key, + signing_algorithm=signing_algorithm, + signing_key=signing_key, + ) + + req = self.build_request( + method="POST", + path="/jwt_templates", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=False, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + get_serialized_body=lambda: utils.serialize_request_body(request, False, True, "json", Optional[models.CreateJWTTemplateRequestBody]), + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="CreateJWTTemplate", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","402","422","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.JWTTemplate]) + if utils.match_response(http_res, ["400","402","422"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + async def create_async( + self, *, + name: Optional[str] = None, + claims: Optional[Union[models.CreateJWTTemplateClaims, models.CreateJWTTemplateClaimsTypedDict]] = None, + lifetime: Optional[Nullable[float]] = None, + allowed_clock_skew: Optional[Nullable[float]] = None, + custom_signing_key: Optional[bool] = None, + signing_algorithm: Optional[Nullable[str]] = None, + signing_key: Optional[Nullable[str]] = None, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.JWTTemplate: + r"""Create a JWT template + + Create a new JWT template + + :param name: JWT template name + :param claims: JWT template claims in JSON format + :param lifetime: JWT token lifetime + :param allowed_clock_skew: JWT token allowed clock skew + :param custom_signing_key: Whether a custom signing key/algorithm is also provided for this template + :param signing_algorithm: The custom signing algorithm to use when minting JWTs + :param signing_key: The custom signing private key to use when minting JWTs + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.CreateJWTTemplateRequestBody( + name=name, + claims=utils.unmarshal(claims, models.CreateJWTTemplateClaims) if not isinstance(claims, BaseModel) and claims is not None else claims, + lifetime=lifetime, + allowed_clock_skew=allowed_clock_skew, + custom_signing_key=custom_signing_key, + signing_algorithm=signing_algorithm, + signing_key=signing_key, + ) + + req = self.build_request( + method="POST", + path="/jwt_templates", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=False, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + get_serialized_body=lambda: utils.serialize_request_body(request, False, True, "json", Optional[models.CreateJWTTemplateRequestBody]), + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="CreateJWTTemplate", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","402","422","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.JWTTemplate]) + if utils.match_response(http_res, ["400","402","422"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + def get( + self, *, + template_id: str, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.JWTTemplate: + r"""Retrieve a template + + Retrieve the details of a given JWT template + + :param template_id: JWT Template ID + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.GetJWTTemplateRequest( + template_id=template_id, + ) + + req = self.build_request( + method="GET", + path="/jwt_templates/{template_id}", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="GetJWTTemplate", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["404","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.JWTTemplate]) + if utils.match_response(http_res, "404", "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + async def get_async( + self, *, + template_id: str, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.JWTTemplate: + r"""Retrieve a template + + Retrieve the details of a given JWT template + + :param template_id: JWT Template ID + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.GetJWTTemplateRequest( + template_id=template_id, + ) + + req = self.build_request( + method="GET", + path="/jwt_templates/{template_id}", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="GetJWTTemplate", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["404","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.JWTTemplate]) + if utils.match_response(http_res, "404", "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + def update( + self, *, + template_id: str, + name: Optional[str] = None, + claims: Optional[Union[models.UpdateJWTTemplateClaims, models.UpdateJWTTemplateClaimsTypedDict]] = None, + lifetime: Optional[Nullable[float]] = None, + allowed_clock_skew: Optional[Nullable[float]] = None, + custom_signing_key: Optional[bool] = None, + signing_algorithm: Optional[Nullable[str]] = None, + signing_key: Optional[Nullable[str]] = None, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.JWTTemplate: + r"""Update a JWT template + + Updates an existing JWT template + + :param template_id: The ID of the JWT template to update + :param name: JWT template name + :param claims: JWT template claims in JSON format + :param lifetime: JWT token lifetime + :param allowed_clock_skew: JWT token allowed clock skew + :param custom_signing_key: Whether a custom signing key/algorithm is also provided for this template + :param signing_algorithm: The custom signing algorithm to use when minting JWTs + :param signing_key: The custom signing private key to use when minting JWTs + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.UpdateJWTTemplateRequest( + template_id=template_id, + request_body=models.UpdateJWTTemplateRequestBody( + name=name, + claims=utils.unmarshal(claims, models.UpdateJWTTemplateClaims) if not isinstance(claims, BaseModel) and claims is not None else claims, + lifetime=lifetime, + allowed_clock_skew=allowed_clock_skew, + custom_signing_key=custom_signing_key, + signing_algorithm=signing_algorithm, + signing_key=signing_key, + ), + ) + + req = self.build_request( + method="PATCH", + path="/jwt_templates/{template_id}", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + get_serialized_body=lambda: utils.serialize_request_body(request.request_body, False, True, "json", Optional[models.UpdateJWTTemplateRequestBody]), + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="UpdateJWTTemplate", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","402","422","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.JWTTemplate]) + if utils.match_response(http_res, ["400","402","422"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + async def update_async( + self, *, + template_id: str, + name: Optional[str] = None, + claims: Optional[Union[models.UpdateJWTTemplateClaims, models.UpdateJWTTemplateClaimsTypedDict]] = None, + lifetime: Optional[Nullable[float]] = None, + allowed_clock_skew: Optional[Nullable[float]] = None, + custom_signing_key: Optional[bool] = None, + signing_algorithm: Optional[Nullable[str]] = None, + signing_key: Optional[Nullable[str]] = None, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.JWTTemplate: + r"""Update a JWT template + + Updates an existing JWT template + + :param template_id: The ID of the JWT template to update + :param name: JWT template name + :param claims: JWT template claims in JSON format + :param lifetime: JWT token lifetime + :param allowed_clock_skew: JWT token allowed clock skew + :param custom_signing_key: Whether a custom signing key/algorithm is also provided for this template + :param signing_algorithm: The custom signing algorithm to use when minting JWTs + :param signing_key: The custom signing private key to use when minting JWTs + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.UpdateJWTTemplateRequest( + template_id=template_id, + request_body=models.UpdateJWTTemplateRequestBody( + name=name, + claims=utils.unmarshal(claims, models.UpdateJWTTemplateClaims) if not isinstance(claims, BaseModel) and claims is not None else claims, + lifetime=lifetime, + allowed_clock_skew=allowed_clock_skew, + custom_signing_key=custom_signing_key, + signing_algorithm=signing_algorithm, + signing_key=signing_key, + ), + ) + + req = self.build_request( + method="PATCH", + path="/jwt_templates/{template_id}", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + get_serialized_body=lambda: utils.serialize_request_body(request.request_body, False, True, "json", Optional[models.UpdateJWTTemplateRequestBody]), + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="UpdateJWTTemplate", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","402","422","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.JWTTemplate]) + if utils.match_response(http_res, ["400","402","422"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + def delete( + self, *, + template_id: str, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.DeletedObject: + r"""Delete a Template + + :param template_id: JWT Template ID + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.DeleteJWTTemplateRequest( + template_id=template_id, + ) + + req = self.build_request( + method="DELETE", + path="/jwt_templates/{template_id}", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="DeleteJWTTemplate", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["403","404","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.DeletedObject]) + if utils.match_response(http_res, ["403","404"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + async def delete_async( + self, *, + template_id: str, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.DeletedObject: + r"""Delete a Template + + :param template_id: JWT Template ID + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.DeleteJWTTemplateRequest( + template_id=template_id, + ) + + req = self.build_request( + method="DELETE", + path="/jwt_templates/{template_id}", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="DeleteJWTTemplate", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["403","404","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.DeletedObject]) + if utils.match_response(http_res, ["403","404"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + diff --git a/src/clerk/misc.py b/src/clerk/misc.py new file mode 100644 index 0000000..e8a2263 --- /dev/null +++ b/src/clerk/misc.py @@ -0,0 +1,165 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from .basesdk import BaseSDK +from clerk import models +from clerk._hooks import HookContext +from clerk.types import Nullable, UNSET +import clerk.utils as utils +from typing import Optional + +class Misc(BaseSDK): + + + def get_public_interstitial( + self, *, + frontend_api: Optional[str] = None, + publishable_key: Optional[str] = None, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ): + r"""Returns the markup for the interstitial page + + The Clerk interstitial endpoint serves an html page that loads clerk.js in order to check the user's authentication state. + It is used by Clerk SDKs when the user's authentication state cannot be immediately determined. + + :param frontend_api: The Frontend API key of your instance + :param publishable_key: The publishable key of your instance + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.GetPublicInterstitialRequest( + frontend_api=frontend_api, + publishable_key=publishable_key, + ) + + req = self.build_request( + method="GET", + path="/public/interstitial", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=False, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="*/*", + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="GetPublicInterstitial", oauth2_scopes=[], security_source=None), + request=req, + error_status_codes=["400","4XX","500","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "*"): + return + if utils.match_response(http_res, ["400","4XX","500","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + async def get_public_interstitial_async( + self, *, + frontend_api: Optional[str] = None, + publishable_key: Optional[str] = None, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ): + r"""Returns the markup for the interstitial page + + The Clerk interstitial endpoint serves an html page that loads clerk.js in order to check the user's authentication state. + It is used by Clerk SDKs when the user's authentication state cannot be immediately determined. + + :param frontend_api: The Frontend API key of your instance + :param publishable_key: The publishable key of your instance + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.GetPublicInterstitialRequest( + frontend_api=frontend_api, + publishable_key=publishable_key, + ) + + req = self.build_request( + method="GET", + path="/public/interstitial", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=False, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="*/*", + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="GetPublicInterstitial", oauth2_scopes=[], security_source=None), + request=req, + error_status_codes=["400","4XX","500","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "*"): + return + if utils.match_response(http_res, ["400","4XX","500","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + diff --git a/src/clerk/models/__init__.py b/src/clerk/models/__init__.py new file mode 100644 index 0000000..55dfc04 --- /dev/null +++ b/src/clerk/models/__init__.py @@ -0,0 +1,151 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from .actortoken import * +from .adddomainop import * +from .allowlistidentifier import * +from .banuserop import * +from .blocklistidentifier import * +from .blocklistidentifiers import * +from .changeproductioninstancedomainop import * +from .clerkerror import * +from .clerkerrors import * +from .client import * +from .cnametarget import * +from .createactortokenop import * +from .createallowlistidentifierop import * +from .createblocklistidentifierop import * +from .createemailaddressop import * +from .createinvitationop import * +from .createjwttemplateop import * +from .createoauthapplicationop import * +from .createorganizationinvitationbulkop import * +from .createorganizationinvitationop import * +from .createorganizationmembershipop import * +from .createorganizationop import * +from .createphonenumberop import * +from .createredirecturlop import * +from .createsamlconnectionop import * +from .createsessiontokenfromtemplateop import * +from .createsignintokenop import * +from .createuserop import * +from .deleteallowlistidentifierop import * +from .deleteblocklistidentifierop import * +from .deletedobject import * +from .deletedomainop import * +from .deleteemailaddressop import * +from .deletejwttemplateop import * +from .deleteoauthapplicationop import * +from .deleteorganizationlogoop import * +from .deleteorganizationmembershipop import * +from .deleteorganizationop import * +from .deletephonenumberop import * +from .deleteredirecturlop import * +from .deletesamlconnectionop import * +from .deleteuserop import * +from .deleteuserprofileimageop import * +from .disablemfaop import * +from .domain import * +from .domains import * +from .emailaddress import * +from .getclientlistop import * +from .getclientop import * +from .getemailaddressop import * +from .getjwttemplateop import * +from .getoauthaccesstokenop import * +from .getoauthapplicationop import * +from .getorganizationinvitationop import * +from .getorganizationop import * +from .getphonenumberop import * +from .getpublicinterstitialop import * +from .getredirecturlop import * +from .getsamlconnectionop import * +from .getsessionlistop import * +from .getsessionop import * +from .gettemplatelistop import * +from .gettemplateop import * +from .getuserlistop import * +from .getuserop import * +from .getuserscountop import * +from .identificationlink import * +from .instancerestrictions import * +from .instancesettings import * +from .invitation import * +from .invitation_revoked import * +from .jwttemplate import * +from .listinvitationsop import * +from .listoauthapplicationsop import * +from .listorganizationinvitationsop import * +from .listorganizationmembershipsop import * +from .listorganizationsop import * +from .listpendingorganizationinvitationsop import * +from .listsamlconnectionsop import * +from .lockuserop import * +from .mergeorganizationmetadataop import * +from .oauthapplication import * +from .oauthapplications import * +from .oauthapplicationwithsecret import * +from .organization import * +from .organizationinvitation import * +from .organizationinvitations import * +from .organizationmembership import * +from .organizationmemberships import * +from .organizations import * +from .organizationsettings import * +from .organizationwithlogo import * +from .phonenumber import * +from .previewtemplateop import * +from .proxycheck import * +from .redirecturl import * +from .reverttemplateop import * +from .revokeactortokenop import * +from .revokeinvitationop import * +from .revokeorganizationinvitationop import * +from .revokesessionop import * +from .revokesignintokenop import * +from .rotateoauthapplicationsecretop import * +from .samlaccount import * +from .samlconnection import * +from .samlconnections import * +from .schemas_passkey import * +from .sdkerror import * +from .security import * +from .session import * +from .setuserprofileimageop import * +from .signintoken import * +from .signup import * +from .svixurl import * +from .template import * +from .testingtoken import * +from .toggletemplatedeliveryop import * +from .totalcount import * +from .unbanuserop import * +from .unlockuserop import * +from .updatedomainop import * +from .updateemailaddressop import * +from .updateinstanceauthconfigop import * +from .updateinstanceop import * +from .updateinstanceorganizationsettingsop import * +from .updateinstancerestrictionsop import * +from .updatejwttemplateop import * +from .updateoauthapplicationop import * +from .updateorganizationmembershipmetadataop import * +from .updateorganizationmembershipop import * +from .updateorganizationop import * +from .updatephonenumberop import * +from .updateproductioninstancedomainop import * +from .updatesamlconnectionop import * +from .updatesignupop import * +from .updateusermetadataop import * +from .updateuserop import * +from .uploadorganizationlogoop import * +from .upserttemplateop import * +from .user import * +from .usersgetorganizationmembershipsop import * +from .verifyclientop import * +from .verifydomainproxyop import * +from .verifypasswordop import * +from .verifysessionop import * +from .verifytotpop import * +from .web3wallet import * + +__all__ = ["Actor","ActorToken","ActorTokenActor","ActorTokenObject","ActorTokenStatus","AddDomainRequestBody","Admin","AdminVerificationPhoneNumberStatus","AdminVerificationStatus","AdminVerificationStrategy","AdminVerificationWeb3WalletStatus","AdminVerificationWeb3WalletStrategy","AllowlistIdentifier","AllowlistIdentifierObject","AttributeMapping","BanUserRequest","BlocklistIdentifier","BlocklistIdentifierIdentifierType","BlocklistIdentifierObject","BlocklistIdentifiers","CNameTarget","ChangeProductionInstanceDomainRequestBody","Claims","ClerkError","ClerkErrorErrorMeta","ClerkErrors","ClerkErrorsMeta","Client","CodeType","CreateActorTokenRequestBody","CreateAllowlistIdentifierRequestBody","CreateBlocklistIdentifierRequestBody","CreateEmailAddressRequestBody","CreateInvitationPublicMetadata","CreateInvitationRequestBody","CreateJWTTemplateClaims","CreateJWTTemplateRequestBody","CreateOAuthApplicationRequestBody","CreateOrganizationInvitationBulkPrivateMetadata","CreateOrganizationInvitationBulkPublicMetadata","CreateOrganizationInvitationBulkRequest","CreateOrganizationInvitationPrivateMetadata","CreateOrganizationInvitationPublicMetadata","CreateOrganizationInvitationRequest","CreateOrganizationInvitationRequestBody","CreateOrganizationMembershipRequest","CreateOrganizationMembershipRequestBody","CreateOrganizationPrivateMetadata","CreateOrganizationPublicMetadata","CreateOrganizationRequestBody","CreatePhoneNumberRequestBody","CreateRedirectURLRequestBody","CreateSAMLConnectionAttributeMapping","CreateSAMLConnectionRequestBody","CreateSessionTokenFromTemplateObject","CreateSessionTokenFromTemplateRequest","CreateSessionTokenFromTemplateResponseBody","CreateSignInTokenRequestBody","CreateUserPrivateMetadata","CreateUserPublicMetadata","CreateUserRequestBody","CreateUserUnsafeMetadata","DeleteAllowlistIdentifierRequest","DeleteBlocklistIdentifierRequest","DeleteDomainRequest","DeleteEmailAddressRequest","DeleteJWTTemplateRequest","DeleteOAuthApplicationRequest","DeleteOrganizationLogoRequest","DeleteOrganizationMembershipRequest","DeleteOrganizationRequest","DeletePhoneNumberRequest","DeleteRedirectURLRequest","DeleteSAMLConnectionRequest","DeleteUserProfileImageRequest","DeleteUserRequest","DeletedObject","DisableMFARequest","DisableMFAResponseBody","Domain","DomainObject","Domains","DomainsEnrollmentModes","EmailAddress","EmailAddressObject","Error","ErrorClerkError","ErrorMeta","ExternalAccount","ExternalAccounts","File","GetClientListRequest","GetClientListResponse","GetClientRequest","GetEmailAddressRequest","GetJWTTemplateRequest","GetOAuthAccessTokenPublicMetadata","GetOAuthAccessTokenRequest","GetOAuthApplicationRequest","GetOrganizationInvitationRequest","GetOrganizationRequest","GetPhoneNumberRequest","GetPublicInterstitialRequest","GetRedirectURLRequest","GetSAMLConnectionRequest","GetSessionListRequest","GetSessionRequest","GetTemplateListRequest","GetTemplateRequest","GetUserListRequest","GetUserRequest","GetUsersCountRequest","IdentificationLink","IdentifierType","InstanceRestrictions","InstanceRestrictionsObject","InstanceSettings","InstanceSettingsObject","Invitation","InvitationObject","InvitationPublicMetadata","InvitationRevoked","InvitationRevokedObject","InvitationRevokedPublicMetadata","InvitationRevokedStatus","InvitationStatus","JWTTemplate","JWTTemplateObject","ListInvitationsQueryParamStatus","ListInvitationsRequest","ListInvitationsResponse","ListOAuthApplicationsRequest","ListOAuthApplicationsResponse","ListOrganizationInvitationsQueryParamStatus","ListOrganizationInvitationsRequest","ListOrganizationInvitationsResponse","ListOrganizationMembershipsRequest","ListOrganizationMembershipsResponse","ListOrganizationsRequest","ListPendingOrganizationInvitationsRequest","ListPendingOrganizationInvitationsResponse","ListSAMLConnectionsRequest","ListSAMLConnectionsResponse","LockUserRequest","MergeOrganizationMetadataPrivateMetadata","MergeOrganizationMetadataPublicMetadata","MergeOrganizationMetadataRequest","MergeOrganizationMetadataRequestBody","Meta","Nonce","OAuthApplication","OAuthApplicationObject","OAuthApplicationWithSecret","OAuthApplicationWithSecretObject","OAuthApplications","OTPVerificationStatus","OTPVerificationStrategy","Oauth","OauthVerificationStatus","OauthVerificationStrategy","Object","Organization","OrganizationInvitation","OrganizationInvitationObject","OrganizationInvitationPrivateMetadata","OrganizationInvitationPublicMetadata","OrganizationInvitations","OrganizationMembership","OrganizationMembershipObject","OrganizationMembershipOrganization","OrganizationMembershipOrganizationObject","OrganizationMembershipOrganizationPrivateMetadata","OrganizationMembershipOrganizationPublicMetadata","OrganizationMembershipPrivateMetadata","OrganizationMembershipPublicMetadata","OrganizationMemberships","OrganizationObject","OrganizationPrivateMetadata","OrganizationPublicMetadata","OrganizationSettings","OrganizationSettingsObject","OrganizationWithLogo","OrganizationWithLogoObject","OrganizationWithLogoPrivateMetadata","OrganizationWithLogoPublicMetadata","Organizations","Otp","Passkey","PasskeyVerificationStatus","PasskeyVerificationStrategy","PasswordHasher","PathParamTemplateType","PhoneNumber","PhoneNumberObject","PhoneNumberVerification","PreviewTemplateRequest","PreviewTemplateRequestBody","PreviewTemplateResponseBody","PrivateMetadata","Provider","ProxyCheck","ProxyCheckObject","PublicMetadata","PublicUserData","QueryParamStatus","RedirectURL","RedirectURLObject","RequestBody","ResponseBody","RevertTemplatePathParamTemplateType","RevertTemplateRequest","RevokeActorTokenRequest","RevokeInvitationRequest","RevokeOrganizationInvitationRequest","RevokeOrganizationInvitationRequestBody","RevokeSessionRequest","RevokeSignInTokenRequest","RotateOAuthApplicationSecretRequest","SAMLAccount","SAMLAccountObject","SAMLAccountPublicMetadata","SAMLAccountVerification","SAMLConnection","SAMLConnectionObject","SAMLConnections","SAMLErrorClerkError","SAMLVerificationStatus","SAMLVerificationStrategy","SDKError","Saml","SchemasPasskey","SchemasPasskeyObject","SchemasPasskeyVerification","Security","Session","SessionObject","SetUserProfileImageRequest","SetUserProfileImageRequestBody","SignInToken","SignInTokenObject","SignInTokenStatus","SignUp","SignUpObject","SignUpPublicMetadata","SignUpStatus","SignUpUnsafeMetadata","Status","Strategy","SvixURL","Template","TemplateObject","TemplateType","TestingToken","TestingTokenObject","Ticket","TicketVerificationStatus","TicketVerificationStrategy","ToggleTemplateDeliveryPathParamTemplateType","ToggleTemplateDeliveryRequest","ToggleTemplateDeliveryRequestBody","TotalCount","TotalCountObject","Type","UnbanUserRequest","UnlockUserRequest","UnsafeMetadata","UpdateDomainRequest","UpdateDomainRequestBody","UpdateEmailAddressRequest","UpdateEmailAddressRequestBody","UpdateInstanceAuthConfigRequestBody","UpdateInstanceOrganizationSettingsRequestBody","UpdateInstanceRequestBody","UpdateInstanceRestrictionsRequestBody","UpdateJWTTemplateClaims","UpdateJWTTemplateRequest","UpdateJWTTemplateRequestBody","UpdateOAuthApplicationRequest","UpdateOAuthApplicationRequestBody","UpdateOrganizationMembershipMetadataPrivateMetadata","UpdateOrganizationMembershipMetadataPublicMetadata","UpdateOrganizationMembershipMetadataRequest","UpdateOrganizationMembershipMetadataRequestBody","UpdateOrganizationMembershipRequest","UpdateOrganizationMembershipRequestBody","UpdateOrganizationPrivateMetadata","UpdateOrganizationPublicMetadata","UpdateOrganizationRequest","UpdateOrganizationRequestBody","UpdatePhoneNumberRequest","UpdatePhoneNumberRequestBody","UpdateProductionInstanceDomainRequestBody","UpdateSAMLConnectionAttributeMapping","UpdateSAMLConnectionRequest","UpdateSAMLConnectionRequestBody","UpdateSignUpRequest","UpdateSignUpRequestBody","UpdateUserMetadataPrivateMetadata","UpdateUserMetadataRequest","UpdateUserMetadataRequestBody","UpdateUserMetadataUnsafeMetadata","UpdateUserPasswordHasher","UpdateUserPrivateMetadata","UpdateUserPublicMetadata","UpdateUserRequest","UpdateUserRequestBody","UpdateUserUnsafeMetadata","UploadOrganizationLogoFile","UploadOrganizationLogoRequest","UploadOrganizationLogoRequestBody","UpsertTemplatePathParamTemplateType","UpsertTemplateRequest","UpsertTemplateRequestBody","User","UserObject","UsersGetOrganizationMembershipsRequest","UsersGetOrganizationMembershipsResponse","Verification","VerificationAdmin","VerificationError","VerificationNonce","VerificationOTP","VerificationStatus","VerificationStrategy","Verifications","VerifyClientRequestBody","VerifyDomainProxyRequestBody","VerifyPasswordRequest","VerifyPasswordRequestBody","VerifyPasswordResponseBody","VerifySessionRequest","VerifySessionRequestBody","VerifyTOTPRequest","VerifyTOTPRequestBody","VerifyTOTPResponseBody","Web3Signature","Web3SignatureVerificationStatus","Web3SignatureVerificationStrategy","Web3Wallet","Web3WalletObject","Web3WalletVerification","Web3WalletVerificationAdmin"] diff --git a/src/clerk/models/actortoken.py b/src/clerk/models/actortoken.py new file mode 100644 index 0000000..1d0e11c --- /dev/null +++ b/src/clerk/models/actortoken.py @@ -0,0 +1,88 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel, Nullable +from enum import Enum +from pydantic import model_serializer +from typing import Optional, TypedDict +from typing_extensions import NotRequired + + +class ActorTokenObject(str, Enum): + ACTOR_TOKEN = "actor_token" + + +class ActorTokenStatus(str, Enum): + PENDING = "pending" + ACCEPTED = "accepted" + REVOKED = "revoked" + + +class ActorTokenActorTypedDict(TypedDict): + pass + + +class ActorTokenActor(BaseModel): + pass + + +class ActorTokenTypedDict(TypedDict): + object: ActorTokenObject + id: str + status: ActorTokenStatus + user_id: str + actor: ActorTokenActorTypedDict + created_at: int + r"""Unix timestamp of creation. + + """ + updated_at: int + r"""Unix timestamp of last update. + + """ + token: NotRequired[Nullable[str]] + url: NotRequired[Nullable[str]] + + +class ActorToken(BaseModel): + object: ActorTokenObject + id: str + status: ActorTokenStatus + user_id: str + actor: ActorTokenActor + created_at: int + r"""Unix timestamp of creation. + + """ + updated_at: int + r"""Unix timestamp of last update. + + """ + token: Optional[Nullable[str]] = None + url: Optional[Nullable[str]] = None + + @model_serializer(mode="wrap") + def serialize_model(self, handler): + optional_fields = ["token", "url"] + nullable_fields = ["token", "url"] + null_default_fields = [] + + serialized = handler(self) + + m = {} + + for n, f in self.model_fields.items(): + k = f.alias or n + val = serialized.get(k) + + if val is not None: + m[k] = val + elif not k in optional_fields or ( + k in optional_fields + and k in nullable_fields + and (self.__pydantic_fields_set__.intersection({n}) or k in null_default_fields) # pylint: disable=no-member + ): + m[k] = val + + return m + diff --git a/src/clerk/models/adddomainop.py b/src/clerk/models/adddomainop.py new file mode 100644 index 0000000..b14133d --- /dev/null +++ b/src/clerk/models/adddomainop.py @@ -0,0 +1,25 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel +from typing import Optional, TypedDict +from typing_extensions import NotRequired + + +class AddDomainRequestBodyTypedDict(TypedDict): + name: str + r"""The new domain name. Can contain the port for development instances.""" + is_satellite: bool + r"""Marks the new domain as satellite. Only `true` is accepted at the moment.""" + proxy_url: NotRequired[str] + r"""The full URL of the proxy which will forward requests to the Clerk Frontend API for this domain. Applicable only to production instances.""" + + +class AddDomainRequestBody(BaseModel): + name: str + r"""The new domain name. Can contain the port for development instances.""" + is_satellite: bool + r"""Marks the new domain as satellite. Only `true` is accepted at the moment.""" + proxy_url: Optional[str] = None + r"""The full URL of the proxy which will forward requests to the Clerk Frontend API for this domain. Applicable only to production instances.""" + diff --git a/src/clerk/models/allowlistidentifier.py b/src/clerk/models/allowlistidentifier.py new file mode 100644 index 0000000..4185426 --- /dev/null +++ b/src/clerk/models/allowlistidentifier.py @@ -0,0 +1,67 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel +from enum import Enum +from typing import Optional, TypedDict +from typing_extensions import NotRequired + + +class AllowlistIdentifierObject(str, Enum): + r"""String representing the object's type. Objects of the same type share the same value. + + """ + ALLOWLIST_IDENTIFIER = "allowlist_identifier" + + +class IdentifierType(str, Enum): + EMAIL_ADDRESS = "email_address" + PHONE_NUMBER = "phone_number" + WEB3_WALLET = "web3_wallet" + + +class AllowlistIdentifierTypedDict(TypedDict): + object: NotRequired[AllowlistIdentifierObject] + r"""String representing the object's type. Objects of the same type share the same value. + + """ + id: NotRequired[str] + invitation_id: NotRequired[str] + identifier: NotRequired[str] + r"""An email address or a phone number. + + """ + identifier_type: NotRequired[IdentifierType] + instance_id: NotRequired[str] + created_at: NotRequired[int] + r"""Unix timestamp of creation + + """ + updated_at: NotRequired[int] + r"""Unix timestamp of last update. + + """ + + +class AllowlistIdentifier(BaseModel): + object: Optional[AllowlistIdentifierObject] = None + r"""String representing the object's type. Objects of the same type share the same value. + + """ + id: Optional[str] = None + invitation_id: Optional[str] = None + identifier: Optional[str] = None + r"""An email address or a phone number. + + """ + identifier_type: Optional[IdentifierType] = None + instance_id: Optional[str] = None + created_at: Optional[int] = None + r"""Unix timestamp of creation + + """ + updated_at: Optional[int] = None + r"""Unix timestamp of last update. + + """ + diff --git a/src/clerk/models/banuserop.py b/src/clerk/models/banuserop.py new file mode 100644 index 0000000..ea0feda --- /dev/null +++ b/src/clerk/models/banuserop.py @@ -0,0 +1,18 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel +from clerk.utils import FieldMetadata, PathParamMetadata +from typing import TypedDict +from typing_extensions import Annotated + + +class BanUserRequestTypedDict(TypedDict): + user_id: str + r"""The ID of the user to ban""" + + +class BanUserRequest(BaseModel): + user_id: Annotated[str, FieldMetadata(path=PathParamMetadata(style="simple", explode=False))] + r"""The ID of the user to ban""" + diff --git a/src/clerk/models/blocklistidentifier.py b/src/clerk/models/blocklistidentifier.py new file mode 100644 index 0000000..f4c545c --- /dev/null +++ b/src/clerk/models/blocklistidentifier.py @@ -0,0 +1,65 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel +from enum import Enum +from typing import Optional, TypedDict +from typing_extensions import NotRequired + + +class BlocklistIdentifierObject(str, Enum): + r"""String representing the object's type. Objects of the same type share the same value. + + """ + BLOCKLIST_IDENTIFIER = "blocklist_identifier" + + +class BlocklistIdentifierIdentifierType(str, Enum): + EMAIL_ADDRESS = "email_address" + PHONE_NUMBER = "phone_number" + WEB3_WALLET = "web3_wallet" + + +class BlocklistIdentifierTypedDict(TypedDict): + object: NotRequired[BlocklistIdentifierObject] + r"""String representing the object's type. Objects of the same type share the same value. + + """ + id: NotRequired[str] + identifier: NotRequired[str] + r"""An email address, email domain, phone number or web3 wallet. + + """ + identifier_type: NotRequired[BlocklistIdentifierIdentifierType] + instance_id: NotRequired[str] + created_at: NotRequired[int] + r"""Unix timestamp of creation + + """ + updated_at: NotRequired[int] + r"""Unix timestamp of last update. + + """ + + +class BlocklistIdentifier(BaseModel): + object: Optional[BlocklistIdentifierObject] = None + r"""String representing the object's type. Objects of the same type share the same value. + + """ + id: Optional[str] = None + identifier: Optional[str] = None + r"""An email address, email domain, phone number or web3 wallet. + + """ + identifier_type: Optional[BlocklistIdentifierIdentifierType] = None + instance_id: Optional[str] = None + created_at: Optional[int] = None + r"""Unix timestamp of creation + + """ + updated_at: Optional[int] = None + r"""Unix timestamp of last update. + + """ + diff --git a/src/clerk/models/blocklistidentifiers.py b/src/clerk/models/blocklistidentifiers.py new file mode 100644 index 0000000..d6f6fb2 --- /dev/null +++ b/src/clerk/models/blocklistidentifiers.py @@ -0,0 +1,23 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from .blocklistidentifier import BlocklistIdentifier, BlocklistIdentifierTypedDict +from clerk.types import BaseModel +from typing import List, TypedDict + + +class BlocklistIdentifiersTypedDict(TypedDict): + data: List[BlocklistIdentifierTypedDict] + total_count: int + r"""Total number of blocklist identifiers + + """ + + +class BlocklistIdentifiers(BaseModel): + data: List[BlocklistIdentifier] + total_count: int + r"""Total number of blocklist identifiers + + """ + diff --git a/src/clerk/models/changeproductioninstancedomainop.py b/src/clerk/models/changeproductioninstancedomainop.py new file mode 100644 index 0000000..2e73e29 --- /dev/null +++ b/src/clerk/models/changeproductioninstancedomainop.py @@ -0,0 +1,17 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel +from typing import Optional, TypedDict +from typing_extensions import NotRequired + + +class ChangeProductionInstanceDomainRequestBodyTypedDict(TypedDict): + home_url: NotRequired[str] + r"""The new home URL of the production instance e.g. https://www.example.com""" + + +class ChangeProductionInstanceDomainRequestBody(BaseModel): + home_url: Optional[str] = None + r"""The new home URL of the production instance e.g. https://www.example.com""" + diff --git a/src/clerk/models/clerkerror.py b/src/clerk/models/clerkerror.py new file mode 100644 index 0000000..4ffb7be --- /dev/null +++ b/src/clerk/models/clerkerror.py @@ -0,0 +1,31 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel +from typing import Optional, TypedDict +from typing_extensions import NotRequired + + +class MetaTypedDict(TypedDict): + pass + + +class Meta(BaseModel): + pass + + +class ClerkErrorTypedDict(TypedDict): + message: str + long_message: str + code: str + meta: NotRequired[MetaTypedDict] + clerk_trace_id: NotRequired[str] + + +class ClerkError(BaseModel): + message: str + long_message: str + code: str + meta: Optional[Meta] = None + clerk_trace_id: Optional[str] = None + diff --git a/src/clerk/models/clerkerrors.py b/src/clerk/models/clerkerrors.py new file mode 100644 index 0000000..2541053 --- /dev/null +++ b/src/clerk/models/clerkerrors.py @@ -0,0 +1,32 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from .clerkerror import ClerkError +from clerk.types import BaseModel +import clerk.utils as utils +from typing import List, Optional, TypedDict + + +class ClerkErrorsMetaTypedDict(TypedDict): + pass + + +class ClerkErrorsMeta(BaseModel): + pass + +class ClerkErrorsData(BaseModel): + errors: List[ClerkError] + meta: Optional[ClerkErrorsMeta] = None + + + +class ClerkErrors(Exception): + r"""Request was not successful""" + data: ClerkErrorsData + + def __init__(self, data: ClerkErrorsData): + self.data = data + + def __str__(self) -> str: + return utils.marshal_json(self.data, ClerkErrorsData) + diff --git a/src/clerk/models/client.py b/src/clerk/models/client.py new file mode 100644 index 0000000..145e1b8 --- /dev/null +++ b/src/clerk/models/client.py @@ -0,0 +1,95 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from .session import Session, SessionTypedDict +from clerk.types import BaseModel, Nullable +from enum import Enum +from pydantic import model_serializer +from typing import List, TypedDict + + +class Object(str, Enum): + r"""String representing the object's type. Objects of the same type share the same value. + + """ + CLIENT = "client" + + +class ClientTypedDict(TypedDict): + object: Object + r"""String representing the object's type. Objects of the same type share the same value. + + """ + id: str + r"""String representing the identifier of the session. + + """ + session_ids: List[str] + sessions: List[SessionTypedDict] + sign_in_id: Nullable[str] + sign_up_id: Nullable[str] + last_active_session_id: Nullable[str] + r"""Last active session_id. + + """ + updated_at: int + r"""Unix timestamp of last update. + + """ + created_at: int + r"""Unix timestamp of creation. + + """ + + +class Client(BaseModel): + object: Object + r"""String representing the object's type. Objects of the same type share the same value. + + """ + id: str + r"""String representing the identifier of the session. + + """ + session_ids: List[str] + sessions: List[Session] + sign_in_id: Nullable[str] + sign_up_id: Nullable[str] + last_active_session_id: Nullable[str] + r"""Last active session_id. + + """ + updated_at: int + r"""Unix timestamp of last update. + + """ + created_at: int + r"""Unix timestamp of creation. + + """ + + @model_serializer(mode="wrap") + def serialize_model(self, handler): + optional_fields = [] + nullable_fields = ["sign_in_id", "sign_up_id", "last_active_session_id"] + null_default_fields = [] + + serialized = handler(self) + + m = {} + + for n, f in self.model_fields.items(): + k = f.alias or n + val = serialized.get(k) + + if val is not None: + m[k] = val + elif not k in optional_fields or ( + k in optional_fields + and k in nullable_fields + and (self.__pydantic_fields_set__.intersection({n}) or k in null_default_fields) # pylint: disable=no-member + ): + m[k] = val + + return m + diff --git a/src/clerk/models/cnametarget.py b/src/clerk/models/cnametarget.py new file mode 100644 index 0000000..bba3fbf --- /dev/null +++ b/src/clerk/models/cnametarget.py @@ -0,0 +1,24 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel +from typing import TypedDict + + +class CNameTargetTypedDict(TypedDict): + host: str + value: str + required: bool + r"""Denotes whether this CNAME target is required to be set in order for the domain to be considered deployed. + + """ + + +class CNameTarget(BaseModel): + host: str + value: str + required: bool + r"""Denotes whether this CNAME target is required to be set in order for the domain to be considered deployed. + + """ + diff --git a/src/clerk/models/createactortokenop.py b/src/clerk/models/createactortokenop.py new file mode 100644 index 0000000..e085480 --- /dev/null +++ b/src/clerk/models/createactortokenop.py @@ -0,0 +1,41 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel +from typing import Any, Dict, Optional, TypedDict +from typing_extensions import NotRequired + + +class CreateActorTokenRequestBodyTypedDict(TypedDict): + user_id: str + r"""The ID of the user that can use the newly created sign in token.""" + actor: Dict[str, Any] + r"""The actor payload. It needs to include a sub property which should contain the ID of the actor. + This whole payload will be also included in the JWT session token. + """ + expires_in_seconds: NotRequired[int] + r"""Optional parameter to specify the life duration of the actor token in seconds. + By default, the duration is 1 hour. + """ + session_max_duration_in_seconds: NotRequired[int] + r"""The maximum duration that the session which will be created by the generated actor token should last. + By default, the duration of a session created via an actor token, lasts 30 minutes. + """ + + +class CreateActorTokenRequestBody(BaseModel): + user_id: str + r"""The ID of the user that can use the newly created sign in token.""" + actor: Dict[str, Any] + r"""The actor payload. It needs to include a sub property which should contain the ID of the actor. + This whole payload will be also included in the JWT session token. + """ + expires_in_seconds: Optional[int] = 3600 + r"""Optional parameter to specify the life duration of the actor token in seconds. + By default, the duration is 1 hour. + """ + session_max_duration_in_seconds: Optional[int] = 1800 + r"""The maximum duration that the session which will be created by the generated actor token should last. + By default, the duration of a session created via an actor token, lasts 30 minutes. + """ + diff --git a/src/clerk/models/createallowlistidentifierop.py b/src/clerk/models/createallowlistidentifierop.py new file mode 100644 index 0000000..388ea90 --- /dev/null +++ b/src/clerk/models/createallowlistidentifierop.py @@ -0,0 +1,29 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel +from typing import Optional, TypedDict +from typing_extensions import NotRequired + + +class CreateAllowlistIdentifierRequestBodyTypedDict(TypedDict): + identifier: str + r"""The identifier to be added in the allow-list. + This can be an email address, a phone number or a web3 wallet. + """ + notify: NotRequired[bool] + r"""This flag denotes whether the given identifier will receive an invitation to join the application. + Note that this only works for email address and phone number identifiers. + """ + + +class CreateAllowlistIdentifierRequestBody(BaseModel): + identifier: str + r"""The identifier to be added in the allow-list. + This can be an email address, a phone number or a web3 wallet. + """ + notify: Optional[bool] = False + r"""This flag denotes whether the given identifier will receive an invitation to join the application. + Note that this only works for email address and phone number identifiers. + """ + diff --git a/src/clerk/models/createblocklistidentifierop.py b/src/clerk/models/createblocklistidentifierop.py new file mode 100644 index 0000000..f155cdd --- /dev/null +++ b/src/clerk/models/createblocklistidentifierop.py @@ -0,0 +1,20 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel +from typing import TypedDict + + +class CreateBlocklistIdentifierRequestBodyTypedDict(TypedDict): + identifier: str + r"""The identifier to be added in the block-list. + This can be an email address, a phone number or a web3 wallet. + """ + + +class CreateBlocklistIdentifierRequestBody(BaseModel): + identifier: str + r"""The identifier to be added in the block-list. + This can be an email address, a phone number or a web3 wallet. + """ + diff --git a/src/clerk/models/createemailaddressop.py b/src/clerk/models/createemailaddressop.py new file mode 100644 index 0000000..09a5676 --- /dev/null +++ b/src/clerk/models/createemailaddressop.py @@ -0,0 +1,59 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel, Nullable +from pydantic import model_serializer +from typing import Optional, TypedDict +from typing_extensions import NotRequired + + +class CreateEmailAddressRequestBodyTypedDict(TypedDict): + user_id: NotRequired[str] + r"""The ID representing the user""" + email_address: NotRequired[str] + r"""The new email address. Must adhere to the RFC 5322 specification for email address format.""" + verified: NotRequired[Nullable[bool]] + r"""When created, the email address will be marked as verified.""" + primary: NotRequired[Nullable[bool]] + r"""Create this email address as the primary email address for the user. + Default: false, unless it is the first email address. + """ + + +class CreateEmailAddressRequestBody(BaseModel): + user_id: Optional[str] = None + r"""The ID representing the user""" + email_address: Optional[str] = None + r"""The new email address. Must adhere to the RFC 5322 specification for email address format.""" + verified: Optional[Nullable[bool]] = None + r"""When created, the email address will be marked as verified.""" + primary: Optional[Nullable[bool]] = None + r"""Create this email address as the primary email address for the user. + Default: false, unless it is the first email address. + """ + + @model_serializer(mode="wrap") + def serialize_model(self, handler): + optional_fields = ["user_id", "email_address", "verified", "primary"] + nullable_fields = ["verified", "primary"] + null_default_fields = [] + + serialized = handler(self) + + m = {} + + for n, f in self.model_fields.items(): + k = f.alias or n + val = serialized.get(k) + + if val is not None: + m[k] = val + elif not k in optional_fields or ( + k in optional_fields + and k in nullable_fields + and (self.__pydantic_fields_set__.intersection({n}) or k in null_default_fields) # pylint: disable=no-member + ): + m[k] = val + + return m + diff --git a/src/clerk/models/createinvitationop.py b/src/clerk/models/createinvitationop.py new file mode 100644 index 0000000..7b50309 --- /dev/null +++ b/src/clerk/models/createinvitationop.py @@ -0,0 +1,93 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel, Nullable +from pydantic import model_serializer +from typing import Optional, TypedDict +from typing_extensions import NotRequired + + +class CreateInvitationPublicMetadataTypedDict(TypedDict): + r"""Metadata that will be attached to the newly created invitation. + The value of this property should be a well-formed JSON object. + Once the user accepts the invitation and signs up, these metadata will end up in the user's public metadata. + """ + + + +class CreateInvitationPublicMetadata(BaseModel): + r"""Metadata that will be attached to the newly created invitation. + The value of this property should be a well-formed JSON object. + Once the user accepts the invitation and signs up, these metadata will end up in the user's public metadata. + """ + + + +class CreateInvitationRequestBodyTypedDict(TypedDict): + r"""Required parameters""" + + email_address: str + r"""The email address the invitation will be sent to""" + public_metadata: NotRequired[CreateInvitationPublicMetadataTypedDict] + r"""Metadata that will be attached to the newly created invitation. + The value of this property should be a well-formed JSON object. + Once the user accepts the invitation and signs up, these metadata will end up in the user's public metadata. + """ + redirect_url: NotRequired[str] + r"""Optional URL which specifies where to redirect the user once they click the invitation link. + This is only required if you have implemented a [custom flow](https://clerk.com/docs/authentication/invitations#custom-flow) and you're not using Clerk Hosted Pages or Clerk Components. + """ + notify: NotRequired[Nullable[bool]] + r"""Optional flag which denotes whether an email invitation should be sent to the given email address. + Defaults to true. + """ + ignore_existing: NotRequired[Nullable[bool]] + r"""Whether an invitation should be created if there is already an existing invitation for this email address, or it's claimed by another user.""" + + +class CreateInvitationRequestBody(BaseModel): + r"""Required parameters""" + + email_address: str + r"""The email address the invitation will be sent to""" + public_metadata: Optional[CreateInvitationPublicMetadata] = None + r"""Metadata that will be attached to the newly created invitation. + The value of this property should be a well-formed JSON object. + Once the user accepts the invitation and signs up, these metadata will end up in the user's public metadata. + """ + redirect_url: Optional[str] = None + r"""Optional URL which specifies where to redirect the user once they click the invitation link. + This is only required if you have implemented a [custom flow](https://clerk.com/docs/authentication/invitations#custom-flow) and you're not using Clerk Hosted Pages or Clerk Components. + """ + notify: Optional[Nullable[bool]] = True + r"""Optional flag which denotes whether an email invitation should be sent to the given email address. + Defaults to true. + """ + ignore_existing: Optional[Nullable[bool]] = False + r"""Whether an invitation should be created if there is already an existing invitation for this email address, or it's claimed by another user.""" + + @model_serializer(mode="wrap") + def serialize_model(self, handler): + optional_fields = ["public_metadata", "redirect_url", "notify", "ignore_existing"] + nullable_fields = ["notify", "ignore_existing"] + null_default_fields = [] + + serialized = handler(self) + + m = {} + + for n, f in self.model_fields.items(): + k = f.alias or n + val = serialized.get(k) + + if val is not None: + m[k] = val + elif not k in optional_fields or ( + k in optional_fields + and k in nullable_fields + and (self.__pydantic_fields_set__.intersection({n}) or k in null_default_fields) # pylint: disable=no-member + ): + m[k] = val + + return m + diff --git a/src/clerk/models/createjwttemplateop.py b/src/clerk/models/createjwttemplateop.py new file mode 100644 index 0000000..4e4941c --- /dev/null +++ b/src/clerk/models/createjwttemplateop.py @@ -0,0 +1,77 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel, Nullable +from pydantic import model_serializer +from typing import Optional, TypedDict +from typing_extensions import NotRequired + + +class CreateJWTTemplateClaimsTypedDict(TypedDict): + r"""JWT template claims in JSON format""" + + + +class CreateJWTTemplateClaims(BaseModel): + r"""JWT template claims in JSON format""" + + + +class CreateJWTTemplateRequestBodyTypedDict(TypedDict): + name: NotRequired[str] + r"""JWT template name""" + claims: NotRequired[CreateJWTTemplateClaimsTypedDict] + r"""JWT template claims in JSON format""" + lifetime: NotRequired[Nullable[float]] + r"""JWT token lifetime""" + allowed_clock_skew: NotRequired[Nullable[float]] + r"""JWT token allowed clock skew""" + custom_signing_key: NotRequired[bool] + r"""Whether a custom signing key/algorithm is also provided for this template""" + signing_algorithm: NotRequired[Nullable[str]] + r"""The custom signing algorithm to use when minting JWTs""" + signing_key: NotRequired[Nullable[str]] + r"""The custom signing private key to use when minting JWTs""" + + +class CreateJWTTemplateRequestBody(BaseModel): + name: Optional[str] = None + r"""JWT template name""" + claims: Optional[CreateJWTTemplateClaims] = None + r"""JWT template claims in JSON format""" + lifetime: Optional[Nullable[float]] = None + r"""JWT token lifetime""" + allowed_clock_skew: Optional[Nullable[float]] = None + r"""JWT token allowed clock skew""" + custom_signing_key: Optional[bool] = None + r"""Whether a custom signing key/algorithm is also provided for this template""" + signing_algorithm: Optional[Nullable[str]] = None + r"""The custom signing algorithm to use when minting JWTs""" + signing_key: Optional[Nullable[str]] = None + r"""The custom signing private key to use when minting JWTs""" + + @model_serializer(mode="wrap") + def serialize_model(self, handler): + optional_fields = ["name", "claims", "lifetime", "allowed_clock_skew", "custom_signing_key", "signing_algorithm", "signing_key"] + nullable_fields = ["lifetime", "allowed_clock_skew", "signing_algorithm", "signing_key"] + null_default_fields = [] + + serialized = handler(self) + + m = {} + + for n, f in self.model_fields.items(): + k = f.alias or n + val = serialized.get(k) + + if val is not None: + m[k] = val + elif not k in optional_fields or ( + k in optional_fields + and k in nullable_fields + and (self.__pydantic_fields_set__.intersection({n}) or k in null_default_fields) # pylint: disable=no-member + ): + m[k] = val + + return m + diff --git a/src/clerk/models/createoauthapplicationop.py b/src/clerk/models/createoauthapplicationop.py new file mode 100644 index 0000000..97a9390 --- /dev/null +++ b/src/clerk/models/createoauthapplicationop.py @@ -0,0 +1,35 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel +from typing import Optional, TypedDict +from typing_extensions import NotRequired + + +class CreateOAuthApplicationRequestBodyTypedDict(TypedDict): + name: str + r"""The name of the new OAuth application""" + callback_url: str + r"""The callback URL of the new OAuth application""" + scopes: NotRequired[str] + r"""Define the allowed scopes for the new OAuth applications that dictate the user payload of the OAuth user info endpoint. Available scopes are `profile`, `email`, `public_metadata`, `private_metadata`. Provide the requested scopes as a string, separated by spaces.""" + public: NotRequired[bool] + r"""If true, this client is public and cannot securely store a client secret. + Only the authorization code flow with proof key for code exchange (PKCE) may be used. + Public clients cannot be updated to be confidential clients, and vice versa. + """ + + +class CreateOAuthApplicationRequestBody(BaseModel): + name: str + r"""The name of the new OAuth application""" + callback_url: str + r"""The callback URL of the new OAuth application""" + scopes: Optional[str] = "profile email" + r"""Define the allowed scopes for the new OAuth applications that dictate the user payload of the OAuth user info endpoint. Available scopes are `profile`, `email`, `public_metadata`, `private_metadata`. Provide the requested scopes as a string, separated by spaces.""" + public: Optional[bool] = None + r"""If true, this client is public and cannot securely store a client secret. + Only the authorization code flow with proof key for code exchange (PKCE) may be used. + Public clients cannot be updated to be confidential clients, and vice versa. + """ + diff --git a/src/clerk/models/createorganizationinvitationbulkop.py b/src/clerk/models/createorganizationinvitationbulkop.py new file mode 100644 index 0000000..dcf2658 --- /dev/null +++ b/src/clerk/models/createorganizationinvitationbulkop.py @@ -0,0 +1,74 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel +from clerk.utils import FieldMetadata, PathParamMetadata, RequestMetadata +from typing import List, Optional, TypedDict +from typing_extensions import Annotated, NotRequired + + +class CreateOrganizationInvitationBulkPublicMetadataTypedDict(TypedDict): + r"""Metadata saved on the organization invitation, read-only from the Frontend API and fully accessible (read/write) from the Backend API.""" + + + +class CreateOrganizationInvitationBulkPublicMetadata(BaseModel): + r"""Metadata saved on the organization invitation, read-only from the Frontend API and fully accessible (read/write) from the Backend API.""" + + + +class CreateOrganizationInvitationBulkPrivateMetadataTypedDict(TypedDict): + r"""Metadata saved on the organization invitation, fully accessible (read/write) from the Backend API but not visible from the Frontend API.""" + + + +class CreateOrganizationInvitationBulkPrivateMetadata(BaseModel): + r"""Metadata saved on the organization invitation, fully accessible (read/write) from the Backend API but not visible from the Frontend API.""" + + + +class RequestBodyTypedDict(TypedDict): + email_address: str + r"""The email address of the new member that is going to be invited to the organization""" + inviter_user_id: str + r"""The ID of the user that invites the new member to the organization. + Must be an administrator in the organization. + """ + role: str + r"""The role of the new member in the organization.""" + public_metadata: NotRequired[CreateOrganizationInvitationBulkPublicMetadataTypedDict] + r"""Metadata saved on the organization invitation, read-only from the Frontend API and fully accessible (read/write) from the Backend API.""" + private_metadata: NotRequired[CreateOrganizationInvitationBulkPrivateMetadataTypedDict] + r"""Metadata saved on the organization invitation, fully accessible (read/write) from the Backend API but not visible from the Frontend API.""" + redirect_url: NotRequired[str] + r"""Optional URL that the invitee will be redirected to once they accept the invitation by clicking the join link in the invitation email.""" + + +class RequestBody(BaseModel): + email_address: str + r"""The email address of the new member that is going to be invited to the organization""" + inviter_user_id: str + r"""The ID of the user that invites the new member to the organization. + Must be an administrator in the organization. + """ + role: str + r"""The role of the new member in the organization.""" + public_metadata: Optional[CreateOrganizationInvitationBulkPublicMetadata] = None + r"""Metadata saved on the organization invitation, read-only from the Frontend API and fully accessible (read/write) from the Backend API.""" + private_metadata: Optional[CreateOrganizationInvitationBulkPrivateMetadata] = None + r"""Metadata saved on the organization invitation, fully accessible (read/write) from the Backend API but not visible from the Frontend API.""" + redirect_url: Optional[str] = None + r"""Optional URL that the invitee will be redirected to once they accept the invitation by clicking the join link in the invitation email.""" + + +class CreateOrganizationInvitationBulkRequestTypedDict(TypedDict): + organization_id: str + r"""The organization ID.""" + request_body: List[RequestBodyTypedDict] + + +class CreateOrganizationInvitationBulkRequest(BaseModel): + organization_id: Annotated[str, FieldMetadata(path=PathParamMetadata(style="simple", explode=False))] + r"""The organization ID.""" + request_body: Annotated[List[RequestBody], FieldMetadata(request=RequestMetadata(media_type="application/json"))] + diff --git a/src/clerk/models/createorganizationinvitationop.py b/src/clerk/models/createorganizationinvitationop.py new file mode 100644 index 0000000..810f4f4 --- /dev/null +++ b/src/clerk/models/createorganizationinvitationop.py @@ -0,0 +1,74 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel +from clerk.utils import FieldMetadata, PathParamMetadata, RequestMetadata +from typing import Optional, TypedDict +from typing_extensions import Annotated, NotRequired + + +class CreateOrganizationInvitationPublicMetadataTypedDict(TypedDict): + r"""Metadata saved on the organization invitation, read-only from the Frontend API and fully accessible (read/write) from the Backend API.""" + + + +class CreateOrganizationInvitationPublicMetadata(BaseModel): + r"""Metadata saved on the organization invitation, read-only from the Frontend API and fully accessible (read/write) from the Backend API.""" + + + +class CreateOrganizationInvitationPrivateMetadataTypedDict(TypedDict): + r"""Metadata saved on the organization invitation, fully accessible (read/write) from the Backend API but not visible from the Frontend API.""" + + + +class CreateOrganizationInvitationPrivateMetadata(BaseModel): + r"""Metadata saved on the organization invitation, fully accessible (read/write) from the Backend API but not visible from the Frontend API.""" + + + +class CreateOrganizationInvitationRequestBodyTypedDict(TypedDict): + email_address: str + r"""The email address of the new member that is going to be invited to the organization""" + inviter_user_id: str + r"""The ID of the user that invites the new member to the organization. + Must be an administrator in the organization. + """ + role: str + r"""The role of the new member in the organization""" + public_metadata: NotRequired[CreateOrganizationInvitationPublicMetadataTypedDict] + r"""Metadata saved on the organization invitation, read-only from the Frontend API and fully accessible (read/write) from the Backend API.""" + private_metadata: NotRequired[CreateOrganizationInvitationPrivateMetadataTypedDict] + r"""Metadata saved on the organization invitation, fully accessible (read/write) from the Backend API but not visible from the Frontend API.""" + redirect_url: NotRequired[str] + r"""Optional URL that the invitee will be redirected to once they accept the invitation by clicking the join link in the invitation email.""" + + +class CreateOrganizationInvitationRequestBody(BaseModel): + email_address: str + r"""The email address of the new member that is going to be invited to the organization""" + inviter_user_id: str + r"""The ID of the user that invites the new member to the organization. + Must be an administrator in the organization. + """ + role: str + r"""The role of the new member in the organization""" + public_metadata: Optional[CreateOrganizationInvitationPublicMetadata] = None + r"""Metadata saved on the organization invitation, read-only from the Frontend API and fully accessible (read/write) from the Backend API.""" + private_metadata: Optional[CreateOrganizationInvitationPrivateMetadata] = None + r"""Metadata saved on the organization invitation, fully accessible (read/write) from the Backend API but not visible from the Frontend API.""" + redirect_url: Optional[str] = None + r"""Optional URL that the invitee will be redirected to once they accept the invitation by clicking the join link in the invitation email.""" + + +class CreateOrganizationInvitationRequestTypedDict(TypedDict): + organization_id: str + r"""The ID of the organization for which to send the invitation""" + request_body: CreateOrganizationInvitationRequestBodyTypedDict + + +class CreateOrganizationInvitationRequest(BaseModel): + organization_id: Annotated[str, FieldMetadata(path=PathParamMetadata(style="simple", explode=False))] + r"""The ID of the organization for which to send the invitation""" + request_body: Annotated[CreateOrganizationInvitationRequestBody, FieldMetadata(request=RequestMetadata(media_type="application/json"))] + diff --git a/src/clerk/models/createorganizationmembershipop.py b/src/clerk/models/createorganizationmembershipop.py new file mode 100644 index 0000000..2d3739b --- /dev/null +++ b/src/clerk/models/createorganizationmembershipop.py @@ -0,0 +1,34 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel +from clerk.utils import FieldMetadata, PathParamMetadata, RequestMetadata +from typing import TypedDict +from typing_extensions import Annotated + + +class CreateOrganizationMembershipRequestBodyTypedDict(TypedDict): + user_id: str + r"""The ID of the user that will be added as a member in the organization.""" + role: str + r"""The role that the new member will have in the organization.""" + + +class CreateOrganizationMembershipRequestBody(BaseModel): + user_id: str + r"""The ID of the user that will be added as a member in the organization.""" + role: str + r"""The role that the new member will have in the organization.""" + + +class CreateOrganizationMembershipRequestTypedDict(TypedDict): + organization_id: str + r"""The ID of the organization where the new membership will be created""" + request_body: CreateOrganizationMembershipRequestBodyTypedDict + + +class CreateOrganizationMembershipRequest(BaseModel): + organization_id: Annotated[str, FieldMetadata(path=PathParamMetadata(style="simple", explode=False))] + r"""The ID of the organization where the new membership will be created""" + request_body: Annotated[CreateOrganizationMembershipRequestBody, FieldMetadata(request=RequestMetadata(media_type="application/json"))] + diff --git a/src/clerk/models/createorganizationop.py b/src/clerk/models/createorganizationop.py new file mode 100644 index 0000000..c80de32 --- /dev/null +++ b/src/clerk/models/createorganizationop.py @@ -0,0 +1,63 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel +from typing import Optional, TypedDict +from typing_extensions import NotRequired + + +class CreateOrganizationPrivateMetadataTypedDict(TypedDict): + r"""Metadata saved on the organization, accessible only from the Backend API""" + + + +class CreateOrganizationPrivateMetadata(BaseModel): + r"""Metadata saved on the organization, accessible only from the Backend API""" + + + +class CreateOrganizationPublicMetadataTypedDict(TypedDict): + r"""Metadata saved on the organization, read-only from the Frontend API and fully accessible (read/write) from the Backend API""" + + + +class CreateOrganizationPublicMetadata(BaseModel): + r"""Metadata saved on the organization, read-only from the Frontend API and fully accessible (read/write) from the Backend API""" + + + +class CreateOrganizationRequestBodyTypedDict(TypedDict): + name: str + r"""The name of the new organization""" + created_by: str + r"""The ID of the User who will become the administrator for the new organization""" + private_metadata: NotRequired[CreateOrganizationPrivateMetadataTypedDict] + r"""Metadata saved on the organization, accessible only from the Backend API""" + public_metadata: NotRequired[CreateOrganizationPublicMetadataTypedDict] + r"""Metadata saved on the organization, read-only from the Frontend API and fully accessible (read/write) from the Backend API""" + slug: NotRequired[str] + r"""A slug for the new organization. + Can contain only lowercase alphanumeric characters and the dash \"-\". + Must be unique for the instance. + """ + max_allowed_memberships: NotRequired[int] + r"""The maximum number of memberships allowed for this organization""" + + +class CreateOrganizationRequestBody(BaseModel): + name: str + r"""The name of the new organization""" + created_by: str + r"""The ID of the User who will become the administrator for the new organization""" + private_metadata: Optional[CreateOrganizationPrivateMetadata] = None + r"""Metadata saved on the organization, accessible only from the Backend API""" + public_metadata: Optional[CreateOrganizationPublicMetadata] = None + r"""Metadata saved on the organization, read-only from the Frontend API and fully accessible (read/write) from the Backend API""" + slug: Optional[str] = None + r"""A slug for the new organization. + Can contain only lowercase alphanumeric characters and the dash \"-\". + Must be unique for the instance. + """ + max_allowed_memberships: Optional[int] = None + r"""The maximum number of memberships allowed for this organization""" + diff --git a/src/clerk/models/createphonenumberop.py b/src/clerk/models/createphonenumberop.py new file mode 100644 index 0000000..af0baeb --- /dev/null +++ b/src/clerk/models/createphonenumberop.py @@ -0,0 +1,69 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel, Nullable +from pydantic import model_serializer +from typing import Optional, TypedDict +from typing_extensions import NotRequired + + +class CreatePhoneNumberRequestBodyTypedDict(TypedDict): + user_id: NotRequired[str] + r"""The ID representing the user""" + phone_number: NotRequired[str] + r"""The new phone number. Must adhere to the E.164 standard for phone number format.""" + verified: NotRequired[Nullable[bool]] + r"""When created, the phone number will be marked as verified.""" + primary: NotRequired[Nullable[bool]] + r"""Create this phone number as the primary phone number for the user. + Default: false, unless it is the first phone number. + """ + reserved_for_second_factor: NotRequired[Nullable[bool]] + r"""Create this phone number as reserved for multi-factor authentication. + The phone number must also be verified. + If there are no other reserved second factors, the phone number will be set as the default second factor. + """ + + +class CreatePhoneNumberRequestBody(BaseModel): + user_id: Optional[str] = None + r"""The ID representing the user""" + phone_number: Optional[str] = None + r"""The new phone number. Must adhere to the E.164 standard for phone number format.""" + verified: Optional[Nullable[bool]] = None + r"""When created, the phone number will be marked as verified.""" + primary: Optional[Nullable[bool]] = None + r"""Create this phone number as the primary phone number for the user. + Default: false, unless it is the first phone number. + """ + reserved_for_second_factor: Optional[Nullable[bool]] = None + r"""Create this phone number as reserved for multi-factor authentication. + The phone number must also be verified. + If there are no other reserved second factors, the phone number will be set as the default second factor. + """ + + @model_serializer(mode="wrap") + def serialize_model(self, handler): + optional_fields = ["user_id", "phone_number", "verified", "primary", "reserved_for_second_factor"] + nullable_fields = ["verified", "primary", "reserved_for_second_factor"] + null_default_fields = [] + + serialized = handler(self) + + m = {} + + for n, f in self.model_fields.items(): + k = f.alias or n + val = serialized.get(k) + + if val is not None: + m[k] = val + elif not k in optional_fields or ( + k in optional_fields + and k in nullable_fields + and (self.__pydantic_fields_set__.intersection({n}) or k in null_default_fields) # pylint: disable=no-member + ): + m[k] = val + + return m + diff --git a/src/clerk/models/createredirecturlop.py b/src/clerk/models/createredirecturlop.py new file mode 100644 index 0000000..ec96e9a --- /dev/null +++ b/src/clerk/models/createredirecturlop.py @@ -0,0 +1,17 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel +from typing import Optional, TypedDict +from typing_extensions import NotRequired + + +class CreateRedirectURLRequestBodyTypedDict(TypedDict): + url: NotRequired[str] + r"""The full url value prefixed with `https://` or a custom scheme e.g. `\"https://my-app.com/oauth-callback\"` or `\"my-app://oauth-callback\"`""" + + +class CreateRedirectURLRequestBody(BaseModel): + url: Optional[str] = None + r"""The full url value prefixed with `https://` or a custom scheme e.g. `\"https://my-app.com/oauth-callback\"` or `\"my-app://oauth-callback\"`""" + diff --git a/src/clerk/models/createsamlconnectionop.py b/src/clerk/models/createsamlconnectionop.py new file mode 100644 index 0000000..e7f7479 --- /dev/null +++ b/src/clerk/models/createsamlconnectionop.py @@ -0,0 +1,102 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel, Nullable +from enum import Enum +from pydantic import model_serializer +from typing import Optional, TypedDict +from typing_extensions import NotRequired + + +class Provider(str, Enum): + r"""The IdP provider of the connection.""" + SAML_CUSTOM = "saml_custom" + SAML_OKTA = "saml_okta" + SAML_GOOGLE = "saml_google" + SAML_MICROSOFT = "saml_microsoft" + + +class CreateSAMLConnectionAttributeMappingTypedDict(TypedDict): + r"""Define the attribute name mapping between Identity Provider and Clerk's user properties""" + + user_id: NotRequired[str] + email_address: NotRequired[str] + first_name: NotRequired[str] + last_name: NotRequired[str] + + +class CreateSAMLConnectionAttributeMapping(BaseModel): + r"""Define the attribute name mapping between Identity Provider and Clerk's user properties""" + + user_id: Optional[str] = None + email_address: Optional[str] = None + first_name: Optional[str] = None + last_name: Optional[str] = None + + +class CreateSAMLConnectionRequestBodyTypedDict(TypedDict): + name: str + r"""The name to use as a label for this SAML Connection""" + domain: str + r"""The domain of your organization. Sign in flows using an email with this domain, will use this SAML Connection.""" + provider: Provider + r"""The IdP provider of the connection.""" + idp_entity_id: NotRequired[Nullable[str]] + r"""The Entity ID as provided by the IdP""" + idp_sso_url: NotRequired[Nullable[str]] + r"""The Single-Sign On URL as provided by the IdP""" + idp_certificate: NotRequired[Nullable[str]] + r"""The X.509 certificate as provided by the IdP""" + idp_metadata_url: NotRequired[Nullable[str]] + r"""The URL which serves the IdP metadata. If present, it takes priority over the corresponding individual properties""" + idp_metadata: NotRequired[Nullable[str]] + r"""The XML content of the IdP metadata file. If present, it takes priority over the corresponding individual properties""" + attribute_mapping: NotRequired[Nullable[CreateSAMLConnectionAttributeMappingTypedDict]] + r"""Define the attribute name mapping between Identity Provider and Clerk's user properties""" + + +class CreateSAMLConnectionRequestBody(BaseModel): + name: str + r"""The name to use as a label for this SAML Connection""" + domain: str + r"""The domain of your organization. Sign in flows using an email with this domain, will use this SAML Connection.""" + provider: Provider + r"""The IdP provider of the connection.""" + idp_entity_id: Optional[Nullable[str]] = None + r"""The Entity ID as provided by the IdP""" + idp_sso_url: Optional[Nullable[str]] = None + r"""The Single-Sign On URL as provided by the IdP""" + idp_certificate: Optional[Nullable[str]] = None + r"""The X.509 certificate as provided by the IdP""" + idp_metadata_url: Optional[Nullable[str]] = None + r"""The URL which serves the IdP metadata. If present, it takes priority over the corresponding individual properties""" + idp_metadata: Optional[Nullable[str]] = None + r"""The XML content of the IdP metadata file. If present, it takes priority over the corresponding individual properties""" + attribute_mapping: Optional[Nullable[CreateSAMLConnectionAttributeMapping]] = None + r"""Define the attribute name mapping between Identity Provider and Clerk's user properties""" + + @model_serializer(mode="wrap") + def serialize_model(self, handler): + optional_fields = ["idp_entity_id", "idp_sso_url", "idp_certificate", "idp_metadata_url", "idp_metadata", "attribute_mapping"] + nullable_fields = ["idp_entity_id", "idp_sso_url", "idp_certificate", "idp_metadata_url", "idp_metadata", "attribute_mapping"] + null_default_fields = [] + + serialized = handler(self) + + m = {} + + for n, f in self.model_fields.items(): + k = f.alias or n + val = serialized.get(k) + + if val is not None: + m[k] = val + elif not k in optional_fields or ( + k in optional_fields + and k in nullable_fields + and (self.__pydantic_fields_set__.intersection({n}) or k in null_default_fields) # pylint: disable=no-member + ): + m[k] = val + + return m + diff --git a/src/clerk/models/createsessiontokenfromtemplateop.py b/src/clerk/models/createsessiontokenfromtemplateop.py new file mode 100644 index 0000000..03de11e --- /dev/null +++ b/src/clerk/models/createsessiontokenfromtemplateop.py @@ -0,0 +1,41 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel +from clerk.utils import FieldMetadata, PathParamMetadata +from enum import Enum +from typing import Optional, TypedDict +from typing_extensions import Annotated, NotRequired + + +class CreateSessionTokenFromTemplateRequestTypedDict(TypedDict): + session_id: str + r"""The ID of the session""" + template_name: str + r"""The name of the JWT Template defined in your instance (e.g. `custom_hasura`).""" + + +class CreateSessionTokenFromTemplateRequest(BaseModel): + session_id: Annotated[str, FieldMetadata(path=PathParamMetadata(style="simple", explode=False))] + r"""The ID of the session""" + template_name: Annotated[str, FieldMetadata(path=PathParamMetadata(style="simple", explode=False))] + r"""The name of the JWT Template defined in your instance (e.g. `custom_hasura`).""" + + +class CreateSessionTokenFromTemplateObject(str, Enum): + TOKEN = "token" + + +class CreateSessionTokenFromTemplateResponseBodyTypedDict(TypedDict): + r"""OK""" + + object: NotRequired[CreateSessionTokenFromTemplateObject] + jwt: NotRequired[str] + + +class CreateSessionTokenFromTemplateResponseBody(BaseModel): + r"""OK""" + + object: Optional[CreateSessionTokenFromTemplateObject] = None + jwt: Optional[str] = None + diff --git a/src/clerk/models/createsignintokenop.py b/src/clerk/models/createsignintokenop.py new file mode 100644 index 0000000..aa12d57 --- /dev/null +++ b/src/clerk/models/createsignintokenop.py @@ -0,0 +1,25 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel +from typing import Optional, TypedDict +from typing_extensions import NotRequired + + +class CreateSignInTokenRequestBodyTypedDict(TypedDict): + user_id: NotRequired[str] + r"""The ID of the user that can use the newly created sign in token""" + expires_in_seconds: NotRequired[int] + r"""Optional parameter to specify the life duration of the sign in token in seconds. + By default, the duration is 30 days. + """ + + +class CreateSignInTokenRequestBody(BaseModel): + user_id: Optional[str] = None + r"""The ID of the user that can use the newly created sign in token""" + expires_in_seconds: Optional[int] = 2592000 + r"""Optional parameter to specify the life duration of the sign in token in seconds. + By default, the duration is 30 days. + """ + diff --git a/src/clerk/models/createuserop.py b/src/clerk/models/createuserop.py new file mode 100644 index 0000000..b52bbbe --- /dev/null +++ b/src/clerk/models/createuserop.py @@ -0,0 +1,599 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel, Nullable +from enum import Enum +from pydantic import model_serializer +from typing import List, Optional, TypedDict +from typing_extensions import NotRequired + + +class PasswordHasher(str, Enum): + r"""The hashing algorithm that was used to generate the password digest. + The algorithms we support at the moment are [bcrypt](https://en.wikipedia.org/wiki/Bcrypt), [bcrypt_sha256_django](https://docs.djangoproject.com/en/4.0/topics/auth/passwords/), + [md5](https://en.wikipedia.org/wiki/MD5), pbkdf2_sha256, pbkdf2_sha512, [pbkdf2_sha256_django](https://docs.djangoproject.com/en/4.0/topics/auth/passwords/), + [phpass](https://www.openwall.com/phpass/), [scrypt_firebase](https://firebaseopensource.com/projects/firebase/scrypt/), + [scrypt_werkzeug](https://werkzeug.palletsprojects.com/en/3.0.x/utils/#werkzeug.security.generate_password_hash), [sha256](https://en.wikipedia.org/wiki/SHA-2) + and the [argon2](https://argon2.online/) variants argon2i and argon2id. + + If you need support for any particular hashing algorithm, [please let us know](https://clerk.com/support). + + Note: for password hashers considered insecure (at this moment MD5 and SHA256), the corresponding user password hashes will be transparently migrated to Bcrypt (a secure hasher) upon the user's first successful password sign in. + Insecure schemes are marked with `(insecure)` in the list below. + + Each of the supported hashers expects the incoming digest to be in a particular format. Specifically: + + **bcrypt:** The digest should be of the following form: + + `$$$` + + **bcrypt_sha256_django:** This is the Django-specific variant of Bcrypt, using SHA256 hashing function. The format should be as follows (as exported from Django): + + `bcrypt_sha256$$$$` + + **md5** (insecure): The digest should follow the regular form e.g.: + + `5f4dcc3b5aa765d61d8327deb882cf99` + + **pbkdf2_sha256:** This is the PBKDF2 algorithm using the SHA256 hashing function. The format should be as follows: + + `pbkdf2_sha256$$$` + + Note: Both the salt and the hash are expected to be base64-encoded. + + **pbkdf2_sha512:** This is the PBKDF2 algorithm using the SHA512 hashing function. The format should be as follows: + + `pbkdf2_sha512$$$` + + _iterations:_ The number of iterations used. Must be an integer less than 420000. + _salt:_ The salt used when generating the hash. Must be less than 1024 bytes. + _hash:_ The hex-encoded hash. Must have been generated with a key length less than 1024 bytes. + + **pbkdf2_sha256_django:** This is the Django-specific variant of PBKDF2 and the digest should have the following format (as exported from Django): + + `pbkdf2_sha256$$$` + + Note: The salt is expected to be un-encoded, the hash is expected base64-encoded. + + **pbkdf2_sha1:** This is similar to pkbdf2_sha256_django, but with two differences: + 1. uses sha1 instead of sha256 + 2. accepts the hash as a hex-encoded string + + The format is the following: + + `pbkdf2_sha1$$$` + + **phpass:** Portable public domain password hashing framework for use in PHP applications. Digests hashed with phpass have the following sections: + + The format is the following: + + `$P$` + + - $P$ is the prefix used to identify phpass hashes. + - rounds is a single character encoding a 6-bit integer representing the number of rounds used. + - salt is eight characters drawn from [./0-9A-Za-z], providing a 48-bit salt. + - checksum is 22 characters drawn from the same set, encoding the 128-bit checksum with MD5. + + **scrypt_firebase:** The Firebase-specific variant of scrypt. + The value is expected to have 6 segments separated by the $ character and include the following information: + + _hash:_ The actual Base64 hash. This can be retrieved when exporting the user from Firebase. + _salt:_ The salt used to generate the above hash. Again, this is given when exporting the user. + _signer key:_ The base64 encoded signer key. + _salt separator:_ The base64 encoded salt separator. + _rounds:_ The number of rounds the algorithm needs to run. + _memory cost:_ The cost of the algorithm run + + The first 2 (hash and salt) are per user and can be retrieved when exporting the user from Firebase. + The other 4 values (signer key, salt separator, rounds and memory cost) are project-wide settings and can be retrieved from the project's password hash parameters. + + Once you have all these, you can combine it in the following format and send this as the digest in order for Clerk to accept it: + + `$$$$$` + + **scrypt_werkzeug:** The Werkzeug-specific variant of scrypt. + + The value is expected to have 3 segments separated by the $ character and include the following information: + + _algorithm args:_ The algorithm used to generate the hash. + _salt:_ The salt used to generate the above hash. + _hash:_ The actual Base64 hash. + + The algorithm args are the parameters used to generate the hash and are included in the digest. + + **argon2i:** Algorithms in the argon2 family generate digests that encode the following information: + + _version (v):_ The argon version, version 19 is assumed + _memory (m):_ The memory used by the algorithm (in kibibytes) + _iterations (t):_ The number of iterations to perform + _parallelism (p):_ The number of threads to use + + Parts are demarcated by the `$` character, with the first part identifying the algorithm variant. + The middle part is a comma-separated list of the encoding options (memory, iterations, parallelism). + The final part is the actual digest. + + `$argon2i$v=19$m=4096,t=3,p=1$4t6CL3P7YiHBtwESXawI8Hm20zJj4cs7/4/G3c187e0$m7RQFczcKr5bIR0IIxbpO2P0tyrLjf3eUW3M3QSwnLc` + + **argon2id:** See the previous algorithm for an explanation of the formatting. + + For the argon2id case, the value of the algorithm in the first part of the digest is `argon2id`: + + `$argon2id$v=19$m=64,t=4,p=8$Z2liZXJyaXNo$iGXEpMBTDYQ8G/71tF0qGjxRHEmR3gpGULcE93zUJVU` + + **sha256** (insecure): The digest should be a 64-length hex string, e.g.: + + `9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08` + + **sha256_salted** (insecure): The digest should be a 64-length hex string with a salt. + + The format is the following: + `$` + + The value is expected to have 2 segments separated by the $ character and include the following information: + _hash:_ The sha256 hash, a 64-length hex string. + _salt:_ The salt used to generate the above hash. Must be between 1 and 1024 bits. + """ + ARGON2I = "argon2i" + ARGON2ID = "argon2id" + BCRYPT = "bcrypt" + BCRYPT_SHA256_DJANGO = "bcrypt_sha256_django" + MD5 = "md5" + PBKDF2_SHA256 = "pbkdf2_sha256" + PBKDF2_SHA512 = "pbkdf2_sha512" + PBKDF2_SHA256_DJANGO = "pbkdf2_sha256_django" + PBKDF2_SHA1 = "pbkdf2_sha1" + PHPASS = "phpass" + SCRYPT_FIREBASE = "scrypt_firebase" + SCRYPT_WERKZEUG = "scrypt_werkzeug" + SHA256 = "sha256" + SHA256_SALTED = "sha256_salted" + + +class CreateUserPublicMetadataTypedDict(TypedDict): + r"""Metadata saved on the user, that is visible to both your Frontend and Backend APIs""" + + + +class CreateUserPublicMetadata(BaseModel): + r"""Metadata saved on the user, that is visible to both your Frontend and Backend APIs""" + + + +class CreateUserPrivateMetadataTypedDict(TypedDict): + r"""Metadata saved on the user, that is only visible to your Backend API""" + + + +class CreateUserPrivateMetadata(BaseModel): + r"""Metadata saved on the user, that is only visible to your Backend API""" + + + +class CreateUserUnsafeMetadataTypedDict(TypedDict): + r"""Metadata saved on the user, that can be updated from both the Frontend and Backend APIs. + Note: Since this data can be modified from the frontend, it is not guaranteed to be safe. + """ + + + +class CreateUserUnsafeMetadata(BaseModel): + r"""Metadata saved on the user, that can be updated from both the Frontend and Backend APIs. + Note: Since this data can be modified from the frontend, it is not guaranteed to be safe. + """ + + + +class CreateUserRequestBodyTypedDict(TypedDict): + external_id: NotRequired[Nullable[str]] + r"""The ID of the user as used in your external systems or your previous authentication solution. + Must be unique across your instance. + """ + first_name: NotRequired[Nullable[str]] + r"""The first name to assign to the user""" + last_name: NotRequired[Nullable[str]] + r"""The last name to assign to the user""" + email_address: NotRequired[List[str]] + r"""Email addresses to add to the user. + Must be unique across your instance. + The first email address will be set as the user's primary email address. + """ + phone_number: NotRequired[List[str]] + r"""Phone numbers to add to the user. + Must be unique across your instance. + The first phone number will be set as the user's primary phone number. + """ + web3_wallet: NotRequired[List[str]] + r"""Web3 wallets to add to the user. + Must be unique across your instance. + The first wallet will be set as the user's primary wallet. + """ + username: NotRequired[Nullable[str]] + r"""The username to give to the user. + It must be unique across your instance. + """ + password: NotRequired[Nullable[str]] + r"""The plaintext password to give the user. + Must be at least 8 characters long, and can not be in any list of hacked passwords. + """ + password_digest: NotRequired[str] + r"""In case you already have the password digests and not the passwords, you can use them for the newly created user via this property. + The digests should be generated with one of the supported algorithms. + The hashing algorithm can be specified using the `password_hasher` property. + """ + password_hasher: NotRequired[PasswordHasher] + r"""The hashing algorithm that was used to generate the password digest. + The algorithms we support at the moment are [bcrypt](https://en.wikipedia.org/wiki/Bcrypt), [bcrypt_sha256_django](https://docs.djangoproject.com/en/4.0/topics/auth/passwords/), + [md5](https://en.wikipedia.org/wiki/MD5), pbkdf2_sha256, pbkdf2_sha512, [pbkdf2_sha256_django](https://docs.djangoproject.com/en/4.0/topics/auth/passwords/), + [phpass](https://www.openwall.com/phpass/), [scrypt_firebase](https://firebaseopensource.com/projects/firebase/scrypt/), + [scrypt_werkzeug](https://werkzeug.palletsprojects.com/en/3.0.x/utils/#werkzeug.security.generate_password_hash), [sha256](https://en.wikipedia.org/wiki/SHA-2) + and the [argon2](https://argon2.online/) variants argon2i and argon2id. + + If you need support for any particular hashing algorithm, [please let us know](https://clerk.com/support). + + Note: for password hashers considered insecure (at this moment MD5 and SHA256), the corresponding user password hashes will be transparently migrated to Bcrypt (a secure hasher) upon the user's first successful password sign in. + Insecure schemes are marked with `(insecure)` in the list below. + + Each of the supported hashers expects the incoming digest to be in a particular format. Specifically: + + **bcrypt:** The digest should be of the following form: + + `$$$` + + **bcrypt_sha256_django:** This is the Django-specific variant of Bcrypt, using SHA256 hashing function. The format should be as follows (as exported from Django): + + `bcrypt_sha256$$$$` + + **md5** (insecure): The digest should follow the regular form e.g.: + + `5f4dcc3b5aa765d61d8327deb882cf99` + + **pbkdf2_sha256:** This is the PBKDF2 algorithm using the SHA256 hashing function. The format should be as follows: + + `pbkdf2_sha256$$$` + + Note: Both the salt and the hash are expected to be base64-encoded. + + **pbkdf2_sha512:** This is the PBKDF2 algorithm using the SHA512 hashing function. The format should be as follows: + + `pbkdf2_sha512$$$` + + _iterations:_ The number of iterations used. Must be an integer less than 420000. + _salt:_ The salt used when generating the hash. Must be less than 1024 bytes. + _hash:_ The hex-encoded hash. Must have been generated with a key length less than 1024 bytes. + + **pbkdf2_sha256_django:** This is the Django-specific variant of PBKDF2 and the digest should have the following format (as exported from Django): + + `pbkdf2_sha256$$$` + + Note: The salt is expected to be un-encoded, the hash is expected base64-encoded. + + **pbkdf2_sha1:** This is similar to pkbdf2_sha256_django, but with two differences: + 1. uses sha1 instead of sha256 + 2. accepts the hash as a hex-encoded string + + The format is the following: + + `pbkdf2_sha1$$$` + + **phpass:** Portable public domain password hashing framework for use in PHP applications. Digests hashed with phpass have the following sections: + + The format is the following: + + `$P$` + + - $P$ is the prefix used to identify phpass hashes. + - rounds is a single character encoding a 6-bit integer representing the number of rounds used. + - salt is eight characters drawn from [./0-9A-Za-z], providing a 48-bit salt. + - checksum is 22 characters drawn from the same set, encoding the 128-bit checksum with MD5. + + **scrypt_firebase:** The Firebase-specific variant of scrypt. + The value is expected to have 6 segments separated by the $ character and include the following information: + + _hash:_ The actual Base64 hash. This can be retrieved when exporting the user from Firebase. + _salt:_ The salt used to generate the above hash. Again, this is given when exporting the user. + _signer key:_ The base64 encoded signer key. + _salt separator:_ The base64 encoded salt separator. + _rounds:_ The number of rounds the algorithm needs to run. + _memory cost:_ The cost of the algorithm run + + The first 2 (hash and salt) are per user and can be retrieved when exporting the user from Firebase. + The other 4 values (signer key, salt separator, rounds and memory cost) are project-wide settings and can be retrieved from the project's password hash parameters. + + Once you have all these, you can combine it in the following format and send this as the digest in order for Clerk to accept it: + + `$$$$$` + + **scrypt_werkzeug:** The Werkzeug-specific variant of scrypt. + + The value is expected to have 3 segments separated by the $ character and include the following information: + + _algorithm args:_ The algorithm used to generate the hash. + _salt:_ The salt used to generate the above hash. + _hash:_ The actual Base64 hash. + + The algorithm args are the parameters used to generate the hash and are included in the digest. + + **argon2i:** Algorithms in the argon2 family generate digests that encode the following information: + + _version (v):_ The argon version, version 19 is assumed + _memory (m):_ The memory used by the algorithm (in kibibytes) + _iterations (t):_ The number of iterations to perform + _parallelism (p):_ The number of threads to use + + Parts are demarcated by the `$` character, with the first part identifying the algorithm variant. + The middle part is a comma-separated list of the encoding options (memory, iterations, parallelism). + The final part is the actual digest. + + `$argon2i$v=19$m=4096,t=3,p=1$4t6CL3P7YiHBtwESXawI8Hm20zJj4cs7/4/G3c187e0$m7RQFczcKr5bIR0IIxbpO2P0tyrLjf3eUW3M3QSwnLc` + + **argon2id:** See the previous algorithm for an explanation of the formatting. + + For the argon2id case, the value of the algorithm in the first part of the digest is `argon2id`: + + `$argon2id$v=19$m=64,t=4,p=8$Z2liZXJyaXNo$iGXEpMBTDYQ8G/71tF0qGjxRHEmR3gpGULcE93zUJVU` + + **sha256** (insecure): The digest should be a 64-length hex string, e.g.: + + `9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08` + + **sha256_salted** (insecure): The digest should be a 64-length hex string with a salt. + + The format is the following: + `$` + + The value is expected to have 2 segments separated by the $ character and include the following information: + _hash:_ The sha256 hash, a 64-length hex string. + _salt:_ The salt used to generate the above hash. Must be between 1 and 1024 bits. + """ + skip_password_checks: NotRequired[bool] + r"""When set to `true` all password checks are skipped. + It is recommended to use this method only when migrating plaintext passwords to Clerk. + Upon migration the user base should be prompted to pick stronger password. + """ + skip_password_requirement: NotRequired[bool] + r"""When set to `true`, `password` is not required anymore when creating the user and can be omitted. + This is useful when you are trying to create a user that doesn't have a password, in an instance that is using passwords. + Please note that you cannot use this flag if password is the only way for a user to sign into your instance. + """ + totp_secret: NotRequired[str] + r"""In case TOTP is configured on the instance, you can provide the secret to enable it on the newly created user without the need to reset it. + Please note that currently the supported options are: + * Period: 30 seconds + * Code length: 6 digits + * Algorithm: SHA1 + """ + backup_codes: NotRequired[List[str]] + r"""If Backup Codes are configured on the instance, you can provide them to enable it on the newly created user without the need to reset them. + You must provide the backup codes in plain format or the corresponding bcrypt digest. + """ + public_metadata: NotRequired[CreateUserPublicMetadataTypedDict] + r"""Metadata saved on the user, that is visible to both your Frontend and Backend APIs""" + private_metadata: NotRequired[CreateUserPrivateMetadataTypedDict] + r"""Metadata saved on the user, that is only visible to your Backend API""" + unsafe_metadata: NotRequired[CreateUserUnsafeMetadataTypedDict] + r"""Metadata saved on the user, that can be updated from both the Frontend and Backend APIs. + Note: Since this data can be modified from the frontend, it is not guaranteed to be safe. + """ + created_at: NotRequired[str] + r"""A custom date/time denoting _when_ the user signed up to the application, specified in RFC3339 format (e.g. `2012-10-20T07:15:20.902Z`).""" + + +class CreateUserRequestBody(BaseModel): + external_id: Optional[Nullable[str]] = None + r"""The ID of the user as used in your external systems or your previous authentication solution. + Must be unique across your instance. + """ + first_name: Optional[Nullable[str]] = None + r"""The first name to assign to the user""" + last_name: Optional[Nullable[str]] = None + r"""The last name to assign to the user""" + email_address: Optional[List[str]] = None + r"""Email addresses to add to the user. + Must be unique across your instance. + The first email address will be set as the user's primary email address. + """ + phone_number: Optional[List[str]] = None + r"""Phone numbers to add to the user. + Must be unique across your instance. + The first phone number will be set as the user's primary phone number. + """ + web3_wallet: Optional[List[str]] = None + r"""Web3 wallets to add to the user. + Must be unique across your instance. + The first wallet will be set as the user's primary wallet. + """ + username: Optional[Nullable[str]] = None + r"""The username to give to the user. + It must be unique across your instance. + """ + password: Optional[Nullable[str]] = None + r"""The plaintext password to give the user. + Must be at least 8 characters long, and can not be in any list of hacked passwords. + """ + password_digest: Optional[str] = None + r"""In case you already have the password digests and not the passwords, you can use them for the newly created user via this property. + The digests should be generated with one of the supported algorithms. + The hashing algorithm can be specified using the `password_hasher` property. + """ + password_hasher: Optional[PasswordHasher] = None + r"""The hashing algorithm that was used to generate the password digest. + The algorithms we support at the moment are [bcrypt](https://en.wikipedia.org/wiki/Bcrypt), [bcrypt_sha256_django](https://docs.djangoproject.com/en/4.0/topics/auth/passwords/), + [md5](https://en.wikipedia.org/wiki/MD5), pbkdf2_sha256, pbkdf2_sha512, [pbkdf2_sha256_django](https://docs.djangoproject.com/en/4.0/topics/auth/passwords/), + [phpass](https://www.openwall.com/phpass/), [scrypt_firebase](https://firebaseopensource.com/projects/firebase/scrypt/), + [scrypt_werkzeug](https://werkzeug.palletsprojects.com/en/3.0.x/utils/#werkzeug.security.generate_password_hash), [sha256](https://en.wikipedia.org/wiki/SHA-2) + and the [argon2](https://argon2.online/) variants argon2i and argon2id. + + If you need support for any particular hashing algorithm, [please let us know](https://clerk.com/support). + + Note: for password hashers considered insecure (at this moment MD5 and SHA256), the corresponding user password hashes will be transparently migrated to Bcrypt (a secure hasher) upon the user's first successful password sign in. + Insecure schemes are marked with `(insecure)` in the list below. + + Each of the supported hashers expects the incoming digest to be in a particular format. Specifically: + + **bcrypt:** The digest should be of the following form: + + `$$$` + + **bcrypt_sha256_django:** This is the Django-specific variant of Bcrypt, using SHA256 hashing function. The format should be as follows (as exported from Django): + + `bcrypt_sha256$$$$` + + **md5** (insecure): The digest should follow the regular form e.g.: + + `5f4dcc3b5aa765d61d8327deb882cf99` + + **pbkdf2_sha256:** This is the PBKDF2 algorithm using the SHA256 hashing function. The format should be as follows: + + `pbkdf2_sha256$$$` + + Note: Both the salt and the hash are expected to be base64-encoded. + + **pbkdf2_sha512:** This is the PBKDF2 algorithm using the SHA512 hashing function. The format should be as follows: + + `pbkdf2_sha512$$$` + + _iterations:_ The number of iterations used. Must be an integer less than 420000. + _salt:_ The salt used when generating the hash. Must be less than 1024 bytes. + _hash:_ The hex-encoded hash. Must have been generated with a key length less than 1024 bytes. + + **pbkdf2_sha256_django:** This is the Django-specific variant of PBKDF2 and the digest should have the following format (as exported from Django): + + `pbkdf2_sha256$$$` + + Note: The salt is expected to be un-encoded, the hash is expected base64-encoded. + + **pbkdf2_sha1:** This is similar to pkbdf2_sha256_django, but with two differences: + 1. uses sha1 instead of sha256 + 2. accepts the hash as a hex-encoded string + + The format is the following: + + `pbkdf2_sha1$$$` + + **phpass:** Portable public domain password hashing framework for use in PHP applications. Digests hashed with phpass have the following sections: + + The format is the following: + + `$P$` + + - $P$ is the prefix used to identify phpass hashes. + - rounds is a single character encoding a 6-bit integer representing the number of rounds used. + - salt is eight characters drawn from [./0-9A-Za-z], providing a 48-bit salt. + - checksum is 22 characters drawn from the same set, encoding the 128-bit checksum with MD5. + + **scrypt_firebase:** The Firebase-specific variant of scrypt. + The value is expected to have 6 segments separated by the $ character and include the following information: + + _hash:_ The actual Base64 hash. This can be retrieved when exporting the user from Firebase. + _salt:_ The salt used to generate the above hash. Again, this is given when exporting the user. + _signer key:_ The base64 encoded signer key. + _salt separator:_ The base64 encoded salt separator. + _rounds:_ The number of rounds the algorithm needs to run. + _memory cost:_ The cost of the algorithm run + + The first 2 (hash and salt) are per user and can be retrieved when exporting the user from Firebase. + The other 4 values (signer key, salt separator, rounds and memory cost) are project-wide settings and can be retrieved from the project's password hash parameters. + + Once you have all these, you can combine it in the following format and send this as the digest in order for Clerk to accept it: + + `$$$$$` + + **scrypt_werkzeug:** The Werkzeug-specific variant of scrypt. + + The value is expected to have 3 segments separated by the $ character and include the following information: + + _algorithm args:_ The algorithm used to generate the hash. + _salt:_ The salt used to generate the above hash. + _hash:_ The actual Base64 hash. + + The algorithm args are the parameters used to generate the hash and are included in the digest. + + **argon2i:** Algorithms in the argon2 family generate digests that encode the following information: + + _version (v):_ The argon version, version 19 is assumed + _memory (m):_ The memory used by the algorithm (in kibibytes) + _iterations (t):_ The number of iterations to perform + _parallelism (p):_ The number of threads to use + + Parts are demarcated by the `$` character, with the first part identifying the algorithm variant. + The middle part is a comma-separated list of the encoding options (memory, iterations, parallelism). + The final part is the actual digest. + + `$argon2i$v=19$m=4096,t=3,p=1$4t6CL3P7YiHBtwESXawI8Hm20zJj4cs7/4/G3c187e0$m7RQFczcKr5bIR0IIxbpO2P0tyrLjf3eUW3M3QSwnLc` + + **argon2id:** See the previous algorithm for an explanation of the formatting. + + For the argon2id case, the value of the algorithm in the first part of the digest is `argon2id`: + + `$argon2id$v=19$m=64,t=4,p=8$Z2liZXJyaXNo$iGXEpMBTDYQ8G/71tF0qGjxRHEmR3gpGULcE93zUJVU` + + **sha256** (insecure): The digest should be a 64-length hex string, e.g.: + + `9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08` + + **sha256_salted** (insecure): The digest should be a 64-length hex string with a salt. + + The format is the following: + `$` + + The value is expected to have 2 segments separated by the $ character and include the following information: + _hash:_ The sha256 hash, a 64-length hex string. + _salt:_ The salt used to generate the above hash. Must be between 1 and 1024 bits. + """ + skip_password_checks: Optional[bool] = None + r"""When set to `true` all password checks are skipped. + It is recommended to use this method only when migrating plaintext passwords to Clerk. + Upon migration the user base should be prompted to pick stronger password. + """ + skip_password_requirement: Optional[bool] = None + r"""When set to `true`, `password` is not required anymore when creating the user and can be omitted. + This is useful when you are trying to create a user that doesn't have a password, in an instance that is using passwords. + Please note that you cannot use this flag if password is the only way for a user to sign into your instance. + """ + totp_secret: Optional[str] = None + r"""In case TOTP is configured on the instance, you can provide the secret to enable it on the newly created user without the need to reset it. + Please note that currently the supported options are: + * Period: 30 seconds + * Code length: 6 digits + * Algorithm: SHA1 + """ + backup_codes: Optional[List[str]] = None + r"""If Backup Codes are configured on the instance, you can provide them to enable it on the newly created user without the need to reset them. + You must provide the backup codes in plain format or the corresponding bcrypt digest. + """ + public_metadata: Optional[CreateUserPublicMetadata] = None + r"""Metadata saved on the user, that is visible to both your Frontend and Backend APIs""" + private_metadata: Optional[CreateUserPrivateMetadata] = None + r"""Metadata saved on the user, that is only visible to your Backend API""" + unsafe_metadata: Optional[CreateUserUnsafeMetadata] = None + r"""Metadata saved on the user, that can be updated from both the Frontend and Backend APIs. + Note: Since this data can be modified from the frontend, it is not guaranteed to be safe. + """ + created_at: Optional[str] = None + r"""A custom date/time denoting _when_ the user signed up to the application, specified in RFC3339 format (e.g. `2012-10-20T07:15:20.902Z`).""" + + @model_serializer(mode="wrap") + def serialize_model(self, handler): + optional_fields = ["external_id", "first_name", "last_name", "email_address", "phone_number", "web3_wallet", "username", "password", "password_digest", "password_hasher", "skip_password_checks", "skip_password_requirement", "totp_secret", "backup_codes", "public_metadata", "private_metadata", "unsafe_metadata", "created_at"] + nullable_fields = ["external_id", "first_name", "last_name", "username", "password"] + null_default_fields = [] + + serialized = handler(self) + + m = {} + + for n, f in self.model_fields.items(): + k = f.alias or n + val = serialized.get(k) + + if val is not None: + m[k] = val + elif not k in optional_fields or ( + k in optional_fields + and k in nullable_fields + and (self.__pydantic_fields_set__.intersection({n}) or k in null_default_fields) # pylint: disable=no-member + ): + m[k] = val + + return m + diff --git a/src/clerk/models/deleteallowlistidentifierop.py b/src/clerk/models/deleteallowlistidentifierop.py new file mode 100644 index 0000000..fa4acd5 --- /dev/null +++ b/src/clerk/models/deleteallowlistidentifierop.py @@ -0,0 +1,18 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel +from clerk.utils import FieldMetadata, PathParamMetadata +from typing import TypedDict +from typing_extensions import Annotated + + +class DeleteAllowlistIdentifierRequestTypedDict(TypedDict): + identifier_id: str + r"""The ID of the identifier to delete from the allow-list""" + + +class DeleteAllowlistIdentifierRequest(BaseModel): + identifier_id: Annotated[str, FieldMetadata(path=PathParamMetadata(style="simple", explode=False))] + r"""The ID of the identifier to delete from the allow-list""" + diff --git a/src/clerk/models/deleteblocklistidentifierop.py b/src/clerk/models/deleteblocklistidentifierop.py new file mode 100644 index 0000000..620c1d8 --- /dev/null +++ b/src/clerk/models/deleteblocklistidentifierop.py @@ -0,0 +1,18 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel +from clerk.utils import FieldMetadata, PathParamMetadata +from typing import TypedDict +from typing_extensions import Annotated + + +class DeleteBlocklistIdentifierRequestTypedDict(TypedDict): + identifier_id: str + r"""The ID of the identifier to delete from the block-list""" + + +class DeleteBlocklistIdentifierRequest(BaseModel): + identifier_id: Annotated[str, FieldMetadata(path=PathParamMetadata(style="simple", explode=False))] + r"""The ID of the identifier to delete from the block-list""" + diff --git a/src/clerk/models/deletedobject.py b/src/clerk/models/deletedobject.py new file mode 100644 index 0000000..bd06e60 --- /dev/null +++ b/src/clerk/models/deletedobject.py @@ -0,0 +1,21 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel +from typing import Optional, TypedDict +from typing_extensions import NotRequired + + +class DeletedObjectTypedDict(TypedDict): + object: str + deleted: bool + id: NotRequired[str] + slug: NotRequired[str] + + +class DeletedObject(BaseModel): + object: str + deleted: bool + id: Optional[str] = None + slug: Optional[str] = None + diff --git a/src/clerk/models/deletedomainop.py b/src/clerk/models/deletedomainop.py new file mode 100644 index 0000000..ffe52da --- /dev/null +++ b/src/clerk/models/deletedomainop.py @@ -0,0 +1,18 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel +from clerk.utils import FieldMetadata, PathParamMetadata +from typing import TypedDict +from typing_extensions import Annotated + + +class DeleteDomainRequestTypedDict(TypedDict): + domain_id: str + r"""The ID of the domain that will be deleted. Must be a satellite domain.""" + + +class DeleteDomainRequest(BaseModel): + domain_id: Annotated[str, FieldMetadata(path=PathParamMetadata(style="simple", explode=False))] + r"""The ID of the domain that will be deleted. Must be a satellite domain.""" + diff --git a/src/clerk/models/deleteemailaddressop.py b/src/clerk/models/deleteemailaddressop.py new file mode 100644 index 0000000..372c876 --- /dev/null +++ b/src/clerk/models/deleteemailaddressop.py @@ -0,0 +1,18 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel +from clerk.utils import FieldMetadata, PathParamMetadata +from typing import TypedDict +from typing_extensions import Annotated + + +class DeleteEmailAddressRequestTypedDict(TypedDict): + email_address_id: str + r"""The ID of the email address to delete""" + + +class DeleteEmailAddressRequest(BaseModel): + email_address_id: Annotated[str, FieldMetadata(path=PathParamMetadata(style="simple", explode=False))] + r"""The ID of the email address to delete""" + diff --git a/src/clerk/models/deletejwttemplateop.py b/src/clerk/models/deletejwttemplateop.py new file mode 100644 index 0000000..6017f2e --- /dev/null +++ b/src/clerk/models/deletejwttemplateop.py @@ -0,0 +1,18 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel +from clerk.utils import FieldMetadata, PathParamMetadata +from typing import TypedDict +from typing_extensions import Annotated + + +class DeleteJWTTemplateRequestTypedDict(TypedDict): + template_id: str + r"""JWT Template ID""" + + +class DeleteJWTTemplateRequest(BaseModel): + template_id: Annotated[str, FieldMetadata(path=PathParamMetadata(style="simple", explode=False))] + r"""JWT Template ID""" + diff --git a/src/clerk/models/deleteoauthapplicationop.py b/src/clerk/models/deleteoauthapplicationop.py new file mode 100644 index 0000000..316a154 --- /dev/null +++ b/src/clerk/models/deleteoauthapplicationop.py @@ -0,0 +1,18 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel +from clerk.utils import FieldMetadata, PathParamMetadata +from typing import TypedDict +from typing_extensions import Annotated + + +class DeleteOAuthApplicationRequestTypedDict(TypedDict): + oauth_application_id: str + r"""The ID of the OAuth application to delete""" + + +class DeleteOAuthApplicationRequest(BaseModel): + oauth_application_id: Annotated[str, FieldMetadata(path=PathParamMetadata(style="simple", explode=False))] + r"""The ID of the OAuth application to delete""" + diff --git a/src/clerk/models/deleteorganizationlogoop.py b/src/clerk/models/deleteorganizationlogoop.py new file mode 100644 index 0000000..ec1a759 --- /dev/null +++ b/src/clerk/models/deleteorganizationlogoop.py @@ -0,0 +1,18 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel +from clerk.utils import FieldMetadata, PathParamMetadata +from typing import TypedDict +from typing_extensions import Annotated + + +class DeleteOrganizationLogoRequestTypedDict(TypedDict): + organization_id: str + r"""The ID of the organization for which the logo will be deleted.""" + + +class DeleteOrganizationLogoRequest(BaseModel): + organization_id: Annotated[str, FieldMetadata(path=PathParamMetadata(style="simple", explode=False))] + r"""The ID of the organization for which the logo will be deleted.""" + diff --git a/src/clerk/models/deleteorganizationmembershipop.py b/src/clerk/models/deleteorganizationmembershipop.py new file mode 100644 index 0000000..5a7c334 --- /dev/null +++ b/src/clerk/models/deleteorganizationmembershipop.py @@ -0,0 +1,22 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel +from clerk.utils import FieldMetadata, PathParamMetadata +from typing import TypedDict +from typing_extensions import Annotated + + +class DeleteOrganizationMembershipRequestTypedDict(TypedDict): + organization_id: str + r"""The ID of the organization the membership belongs to""" + user_id: str + r"""The ID of the user that this membership belongs to""" + + +class DeleteOrganizationMembershipRequest(BaseModel): + organization_id: Annotated[str, FieldMetadata(path=PathParamMetadata(style="simple", explode=False))] + r"""The ID of the organization the membership belongs to""" + user_id: Annotated[str, FieldMetadata(path=PathParamMetadata(style="simple", explode=False))] + r"""The ID of the user that this membership belongs to""" + diff --git a/src/clerk/models/deleteorganizationop.py b/src/clerk/models/deleteorganizationop.py new file mode 100644 index 0000000..4e3f685 --- /dev/null +++ b/src/clerk/models/deleteorganizationop.py @@ -0,0 +1,18 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel +from clerk.utils import FieldMetadata, PathParamMetadata +from typing import TypedDict +from typing_extensions import Annotated + + +class DeleteOrganizationRequestTypedDict(TypedDict): + organization_id: str + r"""The ID of the organization to delete""" + + +class DeleteOrganizationRequest(BaseModel): + organization_id: Annotated[str, FieldMetadata(path=PathParamMetadata(style="simple", explode=False))] + r"""The ID of the organization to delete""" + diff --git a/src/clerk/models/deletephonenumberop.py b/src/clerk/models/deletephonenumberop.py new file mode 100644 index 0000000..f5272c0 --- /dev/null +++ b/src/clerk/models/deletephonenumberop.py @@ -0,0 +1,18 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel +from clerk.utils import FieldMetadata, PathParamMetadata +from typing import TypedDict +from typing_extensions import Annotated + + +class DeletePhoneNumberRequestTypedDict(TypedDict): + phone_number_id: str + r"""The ID of the phone number to delete""" + + +class DeletePhoneNumberRequest(BaseModel): + phone_number_id: Annotated[str, FieldMetadata(path=PathParamMetadata(style="simple", explode=False))] + r"""The ID of the phone number to delete""" + diff --git a/src/clerk/models/deleteredirecturlop.py b/src/clerk/models/deleteredirecturlop.py new file mode 100644 index 0000000..7d50a6d --- /dev/null +++ b/src/clerk/models/deleteredirecturlop.py @@ -0,0 +1,18 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel +from clerk.utils import FieldMetadata, PathParamMetadata +from typing import TypedDict +from typing_extensions import Annotated + + +class DeleteRedirectURLRequestTypedDict(TypedDict): + id: str + r"""The ID of the redirect URL""" + + +class DeleteRedirectURLRequest(BaseModel): + id: Annotated[str, FieldMetadata(path=PathParamMetadata(style="simple", explode=False))] + r"""The ID of the redirect URL""" + diff --git a/src/clerk/models/deletesamlconnectionop.py b/src/clerk/models/deletesamlconnectionop.py new file mode 100644 index 0000000..7bd9ec8 --- /dev/null +++ b/src/clerk/models/deletesamlconnectionop.py @@ -0,0 +1,18 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel +from clerk.utils import FieldMetadata, PathParamMetadata +from typing import TypedDict +from typing_extensions import Annotated + + +class DeleteSAMLConnectionRequestTypedDict(TypedDict): + saml_connection_id: str + r"""The ID of the SAML Connection to delete""" + + +class DeleteSAMLConnectionRequest(BaseModel): + saml_connection_id: Annotated[str, FieldMetadata(path=PathParamMetadata(style="simple", explode=False))] + r"""The ID of the SAML Connection to delete""" + diff --git a/src/clerk/models/deleteuserop.py b/src/clerk/models/deleteuserop.py new file mode 100644 index 0000000..70ccbbc --- /dev/null +++ b/src/clerk/models/deleteuserop.py @@ -0,0 +1,18 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel +from clerk.utils import FieldMetadata, PathParamMetadata +from typing import TypedDict +from typing_extensions import Annotated + + +class DeleteUserRequestTypedDict(TypedDict): + user_id: str + r"""The ID of the user to delete""" + + +class DeleteUserRequest(BaseModel): + user_id: Annotated[str, FieldMetadata(path=PathParamMetadata(style="simple", explode=False))] + r"""The ID of the user to delete""" + diff --git a/src/clerk/models/deleteuserprofileimageop.py b/src/clerk/models/deleteuserprofileimageop.py new file mode 100644 index 0000000..d52b068 --- /dev/null +++ b/src/clerk/models/deleteuserprofileimageop.py @@ -0,0 +1,18 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel +from clerk.utils import FieldMetadata, PathParamMetadata +from typing import TypedDict +from typing_extensions import Annotated + + +class DeleteUserProfileImageRequestTypedDict(TypedDict): + user_id: str + r"""The ID of the user to delete the profile image for""" + + +class DeleteUserProfileImageRequest(BaseModel): + user_id: Annotated[str, FieldMetadata(path=PathParamMetadata(style="simple", explode=False))] + r"""The ID of the user to delete the profile image for""" + diff --git a/src/clerk/models/disablemfaop.py b/src/clerk/models/disablemfaop.py new file mode 100644 index 0000000..cac1c91 --- /dev/null +++ b/src/clerk/models/disablemfaop.py @@ -0,0 +1,30 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel +from clerk.utils import FieldMetadata, PathParamMetadata +from typing import Optional, TypedDict +from typing_extensions import Annotated, NotRequired + + +class DisableMFARequestTypedDict(TypedDict): + user_id: str + r"""The ID of the user whose MFA methods are to be disabled""" + + +class DisableMFARequest(BaseModel): + user_id: Annotated[str, FieldMetadata(path=PathParamMetadata(style="simple", explode=False))] + r"""The ID of the user whose MFA methods are to be disabled""" + + +class DisableMFAResponseBodyTypedDict(TypedDict): + r"""Successful operation.""" + + user_id: NotRequired[str] + + +class DisableMFAResponseBody(BaseModel): + r"""Successful operation.""" + + user_id: Optional[str] = None + diff --git a/src/clerk/models/domain.py b/src/clerk/models/domain.py new file mode 100644 index 0000000..b6297aa --- /dev/null +++ b/src/clerk/models/domain.py @@ -0,0 +1,69 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from .cnametarget import CNameTarget, CNameTargetTypedDict +from clerk.types import BaseModel, Nullable +from enum import Enum +from pydantic import model_serializer +from typing import List, Optional, TypedDict +from typing_extensions import NotRequired + + +class DomainObject(str, Enum): + DOMAIN = "domain" + + +class DomainTypedDict(TypedDict): + object: DomainObject + id: str + name: str + is_satellite: bool + frontend_api_url: str + development_origin: str + accounts_portal_url: NotRequired[Nullable[str]] + r"""Null for satellite domains. + + """ + proxy_url: NotRequired[Nullable[str]] + cname_targets: NotRequired[Nullable[List[CNameTargetTypedDict]]] + + +class Domain(BaseModel): + object: DomainObject + id: str + name: str + is_satellite: bool + frontend_api_url: str + development_origin: str + accounts_portal_url: Optional[Nullable[str]] = None + r"""Null for satellite domains. + + """ + proxy_url: Optional[Nullable[str]] = None + cname_targets: Optional[Nullable[List[CNameTarget]]] = None + + @model_serializer(mode="wrap") + def serialize_model(self, handler): + optional_fields = ["accounts_portal_url", "proxy_url", "cname_targets"] + nullable_fields = ["accounts_portal_url", "proxy_url", "cname_targets"] + null_default_fields = [] + + serialized = handler(self) + + m = {} + + for n, f in self.model_fields.items(): + k = f.alias or n + val = serialized.get(k) + + if val is not None: + m[k] = val + elif not k in optional_fields or ( + k in optional_fields + and k in nullable_fields + and (self.__pydantic_fields_set__.intersection({n}) or k in null_default_fields) # pylint: disable=no-member + ): + m[k] = val + + return m + diff --git a/src/clerk/models/domains.py b/src/clerk/models/domains.py new file mode 100644 index 0000000..f57a1ba --- /dev/null +++ b/src/clerk/models/domains.py @@ -0,0 +1,23 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from .domain import Domain, DomainTypedDict +from clerk.types import BaseModel +from typing import List, TypedDict + + +class DomainsTypedDict(TypedDict): + data: List[DomainTypedDict] + total_count: int + r"""Total number of domains + + """ + + +class Domains(BaseModel): + data: List[Domain] + total_count: int + r"""Total number of domains + + """ + diff --git a/src/clerk/models/emailaddress.py b/src/clerk/models/emailaddress.py new file mode 100644 index 0000000..984be06 --- /dev/null +++ b/src/clerk/models/emailaddress.py @@ -0,0 +1,277 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from .identificationlink import IdentificationLink, IdentificationLinkTypedDict +from clerk.types import BaseModel, Nullable +from enum import Enum +from pydantic import model_serializer +from typing import List, Optional, TypedDict, Union +from typing_extensions import NotRequired + + +class EmailAddressObject(str, Enum): + r"""String representing the object's type. Objects of the same type share the same value. + + """ + EMAIL_ADDRESS = "email_address" + + +class OauthVerificationStatus(str, Enum): + UNVERIFIED = "unverified" + VERIFIED = "verified" + FAILED = "failed" + EXPIRED = "expired" + TRANSFERABLE = "transferable" + + +class OauthVerificationStrategy(str, Enum): + OAUTH_GOOGLE = "oauth_google" + OAUTH_MOCK = "oauth_mock" + FROM_OAUTH_DISCORD = "from_oauth_discord" + FROM_OAUTH_GOOGLE = "from_oauth_google" + + +class ErrorMetaTypedDict(TypedDict): + pass + + +class ErrorMeta(BaseModel): + pass + + +class ErrorClerkErrorTypedDict(TypedDict): + message: str + long_message: str + code: str + meta: NotRequired[ErrorMetaTypedDict] + clerk_trace_id: NotRequired[str] + + +class ErrorClerkError(BaseModel): + message: str + long_message: str + code: str + meta: Optional[ErrorMeta] = None + clerk_trace_id: Optional[str] = None + + +class OauthTypedDict(TypedDict): + status: OauthVerificationStatus + strategy: OauthVerificationStrategy + expire_at: Nullable[int] + external_verification_redirect_url: NotRequired[str] + error: NotRequired[Nullable[ErrorTypedDict]] + attempts: NotRequired[Nullable[int]] + + +class Oauth(BaseModel): + status: OauthVerificationStatus + strategy: OauthVerificationStrategy + expire_at: Nullable[int] + external_verification_redirect_url: Optional[str] = None + error: Optional[Nullable[Error]] = None + attempts: Optional[Nullable[int]] = None + + @model_serializer(mode="wrap") + def serialize_model(self, handler): + optional_fields = ["external_verification_redirect_url", "error", "attempts"] + nullable_fields = ["expire_at", "error", "attempts"] + null_default_fields = [] + + serialized = handler(self) + + m = {} + + for n, f in self.model_fields.items(): + k = f.alias or n + val = serialized.get(k) + + if val is not None: + m[k] = val + elif not k in optional_fields or ( + k in optional_fields + and k in nullable_fields + and (self.__pydantic_fields_set__.intersection({n}) or k in null_default_fields) # pylint: disable=no-member + ): + m[k] = val + + return m + + +class AdminVerificationStatus(str, Enum): + VERIFIED = "verified" + + +class VerificationStrategy(str, Enum): + ADMIN = "admin" + FROM_OAUTH_DISCORD = "from_oauth_discord" + + +class AdminTypedDict(TypedDict): + status: AdminVerificationStatus + strategy: VerificationStrategy + attempts: NotRequired[Nullable[int]] + expire_at: NotRequired[Nullable[int]] + + +class Admin(BaseModel): + status: AdminVerificationStatus + strategy: VerificationStrategy + attempts: Optional[Nullable[int]] = None + expire_at: Optional[Nullable[int]] = None + + @model_serializer(mode="wrap") + def serialize_model(self, handler): + optional_fields = ["attempts", "expire_at"] + nullable_fields = ["attempts", "expire_at"] + null_default_fields = [] + + serialized = handler(self) + + m = {} + + for n, f in self.model_fields.items(): + k = f.alias or n + val = serialized.get(k) + + if val is not None: + m[k] = val + elif not k in optional_fields or ( + k in optional_fields + and k in nullable_fields + and (self.__pydantic_fields_set__.intersection({n}) or k in null_default_fields) # pylint: disable=no-member + ): + m[k] = val + + return m + + +class VerificationStatus(str, Enum): + UNVERIFIED = "unverified" + VERIFIED = "verified" + FAILED = "failed" + EXPIRED = "expired" + + +class Strategy(str, Enum): + PHONE_CODE = "phone_code" + EMAIL_CODE = "email_code" + RESET_PASSWORD_EMAIL_CODE = "reset_password_email_code" + FROM_OAUTH_DISCORD = "from_oauth_discord" + + +class OtpTypedDict(TypedDict): + status: VerificationStatus + strategy: Strategy + attempts: Nullable[int] + expire_at: Nullable[int] + + +class Otp(BaseModel): + status: VerificationStatus + strategy: Strategy + attempts: Nullable[int] + expire_at: Nullable[int] + + @model_serializer(mode="wrap") + def serialize_model(self, handler): + optional_fields = [] + nullable_fields = ["attempts", "expire_at"] + null_default_fields = [] + + serialized = handler(self) + + m = {} + + for n, f in self.model_fields.items(): + k = f.alias or n + val = serialized.get(k) + + if val is not None: + m[k] = val + elif not k in optional_fields or ( + k in optional_fields + and k in nullable_fields + and (self.__pydantic_fields_set__.intersection({n}) or k in null_default_fields) # pylint: disable=no-member + ): + m[k] = val + + return m + + +class EmailAddressTypedDict(TypedDict): + object: EmailAddressObject + r"""String representing the object's type. Objects of the same type share the same value. + + """ + email_address: str + reserved: bool + verification: Nullable[VerificationTypedDict] + linked_to: List[IdentificationLinkTypedDict] + created_at: int + r"""Unix timestamp of creation + + """ + updated_at: int + r"""Unix timestamp of creation + + """ + id: NotRequired[str] + + +class EmailAddress(BaseModel): + object: EmailAddressObject + r"""String representing the object's type. Objects of the same type share the same value. + + """ + email_address: str + reserved: bool + verification: Nullable[Verification] + linked_to: List[IdentificationLink] + created_at: int + r"""Unix timestamp of creation + + """ + updated_at: int + r"""Unix timestamp of creation + + """ + id: Optional[str] = None + + @model_serializer(mode="wrap") + def serialize_model(self, handler): + optional_fields = ["id"] + nullable_fields = ["verification"] + null_default_fields = [] + + serialized = handler(self) + + m = {} + + for n, f in self.model_fields.items(): + k = f.alias or n + val = serialized.get(k) + + if val is not None: + m[k] = val + elif not k in optional_fields or ( + k in optional_fields + and k in nullable_fields + and (self.__pydantic_fields_set__.intersection({n}) or k in null_default_fields) # pylint: disable=no-member + ): + m[k] = val + + return m + + +ErrorTypedDict = Union[ErrorClerkErrorTypedDict] + + +Error = Union[ErrorClerkError] + + +VerificationTypedDict = Union[OtpTypedDict, AdminTypedDict, OauthTypedDict] + + +Verification = Union[Otp, Admin, Oauth] + diff --git a/src/clerk/models/getclientlistop.py b/src/clerk/models/getclientlistop.py new file mode 100644 index 0000000..7773032 --- /dev/null +++ b/src/clerk/models/getclientlistop.py @@ -0,0 +1,43 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from .client import Client, ClientTypedDict +from clerk.types import BaseModel +from clerk.utils import FieldMetadata, QueryParamMetadata +from typing import Callable, List, Optional, TypedDict +from typing_extensions import Annotated, NotRequired + + +class GetClientListRequestTypedDict(TypedDict): + limit: NotRequired[float] + r"""Applies a limit to the number of results returned. + Can be used for paginating the results together with `offset`. + """ + offset: NotRequired[float] + r"""Skip the first `offset` results when paginating. + Needs to be an integer greater or equal to zero. + To be used in conjunction with `limit`. + """ + + +class GetClientListRequest(BaseModel): + limit: Annotated[Optional[float], FieldMetadata(query=QueryParamMetadata(style="form", explode=True))] = 10 + r"""Applies a limit to the number of results returned. + Can be used for paginating the results together with `offset`. + """ + offset: Annotated[Optional[float], FieldMetadata(query=QueryParamMetadata(style="form", explode=True))] = 0 + r"""Skip the first `offset` results when paginating. + Needs to be an integer greater or equal to zero. + To be used in conjunction with `limit`. + """ + + +class GetClientListResponseTypedDict(TypedDict): + result: List[ClientTypedDict] + + +class GetClientListResponse(BaseModel): + next: Callable[[], Optional[GetClientListResponse]] + + result: List[Client] + diff --git a/src/clerk/models/getclientop.py b/src/clerk/models/getclientop.py new file mode 100644 index 0000000..5bdc4e0 --- /dev/null +++ b/src/clerk/models/getclientop.py @@ -0,0 +1,18 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel +from clerk.utils import FieldMetadata, PathParamMetadata +from typing import TypedDict +from typing_extensions import Annotated + + +class GetClientRequestTypedDict(TypedDict): + client_id: str + r"""Client ID.""" + + +class GetClientRequest(BaseModel): + client_id: Annotated[str, FieldMetadata(path=PathParamMetadata(style="simple", explode=False))] + r"""Client ID.""" + diff --git a/src/clerk/models/getemailaddressop.py b/src/clerk/models/getemailaddressop.py new file mode 100644 index 0000000..7bc5fb0 --- /dev/null +++ b/src/clerk/models/getemailaddressop.py @@ -0,0 +1,18 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel +from clerk.utils import FieldMetadata, PathParamMetadata +from typing import TypedDict +from typing_extensions import Annotated + + +class GetEmailAddressRequestTypedDict(TypedDict): + email_address_id: str + r"""The ID of the email address to retrieve""" + + +class GetEmailAddressRequest(BaseModel): + email_address_id: Annotated[str, FieldMetadata(path=PathParamMetadata(style="simple", explode=False))] + r"""The ID of the email address to retrieve""" + diff --git a/src/clerk/models/getjwttemplateop.py b/src/clerk/models/getjwttemplateop.py new file mode 100644 index 0000000..5d83aff --- /dev/null +++ b/src/clerk/models/getjwttemplateop.py @@ -0,0 +1,18 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel +from clerk.utils import FieldMetadata, PathParamMetadata +from typing import TypedDict +from typing_extensions import Annotated + + +class GetJWTTemplateRequestTypedDict(TypedDict): + template_id: str + r"""JWT Template ID""" + + +class GetJWTTemplateRequest(BaseModel): + template_id: Annotated[str, FieldMetadata(path=PathParamMetadata(style="simple", explode=False))] + r"""JWT Template ID""" + diff --git a/src/clerk/models/getoauthaccesstokenop.py b/src/clerk/models/getoauthaccesstokenop.py new file mode 100644 index 0000000..7c1ecf6 --- /dev/null +++ b/src/clerk/models/getoauthaccesstokenop.py @@ -0,0 +1,96 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel, Nullable +from clerk.utils import FieldMetadata, PathParamMetadata +from pydantic import model_serializer +from typing import List, Optional, TypedDict +from typing_extensions import Annotated, NotRequired + + +class GetOAuthAccessTokenRequestTypedDict(TypedDict): + user_id: str + r"""The ID of the user for which to retrieve the OAuth access token""" + provider: str + r"""The ID of the OAuth provider (e.g. `oauth_google`)""" + + +class GetOAuthAccessTokenRequest(BaseModel): + user_id: Annotated[str, FieldMetadata(path=PathParamMetadata(style="simple", explode=False))] + r"""The ID of the user for which to retrieve the OAuth access token""" + provider: Annotated[str, FieldMetadata(path=PathParamMetadata(style="simple", explode=False))] + r"""The ID of the OAuth provider (e.g. `oauth_google`)""" + + +class GetOAuthAccessTokenPublicMetadataTypedDict(TypedDict): + pass + + +class GetOAuthAccessTokenPublicMetadata(BaseModel): + pass + + +class ResponseBodyTypedDict(TypedDict): + object: NotRequired[str] + external_account_id: NotRequired[str] + r"""External account ID""" + provider_user_id: NotRequired[str] + r"""The unique ID of the user in the external provider's system""" + token: NotRequired[str] + r"""The access token""" + provider: NotRequired[str] + r"""The ID of the provider""" + public_metadata: NotRequired[GetOAuthAccessTokenPublicMetadataTypedDict] + label: NotRequired[Nullable[str]] + scopes: NotRequired[List[str]] + r"""The list of scopes that the token is valid for. + Only present for OAuth 2.0 tokens. + """ + token_secret: NotRequired[str] + r"""The token secret. Only present for OAuth 1.0 tokens.""" + + +class ResponseBody(BaseModel): + object: Optional[str] = None + external_account_id: Optional[str] = None + r"""External account ID""" + provider_user_id: Optional[str] = None + r"""The unique ID of the user in the external provider's system""" + token: Optional[str] = None + r"""The access token""" + provider: Optional[str] = None + r"""The ID of the provider""" + public_metadata: Optional[GetOAuthAccessTokenPublicMetadata] = None + label: Optional[Nullable[str]] = None + scopes: Optional[List[str]] = None + r"""The list of scopes that the token is valid for. + Only present for OAuth 2.0 tokens. + """ + token_secret: Optional[str] = None + r"""The token secret. Only present for OAuth 1.0 tokens.""" + + @model_serializer(mode="wrap") + def serialize_model(self, handler): + optional_fields = ["object", "external_account_id", "provider_user_id", "token", "provider", "public_metadata", "label", "scopes", "token_secret"] + nullable_fields = ["label"] + null_default_fields = [] + + serialized = handler(self) + + m = {} + + for n, f in self.model_fields.items(): + k = f.alias or n + val = serialized.get(k) + + if val is not None: + m[k] = val + elif not k in optional_fields or ( + k in optional_fields + and k in nullable_fields + and (self.__pydantic_fields_set__.intersection({n}) or k in null_default_fields) # pylint: disable=no-member + ): + m[k] = val + + return m + diff --git a/src/clerk/models/getoauthapplicationop.py b/src/clerk/models/getoauthapplicationop.py new file mode 100644 index 0000000..52613ea --- /dev/null +++ b/src/clerk/models/getoauthapplicationop.py @@ -0,0 +1,18 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel +from clerk.utils import FieldMetadata, PathParamMetadata +from typing import TypedDict +from typing_extensions import Annotated + + +class GetOAuthApplicationRequestTypedDict(TypedDict): + oauth_application_id: str + r"""The ID of the OAuth application""" + + +class GetOAuthApplicationRequest(BaseModel): + oauth_application_id: Annotated[str, FieldMetadata(path=PathParamMetadata(style="simple", explode=False))] + r"""The ID of the OAuth application""" + diff --git a/src/clerk/models/getorganizationinvitationop.py b/src/clerk/models/getorganizationinvitationop.py new file mode 100644 index 0000000..608dd15 --- /dev/null +++ b/src/clerk/models/getorganizationinvitationop.py @@ -0,0 +1,22 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel +from clerk.utils import FieldMetadata, PathParamMetadata +from typing import TypedDict +from typing_extensions import Annotated + + +class GetOrganizationInvitationRequestTypedDict(TypedDict): + organization_id: str + r"""The organization ID.""" + invitation_id: str + r"""The organization invitation ID.""" + + +class GetOrganizationInvitationRequest(BaseModel): + organization_id: Annotated[str, FieldMetadata(path=PathParamMetadata(style="simple", explode=False))] + r"""The organization ID.""" + invitation_id: Annotated[str, FieldMetadata(path=PathParamMetadata(style="simple", explode=False))] + r"""The organization invitation ID.""" + diff --git a/src/clerk/models/getorganizationop.py b/src/clerk/models/getorganizationop.py new file mode 100644 index 0000000..25308f8 --- /dev/null +++ b/src/clerk/models/getorganizationop.py @@ -0,0 +1,18 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel +from clerk.utils import FieldMetadata, PathParamMetadata +from typing import TypedDict +from typing_extensions import Annotated + + +class GetOrganizationRequestTypedDict(TypedDict): + organization_id: str + r"""The ID or slug of the organization""" + + +class GetOrganizationRequest(BaseModel): + organization_id: Annotated[str, FieldMetadata(path=PathParamMetadata(style="simple", explode=False))] + r"""The ID or slug of the organization""" + diff --git a/src/clerk/models/getphonenumberop.py b/src/clerk/models/getphonenumberop.py new file mode 100644 index 0000000..e0a44db --- /dev/null +++ b/src/clerk/models/getphonenumberop.py @@ -0,0 +1,18 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel +from clerk.utils import FieldMetadata, PathParamMetadata +from typing import TypedDict +from typing_extensions import Annotated + + +class GetPhoneNumberRequestTypedDict(TypedDict): + phone_number_id: str + r"""The ID of the phone number to retrieve""" + + +class GetPhoneNumberRequest(BaseModel): + phone_number_id: Annotated[str, FieldMetadata(path=PathParamMetadata(style="simple", explode=False))] + r"""The ID of the phone number to retrieve""" + diff --git a/src/clerk/models/getpublicinterstitialop.py b/src/clerk/models/getpublicinterstitialop.py new file mode 100644 index 0000000..d3683fb --- /dev/null +++ b/src/clerk/models/getpublicinterstitialop.py @@ -0,0 +1,23 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel +from clerk.utils import FieldMetadata, QueryParamMetadata +import pydantic +from typing import Optional, TypedDict +from typing_extensions import Annotated, NotRequired + + +class GetPublicInterstitialRequestTypedDict(TypedDict): + frontend_api: NotRequired[str] + r"""The Frontend API key of your instance""" + publishable_key: NotRequired[str] + r"""The publishable key of your instance""" + + +class GetPublicInterstitialRequest(BaseModel): + frontend_api: Annotated[Optional[str], pydantic.Field(alias="frontendApi"), FieldMetadata(query=QueryParamMetadata(style="form", explode=True))] = None + r"""The Frontend API key of your instance""" + publishable_key: Annotated[Optional[str], FieldMetadata(query=QueryParamMetadata(style="form", explode=True))] = None + r"""The publishable key of your instance""" + diff --git a/src/clerk/models/getredirecturlop.py b/src/clerk/models/getredirecturlop.py new file mode 100644 index 0000000..143a5ed --- /dev/null +++ b/src/clerk/models/getredirecturlop.py @@ -0,0 +1,18 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel +from clerk.utils import FieldMetadata, PathParamMetadata +from typing import TypedDict +from typing_extensions import Annotated + + +class GetRedirectURLRequestTypedDict(TypedDict): + id: str + r"""The ID of the redirect URL""" + + +class GetRedirectURLRequest(BaseModel): + id: Annotated[str, FieldMetadata(path=PathParamMetadata(style="simple", explode=False))] + r"""The ID of the redirect URL""" + diff --git a/src/clerk/models/getsamlconnectionop.py b/src/clerk/models/getsamlconnectionop.py new file mode 100644 index 0000000..cf8cfae --- /dev/null +++ b/src/clerk/models/getsamlconnectionop.py @@ -0,0 +1,18 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel +from clerk.utils import FieldMetadata, PathParamMetadata +from typing import TypedDict +from typing_extensions import Annotated + + +class GetSAMLConnectionRequestTypedDict(TypedDict): + saml_connection_id: str + r"""The ID of the SAML Connection""" + + +class GetSAMLConnectionRequest(BaseModel): + saml_connection_id: Annotated[str, FieldMetadata(path=PathParamMetadata(style="simple", explode=False))] + r"""The ID of the SAML Connection""" + diff --git a/src/clerk/models/getsessionlistop.py b/src/clerk/models/getsessionlistop.py new file mode 100644 index 0000000..d557a43 --- /dev/null +++ b/src/clerk/models/getsessionlistop.py @@ -0,0 +1,56 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel +from clerk.utils import FieldMetadata, QueryParamMetadata +from enum import Enum +from typing import Optional, TypedDict +from typing_extensions import Annotated, NotRequired + + +class QueryParamStatus(str, Enum): + r"""Filter sessions by the provided status""" + ABANDONED = "abandoned" + ACTIVE = "active" + ENDED = "ended" + EXPIRED = "expired" + REMOVED = "removed" + REPLACED = "replaced" + REVOKED = "revoked" + + +class GetSessionListRequestTypedDict(TypedDict): + client_id: NotRequired[str] + r"""List sessions for the given client""" + user_id: NotRequired[str] + r"""List sessions for the given user""" + status: NotRequired[QueryParamStatus] + r"""Filter sessions by the provided status""" + limit: NotRequired[float] + r"""Applies a limit to the number of results returned. + Can be used for paginating the results together with `offset`. + """ + offset: NotRequired[float] + r"""Skip the first `offset` results when paginating. + Needs to be an integer greater or equal to zero. + To be used in conjunction with `limit`. + """ + + +class GetSessionListRequest(BaseModel): + client_id: Annotated[Optional[str], FieldMetadata(query=QueryParamMetadata(style="form", explode=True))] = None + r"""List sessions for the given client""" + user_id: Annotated[Optional[str], FieldMetadata(query=QueryParamMetadata(style="form", explode=True))] = None + r"""List sessions for the given user""" + status: Annotated[Optional[QueryParamStatus], FieldMetadata(query=QueryParamMetadata(style="form", explode=True))] = None + r"""Filter sessions by the provided status""" + limit: Annotated[Optional[float], FieldMetadata(query=QueryParamMetadata(style="form", explode=True))] = 10 + r"""Applies a limit to the number of results returned. + Can be used for paginating the results together with `offset`. + """ + offset: Annotated[Optional[float], FieldMetadata(query=QueryParamMetadata(style="form", explode=True))] = 0 + r"""Skip the first `offset` results when paginating. + Needs to be an integer greater or equal to zero. + To be used in conjunction with `limit`. + """ + diff --git a/src/clerk/models/getsessionop.py b/src/clerk/models/getsessionop.py new file mode 100644 index 0000000..2ae92fa --- /dev/null +++ b/src/clerk/models/getsessionop.py @@ -0,0 +1,18 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel +from clerk.utils import FieldMetadata, PathParamMetadata +from typing import TypedDict +from typing_extensions import Annotated + + +class GetSessionRequestTypedDict(TypedDict): + session_id: str + r"""The ID of the session""" + + +class GetSessionRequest(BaseModel): + session_id: Annotated[str, FieldMetadata(path=PathParamMetadata(style="simple", explode=False))] + r"""The ID of the session""" + diff --git a/src/clerk/models/gettemplatelistop.py b/src/clerk/models/gettemplatelistop.py new file mode 100644 index 0000000..03a18cd --- /dev/null +++ b/src/clerk/models/gettemplatelistop.py @@ -0,0 +1,25 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel +from clerk.utils import FieldMetadata, PathParamMetadata +from enum import Enum +from typing import TypedDict +from typing_extensions import Annotated + + +class TemplateType(str, Enum): + r"""The type of templates to list (email or SMS)""" + EMAIL = "email" + SMS = "sms" + + +class GetTemplateListRequestTypedDict(TypedDict): + template_type: TemplateType + r"""The type of templates to list (email or SMS)""" + + +class GetTemplateListRequest(BaseModel): + template_type: Annotated[TemplateType, FieldMetadata(path=PathParamMetadata(style="simple", explode=False))] + r"""The type of templates to list (email or SMS)""" + diff --git a/src/clerk/models/gettemplateop.py b/src/clerk/models/gettemplateop.py new file mode 100644 index 0000000..31e9bfb --- /dev/null +++ b/src/clerk/models/gettemplateop.py @@ -0,0 +1,29 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel +from clerk.utils import FieldMetadata, PathParamMetadata +from enum import Enum +from typing import TypedDict +from typing_extensions import Annotated + + +class PathParamTemplateType(str, Enum): + r"""The type of templates to retrieve (email or SMS)""" + EMAIL = "email" + SMS = "sms" + + +class GetTemplateRequestTypedDict(TypedDict): + template_type: PathParamTemplateType + r"""The type of templates to retrieve (email or SMS)""" + slug: str + r"""The slug (i.e. machine-friendly name) of the template to retrieve""" + + +class GetTemplateRequest(BaseModel): + template_type: Annotated[PathParamTemplateType, FieldMetadata(path=PathParamMetadata(style="simple", explode=False))] + r"""The type of templates to retrieve (email or SMS)""" + slug: Annotated[str, FieldMetadata(path=PathParamMetadata(style="simple", explode=False))] + r"""The slug (i.e. machine-friendly name) of the template to retrieve""" + diff --git a/src/clerk/models/getuserlistop.py b/src/clerk/models/getuserlistop.py new file mode 100644 index 0000000..c05ab80 --- /dev/null +++ b/src/clerk/models/getuserlistop.py @@ -0,0 +1,162 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel +from clerk.utils import FieldMetadata, QueryParamMetadata +from typing import List, Optional, TypedDict +from typing_extensions import Annotated, NotRequired + + +class GetUserListRequestTypedDict(TypedDict): + email_address: NotRequired[List[str]] + r"""Returns users with the specified email addresses. + Accepts up to 100 email addresses. + Any email addresses not found are ignored. + """ + phone_number: NotRequired[List[str]] + r"""Returns users with the specified phone numbers. + Accepts up to 100 phone numbers. + Any phone numbers not found are ignored. + """ + external_id: NotRequired[List[str]] + r"""Returns users with the specified external ids. + For each external id, the `+` and `-` can be + prepended to the id, which denote whether the + respective external id should be included or + excluded from the result set. + Accepts up to 100 external ids. + Any external ids not found are ignored. + """ + username: NotRequired[List[str]] + r"""Returns users with the specified usernames. + Accepts up to 100 usernames. + Any usernames not found are ignored. + """ + web3_wallet: NotRequired[List[str]] + r"""Returns users with the specified web3 wallet addresses. + Accepts up to 100 web3 wallet addresses. + Any web3 wallet addressed not found are ignored. + """ + user_id: NotRequired[List[str]] + r"""Returns users with the user ids specified. + For each user id, the `+` and `-` can be + prepended to the id, which denote whether the + respective user id should be included or + excluded from the result set. + Accepts up to 100 user ids. + Any user ids not found are ignored. + """ + organization_id: NotRequired[List[str]] + r"""Returns users that have memberships to the + given organizations. + For each organization id, the `+` and `-` can be + prepended to the id, which denote whether the + respective organization should be included or + excluded from the result set. + Accepts up to 100 organization ids. + """ + query: NotRequired[str] + r"""Returns users that match the given query. + For possible matches, we check the email addresses, phone numbers, usernames, web3 wallets, user ids, first and last names. + The query value doesn't need to match the exact value you are looking for, it is capable of partial matches as well. + """ + last_active_at_since: NotRequired[int] + r"""Returns users that had session activity since the given date, with day precision. + Providing a value with higher precision than day will result in an error. + Example: use 1700690400000 to retrieve users that had session activity from 2023-11-23 until the current day. + """ + limit: NotRequired[float] + r"""Applies a limit to the number of results returned. + Can be used for paginating the results together with `offset`. + """ + offset: NotRequired[float] + r"""Skip the first `offset` results when paginating. + Needs to be an integer greater or equal to zero. + To be used in conjunction with `limit`. + """ + order_by: NotRequired[str] + r"""Allows to return users in a particular order. + At the moment, you can order the returned users by their `created_at`,`updated_at`,`email_address`,`web3wallet`,`first_name`,`last_name`,`phone_number`,`username`,`last_active_at`,`last_sign_in_at`. + In order to specify the direction, you can use the `+/-` symbols prepended in the property to order by. + For example, if you want users to be returned in descending order according to their `created_at` property, you can use `-created_at`. + If you don't use `+` or `-`, then `+` is implied. We only support one `order_by` parameter, and if multiple `order_by` parameters are provided, we will only keep the first one. For example, + if you pass `order_by=username&order_by=created_at`, we will consider only the first `order_by` parameter, which is `username`. The `created_at` parameter will be ignored in this case. + """ + + +class GetUserListRequest(BaseModel): + email_address: Annotated[Optional[List[str]], FieldMetadata(query=QueryParamMetadata(style="form", explode=True))] = None + r"""Returns users with the specified email addresses. + Accepts up to 100 email addresses. + Any email addresses not found are ignored. + """ + phone_number: Annotated[Optional[List[str]], FieldMetadata(query=QueryParamMetadata(style="form", explode=True))] = None + r"""Returns users with the specified phone numbers. + Accepts up to 100 phone numbers. + Any phone numbers not found are ignored. + """ + external_id: Annotated[Optional[List[str]], FieldMetadata(query=QueryParamMetadata(style="form", explode=True))] = None + r"""Returns users with the specified external ids. + For each external id, the `+` and `-` can be + prepended to the id, which denote whether the + respective external id should be included or + excluded from the result set. + Accepts up to 100 external ids. + Any external ids not found are ignored. + """ + username: Annotated[Optional[List[str]], FieldMetadata(query=QueryParamMetadata(style="form", explode=True))] = None + r"""Returns users with the specified usernames. + Accepts up to 100 usernames. + Any usernames not found are ignored. + """ + web3_wallet: Annotated[Optional[List[str]], FieldMetadata(query=QueryParamMetadata(style="form", explode=True))] = None + r"""Returns users with the specified web3 wallet addresses. + Accepts up to 100 web3 wallet addresses. + Any web3 wallet addressed not found are ignored. + """ + user_id: Annotated[Optional[List[str]], FieldMetadata(query=QueryParamMetadata(style="form", explode=True))] = None + r"""Returns users with the user ids specified. + For each user id, the `+` and `-` can be + prepended to the id, which denote whether the + respective user id should be included or + excluded from the result set. + Accepts up to 100 user ids. + Any user ids not found are ignored. + """ + organization_id: Annotated[Optional[List[str]], FieldMetadata(query=QueryParamMetadata(style="form", explode=True))] = None + r"""Returns users that have memberships to the + given organizations. + For each organization id, the `+` and `-` can be + prepended to the id, which denote whether the + respective organization should be included or + excluded from the result set. + Accepts up to 100 organization ids. + """ + query: Annotated[Optional[str], FieldMetadata(query=QueryParamMetadata(style="form", explode=True))] = None + r"""Returns users that match the given query. + For possible matches, we check the email addresses, phone numbers, usernames, web3 wallets, user ids, first and last names. + The query value doesn't need to match the exact value you are looking for, it is capable of partial matches as well. + """ + last_active_at_since: Annotated[Optional[int], FieldMetadata(query=QueryParamMetadata(style="form", explode=True))] = None + r"""Returns users that had session activity since the given date, with day precision. + Providing a value with higher precision than day will result in an error. + Example: use 1700690400000 to retrieve users that had session activity from 2023-11-23 until the current day. + """ + limit: Annotated[Optional[float], FieldMetadata(query=QueryParamMetadata(style="form", explode=True))] = 10 + r"""Applies a limit to the number of results returned. + Can be used for paginating the results together with `offset`. + """ + offset: Annotated[Optional[float], FieldMetadata(query=QueryParamMetadata(style="form", explode=True))] = 0 + r"""Skip the first `offset` results when paginating. + Needs to be an integer greater or equal to zero. + To be used in conjunction with `limit`. + """ + order_by: Annotated[Optional[str], FieldMetadata(query=QueryParamMetadata(style="form", explode=True))] = "-created_at" + r"""Allows to return users in a particular order. + At the moment, you can order the returned users by their `created_at`,`updated_at`,`email_address`,`web3wallet`,`first_name`,`last_name`,`phone_number`,`username`,`last_active_at`,`last_sign_in_at`. + In order to specify the direction, you can use the `+/-` symbols prepended in the property to order by. + For example, if you want users to be returned in descending order according to their `created_at` property, you can use `-created_at`. + If you don't use `+` or `-`, then `+` is implied. We only support one `order_by` parameter, and if multiple `order_by` parameters are provided, we will only keep the first one. For example, + if you pass `order_by=username&order_by=created_at`, we will consider only the first `order_by` parameter, which is `username`. The `created_at` parameter will be ignored in this case. + """ + diff --git a/src/clerk/models/getuserop.py b/src/clerk/models/getuserop.py new file mode 100644 index 0000000..44438ab --- /dev/null +++ b/src/clerk/models/getuserop.py @@ -0,0 +1,18 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel +from clerk.utils import FieldMetadata, PathParamMetadata +from typing import TypedDict +from typing_extensions import Annotated + + +class GetUserRequestTypedDict(TypedDict): + user_id: str + r"""The ID of the user to retrieve""" + + +class GetUserRequest(BaseModel): + user_id: Annotated[str, FieldMetadata(path=PathParamMetadata(style="simple", explode=False))] + r"""The ID of the user to retrieve""" + diff --git a/src/clerk/models/getuserscountop.py b/src/clerk/models/getuserscountop.py new file mode 100644 index 0000000..373646f --- /dev/null +++ b/src/clerk/models/getuserscountop.py @@ -0,0 +1,84 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel +from clerk.utils import FieldMetadata, QueryParamMetadata +from typing import List, Optional, TypedDict +from typing_extensions import Annotated, NotRequired + + +class GetUsersCountRequestTypedDict(TypedDict): + email_address: NotRequired[List[str]] + r"""Counts users with the specified email addresses. + Accepts up to 100 email addresses. + Any email addresses not found are ignored. + """ + phone_number: NotRequired[List[str]] + r"""Counts users with the specified phone numbers. + Accepts up to 100 phone numbers. + Any phone numbers not found are ignored. + """ + external_id: NotRequired[List[str]] + r"""Counts users with the specified external ids. + Accepts up to 100 external ids. + Any external ids not found are ignored. + """ + username: NotRequired[List[str]] + r"""Counts users with the specified usernames. + Accepts up to 100 usernames. + Any usernames not found are ignored. + """ + web3_wallet: NotRequired[List[str]] + r"""Counts users with the specified web3 wallet addresses. + Accepts up to 100 web3 wallet addresses. + Any web3 wallet addressed not found are ignored. + """ + user_id: NotRequired[List[str]] + r"""Counts users with the user ids specified. + Accepts up to 100 user ids. + Any user ids not found are ignored. + """ + query: NotRequired[str] + r"""Counts users that match the given query. + For possible matches, we check the email addresses, phone numbers, usernames, web3 wallets, user ids, first and last names. + The query value doesn't need to match the exact value you are looking for, it is capable of partial matches as well. + """ + + +class GetUsersCountRequest(BaseModel): + email_address: Annotated[Optional[List[str]], FieldMetadata(query=QueryParamMetadata(style="form", explode=True))] = None + r"""Counts users with the specified email addresses. + Accepts up to 100 email addresses. + Any email addresses not found are ignored. + """ + phone_number: Annotated[Optional[List[str]], FieldMetadata(query=QueryParamMetadata(style="form", explode=True))] = None + r"""Counts users with the specified phone numbers. + Accepts up to 100 phone numbers. + Any phone numbers not found are ignored. + """ + external_id: Annotated[Optional[List[str]], FieldMetadata(query=QueryParamMetadata(style="form", explode=True))] = None + r"""Counts users with the specified external ids. + Accepts up to 100 external ids. + Any external ids not found are ignored. + """ + username: Annotated[Optional[List[str]], FieldMetadata(query=QueryParamMetadata(style="form", explode=True))] = None + r"""Counts users with the specified usernames. + Accepts up to 100 usernames. + Any usernames not found are ignored. + """ + web3_wallet: Annotated[Optional[List[str]], FieldMetadata(query=QueryParamMetadata(style="form", explode=True))] = None + r"""Counts users with the specified web3 wallet addresses. + Accepts up to 100 web3 wallet addresses. + Any web3 wallet addressed not found are ignored. + """ + user_id: Annotated[Optional[List[str]], FieldMetadata(query=QueryParamMetadata(style="form", explode=True))] = None + r"""Counts users with the user ids specified. + Accepts up to 100 user ids. + Any user ids not found are ignored. + """ + query: Annotated[Optional[str], FieldMetadata(query=QueryParamMetadata(style="form", explode=True))] = None + r"""Counts users that match the given query. + For possible matches, we check the email addresses, phone numbers, usernames, web3 wallets, user ids, first and last names. + The query value doesn't need to match the exact value you are looking for, it is capable of partial matches as well. + """ + diff --git a/src/clerk/models/identificationlink.py b/src/clerk/models/identificationlink.py new file mode 100644 index 0000000..0e60f84 --- /dev/null +++ b/src/clerk/models/identificationlink.py @@ -0,0 +1,24 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel +from enum import Enum +from typing import TypedDict + + +class Type(str, Enum): + OAUTH_GOOGLE = "oauth_google" + OAUTH_MOCK = "oauth_mock" + SAML = "saml" + OAUTH_DISCORD = "oauth_discord" + + +class IdentificationLinkTypedDict(TypedDict): + type: Type + id: str + + +class IdentificationLink(BaseModel): + type: Type + id: str + diff --git a/src/clerk/models/instancerestrictions.py b/src/clerk/models/instancerestrictions.py new file mode 100644 index 0000000..6a50f37 --- /dev/null +++ b/src/clerk/models/instancerestrictions.py @@ -0,0 +1,31 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel +from enum import Enum +from typing import Optional, TypedDict +from typing_extensions import NotRequired + + +class InstanceRestrictionsObject(str, Enum): + r"""String representing the object's type. Objects of the same type share the same value.""" + INSTANCE_RESTRICTIONS = "instance_restrictions" + + +class InstanceRestrictionsTypedDict(TypedDict): + object: NotRequired[InstanceRestrictionsObject] + r"""String representing the object's type. Objects of the same type share the same value.""" + allowlist: NotRequired[bool] + blocklist: NotRequired[bool] + block_email_subaddresses: NotRequired[bool] + ignore_dots_for_gmail_addresses: NotRequired[bool] + + +class InstanceRestrictions(BaseModel): + object: Optional[InstanceRestrictionsObject] = None + r"""String representing the object's type. Objects of the same type share the same value.""" + allowlist: Optional[bool] = None + blocklist: Optional[bool] = None + block_email_subaddresses: Optional[bool] = None + ignore_dots_for_gmail_addresses: Optional[bool] = None + diff --git a/src/clerk/models/instancesettings.py b/src/clerk/models/instancesettings.py new file mode 100644 index 0000000..709839c --- /dev/null +++ b/src/clerk/models/instancesettings.py @@ -0,0 +1,33 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel +from enum import Enum +from typing import Optional, TypedDict +from typing_extensions import NotRequired + + +class InstanceSettingsObject(str, Enum): + r"""String representing the object's type. Objects of the same type share the same value.""" + INSTANCE_SETTINGS = "instance_settings" + + +class InstanceSettingsTypedDict(TypedDict): + object: NotRequired[InstanceSettingsObject] + r"""String representing the object's type. Objects of the same type share the same value.""" + id: NotRequired[str] + restricted_to_allowlist: NotRequired[bool] + from_email_address: NotRequired[str] + progressive_sign_up: NotRequired[bool] + enhanced_email_deliverability: NotRequired[bool] + + +class InstanceSettings(BaseModel): + object: Optional[InstanceSettingsObject] = None + r"""String representing the object's type. Objects of the same type share the same value.""" + id: Optional[str] = None + restricted_to_allowlist: Optional[bool] = None + from_email_address: Optional[str] = None + progressive_sign_up: Optional[bool] = None + enhanced_email_deliverability: Optional[bool] = None + diff --git a/src/clerk/models/invitation.py b/src/clerk/models/invitation.py new file mode 100644 index 0000000..4d9ff75 --- /dev/null +++ b/src/clerk/models/invitation.py @@ -0,0 +1,88 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel, Nullable +from enum import Enum +from pydantic import model_serializer +from typing import Optional, TypedDict +from typing_extensions import NotRequired + + +class InvitationObject(str, Enum): + INVITATION = "invitation" + + +class InvitationPublicMetadataTypedDict(TypedDict): + pass + + +class InvitationPublicMetadata(BaseModel): + pass + + +class InvitationStatus(str, Enum): + PENDING = "pending" + ACCEPTED = "accepted" + REVOKED = "revoked" + + +class InvitationTypedDict(TypedDict): + object: InvitationObject + id: str + email_address: str + status: InvitationStatus + created_at: int + r"""Unix timestamp of creation. + + """ + updated_at: int + r"""Unix timestamp of last update. + + """ + public_metadata: NotRequired[InvitationPublicMetadataTypedDict] + revoked: NotRequired[bool] + url: NotRequired[Nullable[str]] + + +class Invitation(BaseModel): + object: InvitationObject + id: str + email_address: str + status: InvitationStatus + created_at: int + r"""Unix timestamp of creation. + + """ + updated_at: int + r"""Unix timestamp of last update. + + """ + public_metadata: Optional[InvitationPublicMetadata] = None + revoked: Optional[bool] = None + url: Optional[Nullable[str]] = None + + @model_serializer(mode="wrap") + def serialize_model(self, handler): + optional_fields = ["public_metadata", "revoked", "url"] + nullable_fields = ["url"] + null_default_fields = [] + + serialized = handler(self) + + m = {} + + for n, f in self.model_fields.items(): + k = f.alias or n + val = serialized.get(k) + + if val is not None: + m[k] = val + elif not k in optional_fields or ( + k in optional_fields + and k in nullable_fields + and (self.__pydantic_fields_set__.intersection({n}) or k in null_default_fields) # pylint: disable=no-member + ): + m[k] = val + + return m + diff --git a/src/clerk/models/invitation_revoked.py b/src/clerk/models/invitation_revoked.py new file mode 100644 index 0000000..9f0d395 --- /dev/null +++ b/src/clerk/models/invitation_revoked.py @@ -0,0 +1,86 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel, Nullable +from enum import Enum +from pydantic import model_serializer +from typing import Optional, TypedDict +from typing_extensions import NotRequired + + +class InvitationRevokedObject(str, Enum): + INVITATION = "invitation" + + +class InvitationRevokedPublicMetadataTypedDict(TypedDict): + pass + + +class InvitationRevokedPublicMetadata(BaseModel): + pass + + +class InvitationRevokedStatus(str, Enum): + REVOKED = "revoked" + + +class InvitationRevokedTypedDict(TypedDict): + object: InvitationRevokedObject + id: str + email_address: str + status: InvitationRevokedStatus + created_at: int + r"""Unix timestamp of creation. + + """ + updated_at: int + r"""Unix timestamp of last update. + + """ + public_metadata: NotRequired[InvitationRevokedPublicMetadataTypedDict] + revoked: NotRequired[bool] + url: NotRequired[Nullable[str]] + + +class InvitationRevoked(BaseModel): + object: InvitationRevokedObject + id: str + email_address: str + status: InvitationRevokedStatus + created_at: int + r"""Unix timestamp of creation. + + """ + updated_at: int + r"""Unix timestamp of last update. + + """ + public_metadata: Optional[InvitationRevokedPublicMetadata] = None + revoked: Optional[bool] = None + url: Optional[Nullable[str]] = None + + @model_serializer(mode="wrap") + def serialize_model(self, handler): + optional_fields = ["public_metadata", "revoked", "url"] + nullable_fields = ["url"] + null_default_fields = [] + + serialized = handler(self) + + m = {} + + for n, f in self.model_fields.items(): + k = f.alias or n + val = serialized.get(k) + + if val is not None: + m[k] = val + elif not k in optional_fields or ( + k in optional_fields + and k in nullable_fields + and (self.__pydantic_fields_set__.intersection({n}) or k in null_default_fields) # pylint: disable=no-member + ): + m[k] = val + + return m + diff --git a/src/clerk/models/jwttemplate.py b/src/clerk/models/jwttemplate.py new file mode 100644 index 0000000..426e063 --- /dev/null +++ b/src/clerk/models/jwttemplate.py @@ -0,0 +1,58 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel +from enum import Enum +from typing import Optional, TypedDict +from typing_extensions import NotRequired + + +class JWTTemplateObject(str, Enum): + JWT_TEMPLATE = "jwt_template" + + +class ClaimsTypedDict(TypedDict): + pass + + +class Claims(BaseModel): + pass + + +class JWTTemplateTypedDict(TypedDict): + object: JWTTemplateObject + id: str + name: str + claims: ClaimsTypedDict + lifetime: int + allowed_clock_skew: int + created_at: int + r"""Unix timestamp of creation. + + """ + updated_at: int + r"""Unix timestamp of last update. + + """ + custom_signing_key: NotRequired[bool] + signing_algorithm: NotRequired[str] + + +class JWTTemplate(BaseModel): + object: JWTTemplateObject + id: str + name: str + claims: Claims + lifetime: int + allowed_clock_skew: int + created_at: int + r"""Unix timestamp of creation. + + """ + updated_at: int + r"""Unix timestamp of last update. + + """ + custom_signing_key: Optional[bool] = None + signing_algorithm: Optional[str] = None + diff --git a/src/clerk/models/listinvitationsop.py b/src/clerk/models/listinvitationsop.py new file mode 100644 index 0000000..e3b4ca8 --- /dev/null +++ b/src/clerk/models/listinvitationsop.py @@ -0,0 +1,55 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from .invitation import Invitation, InvitationTypedDict +from clerk.types import BaseModel +from clerk.utils import FieldMetadata, QueryParamMetadata +from enum import Enum +from typing import Callable, List, Optional, TypedDict +from typing_extensions import Annotated, NotRequired + + +class ListInvitationsQueryParamStatus(str, Enum): + r"""Filter invitations based on their status""" + PENDING = "pending" + ACCEPTED = "accepted" + REVOKED = "revoked" + + +class ListInvitationsRequestTypedDict(TypedDict): + limit: NotRequired[float] + r"""Applies a limit to the number of results returned. + Can be used for paginating the results together with `offset`. + """ + offset: NotRequired[float] + r"""Skip the first `offset` results when paginating. + Needs to be an integer greater or equal to zero. + To be used in conjunction with `limit`. + """ + status: NotRequired[ListInvitationsQueryParamStatus] + r"""Filter invitations based on their status""" + + +class ListInvitationsRequest(BaseModel): + limit: Annotated[Optional[float], FieldMetadata(query=QueryParamMetadata(style="form", explode=True))] = 10 + r"""Applies a limit to the number of results returned. + Can be used for paginating the results together with `offset`. + """ + offset: Annotated[Optional[float], FieldMetadata(query=QueryParamMetadata(style="form", explode=True))] = 0 + r"""Skip the first `offset` results when paginating. + Needs to be an integer greater or equal to zero. + To be used in conjunction with `limit`. + """ + status: Annotated[Optional[ListInvitationsQueryParamStatus], FieldMetadata(query=QueryParamMetadata(style="form", explode=True))] = None + r"""Filter invitations based on their status""" + + +class ListInvitationsResponseTypedDict(TypedDict): + result: List[InvitationTypedDict] + + +class ListInvitationsResponse(BaseModel): + next: Callable[[], Optional[ListInvitationsResponse]] + + result: List[Invitation] + diff --git a/src/clerk/models/listoauthapplicationsop.py b/src/clerk/models/listoauthapplicationsop.py new file mode 100644 index 0000000..df645c2 --- /dev/null +++ b/src/clerk/models/listoauthapplicationsop.py @@ -0,0 +1,43 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from .oauthapplications import OAuthApplications, OAuthApplicationsTypedDict +from clerk.types import BaseModel +from clerk.utils import FieldMetadata, QueryParamMetadata +from typing import Callable, Optional, TypedDict +from typing_extensions import Annotated, NotRequired + + +class ListOAuthApplicationsRequestTypedDict(TypedDict): + limit: NotRequired[float] + r"""Applies a limit to the number of results returned. + Can be used for paginating the results together with `offset`. + """ + offset: NotRequired[float] + r"""Skip the first `offset` results when paginating. + Needs to be an integer greater or equal to zero. + To be used in conjunction with `limit`. + """ + + +class ListOAuthApplicationsRequest(BaseModel): + limit: Annotated[Optional[float], FieldMetadata(query=QueryParamMetadata(style="form", explode=True))] = 10 + r"""Applies a limit to the number of results returned. + Can be used for paginating the results together with `offset`. + """ + offset: Annotated[Optional[float], FieldMetadata(query=QueryParamMetadata(style="form", explode=True))] = 0 + r"""Skip the first `offset` results when paginating. + Needs to be an integer greater or equal to zero. + To be used in conjunction with `limit`. + """ + + +class ListOAuthApplicationsResponseTypedDict(TypedDict): + result: OAuthApplicationsTypedDict + + +class ListOAuthApplicationsResponse(BaseModel): + next: Callable[[], Optional[ListOAuthApplicationsResponse]] + + result: OAuthApplications + diff --git a/src/clerk/models/listorganizationinvitationsop.py b/src/clerk/models/listorganizationinvitationsop.py new file mode 100644 index 0000000..e3ac26a --- /dev/null +++ b/src/clerk/models/listorganizationinvitationsop.py @@ -0,0 +1,59 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from .organizationinvitations import OrganizationInvitations, OrganizationInvitationsTypedDict +from clerk.types import BaseModel +from clerk.utils import FieldMetadata, PathParamMetadata, QueryParamMetadata +from enum import Enum +from typing import Callable, Optional, TypedDict +from typing_extensions import Annotated, NotRequired + + +class ListOrganizationInvitationsQueryParamStatus(str, Enum): + r"""Filter organization invitations based on their status""" + PENDING = "pending" + ACCEPTED = "accepted" + REVOKED = "revoked" + + +class ListOrganizationInvitationsRequestTypedDict(TypedDict): + organization_id: str + r"""The organization ID.""" + limit: NotRequired[float] + r"""Applies a limit to the number of results returned. + Can be used for paginating the results together with `offset`. + """ + offset: NotRequired[float] + r"""Skip the first `offset` results when paginating. + Needs to be an integer greater or equal to zero. + To be used in conjunction with `limit`. + """ + status: NotRequired[ListOrganizationInvitationsQueryParamStatus] + r"""Filter organization invitations based on their status""" + + +class ListOrganizationInvitationsRequest(BaseModel): + organization_id: Annotated[str, FieldMetadata(path=PathParamMetadata(style="simple", explode=False))] + r"""The organization ID.""" + limit: Annotated[Optional[float], FieldMetadata(query=QueryParamMetadata(style="form", explode=True))] = 10 + r"""Applies a limit to the number of results returned. + Can be used for paginating the results together with `offset`. + """ + offset: Annotated[Optional[float], FieldMetadata(query=QueryParamMetadata(style="form", explode=True))] = 0 + r"""Skip the first `offset` results when paginating. + Needs to be an integer greater or equal to zero. + To be used in conjunction with `limit`. + """ + status: Annotated[Optional[ListOrganizationInvitationsQueryParamStatus], FieldMetadata(query=QueryParamMetadata(style="form", explode=True))] = None + r"""Filter organization invitations based on their status""" + + +class ListOrganizationInvitationsResponseTypedDict(TypedDict): + result: OrganizationInvitationsTypedDict + + +class ListOrganizationInvitationsResponse(BaseModel): + next: Callable[[], Optional[ListOrganizationInvitationsResponse]] + + result: OrganizationInvitations + diff --git a/src/clerk/models/listorganizationmembershipsop.py b/src/clerk/models/listorganizationmembershipsop.py new file mode 100644 index 0000000..21384d5 --- /dev/null +++ b/src/clerk/models/listorganizationmembershipsop.py @@ -0,0 +1,57 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from .organizationmemberships import OrganizationMemberships, OrganizationMembershipsTypedDict +from clerk.types import BaseModel +from clerk.utils import FieldMetadata, PathParamMetadata, QueryParamMetadata +from typing import Callable, Optional, TypedDict +from typing_extensions import Annotated, NotRequired + + +class ListOrganizationMembershipsRequestTypedDict(TypedDict): + organization_id: str + r"""The organization ID.""" + limit: NotRequired[float] + r"""Applies a limit to the number of results returned. + Can be used for paginating the results together with `offset`. + """ + offset: NotRequired[float] + r"""Skip the first `offset` results when paginating. + Needs to be an integer greater or equal to zero. + To be used in conjunction with `limit`. + """ + order_by: NotRequired[str] + r"""Sorts organizations memberships by phone_number, email_address, created_at, first_name, last_name or username. + By prepending one of those values with + or -, + we can choose to sort in ascending (ASC) or descending (DESC) order.\" + """ + + +class ListOrganizationMembershipsRequest(BaseModel): + organization_id: Annotated[str, FieldMetadata(path=PathParamMetadata(style="simple", explode=False))] + r"""The organization ID.""" + limit: Annotated[Optional[float], FieldMetadata(query=QueryParamMetadata(style="form", explode=True))] = 10 + r"""Applies a limit to the number of results returned. + Can be used for paginating the results together with `offset`. + """ + offset: Annotated[Optional[float], FieldMetadata(query=QueryParamMetadata(style="form", explode=True))] = 0 + r"""Skip the first `offset` results when paginating. + Needs to be an integer greater or equal to zero. + To be used in conjunction with `limit`. + """ + order_by: Annotated[Optional[str], FieldMetadata(query=QueryParamMetadata(style="form", explode=True))] = None + r"""Sorts organizations memberships by phone_number, email_address, created_at, first_name, last_name or username. + By prepending one of those values with + or -, + we can choose to sort in ascending (ASC) or descending (DESC) order.\" + """ + + +class ListOrganizationMembershipsResponseTypedDict(TypedDict): + result: OrganizationMembershipsTypedDict + + +class ListOrganizationMembershipsResponse(BaseModel): + next: Callable[[], Optional[ListOrganizationMembershipsResponse]] + + result: OrganizationMemberships + diff --git a/src/clerk/models/listorganizationsop.py b/src/clerk/models/listorganizationsop.py new file mode 100644 index 0000000..623bc7e --- /dev/null +++ b/src/clerk/models/listorganizationsop.py @@ -0,0 +1,60 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel +from clerk.utils import FieldMetadata, QueryParamMetadata +from typing import Optional, TypedDict +from typing_extensions import Annotated, NotRequired + + +class ListOrganizationsRequestTypedDict(TypedDict): + limit: NotRequired[float] + r"""Applies a limit to the number of results returned. + Can be used for paginating the results together with `offset`. + """ + offset: NotRequired[float] + r"""Skip the first `offset` results when paginating. + Needs to be an integer greater or equal to zero. + To be used in conjunction with `limit`. + """ + include_members_count: NotRequired[bool] + r"""Flag to denote whether the member counts of each organization should be included in the response or not.""" + query: NotRequired[str] + r"""Returns organizations with ID, name, or slug that match the given query. + Uses exact match for organization ID and partial match for name and slug. + """ + order_by: NotRequired[str] + r"""Allows to return organizations in a particular order. + At the moment, you can order the returned organizations either by their `name`, `created_at` or `members_count`. + In order to specify the direction, you can use the `+/-` symbols prepended in the property to order by. + For example, if you want organizations to be returned in descending order according to their `created_at` property, you can use `-created_at`. + If you don't use `+` or `-`, then `+` is implied. + Defaults to `-created_at`. + """ + + +class ListOrganizationsRequest(BaseModel): + limit: Annotated[Optional[float], FieldMetadata(query=QueryParamMetadata(style="form", explode=True))] = 10 + r"""Applies a limit to the number of results returned. + Can be used for paginating the results together with `offset`. + """ + offset: Annotated[Optional[float], FieldMetadata(query=QueryParamMetadata(style="form", explode=True))] = 0 + r"""Skip the first `offset` results when paginating. + Needs to be an integer greater or equal to zero. + To be used in conjunction with `limit`. + """ + include_members_count: Annotated[Optional[bool], FieldMetadata(query=QueryParamMetadata(style="form", explode=True))] = None + r"""Flag to denote whether the member counts of each organization should be included in the response or not.""" + query: Annotated[Optional[str], FieldMetadata(query=QueryParamMetadata(style="form", explode=True))] = None + r"""Returns organizations with ID, name, or slug that match the given query. + Uses exact match for organization ID and partial match for name and slug. + """ + order_by: Annotated[Optional[str], FieldMetadata(query=QueryParamMetadata(style="form", explode=True))] = "-created_at" + r"""Allows to return organizations in a particular order. + At the moment, you can order the returned organizations either by their `name`, `created_at` or `members_count`. + In order to specify the direction, you can use the `+/-` symbols prepended in the property to order by. + For example, if you want organizations to be returned in descending order according to their `created_at` property, you can use `-created_at`. + If you don't use `+` or `-`, then `+` is implied. + Defaults to `-created_at`. + """ + diff --git a/src/clerk/models/listpendingorganizationinvitationsop.py b/src/clerk/models/listpendingorganizationinvitationsop.py new file mode 100644 index 0000000..59cc224 --- /dev/null +++ b/src/clerk/models/listpendingorganizationinvitationsop.py @@ -0,0 +1,47 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from .organizationinvitations import OrganizationInvitations, OrganizationInvitationsTypedDict +from clerk.types import BaseModel +from clerk.utils import FieldMetadata, PathParamMetadata, QueryParamMetadata +from typing import Callable, Optional, TypedDict +from typing_extensions import Annotated, NotRequired + + +class ListPendingOrganizationInvitationsRequestTypedDict(TypedDict): + organization_id: str + r"""The organization ID.""" + limit: NotRequired[float] + r"""Applies a limit to the number of results returned. + Can be used for paginating the results together with `offset`. + """ + offset: NotRequired[float] + r"""Skip the first `offset` results when paginating. + Needs to be an integer greater or equal to zero. + To be used in conjunction with `limit`. + """ + + +class ListPendingOrganizationInvitationsRequest(BaseModel): + organization_id: Annotated[str, FieldMetadata(path=PathParamMetadata(style="simple", explode=False))] + r"""The organization ID.""" + limit: Annotated[Optional[float], FieldMetadata(query=QueryParamMetadata(style="form", explode=True))] = 10 + r"""Applies a limit to the number of results returned. + Can be used for paginating the results together with `offset`. + """ + offset: Annotated[Optional[float], FieldMetadata(query=QueryParamMetadata(style="form", explode=True))] = 0 + r"""Skip the first `offset` results when paginating. + Needs to be an integer greater or equal to zero. + To be used in conjunction with `limit`. + """ + + +class ListPendingOrganizationInvitationsResponseTypedDict(TypedDict): + result: OrganizationInvitationsTypedDict + + +class ListPendingOrganizationInvitationsResponse(BaseModel): + next: Callable[[], Optional[ListPendingOrganizationInvitationsResponse]] + + result: OrganizationInvitations + diff --git a/src/clerk/models/listsamlconnectionsop.py b/src/clerk/models/listsamlconnectionsop.py new file mode 100644 index 0000000..ae2f915 --- /dev/null +++ b/src/clerk/models/listsamlconnectionsop.py @@ -0,0 +1,43 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from .samlconnections import SAMLConnections, SAMLConnectionsTypedDict +from clerk.types import BaseModel +from clerk.utils import FieldMetadata, QueryParamMetadata +from typing import Callable, Optional, TypedDict +from typing_extensions import Annotated, NotRequired + + +class ListSAMLConnectionsRequestTypedDict(TypedDict): + limit: NotRequired[float] + r"""Applies a limit to the number of results returned. + Can be used for paginating the results together with `offset`. + """ + offset: NotRequired[float] + r"""Skip the first `offset` results when paginating. + Needs to be an integer greater or equal to zero. + To be used in conjunction with `limit`. + """ + + +class ListSAMLConnectionsRequest(BaseModel): + limit: Annotated[Optional[float], FieldMetadata(query=QueryParamMetadata(style="form", explode=True))] = 10 + r"""Applies a limit to the number of results returned. + Can be used for paginating the results together with `offset`. + """ + offset: Annotated[Optional[float], FieldMetadata(query=QueryParamMetadata(style="form", explode=True))] = 0 + r"""Skip the first `offset` results when paginating. + Needs to be an integer greater or equal to zero. + To be used in conjunction with `limit`. + """ + + +class ListSAMLConnectionsResponseTypedDict(TypedDict): + result: SAMLConnectionsTypedDict + + +class ListSAMLConnectionsResponse(BaseModel): + next: Callable[[], Optional[ListSAMLConnectionsResponse]] + + result: SAMLConnections + diff --git a/src/clerk/models/lockuserop.py b/src/clerk/models/lockuserop.py new file mode 100644 index 0000000..421c9fb --- /dev/null +++ b/src/clerk/models/lockuserop.py @@ -0,0 +1,18 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel +from clerk.utils import FieldMetadata, PathParamMetadata +from typing import TypedDict +from typing_extensions import Annotated + + +class LockUserRequestTypedDict(TypedDict): + user_id: str + r"""The ID of the user to lock""" + + +class LockUserRequest(BaseModel): + user_id: Annotated[str, FieldMetadata(path=PathParamMetadata(style="simple", explode=False))] + r"""The ID of the user to lock""" + diff --git a/src/clerk/models/mergeorganizationmetadataop.py b/src/clerk/models/mergeorganizationmetadataop.py new file mode 100644 index 0000000..c1bff43 --- /dev/null +++ b/src/clerk/models/mergeorganizationmetadataop.py @@ -0,0 +1,70 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel +from clerk.utils import FieldMetadata, PathParamMetadata, RequestMetadata +from typing import Optional, TypedDict +from typing_extensions import Annotated, NotRequired + + +class MergeOrganizationMetadataPublicMetadataTypedDict(TypedDict): + r"""Metadata saved on the organization, that is visible to both your frontend and backend. + The new object will be merged with the existing value. + """ + + + +class MergeOrganizationMetadataPublicMetadata(BaseModel): + r"""Metadata saved on the organization, that is visible to both your frontend and backend. + The new object will be merged with the existing value. + """ + + + +class MergeOrganizationMetadataPrivateMetadataTypedDict(TypedDict): + r"""Metadata saved on the organization that is only visible to your backend. + The new object will be merged with the existing value. + """ + + + +class MergeOrganizationMetadataPrivateMetadata(BaseModel): + r"""Metadata saved on the organization that is only visible to your backend. + The new object will be merged with the existing value. + """ + + + +class MergeOrganizationMetadataRequestBodyTypedDict(TypedDict): + public_metadata: NotRequired[MergeOrganizationMetadataPublicMetadataTypedDict] + r"""Metadata saved on the organization, that is visible to both your frontend and backend. + The new object will be merged with the existing value. + """ + private_metadata: NotRequired[MergeOrganizationMetadataPrivateMetadataTypedDict] + r"""Metadata saved on the organization that is only visible to your backend. + The new object will be merged with the existing value. + """ + + +class MergeOrganizationMetadataRequestBody(BaseModel): + public_metadata: Optional[MergeOrganizationMetadataPublicMetadata] = None + r"""Metadata saved on the organization, that is visible to both your frontend and backend. + The new object will be merged with the existing value. + """ + private_metadata: Optional[MergeOrganizationMetadataPrivateMetadata] = None + r"""Metadata saved on the organization that is only visible to your backend. + The new object will be merged with the existing value. + """ + + +class MergeOrganizationMetadataRequestTypedDict(TypedDict): + organization_id: str + r"""The ID of the organization for which metadata will be merged or updated""" + request_body: MergeOrganizationMetadataRequestBodyTypedDict + + +class MergeOrganizationMetadataRequest(BaseModel): + organization_id: Annotated[str, FieldMetadata(path=PathParamMetadata(style="simple", explode=False))] + r"""The ID of the organization for which metadata will be merged or updated""" + request_body: Annotated[MergeOrganizationMetadataRequestBody, FieldMetadata(request=RequestMetadata(media_type="application/json"))] + diff --git a/src/clerk/models/oauthapplication.py b/src/clerk/models/oauthapplication.py new file mode 100644 index 0000000..ea15644 --- /dev/null +++ b/src/clerk/models/oauthapplication.py @@ -0,0 +1,55 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel +from enum import Enum +from typing import TypedDict + + +class OAuthApplicationObject(str, Enum): + OAUTH_APPLICATION = "oauth_application" + + +class OAuthApplicationTypedDict(TypedDict): + object: OAuthApplicationObject + id: str + instance_id: str + name: str + client_id: str + public: bool + scopes: str + callback_url: str + authorize_url: str + token_fetch_url: str + user_info_url: str + created_at: int + r"""Unix timestamp of creation. + + """ + updated_at: int + r"""Unix timestamp of last update. + + """ + + +class OAuthApplication(BaseModel): + object: OAuthApplicationObject + id: str + instance_id: str + name: str + client_id: str + public: bool + scopes: str + callback_url: str + authorize_url: str + token_fetch_url: str + user_info_url: str + created_at: int + r"""Unix timestamp of creation. + + """ + updated_at: int + r"""Unix timestamp of last update. + + """ + diff --git a/src/clerk/models/oauthapplications.py b/src/clerk/models/oauthapplications.py new file mode 100644 index 0000000..dd93856 --- /dev/null +++ b/src/clerk/models/oauthapplications.py @@ -0,0 +1,23 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from .oauthapplication import OAuthApplication, OAuthApplicationTypedDict +from clerk.types import BaseModel +from typing import List, TypedDict + + +class OAuthApplicationsTypedDict(TypedDict): + data: List[OAuthApplicationTypedDict] + total_count: int + r"""Total number of OAuth applications + + """ + + +class OAuthApplications(BaseModel): + data: List[OAuthApplication] + total_count: int + r"""Total number of OAuth applications + + """ + diff --git a/src/clerk/models/oauthapplicationwithsecret.py b/src/clerk/models/oauthapplicationwithsecret.py new file mode 100644 index 0000000..78a53cf --- /dev/null +++ b/src/clerk/models/oauthapplicationwithsecret.py @@ -0,0 +1,64 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel +from enum import Enum +from typing import Optional, TypedDict +from typing_extensions import NotRequired + + +class OAuthApplicationWithSecretObject(str, Enum): + OAUTH_APPLICATION = "oauth_application" + + +class OAuthApplicationWithSecretTypedDict(TypedDict): + object: OAuthApplicationWithSecretObject + id: str + instance_id: str + name: str + client_id: str + public: bool + scopes: str + callback_url: str + authorize_url: str + token_fetch_url: str + user_info_url: str + created_at: int + r"""Unix timestamp of creation. + + """ + updated_at: int + r"""Unix timestamp of last update. + + """ + client_secret: NotRequired[str] + r"""Empty if public client. + + """ + + +class OAuthApplicationWithSecret(BaseModel): + object: OAuthApplicationWithSecretObject + id: str + instance_id: str + name: str + client_id: str + public: bool + scopes: str + callback_url: str + authorize_url: str + token_fetch_url: str + user_info_url: str + created_at: int + r"""Unix timestamp of creation. + + """ + updated_at: int + r"""Unix timestamp of last update. + + """ + client_secret: Optional[str] = None + r"""Empty if public client. + + """ + diff --git a/src/clerk/models/organization.py b/src/clerk/models/organization.py new file mode 100644 index 0000000..c29a8e7 --- /dev/null +++ b/src/clerk/models/organization.py @@ -0,0 +1,96 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel, Nullable +from enum import Enum +from pydantic import model_serializer +from typing import Optional, TypedDict +from typing_extensions import NotRequired + + +class OrganizationObject(str, Enum): + ORGANIZATION = "organization" + + +class OrganizationPublicMetadataTypedDict(TypedDict): + pass + + +class OrganizationPublicMetadata(BaseModel): + pass + + +class OrganizationPrivateMetadataTypedDict(TypedDict): + pass + + +class OrganizationPrivateMetadata(BaseModel): + pass + + +class OrganizationTypedDict(TypedDict): + object: OrganizationObject + id: str + name: str + slug: str + max_allowed_memberships: int + public_metadata: OrganizationPublicMetadataTypedDict + private_metadata: OrganizationPrivateMetadataTypedDict + created_at: int + r"""Unix timestamp of creation. + + """ + updated_at: int + r"""Unix timestamp of last update. + + """ + members_count: NotRequired[Nullable[int]] + admin_delete_enabled: NotRequired[bool] + created_by: NotRequired[str] + + +class Organization(BaseModel): + object: OrganizationObject + id: str + name: str + slug: str + max_allowed_memberships: int + public_metadata: OrganizationPublicMetadata + private_metadata: OrganizationPrivateMetadata + created_at: int + r"""Unix timestamp of creation. + + """ + updated_at: int + r"""Unix timestamp of last update. + + """ + members_count: Optional[Nullable[int]] = None + admin_delete_enabled: Optional[bool] = None + created_by: Optional[str] = None + + @model_serializer(mode="wrap") + def serialize_model(self, handler): + optional_fields = ["members_count", "admin_delete_enabled", "created_by"] + nullable_fields = ["members_count"] + null_default_fields = [] + + serialized = handler(self) + + m = {} + + for n, f in self.model_fields.items(): + k = f.alias or n + val = serialized.get(k) + + if val is not None: + m[k] = val + elif not k in optional_fields or ( + k in optional_fields + and k in nullable_fields + and (self.__pydantic_fields_set__.intersection({n}) or k in null_default_fields) # pylint: disable=no-member + ): + m[k] = val + + return m + diff --git a/src/clerk/models/organizationinvitation.py b/src/clerk/models/organizationinvitation.py new file mode 100644 index 0000000..46aa9ba --- /dev/null +++ b/src/clerk/models/organizationinvitation.py @@ -0,0 +1,71 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel +from enum import Enum +from typing import Optional, TypedDict +from typing_extensions import NotRequired + + +class OrganizationInvitationObject(str, Enum): + r"""String representing the object's type. Objects of the same type share the same value. + + """ + ORGANIZATION_INVITATION = "organization_invitation" + + +class OrganizationInvitationPublicMetadataTypedDict(TypedDict): + pass + + +class OrganizationInvitationPublicMetadata(BaseModel): + pass + + +class OrganizationInvitationPrivateMetadataTypedDict(TypedDict): + pass + + +class OrganizationInvitationPrivateMetadata(BaseModel): + pass + + +class OrganizationInvitationTypedDict(TypedDict): + r"""An organization invitation""" + + id: NotRequired[str] + object: NotRequired[OrganizationInvitationObject] + r"""String representing the object's type. Objects of the same type share the same value. + + """ + email_address: NotRequired[str] + role: NotRequired[str] + organization_id: NotRequired[str] + status: NotRequired[str] + public_metadata: NotRequired[OrganizationInvitationPublicMetadataTypedDict] + private_metadata: NotRequired[OrganizationInvitationPrivateMetadataTypedDict] + created_at: NotRequired[int] + r"""Unix timestamp of creation.""" + updated_at: NotRequired[int] + r"""Unix timestamp of last update.""" + + +class OrganizationInvitation(BaseModel): + r"""An organization invitation""" + + id: Optional[str] = None + object: Optional[OrganizationInvitationObject] = None + r"""String representing the object's type. Objects of the same type share the same value. + + """ + email_address: Optional[str] = None + role: Optional[str] = None + organization_id: Optional[str] = None + status: Optional[str] = None + public_metadata: Optional[OrganizationInvitationPublicMetadata] = None + private_metadata: Optional[OrganizationInvitationPrivateMetadata] = None + created_at: Optional[int] = None + r"""Unix timestamp of creation.""" + updated_at: Optional[int] = None + r"""Unix timestamp of last update.""" + diff --git a/src/clerk/models/organizationinvitations.py b/src/clerk/models/organizationinvitations.py new file mode 100644 index 0000000..8b3b43c --- /dev/null +++ b/src/clerk/models/organizationinvitations.py @@ -0,0 +1,23 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from .organizationinvitation import OrganizationInvitation, OrganizationInvitationTypedDict +from clerk.types import BaseModel +from typing import List, TypedDict + + +class OrganizationInvitationsTypedDict(TypedDict): + data: List[OrganizationInvitationTypedDict] + total_count: int + r"""Total number of organization invitations + + """ + + +class OrganizationInvitations(BaseModel): + data: List[OrganizationInvitation] + total_count: int + r"""Total number of organization invitations + + """ + diff --git a/src/clerk/models/organizationmembership.py b/src/clerk/models/organizationmembership.py new file mode 100644 index 0000000..07b5a68 --- /dev/null +++ b/src/clerk/models/organizationmembership.py @@ -0,0 +1,213 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel, Nullable +from enum import Enum +import pydantic +from pydantic import model_serializer +from typing import List, Optional, TypedDict +from typing_extensions import Annotated, NotRequired + + +class OrganizationMembershipObject(str, Enum): + r"""String representing the object's type. Objects of the same type share the same value. + + """ + ORGANIZATION_MEMBERSHIP = "organization_membership" + + +class OrganizationMembershipPublicMetadataTypedDict(TypedDict): + r"""Metadata saved on the organization membership, accessible from both Frontend and Backend APIs""" + + + +class OrganizationMembershipPublicMetadata(BaseModel): + r"""Metadata saved on the organization membership, accessible from both Frontend and Backend APIs""" + + + +class OrganizationMembershipPrivateMetadataTypedDict(TypedDict): + r"""Metadata saved on the organization membership, accessible only from the Backend API""" + + + +class OrganizationMembershipPrivateMetadata(BaseModel): + r"""Metadata saved on the organization membership, accessible only from the Backend API""" + + + +class OrganizationMembershipOrganizationObject(str, Enum): + ORGANIZATION = "organization" + + +class OrganizationMembershipOrganizationPublicMetadataTypedDict(TypedDict): + pass + + +class OrganizationMembershipOrganizationPublicMetadata(BaseModel): + pass + + +class OrganizationMembershipOrganizationPrivateMetadataTypedDict(TypedDict): + pass + + +class OrganizationMembershipOrganizationPrivateMetadata(BaseModel): + pass + + +class OrganizationMembershipOrganizationTypedDict(TypedDict): + object: OrganizationMembershipOrganizationObject + id: str + name: str + slug: str + max_allowed_memberships: int + public_metadata: OrganizationMembershipOrganizationPublicMetadataTypedDict + private_metadata: OrganizationMembershipOrganizationPrivateMetadataTypedDict + created_at: int + r"""Unix timestamp of creation. + + """ + updated_at: int + r"""Unix timestamp of last update. + + """ + members_count: NotRequired[Nullable[int]] + admin_delete_enabled: NotRequired[bool] + created_by: NotRequired[str] + + +class OrganizationMembershipOrganization(BaseModel): + object: OrganizationMembershipOrganizationObject + id: str + name: str + slug: str + max_allowed_memberships: int + public_metadata: OrganizationMembershipOrganizationPublicMetadata + private_metadata: OrganizationMembershipOrganizationPrivateMetadata + created_at: int + r"""Unix timestamp of creation. + + """ + updated_at: int + r"""Unix timestamp of last update. + + """ + members_count: Optional[Nullable[int]] = None + admin_delete_enabled: Optional[bool] = None + created_by: Optional[str] = None + + @model_serializer(mode="wrap") + def serialize_model(self, handler): + optional_fields = ["members_count", "admin_delete_enabled", "created_by"] + nullable_fields = ["members_count"] + null_default_fields = [] + + serialized = handler(self) + + m = {} + + for n, f in self.model_fields.items(): + k = f.alias or n + val = serialized.get(k) + + if val is not None: + m[k] = val + elif not k in optional_fields or ( + k in optional_fields + and k in nullable_fields + and (self.__pydantic_fields_set__.intersection({n}) or k in null_default_fields) # pylint: disable=no-member + ): + m[k] = val + + return m + + +class PublicUserDataTypedDict(TypedDict): + user_id: NotRequired[str] + first_name: NotRequired[Nullable[str]] + last_name: NotRequired[Nullable[str]] + profile_image_url: NotRequired[Nullable[str]] + image_url: NotRequired[str] + has_image: NotRequired[bool] + identifier: NotRequired[Nullable[str]] + + +class PublicUserData(BaseModel): + user_id: Optional[str] = None + first_name: Optional[Nullable[str]] = None + last_name: Optional[Nullable[str]] = None + profile_image_url: Annotated[Optional[Nullable[str]], pydantic.Field(deprecated="warning: ** DEPRECATED ** - This will be removed in a future release, please migrate away from it as soon as possible.")] = None + image_url: Optional[str] = None + has_image: Optional[bool] = None + identifier: Optional[Nullable[str]] = None + + @model_serializer(mode="wrap") + def serialize_model(self, handler): + optional_fields = ["user_id", "first_name", "last_name", "profile_image_url", "image_url", "has_image", "identifier"] + nullable_fields = ["first_name", "last_name", "profile_image_url", "identifier"] + null_default_fields = [] + + serialized = handler(self) + + m = {} + + for n, f in self.model_fields.items(): + k = f.alias or n + val = serialized.get(k) + + if val is not None: + m[k] = val + elif not k in optional_fields or ( + k in optional_fields + and k in nullable_fields + and (self.__pydantic_fields_set__.intersection({n}) or k in null_default_fields) # pylint: disable=no-member + ): + m[k] = val + + return m + + +class OrganizationMembershipTypedDict(TypedDict): + r"""Hello world""" + + id: NotRequired[str] + object: NotRequired[OrganizationMembershipObject] + r"""String representing the object's type. Objects of the same type share the same value. + + """ + role: NotRequired[str] + permissions: NotRequired[List[str]] + public_metadata: NotRequired[OrganizationMembershipPublicMetadataTypedDict] + r"""Metadata saved on the organization membership, accessible from both Frontend and Backend APIs""" + private_metadata: NotRequired[OrganizationMembershipPrivateMetadataTypedDict] + r"""Metadata saved on the organization membership, accessible only from the Backend API""" + organization: NotRequired[OrganizationMembershipOrganizationTypedDict] + public_user_data: NotRequired[PublicUserDataTypedDict] + created_at: NotRequired[int] + r"""Unix timestamp of creation.""" + updated_at: NotRequired[int] + r"""Unix timestamp of last update.""" + + +class OrganizationMembership(BaseModel): + r"""Hello world""" + + id: Optional[str] = None + object: Optional[OrganizationMembershipObject] = None + r"""String representing the object's type. Objects of the same type share the same value. + + """ + role: Optional[str] = None + permissions: Optional[List[str]] = None + public_metadata: Optional[OrganizationMembershipPublicMetadata] = None + r"""Metadata saved on the organization membership, accessible from both Frontend and Backend APIs""" + private_metadata: Optional[OrganizationMembershipPrivateMetadata] = None + r"""Metadata saved on the organization membership, accessible only from the Backend API""" + organization: Optional[OrganizationMembershipOrganization] = None + public_user_data: Optional[PublicUserData] = None + created_at: Optional[int] = None + r"""Unix timestamp of creation.""" + updated_at: Optional[int] = None + r"""Unix timestamp of last update.""" + diff --git a/src/clerk/models/organizationmemberships.py b/src/clerk/models/organizationmemberships.py new file mode 100644 index 0000000..ef7d9e8 --- /dev/null +++ b/src/clerk/models/organizationmemberships.py @@ -0,0 +1,23 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from .organizationmembership import OrganizationMembership, OrganizationMembershipTypedDict +from clerk.types import BaseModel +from typing import List, TypedDict + + +class OrganizationMembershipsTypedDict(TypedDict): + data: List[OrganizationMembershipTypedDict] + total_count: int + r"""Total number of organization memberships + + """ + + +class OrganizationMemberships(BaseModel): + data: List[OrganizationMembership] + total_count: int + r"""Total number of organization memberships + + """ + diff --git a/src/clerk/models/organizations.py b/src/clerk/models/organizations.py new file mode 100644 index 0000000..2eba91a --- /dev/null +++ b/src/clerk/models/organizations.py @@ -0,0 +1,23 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from .organization import Organization, OrganizationTypedDict +from clerk.types import BaseModel +from typing import List, TypedDict + + +class OrganizationsTypedDict(TypedDict): + data: List[OrganizationTypedDict] + total_count: int + r"""Total number of organizations + + """ + + +class Organizations(BaseModel): + data: List[Organization] + total_count: int + r"""Total number of organizations + + """ + diff --git a/src/clerk/models/organizationsettings.py b/src/clerk/models/organizationsettings.py new file mode 100644 index 0000000..820187f --- /dev/null +++ b/src/clerk/models/organizationsettings.py @@ -0,0 +1,53 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel +from enum import Enum +from typing import List, Optional, TypedDict +from typing_extensions import NotRequired + + +class OrganizationSettingsObject(str, Enum): + r"""String representing the object's type. Objects of the same type share the same value.""" + ORGANIZATION_SETTINGS = "organization_settings" + + +class DomainsEnrollmentModes(str, Enum): + MANUAL_INVITATION = "manual_invitation" + AUTOMATIC_INVITATION = "automatic_invitation" + AUTOMATIC_SUGGESTION = "automatic_suggestion" + + +class OrganizationSettingsTypedDict(TypedDict): + object: OrganizationSettingsObject + r"""String representing the object's type. Objects of the same type share the same value.""" + enabled: bool + max_allowed_memberships: int + creator_role: str + r"""The role key that a user will be assigned after creating an organization.""" + admin_delete_enabled: bool + r"""The default for whether an admin can delete an organization with the Frontend API.""" + domains_enabled: bool + domains_enrollment_modes: List[DomainsEnrollmentModes] + domains_default_role: str + r"""The role key that it will be used in order to create an organization invitation or suggestion.""" + max_allowed_roles: NotRequired[int] + max_allowed_permissions: NotRequired[int] + + +class OrganizationSettings(BaseModel): + object: OrganizationSettingsObject + r"""String representing the object's type. Objects of the same type share the same value.""" + enabled: bool + max_allowed_memberships: int + creator_role: str + r"""The role key that a user will be assigned after creating an organization.""" + admin_delete_enabled: bool + r"""The default for whether an admin can delete an organization with the Frontend API.""" + domains_enabled: bool + domains_enrollment_modes: List[DomainsEnrollmentModes] + domains_default_role: str + r"""The role key that it will be used in order to create an organization invitation or suggestion.""" + max_allowed_roles: Optional[int] = None + max_allowed_permissions: Optional[int] = None + diff --git a/src/clerk/models/organizationwithlogo.py b/src/clerk/models/organizationwithlogo.py new file mode 100644 index 0000000..e07a83a --- /dev/null +++ b/src/clerk/models/organizationwithlogo.py @@ -0,0 +1,103 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel, Nullable +from enum import Enum +import pydantic +from pydantic import model_serializer +from typing import Optional, TypedDict +from typing_extensions import Annotated, NotRequired + + +class OrganizationWithLogoObject(str, Enum): + ORGANIZATION = "organization" + + +class OrganizationWithLogoPublicMetadataTypedDict(TypedDict): + pass + + +class OrganizationWithLogoPublicMetadata(BaseModel): + pass + + +class OrganizationWithLogoPrivateMetadataTypedDict(TypedDict): + pass + + +class OrganizationWithLogoPrivateMetadata(BaseModel): + pass + + +class OrganizationWithLogoTypedDict(TypedDict): + object: OrganizationWithLogoObject + id: str + name: str + slug: str + max_allowed_memberships: int + public_metadata: OrganizationWithLogoPublicMetadataTypedDict + private_metadata: OrganizationWithLogoPrivateMetadataTypedDict + created_at: int + r"""Unix timestamp of creation. + + """ + updated_at: int + r"""Unix timestamp of last update. + + """ + image_url: str + members_count: NotRequired[Nullable[int]] + admin_delete_enabled: NotRequired[bool] + created_by: NotRequired[str] + logo_url: NotRequired[str] + has_image: NotRequired[bool] + + +class OrganizationWithLogo(BaseModel): + object: OrganizationWithLogoObject + id: str + name: str + slug: str + max_allowed_memberships: int + public_metadata: OrganizationWithLogoPublicMetadata + private_metadata: OrganizationWithLogoPrivateMetadata + created_at: int + r"""Unix timestamp of creation. + + """ + updated_at: int + r"""Unix timestamp of last update. + + """ + image_url: str + members_count: Optional[Nullable[int]] = None + admin_delete_enabled: Optional[bool] = None + created_by: Optional[str] = None + logo_url: Annotated[Optional[str], pydantic.Field(deprecated="warning: ** DEPRECATED ** - This will be removed in a future release, please migrate away from it as soon as possible.")] = None + has_image: Optional[bool] = None + + @model_serializer(mode="wrap") + def serialize_model(self, handler): + optional_fields = ["members_count", "admin_delete_enabled", "created_by", "logo_url", "has_image"] + nullable_fields = ["members_count"] + null_default_fields = [] + + serialized = handler(self) + + m = {} + + for n, f in self.model_fields.items(): + k = f.alias or n + val = serialized.get(k) + + if val is not None: + m[k] = val + elif not k in optional_fields or ( + k in optional_fields + and k in nullable_fields + and (self.__pydantic_fields_set__.intersection({n}) or k in null_default_fields) # pylint: disable=no-member + ): + m[k] = val + + return m + diff --git a/src/clerk/models/phonenumber.py b/src/clerk/models/phonenumber.py new file mode 100644 index 0000000..8702eb5 --- /dev/null +++ b/src/clerk/models/phonenumber.py @@ -0,0 +1,195 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from .identificationlink import IdentificationLink, IdentificationLinkTypedDict +from clerk.types import BaseModel, Nullable +from enum import Enum +from pydantic import model_serializer +from typing import List, Optional, TypedDict, Union +from typing_extensions import NotRequired + + +class PhoneNumberObject(str, Enum): + r"""String representing the object's type. Objects of the same type share the same value. + + """ + PHONE_NUMBER = "phone_number" + + +class AdminVerificationPhoneNumberStatus(str, Enum): + VERIFIED = "verified" + + +class AdminVerificationStrategy(str, Enum): + ADMIN = "admin" + FROM_OAUTH_DISCORD = "from_oauth_discord" + + +class VerificationAdminTypedDict(TypedDict): + status: AdminVerificationPhoneNumberStatus + strategy: AdminVerificationStrategy + attempts: NotRequired[Nullable[int]] + expire_at: NotRequired[Nullable[int]] + + +class VerificationAdmin(BaseModel): + status: AdminVerificationPhoneNumberStatus + strategy: AdminVerificationStrategy + attempts: Optional[Nullable[int]] = None + expire_at: Optional[Nullable[int]] = None + + @model_serializer(mode="wrap") + def serialize_model(self, handler): + optional_fields = ["attempts", "expire_at"] + nullable_fields = ["attempts", "expire_at"] + null_default_fields = [] + + serialized = handler(self) + + m = {} + + for n, f in self.model_fields.items(): + k = f.alias or n + val = serialized.get(k) + + if val is not None: + m[k] = val + elif not k in optional_fields or ( + k in optional_fields + and k in nullable_fields + and (self.__pydantic_fields_set__.intersection({n}) or k in null_default_fields) # pylint: disable=no-member + ): + m[k] = val + + return m + + +class OTPVerificationStatus(str, Enum): + UNVERIFIED = "unverified" + VERIFIED = "verified" + FAILED = "failed" + EXPIRED = "expired" + + +class OTPVerificationStrategy(str, Enum): + PHONE_CODE = "phone_code" + EMAIL_CODE = "email_code" + RESET_PASSWORD_EMAIL_CODE = "reset_password_email_code" + FROM_OAUTH_DISCORD = "from_oauth_discord" + + +class VerificationOTPTypedDict(TypedDict): + status: OTPVerificationStatus + strategy: OTPVerificationStrategy + attempts: Nullable[int] + expire_at: Nullable[int] + + +class VerificationOTP(BaseModel): + status: OTPVerificationStatus + strategy: OTPVerificationStrategy + attempts: Nullable[int] + expire_at: Nullable[int] + + @model_serializer(mode="wrap") + def serialize_model(self, handler): + optional_fields = [] + nullable_fields = ["attempts", "expire_at"] + null_default_fields = [] + + serialized = handler(self) + + m = {} + + for n, f in self.model_fields.items(): + k = f.alias or n + val = serialized.get(k) + + if val is not None: + m[k] = val + elif not k in optional_fields or ( + k in optional_fields + and k in nullable_fields + and (self.__pydantic_fields_set__.intersection({n}) or k in null_default_fields) # pylint: disable=no-member + ): + m[k] = val + + return m + + +class PhoneNumberTypedDict(TypedDict): + object: PhoneNumberObject + r"""String representing the object's type. Objects of the same type share the same value. + + """ + phone_number: str + reserved: bool + verification: Nullable[PhoneNumberVerificationTypedDict] + linked_to: List[IdentificationLinkTypedDict] + created_at: int + r"""Unix timestamp of creation + + """ + updated_at: int + r"""Unix timestamp of creation + + """ + id: NotRequired[str] + reserved_for_second_factor: NotRequired[bool] + default_second_factor: NotRequired[bool] + backup_codes: NotRequired[Nullable[List[str]]] + + +class PhoneNumber(BaseModel): + object: PhoneNumberObject + r"""String representing the object's type. Objects of the same type share the same value. + + """ + phone_number: str + reserved: bool + verification: Nullable[PhoneNumberVerification] + linked_to: List[IdentificationLink] + created_at: int + r"""Unix timestamp of creation + + """ + updated_at: int + r"""Unix timestamp of creation + + """ + id: Optional[str] = None + reserved_for_second_factor: Optional[bool] = None + default_second_factor: Optional[bool] = None + backup_codes: Optional[Nullable[List[str]]] = None + + @model_serializer(mode="wrap") + def serialize_model(self, handler): + optional_fields = ["id", "reserved_for_second_factor", "default_second_factor", "backup_codes"] + nullable_fields = ["verification", "backup_codes"] + null_default_fields = [] + + serialized = handler(self) + + m = {} + + for n, f in self.model_fields.items(): + k = f.alias or n + val = serialized.get(k) + + if val is not None: + m[k] = val + elif not k in optional_fields or ( + k in optional_fields + and k in nullable_fields + and (self.__pydantic_fields_set__.intersection({n}) or k in null_default_fields) # pylint: disable=no-member + ): + m[k] = val + + return m + + +PhoneNumberVerificationTypedDict = Union[VerificationOTPTypedDict, VerificationAdminTypedDict] + + +PhoneNumberVerification = Union[VerificationOTP, VerificationAdmin] + diff --git a/src/clerk/models/previewtemplateop.py b/src/clerk/models/previewtemplateop.py new file mode 100644 index 0000000..5f6e813 --- /dev/null +++ b/src/clerk/models/previewtemplateop.py @@ -0,0 +1,104 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel, Nullable +from clerk.utils import FieldMetadata, PathParamMetadata, RequestMetadata +from pydantic import model_serializer +from typing import Optional, TypedDict +from typing_extensions import Annotated, NotRequired + + +class PreviewTemplateRequestBodyTypedDict(TypedDict): + r"""Required parameters""" + + subject: NotRequired[Nullable[str]] + r"""The email subject. + Applicable only to email templates. + """ + body: NotRequired[str] + r"""The template body before variable interpolation""" + from_email_name: NotRequired[str] + r"""The local part of the From email address that will be used for emails. + For example, in the address 'hello@example.com', the local part is 'hello'. + Applicable only to email templates. + """ + reply_to_email_name: NotRequired[str] + r"""The local part of the Reply To email address that will be used for emails. + For example, in the address 'hello@example.com', the local part is 'hello'. + Applicable only to email templates. + """ + + +class PreviewTemplateRequestBody(BaseModel): + r"""Required parameters""" + + subject: Optional[Nullable[str]] = None + r"""The email subject. + Applicable only to email templates. + """ + body: Optional[str] = None + r"""The template body before variable interpolation""" + from_email_name: Optional[str] = None + r"""The local part of the From email address that will be used for emails. + For example, in the address 'hello@example.com', the local part is 'hello'. + Applicable only to email templates. + """ + reply_to_email_name: Optional[str] = None + r"""The local part of the Reply To email address that will be used for emails. + For example, in the address 'hello@example.com', the local part is 'hello'. + Applicable only to email templates. + """ + + @model_serializer(mode="wrap") + def serialize_model(self, handler): + optional_fields = ["subject", "body", "from_email_name", "reply_to_email_name"] + nullable_fields = ["subject"] + null_default_fields = [] + + serialized = handler(self) + + m = {} + + for n, f in self.model_fields.items(): + k = f.alias or n + val = serialized.get(k) + + if val is not None: + m[k] = val + elif not k in optional_fields or ( + k in optional_fields + and k in nullable_fields + and (self.__pydantic_fields_set__.intersection({n}) or k in null_default_fields) # pylint: disable=no-member + ): + m[k] = val + + return m + + +class PreviewTemplateRequestTypedDict(TypedDict): + template_type: str + r"""The type of template to preview""" + slug: str + r"""The slug of the template to preview""" + request_body: NotRequired[PreviewTemplateRequestBodyTypedDict] + r"""Required parameters""" + + +class PreviewTemplateRequest(BaseModel): + template_type: Annotated[str, FieldMetadata(path=PathParamMetadata(style="simple", explode=False))] + r"""The type of template to preview""" + slug: Annotated[str, FieldMetadata(path=PathParamMetadata(style="simple", explode=False))] + r"""The slug of the template to preview""" + request_body: Annotated[Optional[PreviewTemplateRequestBody], FieldMetadata(request=RequestMetadata(media_type="application/json"))] = None + r"""Required parameters""" + + +class PreviewTemplateResponseBodyTypedDict(TypedDict): + r"""OK""" + + + +class PreviewTemplateResponseBody(BaseModel): + r"""OK""" + + diff --git a/src/clerk/models/proxycheck.py b/src/clerk/models/proxycheck.py new file mode 100644 index 0000000..24e62a8 --- /dev/null +++ b/src/clerk/models/proxycheck.py @@ -0,0 +1,33 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel +from enum import Enum +from typing import TypedDict + + +class ProxyCheckObject(str, Enum): + PROXY_CHECK = "proxy_check" + + +class ProxyCheckTypedDict(TypedDict): + object: ProxyCheckObject + id: str + domain_id: str + last_run_at: int + proxy_url: str + successful: bool + created_at: int + updated_at: int + + +class ProxyCheck(BaseModel): + object: ProxyCheckObject + id: str + domain_id: str + last_run_at: int + proxy_url: str + successful: bool + created_at: int + updated_at: int + diff --git a/src/clerk/models/redirecturl.py b/src/clerk/models/redirecturl.py new file mode 100644 index 0000000..e3b0c61 --- /dev/null +++ b/src/clerk/models/redirecturl.py @@ -0,0 +1,39 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel +from enum import Enum +from typing import TypedDict + + +class RedirectURLObject(str, Enum): + REDIRECT_URL = "redirect_url" + + +class RedirectURLTypedDict(TypedDict): + object: RedirectURLObject + id: str + url: str + created_at: int + r"""Unix timestamp of creation. + + """ + updated_at: int + r"""Unix timestamp of last update. + + """ + + +class RedirectURL(BaseModel): + object: RedirectURLObject + id: str + url: str + created_at: int + r"""Unix timestamp of creation. + + """ + updated_at: int + r"""Unix timestamp of last update. + + """ + diff --git a/src/clerk/models/reverttemplateop.py b/src/clerk/models/reverttemplateop.py new file mode 100644 index 0000000..f42eadf --- /dev/null +++ b/src/clerk/models/reverttemplateop.py @@ -0,0 +1,29 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel +from clerk.utils import FieldMetadata, PathParamMetadata +from enum import Enum +from typing import TypedDict +from typing_extensions import Annotated + + +class RevertTemplatePathParamTemplateType(str, Enum): + r"""The type of template to revert""" + EMAIL = "email" + SMS = "sms" + + +class RevertTemplateRequestTypedDict(TypedDict): + template_type: RevertTemplatePathParamTemplateType + r"""The type of template to revert""" + slug: str + r"""The slug of the template to revert""" + + +class RevertTemplateRequest(BaseModel): + template_type: Annotated[RevertTemplatePathParamTemplateType, FieldMetadata(path=PathParamMetadata(style="simple", explode=False))] + r"""The type of template to revert""" + slug: Annotated[str, FieldMetadata(path=PathParamMetadata(style="simple", explode=False))] + r"""The slug of the template to revert""" + diff --git a/src/clerk/models/revokeactortokenop.py b/src/clerk/models/revokeactortokenop.py new file mode 100644 index 0000000..d185d7a --- /dev/null +++ b/src/clerk/models/revokeactortokenop.py @@ -0,0 +1,18 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel +from clerk.utils import FieldMetadata, PathParamMetadata +from typing import TypedDict +from typing_extensions import Annotated + + +class RevokeActorTokenRequestTypedDict(TypedDict): + actor_token_id: str + r"""The ID of the actor token to be revoked.""" + + +class RevokeActorTokenRequest(BaseModel): + actor_token_id: Annotated[str, FieldMetadata(path=PathParamMetadata(style="simple", explode=False))] + r"""The ID of the actor token to be revoked.""" + diff --git a/src/clerk/models/revokeinvitationop.py b/src/clerk/models/revokeinvitationop.py new file mode 100644 index 0000000..25cc86d --- /dev/null +++ b/src/clerk/models/revokeinvitationop.py @@ -0,0 +1,18 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel +from clerk.utils import FieldMetadata, PathParamMetadata +from typing import TypedDict +from typing_extensions import Annotated + + +class RevokeInvitationRequestTypedDict(TypedDict): + invitation_id: str + r"""The ID of the invitation to be revoked""" + + +class RevokeInvitationRequest(BaseModel): + invitation_id: Annotated[str, FieldMetadata(path=PathParamMetadata(style="simple", explode=False))] + r"""The ID of the invitation to be revoked""" + diff --git a/src/clerk/models/revokeorganizationinvitationop.py b/src/clerk/models/revokeorganizationinvitationop.py new file mode 100644 index 0000000..b17b11e --- /dev/null +++ b/src/clerk/models/revokeorganizationinvitationop.py @@ -0,0 +1,38 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel +from clerk.utils import FieldMetadata, PathParamMetadata, RequestMetadata +from typing import TypedDict +from typing_extensions import Annotated + + +class RevokeOrganizationInvitationRequestBodyTypedDict(TypedDict): + requesting_user_id: str + r"""The ID of the user that revokes the invitation. + Must be an administrator in the organization. + """ + + +class RevokeOrganizationInvitationRequestBody(BaseModel): + requesting_user_id: str + r"""The ID of the user that revokes the invitation. + Must be an administrator in the organization. + """ + + +class RevokeOrganizationInvitationRequestTypedDict(TypedDict): + organization_id: str + r"""The organization ID.""" + invitation_id: str + r"""The organization invitation ID.""" + request_body: RevokeOrganizationInvitationRequestBodyTypedDict + + +class RevokeOrganizationInvitationRequest(BaseModel): + organization_id: Annotated[str, FieldMetadata(path=PathParamMetadata(style="simple", explode=False))] + r"""The organization ID.""" + invitation_id: Annotated[str, FieldMetadata(path=PathParamMetadata(style="simple", explode=False))] + r"""The organization invitation ID.""" + request_body: Annotated[RevokeOrganizationInvitationRequestBody, FieldMetadata(request=RequestMetadata(media_type="application/json"))] + diff --git a/src/clerk/models/revokesessionop.py b/src/clerk/models/revokesessionop.py new file mode 100644 index 0000000..bdf6197 --- /dev/null +++ b/src/clerk/models/revokesessionop.py @@ -0,0 +1,18 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel +from clerk.utils import FieldMetadata, PathParamMetadata +from typing import TypedDict +from typing_extensions import Annotated + + +class RevokeSessionRequestTypedDict(TypedDict): + session_id: str + r"""The ID of the session""" + + +class RevokeSessionRequest(BaseModel): + session_id: Annotated[str, FieldMetadata(path=PathParamMetadata(style="simple", explode=False))] + r"""The ID of the session""" + diff --git a/src/clerk/models/revokesignintokenop.py b/src/clerk/models/revokesignintokenop.py new file mode 100644 index 0000000..4bcd37a --- /dev/null +++ b/src/clerk/models/revokesignintokenop.py @@ -0,0 +1,18 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel +from clerk.utils import FieldMetadata, PathParamMetadata +from typing import TypedDict +from typing_extensions import Annotated + + +class RevokeSignInTokenRequestTypedDict(TypedDict): + sign_in_token_id: str + r"""The ID of the sign-in token to be revoked""" + + +class RevokeSignInTokenRequest(BaseModel): + sign_in_token_id: Annotated[str, FieldMetadata(path=PathParamMetadata(style="simple", explode=False))] + r"""The ID of the sign-in token to be revoked""" + diff --git a/src/clerk/models/rotateoauthapplicationsecretop.py b/src/clerk/models/rotateoauthapplicationsecretop.py new file mode 100644 index 0000000..ad16bbb --- /dev/null +++ b/src/clerk/models/rotateoauthapplicationsecretop.py @@ -0,0 +1,18 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel +from clerk.utils import FieldMetadata, PathParamMetadata +from typing import TypedDict +from typing_extensions import Annotated + + +class RotateOAuthApplicationSecretRequestTypedDict(TypedDict): + oauth_application_id: str + r"""The ID of the OAuth application for which to rotate the client secret""" + + +class RotateOAuthApplicationSecretRequest(BaseModel): + oauth_application_id: Annotated[str, FieldMetadata(path=PathParamMetadata(style="simple", explode=False))] + r"""The ID of the OAuth application for which to rotate the client secret""" + diff --git a/src/clerk/models/samlaccount.py b/src/clerk/models/samlaccount.py new file mode 100644 index 0000000..07bc3cb --- /dev/null +++ b/src/clerk/models/samlaccount.py @@ -0,0 +1,221 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel, Nullable +from enum import Enum +from pydantic import model_serializer +from typing import Optional, TypedDict, Union +from typing_extensions import NotRequired + + +class SAMLAccountObject(str, Enum): + r"""String representing the object's type. Objects of the same type share the same value. + + """ + SAML_ACCOUNT = "saml_account" + + +class SAMLAccountPublicMetadataTypedDict(TypedDict): + pass + + +class SAMLAccountPublicMetadata(BaseModel): + pass + + +class TicketVerificationStatus(str, Enum): + UNVERIFIED = "unverified" + VERIFIED = "verified" + EXPIRED = "expired" + + +class TicketVerificationStrategy(str, Enum): + TICKET = "ticket" + + +class TicketTypedDict(TypedDict): + status: TicketVerificationStatus + strategy: TicketVerificationStrategy + attempts: NotRequired[Nullable[int]] + expire_at: NotRequired[Nullable[int]] + + +class Ticket(BaseModel): + status: TicketVerificationStatus + strategy: TicketVerificationStrategy + attempts: Optional[Nullable[int]] = None + expire_at: Optional[Nullable[int]] = None + + @model_serializer(mode="wrap") + def serialize_model(self, handler): + optional_fields = ["attempts", "expire_at"] + nullable_fields = ["attempts", "expire_at"] + null_default_fields = [] + + serialized = handler(self) + + m = {} + + for n, f in self.model_fields.items(): + k = f.alias or n + val = serialized.get(k) + + if val is not None: + m[k] = val + elif not k in optional_fields or ( + k in optional_fields + and k in nullable_fields + and (self.__pydantic_fields_set__.intersection({n}) or k in null_default_fields) # pylint: disable=no-member + ): + m[k] = val + + return m + + +class SAMLVerificationStatus(str, Enum): + UNVERIFIED = "unverified" + VERIFIED = "verified" + FAILED = "failed" + EXPIRED = "expired" + TRANSFERABLE = "transferable" + + +class SAMLVerificationStrategy(str, Enum): + SAML = "saml" + + +class ClerkErrorErrorMetaTypedDict(TypedDict): + pass + + +class ClerkErrorErrorMeta(BaseModel): + pass + + +class SAMLErrorClerkErrorTypedDict(TypedDict): + message: str + long_message: str + code: str + meta: NotRequired[ClerkErrorErrorMetaTypedDict] + clerk_trace_id: NotRequired[str] + + +class SAMLErrorClerkError(BaseModel): + message: str + long_message: str + code: str + meta: Optional[ClerkErrorErrorMeta] = None + clerk_trace_id: Optional[str] = None + + +class SamlTypedDict(TypedDict): + status: SAMLVerificationStatus + strategy: SAMLVerificationStrategy + external_verification_redirect_url: Nullable[str] + expire_at: int + error: NotRequired[Nullable[VerificationErrorTypedDict]] + attempts: NotRequired[Nullable[int]] + + +class Saml(BaseModel): + status: SAMLVerificationStatus + strategy: SAMLVerificationStrategy + external_verification_redirect_url: Nullable[str] + expire_at: int + error: Optional[Nullable[VerificationError]] = None + attempts: Optional[Nullable[int]] = None + + @model_serializer(mode="wrap") + def serialize_model(self, handler): + optional_fields = ["error", "attempts"] + nullable_fields = ["external_verification_redirect_url", "error", "attempts"] + null_default_fields = [] + + serialized = handler(self) + + m = {} + + for n, f in self.model_fields.items(): + k = f.alias or n + val = serialized.get(k) + + if val is not None: + m[k] = val + elif not k in optional_fields or ( + k in optional_fields + and k in nullable_fields + and (self.__pydantic_fields_set__.intersection({n}) or k in null_default_fields) # pylint: disable=no-member + ): + m[k] = val + + return m + + +class SAMLAccountTypedDict(TypedDict): + id: str + object: SAMLAccountObject + r"""String representing the object's type. Objects of the same type share the same value. + + """ + provider: str + active: bool + email_address: str + verification: Nullable[SAMLAccountVerificationTypedDict] + first_name: NotRequired[Nullable[str]] + last_name: NotRequired[Nullable[str]] + provider_user_id: NotRequired[Nullable[str]] + public_metadata: NotRequired[SAMLAccountPublicMetadataTypedDict] + + +class SAMLAccount(BaseModel): + id: str + object: SAMLAccountObject + r"""String representing the object's type. Objects of the same type share the same value. + + """ + provider: str + active: bool + email_address: str + verification: Nullable[SAMLAccountVerification] + first_name: Optional[Nullable[str]] = None + last_name: Optional[Nullable[str]] = None + provider_user_id: Optional[Nullable[str]] = None + public_metadata: Optional[SAMLAccountPublicMetadata] = None + + @model_serializer(mode="wrap") + def serialize_model(self, handler): + optional_fields = ["first_name", "last_name", "provider_user_id", "public_metadata"] + nullable_fields = ["verification", "first_name", "last_name", "provider_user_id"] + null_default_fields = [] + + serialized = handler(self) + + m = {} + + for n, f in self.model_fields.items(): + k = f.alias or n + val = serialized.get(k) + + if val is not None: + m[k] = val + elif not k in optional_fields or ( + k in optional_fields + and k in nullable_fields + and (self.__pydantic_fields_set__.intersection({n}) or k in null_default_fields) # pylint: disable=no-member + ): + m[k] = val + + return m + + +VerificationErrorTypedDict = Union[SAMLErrorClerkErrorTypedDict] + + +VerificationError = Union[SAMLErrorClerkError] + + +SAMLAccountVerificationTypedDict = Union[TicketTypedDict, SamlTypedDict] + + +SAMLAccountVerification = Union[Ticket, Saml] + diff --git a/src/clerk/models/samlconnection.py b/src/clerk/models/samlconnection.py new file mode 100644 index 0000000..13ffde1 --- /dev/null +++ b/src/clerk/models/samlconnection.py @@ -0,0 +1,112 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel, Nullable +from enum import Enum +from pydantic import model_serializer +from typing import Optional, TypedDict +from typing_extensions import NotRequired + + +class SAMLConnectionObject(str, Enum): + SAML_CONNECTION = "saml_connection" + + +class AttributeMappingTypedDict(TypedDict): + user_id: NotRequired[str] + email_address: NotRequired[str] + first_name: NotRequired[str] + last_name: NotRequired[str] + + +class AttributeMapping(BaseModel): + user_id: Optional[str] = None + email_address: Optional[str] = None + first_name: Optional[str] = None + last_name: Optional[str] = None + + +class SAMLConnectionTypedDict(TypedDict): + object: SAMLConnectionObject + id: str + name: str + domain: str + idp_entity_id: Nullable[str] + idp_sso_url: Nullable[str] + idp_certificate: Nullable[str] + acs_url: str + sp_entity_id: str + sp_metadata_url: str + active: bool + provider: str + user_count: int + sync_user_attributes: bool + created_at: int + r"""Unix timestamp of creation. + + """ + updated_at: int + r"""Unix timestamp of last update. + + """ + idp_metadata_url: NotRequired[Nullable[str]] + idp_metadata: NotRequired[Nullable[str]] + attribute_mapping: NotRequired[AttributeMappingTypedDict] + allow_subdomains: NotRequired[bool] + allow_idp_initiated: NotRequired[bool] + + +class SAMLConnection(BaseModel): + object: SAMLConnectionObject + id: str + name: str + domain: str + idp_entity_id: Nullable[str] + idp_sso_url: Nullable[str] + idp_certificate: Nullable[str] + acs_url: str + sp_entity_id: str + sp_metadata_url: str + active: bool + provider: str + user_count: int + sync_user_attributes: bool + created_at: int + r"""Unix timestamp of creation. + + """ + updated_at: int + r"""Unix timestamp of last update. + + """ + idp_metadata_url: Optional[Nullable[str]] = None + idp_metadata: Optional[Nullable[str]] = None + attribute_mapping: Optional[AttributeMapping] = None + allow_subdomains: Optional[bool] = None + allow_idp_initiated: Optional[bool] = None + + @model_serializer(mode="wrap") + def serialize_model(self, handler): + optional_fields = ["idp_metadata_url", "idp_metadata", "attribute_mapping", "allow_subdomains", "allow_idp_initiated"] + nullable_fields = ["idp_entity_id", "idp_sso_url", "idp_certificate", "idp_metadata_url", "idp_metadata"] + null_default_fields = [] + + serialized = handler(self) + + m = {} + + for n, f in self.model_fields.items(): + k = f.alias or n + val = serialized.get(k) + + if val is not None: + m[k] = val + elif not k in optional_fields or ( + k in optional_fields + and k in nullable_fields + and (self.__pydantic_fields_set__.intersection({n}) or k in null_default_fields) # pylint: disable=no-member + ): + m[k] = val + + return m + diff --git a/src/clerk/models/samlconnections.py b/src/clerk/models/samlconnections.py new file mode 100644 index 0000000..3a6b0fd --- /dev/null +++ b/src/clerk/models/samlconnections.py @@ -0,0 +1,23 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from .samlconnection import SAMLConnection, SAMLConnectionTypedDict +from clerk.types import BaseModel +from typing import List, TypedDict + + +class SAMLConnectionsTypedDict(TypedDict): + data: List[SAMLConnectionTypedDict] + total_count: int + r"""Total number of SAML Connections + + """ + + +class SAMLConnections(BaseModel): + data: List[SAMLConnection] + total_count: int + r"""Total number of SAML Connections + + """ + diff --git a/src/clerk/models/schemas_passkey.py b/src/clerk/models/schemas_passkey.py new file mode 100644 index 0000000..0cdd911 --- /dev/null +++ b/src/clerk/models/schemas_passkey.py @@ -0,0 +1,128 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel, Nullable +from enum import Enum +from pydantic import model_serializer +from typing import Optional, TypedDict, Union +from typing_extensions import NotRequired + + +class SchemasPasskeyObject(str, Enum): + r"""String representing the object's type. Objects of the same type share the same value. + + """ + PASSKEY = "passkey" + + +class PasskeyVerificationStatus(str, Enum): + VERIFIED = "verified" + + +class PasskeyVerificationStrategy(str, Enum): + PASSKEY = "passkey" + + +class VerificationNonce(str, Enum): + NONCE = "nonce" + + +class PasskeyTypedDict(TypedDict): + status: PasskeyVerificationStatus + strategy: PasskeyVerificationStrategy + nonce: NotRequired[VerificationNonce] + attempts: NotRequired[Nullable[int]] + expire_at: NotRequired[Nullable[int]] + + +class Passkey(BaseModel): + status: PasskeyVerificationStatus + strategy: PasskeyVerificationStrategy + nonce: Optional[VerificationNonce] = None + attempts: Optional[Nullable[int]] = None + expire_at: Optional[Nullable[int]] = None + + @model_serializer(mode="wrap") + def serialize_model(self, handler): + optional_fields = ["nonce", "attempts", "expire_at"] + nullable_fields = ["attempts", "expire_at"] + null_default_fields = [] + + serialized = handler(self) + + m = {} + + for n, f in self.model_fields.items(): + k = f.alias or n + val = serialized.get(k) + + if val is not None: + m[k] = val + elif not k in optional_fields or ( + k in optional_fields + and k in nullable_fields + and (self.__pydantic_fields_set__.intersection({n}) or k in null_default_fields) # pylint: disable=no-member + ): + m[k] = val + + return m + + +class SchemasPasskeyTypedDict(TypedDict): + object: SchemasPasskeyObject + r"""String representing the object's type. Objects of the same type share the same value. + + """ + name: str + last_used_at: int + r"""Unix timestamp of when the passkey was last used. + + """ + verification: Nullable[SchemasPasskeyVerificationTypedDict] + id: NotRequired[str] + + +class SchemasPasskey(BaseModel): + object: SchemasPasskeyObject + r"""String representing the object's type. Objects of the same type share the same value. + + """ + name: str + last_used_at: int + r"""Unix timestamp of when the passkey was last used. + + """ + verification: Nullable[SchemasPasskeyVerification] + id: Optional[str] = None + + @model_serializer(mode="wrap") + def serialize_model(self, handler): + optional_fields = ["id"] + nullable_fields = ["verification"] + null_default_fields = [] + + serialized = handler(self) + + m = {} + + for n, f in self.model_fields.items(): + k = f.alias or n + val = serialized.get(k) + + if val is not None: + m[k] = val + elif not k in optional_fields or ( + k in optional_fields + and k in nullable_fields + and (self.__pydantic_fields_set__.intersection({n}) or k in null_default_fields) # pylint: disable=no-member + ): + m[k] = val + + return m + + +SchemasPasskeyVerificationTypedDict = Union[PasskeyTypedDict] + + +SchemasPasskeyVerification = Union[Passkey] + diff --git a/src/clerk/models/sdkerror.py b/src/clerk/models/sdkerror.py new file mode 100644 index 0000000..cc9bf0f --- /dev/null +++ b/src/clerk/models/sdkerror.py @@ -0,0 +1,22 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from dataclasses import dataclass +from typing import Optional +import httpx + + +@dataclass +class SDKError(Exception): + """Represents an error returned by the API.""" + + message: str + status_code: int = -1 + body: str = "" + raw_response: Optional[httpx.Response] = None + + def __str__(self): + body = "" + if len(self.body) > 0: + body = f"\n{self.body}" + + return f"{self.message}: Status {self.status_code}{body}" diff --git a/src/clerk/models/security.py b/src/clerk/models/security.py new file mode 100644 index 0000000..aa73611 --- /dev/null +++ b/src/clerk/models/security.py @@ -0,0 +1,16 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel +from clerk.utils import FieldMetadata, SecurityMetadata +from typing import TypedDict +from typing_extensions import Annotated + + +class SecurityTypedDict(TypedDict): + bearer_auth: str + + +class Security(BaseModel): + bearer_auth: Annotated[str, FieldMetadata(security=SecurityMetadata(scheme=True, scheme_type="http", sub_type="bearer", field_name="Authorization"))] + diff --git a/src/clerk/models/session.py b/src/clerk/models/session.py new file mode 100644 index 0000000..b38cf80 --- /dev/null +++ b/src/clerk/models/session.py @@ -0,0 +1,107 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel, Nullable +from enum import Enum +from pydantic import model_serializer +from typing import Optional, TypedDict +from typing_extensions import NotRequired + + +class SessionObject(str, Enum): + r"""String representing the object's type. Objects of the same type share the same value. + + """ + SESSION = "session" + + +class ActorTypedDict(TypedDict): + pass + + +class Actor(BaseModel): + pass + + +class Status(str, Enum): + ACTIVE = "active" + REVOKED = "revoked" + ENDED = "ended" + EXPIRED = "expired" + REMOVED = "removed" + ABANDONED = "abandoned" + REPLACED = "replaced" + + +class SessionTypedDict(TypedDict): + object: SessionObject + r"""String representing the object's type. Objects of the same type share the same value. + + """ + id: str + user_id: str + client_id: str + status: Status + last_active_at: int + expire_at: int + abandon_at: int + updated_at: int + r"""Unix timestamp of last update. + + """ + created_at: int + r"""Unix timestamp of creation. + + """ + actor: NotRequired[Nullable[ActorTypedDict]] + last_active_organization_id: NotRequired[Nullable[str]] + + +class Session(BaseModel): + object: SessionObject + r"""String representing the object's type. Objects of the same type share the same value. + + """ + id: str + user_id: str + client_id: str + status: Status + last_active_at: int + expire_at: int + abandon_at: int + updated_at: int + r"""Unix timestamp of last update. + + """ + created_at: int + r"""Unix timestamp of creation. + + """ + actor: Optional[Nullable[Actor]] = None + last_active_organization_id: Optional[Nullable[str]] = None + + @model_serializer(mode="wrap") + def serialize_model(self, handler): + optional_fields = ["actor", "last_active_organization_id"] + nullable_fields = ["actor", "last_active_organization_id"] + null_default_fields = [] + + serialized = handler(self) + + m = {} + + for n, f in self.model_fields.items(): + k = f.alias or n + val = serialized.get(k) + + if val is not None: + m[k] = val + elif not k in optional_fields or ( + k in optional_fields + and k in nullable_fields + and (self.__pydantic_fields_set__.intersection({n}) or k in null_default_fields) # pylint: disable=no-member + ): + m[k] = val + + return m + diff --git a/src/clerk/models/setuserprofileimageop.py b/src/clerk/models/setuserprofileimageop.py new file mode 100644 index 0000000..585c722 --- /dev/null +++ b/src/clerk/models/setuserprofileimageop.py @@ -0,0 +1,42 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel +from clerk.utils import FieldMetadata, MultipartFormMetadata, PathParamMetadata, RequestMetadata +import io +import pydantic +from typing import IO, Optional, TypedDict, Union +from typing_extensions import Annotated, NotRequired + + +class FileTypedDict(TypedDict): + file_name: str + content: Union[bytes, IO[bytes], io.BufferedReader] + content_type: NotRequired[str] + + +class File(BaseModel): + file_name: Annotated[str, pydantic.Field(alias="file"), FieldMetadata(multipart=True)] + content: Annotated[Union[bytes, IO[bytes], io.BufferedReader], pydantic.Field(alias=""), FieldMetadata(multipart=MultipartFormMetadata(content=True))] + content_type: Annotated[Optional[str], pydantic.Field(alias="Content-Type"), FieldMetadata(multipart=True)] = None + + +class SetUserProfileImageRequestBodyTypedDict(TypedDict): + file: NotRequired[FileTypedDict] + + +class SetUserProfileImageRequestBody(BaseModel): + file: Annotated[Optional[File], pydantic.Field(alias=""), FieldMetadata(multipart=MultipartFormMetadata(file=True))] = None + + +class SetUserProfileImageRequestTypedDict(TypedDict): + user_id: str + r"""The ID of the user to update the profile image for""" + request_body: SetUserProfileImageRequestBodyTypedDict + + +class SetUserProfileImageRequest(BaseModel): + user_id: Annotated[str, FieldMetadata(path=PathParamMetadata(style="simple", explode=False))] + r"""The ID of the user to update the profile image for""" + request_body: Annotated[SetUserProfileImageRequestBody, FieldMetadata(request=RequestMetadata(media_type="multipart/form-data"))] + diff --git a/src/clerk/models/signintoken.py b/src/clerk/models/signintoken.py new file mode 100644 index 0000000..3ad519e --- /dev/null +++ b/src/clerk/models/signintoken.py @@ -0,0 +1,78 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel, Nullable +from enum import Enum +from pydantic import model_serializer +from typing import Optional, TypedDict +from typing_extensions import NotRequired + + +class SignInTokenObject(str, Enum): + SIGN_IN_TOKEN = "sign_in_token" + + +class SignInTokenStatus(str, Enum): + PENDING = "pending" + ACCEPTED = "accepted" + REVOKED = "revoked" + + +class SignInTokenTypedDict(TypedDict): + object: SignInTokenObject + id: str + status: SignInTokenStatus + user_id: str + created_at: int + r"""Unix timestamp of creation. + + """ + updated_at: int + r"""Unix timestamp of last update. + + """ + token: NotRequired[str] + url: NotRequired[Nullable[str]] + + +class SignInToken(BaseModel): + object: SignInTokenObject + id: str + status: SignInTokenStatus + user_id: str + created_at: int + r"""Unix timestamp of creation. + + """ + updated_at: int + r"""Unix timestamp of last update. + + """ + token: Optional[str] = None + url: Optional[Nullable[str]] = None + + @model_serializer(mode="wrap") + def serialize_model(self, handler): + optional_fields = ["token", "url"] + nullable_fields = ["url"] + null_default_fields = [] + + serialized = handler(self) + + m = {} + + for n, f in self.model_fields.items(): + k = f.alias or n + val = serialized.get(k) + + if val is not None: + m[k] = val + elif not k in optional_fields or ( + k in optional_fields + and k in nullable_fields + and (self.__pydantic_fields_set__.intersection({n}) or k in null_default_fields) # pylint: disable=no-member + ): + m[k] = val + + return m + diff --git a/src/clerk/models/signup.py b/src/clerk/models/signup.py new file mode 100644 index 0000000..c9f6928 --- /dev/null +++ b/src/clerk/models/signup.py @@ -0,0 +1,128 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel, Nullable +from enum import Enum +from pydantic import model_serializer +from typing import List, Optional, TypedDict +from typing_extensions import NotRequired + + +class SignUpObject(str, Enum): + SIGN_UP_ATTEMPT = "sign_up_attempt" + + +class SignUpStatus(str, Enum): + MISSING_REQUIREMENTS = "missing_requirements" + COMPLETE = "complete" + ABANDONED = "abandoned" + + +class VerificationsTypedDict(TypedDict): + pass + + +class Verifications(BaseModel): + pass + + +class SignUpUnsafeMetadataTypedDict(TypedDict): + pass + + +class SignUpUnsafeMetadata(BaseModel): + pass + + +class SignUpPublicMetadataTypedDict(TypedDict): + pass + + +class SignUpPublicMetadata(BaseModel): + pass + + +class ExternalAccountTypedDict(TypedDict): + pass + + +class ExternalAccount(BaseModel): + pass + + +class SignUpTypedDict(TypedDict): + object: SignUpObject + id: str + status: SignUpStatus + password_enabled: bool + custom_action: bool + abandon_at: int + required_fields: NotRequired[List[str]] + optional_fields: NotRequired[List[str]] + missing_fields: NotRequired[List[str]] + unverified_fields: NotRequired[List[str]] + verifications: NotRequired[VerificationsTypedDict] + username: NotRequired[Nullable[str]] + email_address: NotRequired[Nullable[str]] + phone_number: NotRequired[Nullable[str]] + web3_wallet: NotRequired[Nullable[str]] + first_name: NotRequired[Nullable[str]] + last_name: NotRequired[Nullable[str]] + unsafe_metadata: NotRequired[SignUpUnsafeMetadataTypedDict] + public_metadata: NotRequired[SignUpPublicMetadataTypedDict] + external_id: NotRequired[Nullable[str]] + created_session_id: NotRequired[Nullable[str]] + created_user_id: NotRequired[Nullable[str]] + external_account: NotRequired[ExternalAccountTypedDict] + + +class SignUp(BaseModel): + object: SignUpObject + id: str + status: SignUpStatus + password_enabled: bool + custom_action: bool + abandon_at: int + required_fields: Optional[List[str]] = None + optional_fields: Optional[List[str]] = None + missing_fields: Optional[List[str]] = None + unverified_fields: Optional[List[str]] = None + verifications: Optional[Verifications] = None + username: Optional[Nullable[str]] = None + email_address: Optional[Nullable[str]] = None + phone_number: Optional[Nullable[str]] = None + web3_wallet: Optional[Nullable[str]] = None + first_name: Optional[Nullable[str]] = None + last_name: Optional[Nullable[str]] = None + unsafe_metadata: Optional[SignUpUnsafeMetadata] = None + public_metadata: Optional[SignUpPublicMetadata] = None + external_id: Optional[Nullable[str]] = None + created_session_id: Optional[Nullable[str]] = None + created_user_id: Optional[Nullable[str]] = None + external_account: Optional[ExternalAccount] = None + + @model_serializer(mode="wrap") + def serialize_model(self, handler): + optional_fields = ["required_fields", "optional_fields", "missing_fields", "unverified_fields", "verifications", "username", "email_address", "phone_number", "web3_wallet", "first_name", "last_name", "unsafe_metadata", "public_metadata", "external_id", "created_session_id", "created_user_id", "external_account"] + nullable_fields = ["username", "email_address", "phone_number", "web3_wallet", "first_name", "last_name", "external_id", "created_session_id", "created_user_id"] + null_default_fields = [] + + serialized = handler(self) + + m = {} + + for n, f in self.model_fields.items(): + k = f.alias or n + val = serialized.get(k) + + if val is not None: + m[k] = val + elif not k in optional_fields or ( + k in optional_fields + and k in nullable_fields + and (self.__pydantic_fields_set__.intersection({n}) or k in null_default_fields) # pylint: disable=no-member + ): + m[k] = val + + return m + diff --git a/src/clerk/models/svixurl.py b/src/clerk/models/svixurl.py new file mode 100644 index 0000000..8f7ebba --- /dev/null +++ b/src/clerk/models/svixurl.py @@ -0,0 +1,14 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel +from typing import TypedDict + + +class SvixURLTypedDict(TypedDict): + svix_url: str + + +class SvixURL(BaseModel): + svix_url: str + diff --git a/src/clerk/models/template.py b/src/clerk/models/template.py new file mode 100644 index 0000000..a1c09cc --- /dev/null +++ b/src/clerk/models/template.py @@ -0,0 +1,135 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel, Nullable +from enum import Enum +from pydantic import model_serializer +from typing import List, Optional, TypedDict +from typing_extensions import NotRequired + + +class TemplateObject(str, Enum): + r"""String representing the object's type. Objects of the same type share the same value. + + """ + TEMPLATE = "template" + + +class TemplateTypedDict(TypedDict): + id: NotRequired[str] + object: NotRequired[TemplateObject] + r"""String representing the object's type. Objects of the same type share the same value. + + """ + instance_id: NotRequired[Nullable[str]] + r"""the id of the instance the template belongs to""" + resource_type: NotRequired[str] + r"""whether this is a system (default) or user overridden) template""" + template_type: NotRequired[str] + r"""whether this is an email or SMS template""" + name: NotRequired[str] + r"""user-friendly name of the template""" + slug: NotRequired[str] + r"""machine-friendly name of the template""" + position: NotRequired[int] + r"""position with the listing of templates""" + can_revert: NotRequired[bool] + r"""whether this template can be reverted to the corresponding system default""" + can_delete: NotRequired[bool] + r"""whether this template can be deleted""" + can_disable: NotRequired[bool] + r"""whether this template can be disabled, true only for notification SMS templates""" + subject: NotRequired[Nullable[str]] + r"""email subject""" + markup: NotRequired[str] + r"""the editor markup used to generate the body of the template""" + body: NotRequired[str] + r"""the template body before variable interpolation""" + available_variables: NotRequired[List[str]] + r"""list of variables that are available for use in the template body""" + required_variables: NotRequired[List[str]] + r"""list of variables that must be contained in the template body""" + from_email_name: NotRequired[str] + reply_to_email_name: NotRequired[str] + delivered_by_clerk: NotRequired[bool] + updated_at: NotRequired[int] + r"""Unix timestamp of last update. + + """ + created_at: NotRequired[int] + r"""Unix timestamp of creation. + + """ + + +class Template(BaseModel): + id: Optional[str] = None + object: Optional[TemplateObject] = None + r"""String representing the object's type. Objects of the same type share the same value. + + """ + instance_id: Optional[Nullable[str]] = None + r"""the id of the instance the template belongs to""" + resource_type: Optional[str] = None + r"""whether this is a system (default) or user overridden) template""" + template_type: Optional[str] = None + r"""whether this is an email or SMS template""" + name: Optional[str] = None + r"""user-friendly name of the template""" + slug: Optional[str] = None + r"""machine-friendly name of the template""" + position: Optional[int] = None + r"""position with the listing of templates""" + can_revert: Optional[bool] = None + r"""whether this template can be reverted to the corresponding system default""" + can_delete: Optional[bool] = None + r"""whether this template can be deleted""" + can_disable: Optional[bool] = None + r"""whether this template can be disabled, true only for notification SMS templates""" + subject: Optional[Nullable[str]] = None + r"""email subject""" + markup: Optional[str] = None + r"""the editor markup used to generate the body of the template""" + body: Optional[str] = None + r"""the template body before variable interpolation""" + available_variables: Optional[List[str]] = None + r"""list of variables that are available for use in the template body""" + required_variables: Optional[List[str]] = None + r"""list of variables that must be contained in the template body""" + from_email_name: Optional[str] = None + reply_to_email_name: Optional[str] = None + delivered_by_clerk: Optional[bool] = None + updated_at: Optional[int] = None + r"""Unix timestamp of last update. + + """ + created_at: Optional[int] = None + r"""Unix timestamp of creation. + + """ + + @model_serializer(mode="wrap") + def serialize_model(self, handler): + optional_fields = ["id", "object", "instance_id", "resource_type", "template_type", "name", "slug", "position", "can_revert", "can_delete", "can_disable", "subject", "markup", "body", "available_variables", "required_variables", "from_email_name", "reply_to_email_name", "delivered_by_clerk", "updated_at", "created_at"] + nullable_fields = ["instance_id", "subject"] + null_default_fields = [] + + serialized = handler(self) + + m = {} + + for n, f in self.model_fields.items(): + k = f.alias or n + val = serialized.get(k) + + if val is not None: + m[k] = val + elif not k in optional_fields or ( + k in optional_fields + and k in nullable_fields + and (self.__pydantic_fields_set__.intersection({n}) or k in null_default_fields) # pylint: disable=no-member + ): + m[k] = val + + return m + diff --git a/src/clerk/models/testingtoken.py b/src/clerk/models/testingtoken.py new file mode 100644 index 0000000..e8dc48e --- /dev/null +++ b/src/clerk/models/testingtoken.py @@ -0,0 +1,35 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel +from enum import Enum +from typing import TypedDict + + +class TestingTokenObject(str, Enum): + TESTING_TOKEN = "testing_token" + + +class TestingTokenTypedDict(TypedDict): + __test__ = False + + object: TestingTokenObject + token: str + r"""The actual token. This value is meant to be passed in the `__clerk_testing_token` query parameter with requests to the Frontend API.""" + expires_at: int + r"""Unix timestamp of the token's expiration time. + + """ + + +class TestingToken(BaseModel): + __test__ = False + + object: TestingTokenObject + token: str + r"""The actual token. This value is meant to be passed in the `__clerk_testing_token` query parameter with requests to the Frontend API.""" + expires_at: int + r"""Unix timestamp of the token's expiration time. + + """ + diff --git a/src/clerk/models/toggletemplatedeliveryop.py b/src/clerk/models/toggletemplatedeliveryop.py new file mode 100644 index 0000000..f17cb4b --- /dev/null +++ b/src/clerk/models/toggletemplatedeliveryop.py @@ -0,0 +1,67 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel, Nullable +from clerk.utils import FieldMetadata, PathParamMetadata, RequestMetadata +from enum import Enum +from pydantic import model_serializer +from typing import Optional, TypedDict +from typing_extensions import Annotated, NotRequired + + +class ToggleTemplateDeliveryPathParamTemplateType(str, Enum): + r"""The type of template to toggle delivery for""" + EMAIL = "email" + SMS = "sms" + + +class ToggleTemplateDeliveryRequestBodyTypedDict(TypedDict): + delivered_by_clerk: NotRequired[Nullable[bool]] + r"""Whether Clerk should deliver emails or SMS messages based on the current template""" + + +class ToggleTemplateDeliveryRequestBody(BaseModel): + delivered_by_clerk: Optional[Nullable[bool]] = None + r"""Whether Clerk should deliver emails or SMS messages based on the current template""" + + @model_serializer(mode="wrap") + def serialize_model(self, handler): + optional_fields = ["delivered_by_clerk"] + nullable_fields = ["delivered_by_clerk"] + null_default_fields = [] + + serialized = handler(self) + + m = {} + + for n, f in self.model_fields.items(): + k = f.alias or n + val = serialized.get(k) + + if val is not None: + m[k] = val + elif not k in optional_fields or ( + k in optional_fields + and k in nullable_fields + and (self.__pydantic_fields_set__.intersection({n}) or k in null_default_fields) # pylint: disable=no-member + ): + m[k] = val + + return m + + +class ToggleTemplateDeliveryRequestTypedDict(TypedDict): + template_type: ToggleTemplateDeliveryPathParamTemplateType + r"""The type of template to toggle delivery for""" + slug: str + r"""The slug of the template for which to toggle delivery""" + request_body: NotRequired[ToggleTemplateDeliveryRequestBodyTypedDict] + + +class ToggleTemplateDeliveryRequest(BaseModel): + template_type: Annotated[ToggleTemplateDeliveryPathParamTemplateType, FieldMetadata(path=PathParamMetadata(style="simple", explode=False))] + r"""The type of template to toggle delivery for""" + slug: Annotated[str, FieldMetadata(path=PathParamMetadata(style="simple", explode=False))] + r"""The slug of the template for which to toggle delivery""" + request_body: Annotated[Optional[ToggleTemplateDeliveryRequestBody], FieldMetadata(request=RequestMetadata(media_type="application/json"))] = None + diff --git a/src/clerk/models/totalcount.py b/src/clerk/models/totalcount.py new file mode 100644 index 0000000..4cef600 --- /dev/null +++ b/src/clerk/models/totalcount.py @@ -0,0 +1,30 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel +from enum import Enum +from typing import TypedDict + + +class TotalCountObject(str, Enum): + r"""String representing the object's type. Objects of the same type share the same value. + + """ + TOTAL_COUNT = "total_count" + + +class TotalCountTypedDict(TypedDict): + object: TotalCountObject + r"""String representing the object's type. Objects of the same type share the same value. + + """ + total_count: int + + +class TotalCount(BaseModel): + object: TotalCountObject + r"""String representing the object's type. Objects of the same type share the same value. + + """ + total_count: int + diff --git a/src/clerk/models/unbanuserop.py b/src/clerk/models/unbanuserop.py new file mode 100644 index 0000000..31dd729 --- /dev/null +++ b/src/clerk/models/unbanuserop.py @@ -0,0 +1,18 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel +from clerk.utils import FieldMetadata, PathParamMetadata +from typing import TypedDict +from typing_extensions import Annotated + + +class UnbanUserRequestTypedDict(TypedDict): + user_id: str + r"""The ID of the user to unban""" + + +class UnbanUserRequest(BaseModel): + user_id: Annotated[str, FieldMetadata(path=PathParamMetadata(style="simple", explode=False))] + r"""The ID of the user to unban""" + diff --git a/src/clerk/models/unlockuserop.py b/src/clerk/models/unlockuserop.py new file mode 100644 index 0000000..b8bde28 --- /dev/null +++ b/src/clerk/models/unlockuserop.py @@ -0,0 +1,18 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel +from clerk.utils import FieldMetadata, PathParamMetadata +from typing import TypedDict +from typing_extensions import Annotated + + +class UnlockUserRequestTypedDict(TypedDict): + user_id: str + r"""The ID of the user to unlock""" + + +class UnlockUserRequest(BaseModel): + user_id: Annotated[str, FieldMetadata(path=PathParamMetadata(style="simple", explode=False))] + r"""The ID of the user to unlock""" + diff --git a/src/clerk/models/updatedomainop.py b/src/clerk/models/updatedomainop.py new file mode 100644 index 0000000..3650403 --- /dev/null +++ b/src/clerk/models/updatedomainop.py @@ -0,0 +1,70 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel, Nullable +from clerk.utils import FieldMetadata, PathParamMetadata, RequestMetadata +from pydantic import model_serializer +from typing import Optional, TypedDict +from typing_extensions import Annotated, NotRequired + + +class UpdateDomainRequestBodyTypedDict(TypedDict): + name: NotRequired[Nullable[str]] + r"""The new domain name. For development instances, can contain the port, + i.e `myhostname:3000`. For production instances, must be a valid FQDN, + i.e `mysite.com`. Cannot contain protocol scheme. + """ + proxy_url: NotRequired[Nullable[str]] + r"""The full URL of the proxy that will forward requests to Clerk's Frontend API. + Can only be updated for production instances. + """ + + +class UpdateDomainRequestBody(BaseModel): + name: Optional[Nullable[str]] = None + r"""The new domain name. For development instances, can contain the port, + i.e `myhostname:3000`. For production instances, must be a valid FQDN, + i.e `mysite.com`. Cannot contain protocol scheme. + """ + proxy_url: Optional[Nullable[str]] = None + r"""The full URL of the proxy that will forward requests to Clerk's Frontend API. + Can only be updated for production instances. + """ + + @model_serializer(mode="wrap") + def serialize_model(self, handler): + optional_fields = ["name", "proxy_url"] + nullable_fields = ["name", "proxy_url"] + null_default_fields = [] + + serialized = handler(self) + + m = {} + + for n, f in self.model_fields.items(): + k = f.alias or n + val = serialized.get(k) + + if val is not None: + m[k] = val + elif not k in optional_fields or ( + k in optional_fields + and k in nullable_fields + and (self.__pydantic_fields_set__.intersection({n}) or k in null_default_fields) # pylint: disable=no-member + ): + m[k] = val + + return m + + +class UpdateDomainRequestTypedDict(TypedDict): + domain_id: str + r"""The ID of the domain that will be updated.""" + request_body: UpdateDomainRequestBodyTypedDict + + +class UpdateDomainRequest(BaseModel): + domain_id: Annotated[str, FieldMetadata(path=PathParamMetadata(style="simple", explode=False))] + r"""The ID of the domain that will be updated.""" + request_body: Annotated[UpdateDomainRequestBody, FieldMetadata(request=RequestMetadata(media_type="application/json"))] + diff --git a/src/clerk/models/updateemailaddressop.py b/src/clerk/models/updateemailaddressop.py new file mode 100644 index 0000000..905d475 --- /dev/null +++ b/src/clerk/models/updateemailaddressop.py @@ -0,0 +1,60 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel, Nullable +from clerk.utils import FieldMetadata, PathParamMetadata, RequestMetadata +from pydantic import model_serializer +from typing import Optional, TypedDict +from typing_extensions import Annotated, NotRequired + + +class UpdateEmailAddressRequestBodyTypedDict(TypedDict): + verified: NotRequired[Nullable[bool]] + r"""The email address will be marked as verified.""" + primary: NotRequired[Nullable[bool]] + r"""Set this email address as the primary email address for the user.""" + + +class UpdateEmailAddressRequestBody(BaseModel): + verified: Optional[Nullable[bool]] = None + r"""The email address will be marked as verified.""" + primary: Optional[Nullable[bool]] = None + r"""Set this email address as the primary email address for the user.""" + + @model_serializer(mode="wrap") + def serialize_model(self, handler): + optional_fields = ["verified", "primary"] + nullable_fields = ["verified", "primary"] + null_default_fields = [] + + serialized = handler(self) + + m = {} + + for n, f in self.model_fields.items(): + k = f.alias or n + val = serialized.get(k) + + if val is not None: + m[k] = val + elif not k in optional_fields or ( + k in optional_fields + and k in nullable_fields + and (self.__pydantic_fields_set__.intersection({n}) or k in null_default_fields) # pylint: disable=no-member + ): + m[k] = val + + return m + + +class UpdateEmailAddressRequestTypedDict(TypedDict): + email_address_id: str + r"""The ID of the email address to update""" + request_body: NotRequired[UpdateEmailAddressRequestBodyTypedDict] + + +class UpdateEmailAddressRequest(BaseModel): + email_address_id: Annotated[str, FieldMetadata(path=PathParamMetadata(style="simple", explode=False))] + r"""The ID of the email address to update""" + request_body: Annotated[Optional[UpdateEmailAddressRequestBody], FieldMetadata(request=RequestMetadata(media_type="application/json"))] = None + diff --git a/src/clerk/models/updateinstanceauthconfigop.py b/src/clerk/models/updateinstanceauthconfigop.py new file mode 100644 index 0000000..dedb696 --- /dev/null +++ b/src/clerk/models/updateinstanceauthconfigop.py @@ -0,0 +1,77 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel, Nullable +from pydantic import model_serializer +from typing import Optional, TypedDict +from typing_extensions import NotRequired + + +class UpdateInstanceAuthConfigRequestBodyTypedDict(TypedDict): + restricted_to_allowlist: NotRequired[Nullable[bool]] + r"""Whether sign up is restricted to email addresses, phone numbers and usernames that are on the allowlist.""" + from_email_address: NotRequired[Nullable[str]] + r"""The local part of the email address from which authentication-related emails (e.g. OTP code, magic links) will be sent. + Only alphanumeric values are allowed. + Note that this value should contain only the local part of the address (e.g. `foo` for `foo@example.com`). + """ + progressive_sign_up: NotRequired[Nullable[bool]] + r"""Enable the Progressive Sign Up algorithm. Refer to the [docs](https://clerk.com/docs/upgrade-guides/progressive-sign-up) for more info.""" + session_token_template: NotRequired[Nullable[str]] + r"""The name of the JWT Template used to augment your session tokens. To disable this, pass an empty string.""" + enhanced_email_deliverability: NotRequired[Nullable[bool]] + r"""The \"enhanced_email_deliverability\" feature will send emails from \"verifications@clerk.dev\" instead of your domain. + This can be helpful if you do not have a high domain reputation. + """ + test_mode: NotRequired[Nullable[bool]] + r"""Toggles test mode for this instance, allowing the use of test email addresses and phone numbers. + Defaults to true for development instances. + """ + + +class UpdateInstanceAuthConfigRequestBody(BaseModel): + restricted_to_allowlist: Optional[Nullable[bool]] = False + r"""Whether sign up is restricted to email addresses, phone numbers and usernames that are on the allowlist.""" + from_email_address: Optional[Nullable[str]] = None + r"""The local part of the email address from which authentication-related emails (e.g. OTP code, magic links) will be sent. + Only alphanumeric values are allowed. + Note that this value should contain only the local part of the address (e.g. `foo` for `foo@example.com`). + """ + progressive_sign_up: Optional[Nullable[bool]] = None + r"""Enable the Progressive Sign Up algorithm. Refer to the [docs](https://clerk.com/docs/upgrade-guides/progressive-sign-up) for more info.""" + session_token_template: Optional[Nullable[str]] = None + r"""The name of the JWT Template used to augment your session tokens. To disable this, pass an empty string.""" + enhanced_email_deliverability: Optional[Nullable[bool]] = None + r"""The \"enhanced_email_deliverability\" feature will send emails from \"verifications@clerk.dev\" instead of your domain. + This can be helpful if you do not have a high domain reputation. + """ + test_mode: Optional[Nullable[bool]] = None + r"""Toggles test mode for this instance, allowing the use of test email addresses and phone numbers. + Defaults to true for development instances. + """ + + @model_serializer(mode="wrap") + def serialize_model(self, handler): + optional_fields = ["restricted_to_allowlist", "from_email_address", "progressive_sign_up", "session_token_template", "enhanced_email_deliverability", "test_mode"] + nullable_fields = ["restricted_to_allowlist", "from_email_address", "progressive_sign_up", "session_token_template", "enhanced_email_deliverability", "test_mode"] + null_default_fields = [] + + serialized = handler(self) + + m = {} + + for n, f in self.model_fields.items(): + k = f.alias or n + val = serialized.get(k) + + if val is not None: + m[k] = val + elif not k in optional_fields or ( + k in optional_fields + and k in nullable_fields + and (self.__pydantic_fields_set__.intersection({n}) or k in null_default_fields) # pylint: disable=no-member + ): + m[k] = val + + return m + diff --git a/src/clerk/models/updateinstanceop.py b/src/clerk/models/updateinstanceop.py new file mode 100644 index 0000000..310777e --- /dev/null +++ b/src/clerk/models/updateinstanceop.py @@ -0,0 +1,86 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel, Nullable +import pydantic +from pydantic import model_serializer +from typing import List, Optional, TypedDict +from typing_extensions import Annotated, NotRequired + + +class UpdateInstanceRequestBodyTypedDict(TypedDict): + test_mode: NotRequired[Nullable[bool]] + r"""Toggles test mode for this instance, allowing the use of test email addresses and phone numbers. + Defaults to true for development instances. + """ + hibp: NotRequired[Nullable[bool]] + r"""Whether the instance should be using the HIBP service to check passwords for breaches""" + enhanced_email_deliverability: NotRequired[Nullable[bool]] + r"""The \"enhanced_email_deliverability\" feature will send emails from \"verifications@clerk.dev\" instead of your domain. + This can be helpful if you do not have a high domain reputation. + """ + support_email: NotRequired[Nullable[str]] + clerk_js_version: NotRequired[Nullable[str]] + development_origin: NotRequired[Nullable[str]] + allowed_origins: NotRequired[List[str]] + r"""For browser-like stacks such as browser extensions, Electron, or Capacitor.js the instance allowed origins need to be updated with the request origin value. + For Chrome extensions popup, background, or service worker pages the origin is chrome-extension://extension_uiid. For Electron apps the default origin is http://localhost:3000. For Capacitor, the origin is capacitor://localhost. + """ + cookieless_dev: NotRequired[bool] + r"""Whether the instance should operate in cookieless development mode (i.e. without third-party cookies). + Deprecated: Please use `url_based_session_syncing` instead. + """ + url_based_session_syncing: NotRequired[bool] + r"""Whether the instance should use URL-based session syncing in development mode (i.e. without third-party cookies).""" + + +class UpdateInstanceRequestBody(BaseModel): + test_mode: Optional[Nullable[bool]] = None + r"""Toggles test mode for this instance, allowing the use of test email addresses and phone numbers. + Defaults to true for development instances. + """ + hibp: Optional[Nullable[bool]] = None + r"""Whether the instance should be using the HIBP service to check passwords for breaches""" + enhanced_email_deliverability: Optional[Nullable[bool]] = None + r"""The \"enhanced_email_deliverability\" feature will send emails from \"verifications@clerk.dev\" instead of your domain. + This can be helpful if you do not have a high domain reputation. + """ + support_email: Optional[Nullable[str]] = None + clerk_js_version: Optional[Nullable[str]] = None + development_origin: Optional[Nullable[str]] = None + allowed_origins: Optional[List[str]] = None + r"""For browser-like stacks such as browser extensions, Electron, or Capacitor.js the instance allowed origins need to be updated with the request origin value. + For Chrome extensions popup, background, or service worker pages the origin is chrome-extension://extension_uiid. For Electron apps the default origin is http://localhost:3000. For Capacitor, the origin is capacitor://localhost. + """ + cookieless_dev: Annotated[Optional[bool], pydantic.Field(deprecated="warning: ** DEPRECATED ** - This will be removed in a future release, please migrate away from it as soon as possible.")] = None + r"""Whether the instance should operate in cookieless development mode (i.e. without third-party cookies). + Deprecated: Please use `url_based_session_syncing` instead. + """ + url_based_session_syncing: Optional[bool] = None + r"""Whether the instance should use URL-based session syncing in development mode (i.e. without third-party cookies).""" + + @model_serializer(mode="wrap") + def serialize_model(self, handler): + optional_fields = ["test_mode", "hibp", "enhanced_email_deliverability", "support_email", "clerk_js_version", "development_origin", "allowed_origins", "cookieless_dev", "url_based_session_syncing"] + nullable_fields = ["test_mode", "hibp", "enhanced_email_deliverability", "support_email", "clerk_js_version", "development_origin"] + null_default_fields = [] + + serialized = handler(self) + + m = {} + + for n, f in self.model_fields.items(): + k = f.alias or n + val = serialized.get(k) + + if val is not None: + m[k] = val + elif not k in optional_fields or ( + k in optional_fields + and k in nullable_fields + and (self.__pydantic_fields_set__.intersection({n}) or k in null_default_fields) # pylint: disable=no-member + ): + m[k] = val + + return m + diff --git a/src/clerk/models/updateinstanceorganizationsettingsop.py b/src/clerk/models/updateinstanceorganizationsettingsop.py new file mode 100644 index 0000000..b727cc3 --- /dev/null +++ b/src/clerk/models/updateinstanceorganizationsettingsop.py @@ -0,0 +1,63 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel, Nullable +from pydantic import model_serializer +from typing import List, Optional, TypedDict +from typing_extensions import NotRequired + + +class UpdateInstanceOrganizationSettingsRequestBodyTypedDict(TypedDict): + enabled: NotRequired[Nullable[bool]] + max_allowed_memberships: NotRequired[Nullable[int]] + admin_delete_enabled: NotRequired[Nullable[bool]] + domains_enabled: NotRequired[Nullable[bool]] + domains_enrollment_modes: NotRequired[List[str]] + r"""Specify which enrollment modes to enable for your Organization Domains. + Supported modes are 'automatic_invitation' & 'automatic_suggestion'. + """ + creator_role_id: NotRequired[str] + r"""Specify what the default organization role is for an organization creator.""" + domains_default_role_id: NotRequired[str] + r"""Specify what the default organization role is for the organization domains.""" + + +class UpdateInstanceOrganizationSettingsRequestBody(BaseModel): + enabled: Optional[Nullable[bool]] = None + max_allowed_memberships: Optional[Nullable[int]] = None + admin_delete_enabled: Optional[Nullable[bool]] = None + domains_enabled: Optional[Nullable[bool]] = None + domains_enrollment_modes: Optional[List[str]] = None + r"""Specify which enrollment modes to enable for your Organization Domains. + Supported modes are 'automatic_invitation' & 'automatic_suggestion'. + """ + creator_role_id: Optional[str] = None + r"""Specify what the default organization role is for an organization creator.""" + domains_default_role_id: Optional[str] = None + r"""Specify what the default organization role is for the organization domains.""" + + @model_serializer(mode="wrap") + def serialize_model(self, handler): + optional_fields = ["enabled", "max_allowed_memberships", "admin_delete_enabled", "domains_enabled", "domains_enrollment_modes", "creator_role_id", "domains_default_role_id"] + nullable_fields = ["enabled", "max_allowed_memberships", "admin_delete_enabled", "domains_enabled"] + null_default_fields = [] + + serialized = handler(self) + + m = {} + + for n, f in self.model_fields.items(): + k = f.alias or n + val = serialized.get(k) + + if val is not None: + m[k] = val + elif not k in optional_fields or ( + k in optional_fields + and k in nullable_fields + and (self.__pydantic_fields_set__.intersection({n}) or k in null_default_fields) # pylint: disable=no-member + ): + m[k] = val + + return m + diff --git a/src/clerk/models/updateinstancerestrictionsop.py b/src/clerk/models/updateinstancerestrictionsop.py new file mode 100644 index 0000000..a173516 --- /dev/null +++ b/src/clerk/models/updateinstancerestrictionsop.py @@ -0,0 +1,49 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel, Nullable +from pydantic import model_serializer +from typing import Optional, TypedDict +from typing_extensions import NotRequired + + +class UpdateInstanceRestrictionsRequestBodyTypedDict(TypedDict): + allowlist: NotRequired[Nullable[bool]] + blocklist: NotRequired[Nullable[bool]] + block_email_subaddresses: NotRequired[Nullable[bool]] + block_disposable_email_domains: NotRequired[Nullable[bool]] + ignore_dots_for_gmail_addresses: NotRequired[Nullable[bool]] + + +class UpdateInstanceRestrictionsRequestBody(BaseModel): + allowlist: Optional[Nullable[bool]] = None + blocklist: Optional[Nullable[bool]] = None + block_email_subaddresses: Optional[Nullable[bool]] = None + block_disposable_email_domains: Optional[Nullable[bool]] = None + ignore_dots_for_gmail_addresses: Optional[Nullable[bool]] = None + + @model_serializer(mode="wrap") + def serialize_model(self, handler): + optional_fields = ["allowlist", "blocklist", "block_email_subaddresses", "block_disposable_email_domains", "ignore_dots_for_gmail_addresses"] + nullable_fields = ["allowlist", "blocklist", "block_email_subaddresses", "block_disposable_email_domains", "ignore_dots_for_gmail_addresses"] + null_default_fields = [] + + serialized = handler(self) + + m = {} + + for n, f in self.model_fields.items(): + k = f.alias or n + val = serialized.get(k) + + if val is not None: + m[k] = val + elif not k in optional_fields or ( + k in optional_fields + and k in nullable_fields + and (self.__pydantic_fields_set__.intersection({n}) or k in null_default_fields) # pylint: disable=no-member + ): + m[k] = val + + return m + diff --git a/src/clerk/models/updatejwttemplateop.py b/src/clerk/models/updatejwttemplateop.py new file mode 100644 index 0000000..b683a84 --- /dev/null +++ b/src/clerk/models/updatejwttemplateop.py @@ -0,0 +1,90 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel, Nullable +from clerk.utils import FieldMetadata, PathParamMetadata, RequestMetadata +from pydantic import model_serializer +from typing import Optional, TypedDict +from typing_extensions import Annotated, NotRequired + + +class UpdateJWTTemplateClaimsTypedDict(TypedDict): + r"""JWT template claims in JSON format""" + + + +class UpdateJWTTemplateClaims(BaseModel): + r"""JWT template claims in JSON format""" + + + +class UpdateJWTTemplateRequestBodyTypedDict(TypedDict): + name: NotRequired[str] + r"""JWT template name""" + claims: NotRequired[UpdateJWTTemplateClaimsTypedDict] + r"""JWT template claims in JSON format""" + lifetime: NotRequired[Nullable[float]] + r"""JWT token lifetime""" + allowed_clock_skew: NotRequired[Nullable[float]] + r"""JWT token allowed clock skew""" + custom_signing_key: NotRequired[bool] + r"""Whether a custom signing key/algorithm is also provided for this template""" + signing_algorithm: NotRequired[Nullable[str]] + r"""The custom signing algorithm to use when minting JWTs""" + signing_key: NotRequired[Nullable[str]] + r"""The custom signing private key to use when minting JWTs""" + + +class UpdateJWTTemplateRequestBody(BaseModel): + name: Optional[str] = None + r"""JWT template name""" + claims: Optional[UpdateJWTTemplateClaims] = None + r"""JWT template claims in JSON format""" + lifetime: Optional[Nullable[float]] = None + r"""JWT token lifetime""" + allowed_clock_skew: Optional[Nullable[float]] = None + r"""JWT token allowed clock skew""" + custom_signing_key: Optional[bool] = None + r"""Whether a custom signing key/algorithm is also provided for this template""" + signing_algorithm: Optional[Nullable[str]] = None + r"""The custom signing algorithm to use when minting JWTs""" + signing_key: Optional[Nullable[str]] = None + r"""The custom signing private key to use when minting JWTs""" + + @model_serializer(mode="wrap") + def serialize_model(self, handler): + optional_fields = ["name", "claims", "lifetime", "allowed_clock_skew", "custom_signing_key", "signing_algorithm", "signing_key"] + nullable_fields = ["lifetime", "allowed_clock_skew", "signing_algorithm", "signing_key"] + null_default_fields = [] + + serialized = handler(self) + + m = {} + + for n, f in self.model_fields.items(): + k = f.alias or n + val = serialized.get(k) + + if val is not None: + m[k] = val + elif not k in optional_fields or ( + k in optional_fields + and k in nullable_fields + and (self.__pydantic_fields_set__.intersection({n}) or k in null_default_fields) # pylint: disable=no-member + ): + m[k] = val + + return m + + +class UpdateJWTTemplateRequestTypedDict(TypedDict): + template_id: str + r"""The ID of the JWT template to update""" + request_body: NotRequired[UpdateJWTTemplateRequestBodyTypedDict] + + +class UpdateJWTTemplateRequest(BaseModel): + template_id: Annotated[str, FieldMetadata(path=PathParamMetadata(style="simple", explode=False))] + r"""The ID of the JWT template to update""" + request_body: Annotated[Optional[UpdateJWTTemplateRequestBody], FieldMetadata(request=RequestMetadata(media_type="application/json"))] = None + diff --git a/src/clerk/models/updateoauthapplicationop.py b/src/clerk/models/updateoauthapplicationop.py new file mode 100644 index 0000000..72335aa --- /dev/null +++ b/src/clerk/models/updateoauthapplicationop.py @@ -0,0 +1,38 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel +from clerk.utils import FieldMetadata, PathParamMetadata, RequestMetadata +from typing import Optional, TypedDict +from typing_extensions import Annotated, NotRequired + + +class UpdateOAuthApplicationRequestBodyTypedDict(TypedDict): + name: NotRequired[str] + r"""The new name of the OAuth application""" + callback_url: NotRequired[str] + r"""The new callback URL of the OAuth application""" + scopes: NotRequired[str] + r"""Define the allowed scopes for the new OAuth applications that dictate the user payload of the OAuth user info endpoint. Available scopes are `profile`, `email`, `public_metadata`, `private_metadata`. Provide the requested scopes as a string, separated by spaces.""" + + +class UpdateOAuthApplicationRequestBody(BaseModel): + name: Optional[str] = None + r"""The new name of the OAuth application""" + callback_url: Optional[str] = None + r"""The new callback URL of the OAuth application""" + scopes: Optional[str] = "profile email" + r"""Define the allowed scopes for the new OAuth applications that dictate the user payload of the OAuth user info endpoint. Available scopes are `profile`, `email`, `public_metadata`, `private_metadata`. Provide the requested scopes as a string, separated by spaces.""" + + +class UpdateOAuthApplicationRequestTypedDict(TypedDict): + oauth_application_id: str + r"""The ID of the OAuth application to update""" + request_body: UpdateOAuthApplicationRequestBodyTypedDict + + +class UpdateOAuthApplicationRequest(BaseModel): + oauth_application_id: Annotated[str, FieldMetadata(path=PathParamMetadata(style="simple", explode=False))] + r"""The ID of the OAuth application to update""" + request_body: Annotated[UpdateOAuthApplicationRequestBody, FieldMetadata(request=RequestMetadata(media_type="application/json"))] + diff --git a/src/clerk/models/updateorganizationmembershipmetadataop.py b/src/clerk/models/updateorganizationmembershipmetadataop.py new file mode 100644 index 0000000..8151837 --- /dev/null +++ b/src/clerk/models/updateorganizationmembershipmetadataop.py @@ -0,0 +1,74 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel +from clerk.utils import FieldMetadata, PathParamMetadata, RequestMetadata +from typing import Optional, TypedDict +from typing_extensions import Annotated, NotRequired + + +class UpdateOrganizationMembershipMetadataPublicMetadataTypedDict(TypedDict): + r"""Metadata saved on the organization membership, that is visible to both your frontend and backend. + The new object will be merged with the existing value. + """ + + + +class UpdateOrganizationMembershipMetadataPublicMetadata(BaseModel): + r"""Metadata saved on the organization membership, that is visible to both your frontend and backend. + The new object will be merged with the existing value. + """ + + + +class UpdateOrganizationMembershipMetadataPrivateMetadataTypedDict(TypedDict): + r"""Metadata saved on the organization membership that is only visible to your backend. + The new object will be merged with the existing value. + """ + + + +class UpdateOrganizationMembershipMetadataPrivateMetadata(BaseModel): + r"""Metadata saved on the organization membership that is only visible to your backend. + The new object will be merged with the existing value. + """ + + + +class UpdateOrganizationMembershipMetadataRequestBodyTypedDict(TypedDict): + public_metadata: NotRequired[UpdateOrganizationMembershipMetadataPublicMetadataTypedDict] + r"""Metadata saved on the organization membership, that is visible to both your frontend and backend. + The new object will be merged with the existing value. + """ + private_metadata: NotRequired[UpdateOrganizationMembershipMetadataPrivateMetadataTypedDict] + r"""Metadata saved on the organization membership that is only visible to your backend. + The new object will be merged with the existing value. + """ + + +class UpdateOrganizationMembershipMetadataRequestBody(BaseModel): + public_metadata: Optional[UpdateOrganizationMembershipMetadataPublicMetadata] = None + r"""Metadata saved on the organization membership, that is visible to both your frontend and backend. + The new object will be merged with the existing value. + """ + private_metadata: Optional[UpdateOrganizationMembershipMetadataPrivateMetadata] = None + r"""Metadata saved on the organization membership that is only visible to your backend. + The new object will be merged with the existing value. + """ + + +class UpdateOrganizationMembershipMetadataRequestTypedDict(TypedDict): + organization_id: str + r"""The ID of the organization the membership belongs to""" + user_id: str + r"""The ID of the user that this membership belongs to""" + request_body: UpdateOrganizationMembershipMetadataRequestBodyTypedDict + + +class UpdateOrganizationMembershipMetadataRequest(BaseModel): + organization_id: Annotated[str, FieldMetadata(path=PathParamMetadata(style="simple", explode=False))] + r"""The ID of the organization the membership belongs to""" + user_id: Annotated[str, FieldMetadata(path=PathParamMetadata(style="simple", explode=False))] + r"""The ID of the user that this membership belongs to""" + request_body: Annotated[UpdateOrganizationMembershipMetadataRequestBody, FieldMetadata(request=RequestMetadata(media_type="application/json"))] + diff --git a/src/clerk/models/updateorganizationmembershipop.py b/src/clerk/models/updateorganizationmembershipop.py new file mode 100644 index 0000000..21f1dec --- /dev/null +++ b/src/clerk/models/updateorganizationmembershipop.py @@ -0,0 +1,34 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel +from clerk.utils import FieldMetadata, PathParamMetadata, RequestMetadata +from typing import TypedDict +from typing_extensions import Annotated + + +class UpdateOrganizationMembershipRequestBodyTypedDict(TypedDict): + role: str + r"""The new role of the given membership.""" + + +class UpdateOrganizationMembershipRequestBody(BaseModel): + role: str + r"""The new role of the given membership.""" + + +class UpdateOrganizationMembershipRequestTypedDict(TypedDict): + organization_id: str + r"""The ID of the organization the membership belongs to""" + user_id: str + r"""The ID of the user that this membership belongs to""" + request_body: UpdateOrganizationMembershipRequestBodyTypedDict + + +class UpdateOrganizationMembershipRequest(BaseModel): + organization_id: Annotated[str, FieldMetadata(path=PathParamMetadata(style="simple", explode=False))] + r"""The ID of the organization the membership belongs to""" + user_id: Annotated[str, FieldMetadata(path=PathParamMetadata(style="simple", explode=False))] + r"""The ID of the user that this membership belongs to""" + request_body: Annotated[UpdateOrganizationMembershipRequestBody, FieldMetadata(request=RequestMetadata(media_type="application/json"))] + diff --git a/src/clerk/models/updateorganizationop.py b/src/clerk/models/updateorganizationop.py new file mode 100644 index 0000000..9f23211 --- /dev/null +++ b/src/clerk/models/updateorganizationop.py @@ -0,0 +1,96 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel, Nullable +from clerk.utils import FieldMetadata, PathParamMetadata, RequestMetadata +from pydantic import model_serializer +from typing import Optional, TypedDict +from typing_extensions import Annotated, NotRequired + + +class UpdateOrganizationPublicMetadataTypedDict(TypedDict): + r"""Metadata saved on the organization, that is visible to both your frontend and backend.""" + + + +class UpdateOrganizationPublicMetadata(BaseModel): + r"""Metadata saved on the organization, that is visible to both your frontend and backend.""" + + + +class UpdateOrganizationPrivateMetadataTypedDict(TypedDict): + r"""Metadata saved on the organization that is only visible to your backend.""" + + + +class UpdateOrganizationPrivateMetadata(BaseModel): + r"""Metadata saved on the organization that is only visible to your backend.""" + + + +class UpdateOrganizationRequestBodyTypedDict(TypedDict): + public_metadata: NotRequired[UpdateOrganizationPublicMetadataTypedDict] + r"""Metadata saved on the organization, that is visible to both your frontend and backend.""" + private_metadata: NotRequired[UpdateOrganizationPrivateMetadataTypedDict] + r"""Metadata saved on the organization that is only visible to your backend.""" + name: NotRequired[Nullable[str]] + r"""The new name of the organization""" + slug: NotRequired[Nullable[str]] + r"""The new slug of the organization, which needs to be unique in the instance""" + max_allowed_memberships: NotRequired[Nullable[int]] + r"""The maximum number of memberships allowed for this organization""" + admin_delete_enabled: NotRequired[Nullable[bool]] + r"""If true, an admin can delete this organization with the Frontend API.""" + + +class UpdateOrganizationRequestBody(BaseModel): + public_metadata: Optional[UpdateOrganizationPublicMetadata] = None + r"""Metadata saved on the organization, that is visible to both your frontend and backend.""" + private_metadata: Optional[UpdateOrganizationPrivateMetadata] = None + r"""Metadata saved on the organization that is only visible to your backend.""" + name: Optional[Nullable[str]] = None + r"""The new name of the organization""" + slug: Optional[Nullable[str]] = None + r"""The new slug of the organization, which needs to be unique in the instance""" + max_allowed_memberships: Optional[Nullable[int]] = None + r"""The maximum number of memberships allowed for this organization""" + admin_delete_enabled: Optional[Nullable[bool]] = None + r"""If true, an admin can delete this organization with the Frontend API.""" + + @model_serializer(mode="wrap") + def serialize_model(self, handler): + optional_fields = ["public_metadata", "private_metadata", "name", "slug", "max_allowed_memberships", "admin_delete_enabled"] + nullable_fields = ["name", "slug", "max_allowed_memberships", "admin_delete_enabled"] + null_default_fields = [] + + serialized = handler(self) + + m = {} + + for n, f in self.model_fields.items(): + k = f.alias or n + val = serialized.get(k) + + if val is not None: + m[k] = val + elif not k in optional_fields or ( + k in optional_fields + and k in nullable_fields + and (self.__pydantic_fields_set__.intersection({n}) or k in null_default_fields) # pylint: disable=no-member + ): + m[k] = val + + return m + + +class UpdateOrganizationRequestTypedDict(TypedDict): + organization_id: str + r"""The ID of the organization to update""" + request_body: UpdateOrganizationRequestBodyTypedDict + + +class UpdateOrganizationRequest(BaseModel): + organization_id: Annotated[str, FieldMetadata(path=PathParamMetadata(style="simple", explode=False))] + r"""The ID of the organization to update""" + request_body: Annotated[UpdateOrganizationRequestBody, FieldMetadata(request=RequestMetadata(media_type="application/json"))] + diff --git a/src/clerk/models/updatephonenumberop.py b/src/clerk/models/updatephonenumberop.py new file mode 100644 index 0000000..b6f11b4 --- /dev/null +++ b/src/clerk/models/updatephonenumberop.py @@ -0,0 +1,70 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel, Nullable +from clerk.utils import FieldMetadata, PathParamMetadata, RequestMetadata +from pydantic import model_serializer +from typing import Optional, TypedDict +from typing_extensions import Annotated, NotRequired + + +class UpdatePhoneNumberRequestBodyTypedDict(TypedDict): + verified: NotRequired[Nullable[bool]] + r"""The phone number will be marked as verified.""" + primary: NotRequired[Nullable[bool]] + r"""Set this phone number as the primary phone number for the user.""" + reserved_for_second_factor: NotRequired[Nullable[bool]] + r"""Set this phone number as reserved for multi-factor authentication. + The phone number must also be verified. + If there are no other reserved second factors, the phone number will be set as the default second factor. + """ + + +class UpdatePhoneNumberRequestBody(BaseModel): + verified: Optional[Nullable[bool]] = None + r"""The phone number will be marked as verified.""" + primary: Optional[Nullable[bool]] = None + r"""Set this phone number as the primary phone number for the user.""" + reserved_for_second_factor: Optional[Nullable[bool]] = None + r"""Set this phone number as reserved for multi-factor authentication. + The phone number must also be verified. + If there are no other reserved second factors, the phone number will be set as the default second factor. + """ + + @model_serializer(mode="wrap") + def serialize_model(self, handler): + optional_fields = ["verified", "primary", "reserved_for_second_factor"] + nullable_fields = ["verified", "primary", "reserved_for_second_factor"] + null_default_fields = [] + + serialized = handler(self) + + m = {} + + for n, f in self.model_fields.items(): + k = f.alias or n + val = serialized.get(k) + + if val is not None: + m[k] = val + elif not k in optional_fields or ( + k in optional_fields + and k in nullable_fields + and (self.__pydantic_fields_set__.intersection({n}) or k in null_default_fields) # pylint: disable=no-member + ): + m[k] = val + + return m + + +class UpdatePhoneNumberRequestTypedDict(TypedDict): + phone_number_id: str + r"""The ID of the phone number to update""" + request_body: NotRequired[UpdatePhoneNumberRequestBodyTypedDict] + + +class UpdatePhoneNumberRequest(BaseModel): + phone_number_id: Annotated[str, FieldMetadata(path=PathParamMetadata(style="simple", explode=False))] + r"""The ID of the phone number to update""" + request_body: Annotated[Optional[UpdatePhoneNumberRequestBody], FieldMetadata(request=RequestMetadata(media_type="application/json"))] = None + diff --git a/src/clerk/models/updateproductioninstancedomainop.py b/src/clerk/models/updateproductioninstancedomainop.py new file mode 100644 index 0000000..d2fd66f --- /dev/null +++ b/src/clerk/models/updateproductioninstancedomainop.py @@ -0,0 +1,17 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel +from typing import Optional, TypedDict +from typing_extensions import NotRequired + + +class UpdateProductionInstanceDomainRequestBodyTypedDict(TypedDict): + home_url: NotRequired[str] + r"""The new home URL of the production instance e.g. https://www.example.com""" + + +class UpdateProductionInstanceDomainRequestBody(BaseModel): + home_url: Optional[str] = None + r"""The new home URL of the production instance e.g. https://www.example.com""" + diff --git a/src/clerk/models/updatesamlconnectionop.py b/src/clerk/models/updatesamlconnectionop.py new file mode 100644 index 0000000..42edfeb --- /dev/null +++ b/src/clerk/models/updatesamlconnectionop.py @@ -0,0 +1,118 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel, Nullable +from clerk.utils import FieldMetadata, PathParamMetadata, RequestMetadata +from pydantic import model_serializer +from typing import Optional, TypedDict +from typing_extensions import Annotated, NotRequired + + +class UpdateSAMLConnectionAttributeMappingTypedDict(TypedDict): + r"""Define the atrtibute name mapping between Identity Provider and Clerk's user properties""" + + user_id: NotRequired[str] + email_address: NotRequired[str] + first_name: NotRequired[str] + last_name: NotRequired[str] + + +class UpdateSAMLConnectionAttributeMapping(BaseModel): + r"""Define the atrtibute name mapping between Identity Provider and Clerk's user properties""" + + user_id: Optional[str] = None + email_address: Optional[str] = None + first_name: Optional[str] = None + last_name: Optional[str] = None + + +class UpdateSAMLConnectionRequestBodyTypedDict(TypedDict): + name: NotRequired[Nullable[str]] + r"""The name of the new SAML Connection""" + domain: NotRequired[Nullable[str]] + r"""The domain to use for the new SAML Connection""" + idp_entity_id: NotRequired[Nullable[str]] + r"""The entity id as provided by the IdP""" + idp_sso_url: NotRequired[Nullable[str]] + r"""The SSO url as provided by the IdP""" + idp_certificate: NotRequired[Nullable[str]] + r"""The x509 certificated as provided by the IdP""" + idp_metadata_url: NotRequired[Nullable[str]] + r"""The URL which serves the IdP metadata. If present, it takes priority over the corresponding individual properties and replaces them""" + idp_metadata: NotRequired[Nullable[str]] + r"""The XML content of the IdP metadata file. If present, it takes priority over the corresponding individual properties""" + attribute_mapping: NotRequired[Nullable[UpdateSAMLConnectionAttributeMappingTypedDict]] + r"""Define the atrtibute name mapping between Identity Provider and Clerk's user properties""" + active: NotRequired[Nullable[bool]] + r"""Activate or de-activate the SAML Connection""" + sync_user_attributes: NotRequired[Nullable[bool]] + r"""Controls whether to update the user's attributes in each sign-in""" + allow_subdomains: NotRequired[Nullable[bool]] + r"""Allow users with an email address subdomain to use this connection in order to authenticate""" + allow_idp_initiated: NotRequired[Nullable[bool]] + r"""Enable or deactivate IdP-initiated flows""" + + +class UpdateSAMLConnectionRequestBody(BaseModel): + name: Optional[Nullable[str]] = None + r"""The name of the new SAML Connection""" + domain: Optional[Nullable[str]] = None + r"""The domain to use for the new SAML Connection""" + idp_entity_id: Optional[Nullable[str]] = None + r"""The entity id as provided by the IdP""" + idp_sso_url: Optional[Nullable[str]] = None + r"""The SSO url as provided by the IdP""" + idp_certificate: Optional[Nullable[str]] = None + r"""The x509 certificated as provided by the IdP""" + idp_metadata_url: Optional[Nullable[str]] = None + r"""The URL which serves the IdP metadata. If present, it takes priority over the corresponding individual properties and replaces them""" + idp_metadata: Optional[Nullable[str]] = None + r"""The XML content of the IdP metadata file. If present, it takes priority over the corresponding individual properties""" + attribute_mapping: Optional[Nullable[UpdateSAMLConnectionAttributeMapping]] = None + r"""Define the atrtibute name mapping between Identity Provider and Clerk's user properties""" + active: Optional[Nullable[bool]] = None + r"""Activate or de-activate the SAML Connection""" + sync_user_attributes: Optional[Nullable[bool]] = None + r"""Controls whether to update the user's attributes in each sign-in""" + allow_subdomains: Optional[Nullable[bool]] = None + r"""Allow users with an email address subdomain to use this connection in order to authenticate""" + allow_idp_initiated: Optional[Nullable[bool]] = None + r"""Enable or deactivate IdP-initiated flows""" + + @model_serializer(mode="wrap") + def serialize_model(self, handler): + optional_fields = ["name", "domain", "idp_entity_id", "idp_sso_url", "idp_certificate", "idp_metadata_url", "idp_metadata", "attribute_mapping", "active", "sync_user_attributes", "allow_subdomains", "allow_idp_initiated"] + nullable_fields = ["name", "domain", "idp_entity_id", "idp_sso_url", "idp_certificate", "idp_metadata_url", "idp_metadata", "attribute_mapping", "active", "sync_user_attributes", "allow_subdomains", "allow_idp_initiated"] + null_default_fields = [] + + serialized = handler(self) + + m = {} + + for n, f in self.model_fields.items(): + k = f.alias or n + val = serialized.get(k) + + if val is not None: + m[k] = val + elif not k in optional_fields or ( + k in optional_fields + and k in nullable_fields + and (self.__pydantic_fields_set__.intersection({n}) or k in null_default_fields) # pylint: disable=no-member + ): + m[k] = val + + return m + + +class UpdateSAMLConnectionRequestTypedDict(TypedDict): + saml_connection_id: str + r"""The ID of the SAML Connection to update""" + request_body: UpdateSAMLConnectionRequestBodyTypedDict + + +class UpdateSAMLConnectionRequest(BaseModel): + saml_connection_id: Annotated[str, FieldMetadata(path=PathParamMetadata(style="simple", explode=False))] + r"""The ID of the SAML Connection to update""" + request_body: Annotated[UpdateSAMLConnectionRequestBody, FieldMetadata(request=RequestMetadata(media_type="application/json"))] + diff --git a/src/clerk/models/updatesignupop.py b/src/clerk/models/updatesignupop.py new file mode 100644 index 0000000..597a18b --- /dev/null +++ b/src/clerk/models/updatesignupop.py @@ -0,0 +1,70 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel, Nullable +from clerk.utils import FieldMetadata, PathParamMetadata, RequestMetadata +from pydantic import model_serializer +from typing import Optional, TypedDict +from typing_extensions import Annotated, NotRequired + + +class UpdateSignUpRequestBodyTypedDict(TypedDict): + custom_action: NotRequired[bool] + r"""Specifies whether a custom action has run for this sign-up attempt. + This is important when your instance has been configured to require a custom action to run before converting a sign-up into a user. + After executing any external business logic you deem necessary, you can mark the sign-up as ready-to-convert by setting `custom_action` to `true`. + """ + external_id: NotRequired[Nullable[str]] + r"""The ID of the guest attempting to sign up as used in your external systems or your previous authentication solution. + This will be copied to the resulting user when the sign-up is completed. + """ + + +class UpdateSignUpRequestBody(BaseModel): + custom_action: Optional[bool] = None + r"""Specifies whether a custom action has run for this sign-up attempt. + This is important when your instance has been configured to require a custom action to run before converting a sign-up into a user. + After executing any external business logic you deem necessary, you can mark the sign-up as ready-to-convert by setting `custom_action` to `true`. + """ + external_id: Optional[Nullable[str]] = None + r"""The ID of the guest attempting to sign up as used in your external systems or your previous authentication solution. + This will be copied to the resulting user when the sign-up is completed. + """ + + @model_serializer(mode="wrap") + def serialize_model(self, handler): + optional_fields = ["custom_action", "external_id"] + nullable_fields = ["external_id"] + null_default_fields = [] + + serialized = handler(self) + + m = {} + + for n, f in self.model_fields.items(): + k = f.alias or n + val = serialized.get(k) + + if val is not None: + m[k] = val + elif not k in optional_fields or ( + k in optional_fields + and k in nullable_fields + and (self.__pydantic_fields_set__.intersection({n}) or k in null_default_fields) # pylint: disable=no-member + ): + m[k] = val + + return m + + +class UpdateSignUpRequestTypedDict(TypedDict): + id: str + r"""The ID of the sign-up to update""" + request_body: NotRequired[UpdateSignUpRequestBodyTypedDict] + + +class UpdateSignUpRequest(BaseModel): + id: Annotated[str, FieldMetadata(path=PathParamMetadata(style="simple", explode=False))] + r"""The ID of the sign-up to update""" + request_body: Annotated[Optional[UpdateSignUpRequestBody], FieldMetadata(request=RequestMetadata(media_type="application/json"))] = None + diff --git a/src/clerk/models/updateusermetadataop.py b/src/clerk/models/updateusermetadataop.py new file mode 100644 index 0000000..f7ac159 --- /dev/null +++ b/src/clerk/models/updateusermetadataop.py @@ -0,0 +1,86 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel +from clerk.utils import FieldMetadata, PathParamMetadata, RequestMetadata +from typing import Any, Dict, Optional, TypedDict +from typing_extensions import Annotated, NotRequired + + +class UpdateUserMetadataPrivateMetadataTypedDict(TypedDict): + r"""Metadata saved on the user that is only visible to your backend. + The new object will be merged with the existing value. + """ + + + +class UpdateUserMetadataPrivateMetadata(BaseModel): + r"""Metadata saved on the user that is only visible to your backend. + The new object will be merged with the existing value. + """ + + + +class UpdateUserMetadataUnsafeMetadataTypedDict(TypedDict): + r"""Metadata saved on the user, that can be updated from both the Frontend and Backend APIs. + The new object will be merged with the existing value. + + Note: Since this data can be modified from the frontend, it is not guaranteed to be safe. + """ + + + +class UpdateUserMetadataUnsafeMetadata(BaseModel): + r"""Metadata saved on the user, that can be updated from both the Frontend and Backend APIs. + The new object will be merged with the existing value. + + Note: Since this data can be modified from the frontend, it is not guaranteed to be safe. + """ + + + +class UpdateUserMetadataRequestBodyTypedDict(TypedDict): + public_metadata: NotRequired[Dict[str, Any]] + r"""Metadata saved on the user, that is visible to both your frontend and backend. + The new object will be merged with the existing value. + """ + private_metadata: NotRequired[UpdateUserMetadataPrivateMetadataTypedDict] + r"""Metadata saved on the user that is only visible to your backend. + The new object will be merged with the existing value. + """ + unsafe_metadata: NotRequired[UpdateUserMetadataUnsafeMetadataTypedDict] + r"""Metadata saved on the user, that can be updated from both the Frontend and Backend APIs. + The new object will be merged with the existing value. + + Note: Since this data can be modified from the frontend, it is not guaranteed to be safe. + """ + + +class UpdateUserMetadataRequestBody(BaseModel): + public_metadata: Optional[Dict[str, Any]] = None + r"""Metadata saved on the user, that is visible to both your frontend and backend. + The new object will be merged with the existing value. + """ + private_metadata: Optional[UpdateUserMetadataPrivateMetadata] = None + r"""Metadata saved on the user that is only visible to your backend. + The new object will be merged with the existing value. + """ + unsafe_metadata: Optional[UpdateUserMetadataUnsafeMetadata] = None + r"""Metadata saved on the user, that can be updated from both the Frontend and Backend APIs. + The new object will be merged with the existing value. + + Note: Since this data can be modified from the frontend, it is not guaranteed to be safe. + """ + + +class UpdateUserMetadataRequestTypedDict(TypedDict): + user_id: str + r"""The ID of the user whose metadata will be updated and merged""" + request_body: NotRequired[UpdateUserMetadataRequestBodyTypedDict] + + +class UpdateUserMetadataRequest(BaseModel): + user_id: Annotated[str, FieldMetadata(path=PathParamMetadata(style="simple", explode=False))] + r"""The ID of the user whose metadata will be updated and merged""" + request_body: Annotated[Optional[UpdateUserMetadataRequestBody], FieldMetadata(request=RequestMetadata(media_type="application/json"))] = None + diff --git a/src/clerk/models/updateuserop.py b/src/clerk/models/updateuserop.py new file mode 100644 index 0000000..0421493 --- /dev/null +++ b/src/clerk/models/updateuserop.py @@ -0,0 +1,586 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel, Nullable +from clerk.utils import FieldMetadata, PathParamMetadata, RequestMetadata +from enum import Enum +from pydantic import model_serializer +from typing import List, Optional, TypedDict +from typing_extensions import Annotated, NotRequired + + +class UpdateUserPasswordHasher(str, Enum): + r"""The hashing algorithm that was used to generate the password digest. + The algorithms we support at the moment are [bcrypt](https://en.wikipedia.org/wiki/Bcrypt), [bcrypt_sha256_django](https://docs.djangoproject.com/en/4.0/topics/auth/passwords/), + [md5](https://en.wikipedia.org/wiki/MD5), pbkdf2_sha256, pbkdf2_sha512, [pbkdf2_sha256_django](https://docs.djangoproject.com/en/4.0/topics/auth/passwords/), + [phpass](https://www.openwall.com/phpass/), [scrypt_firebase](https://firebaseopensource.com/projects/firebase/scrypt/), + [sha256](https://en.wikipedia.org/wiki/SHA-2), [scrypt_werkzeug](https://werkzeug.palletsprojects.com/en/3.0.x/utils/#werkzeug.security.generate_password_hash) + and the [argon2](https://argon2.online/) variants argon2i and argon2id. + + If you need support for any particular hashing algorithm, [please let us know](https://clerk.com/support). + + Note: for password hashers considered insecure (at this moment MD5 and SHA256), the corresponding user password hashes will be transparently migrated to Bcrypt (a secure hasher) upon the user's first successful password sign in. + Insecure schemes are marked with `(insecure)` in the list below. + + Each of the supported hashers expects the incoming digest to be in a particular format. Specifically: + + **bcrypt:** The digest should be of the following form: + + `$$$` + + **bcrypt_sha256_django:** This is the Django-specific variant of Bcrypt, using SHA256 hashing function. The format should be as follows (as exported from Django): + + `bcrypt_sha256$$$$` + + **md5** (insecure): The digest should follow the regular form e.g.: + + `5f4dcc3b5aa765d61d8327deb882cf99` + + **pbkdf2_sha256:** This is the PBKDF2 algorithm using the SHA256 hashing function. The format should be as follows: + + `pbkdf2_sha256$$$` + + Note: Both the salt and the hash are expected to be base64-encoded. + + **pbkdf2_sha512:** This is the PBKDF2 algorithm using the SHA512 hashing function. The format should be as follows: + + `pbkdf2_sha512$$$` + + _iterations:_ The number of iterations used. Must be an integer less than 420000. + _salt:_ The salt used when generating the hash. Must be less than bytes. + _hash:_ The hex-encoded hash. Must have been generated with a key length less than 1024 bytes. + + **pbkdf2_sha256_django:** This is the Django-specific variant of PBKDF2 and the digest should have the following format (as exported from Django): + + `pbkdf2_sha256$$$` + + Note: The salt is expected to be un-encoded, the hash is expected base64-encoded. + + **pbkdf2_sha1:** This is similar to pkbdf2_sha256_django, but with two differences: + 1. uses sha1 instead of sha256 + 2. accepts the hash as a hex-encoded string + + The format is the following: + + `pbkdf2_sha1$$$` + + **phpass:** Portable public domain password hashing framework for use in PHP applications. Digests hashed with phpass have the following sections: + + The format is the following: + + `$P$` + + - $P$ is the prefix used to identify phpass hashes. + - rounds is a single character encoding a 6-bit integer representing the number of rounds used. + - salt is eight characters drawn from [./0-9A-Za-z], providing a 48-bit salt. + - checksum is 22 characters drawn from the same set, encoding the 128-bit checksum with MD5. + + **scrypt_firebase:** The Firebase-specific variant of scrypt. + The value is expected to have 6 segments separated by the $ character and include the following information: + + _hash:_ The actual Base64 hash. This can be retrieved when exporting the user from Firebase. + _salt:_ The salt used to generate the above hash. Again, this is given when exporting the user. + _signer key:_ The base64 encoded signer key. + _salt separator:_ The base64 encoded salt separator. + _rounds:_ The number of rounds the algorithm needs to run. + _memory cost:_ The cost of the algorithm run + + The first 2 (hash and salt) are per user and can be retrieved when exporting the user from Firebase. + The other 4 values (signer key, salt separator, rounds and memory cost) are project-wide settings and can be retrieved from the project's password hash parameters. + + Once you have all these, you can combine it in the following format and send this as the digest in order for Clerk to accept it: + + `$$$$$` + + **scrypt_werkzeug:** The Werkzeug-specific variant of scrypt. + + The value is expected to have 3 segments separated by the $ character and include the following information: + + _algorithm args:_ The algorithm used to generate the hash. + _salt:_ The salt used to generate the above hash. + _hash:_ The actual Base64 hash. + + The algorithm args are the parameters used to generate the hash and are included in the digest. + + **argon2i:** Algorithms in the argon2 family generate digests that encode the following information: + + _version (v):_ The argon version, version 19 is assumed + _memory (m):_ The memory used by the algorithm (in kibibytes) + _iterations (t):_ The number of iterations to perform + _parallelism (p):_ The number of threads to use + + Parts are demarcated by the `$` character, with the first part identifying the algorithm variant. + The middle part is a comma-separated list of the encoding options (memory, iterations, parallelism). + The final part is the actual digest. + + `$argon2i$v=19$m=4096,t=3,p=1$4t6CL3P7YiHBtwESXawI8Hm20zJj4cs7/4/G3c187e0$m7RQFczcKr5bIR0IIxbpO2P0tyrLjf3eUW3M3QSwnLc` + + **argon2id:** See the previous algorithm for an explanation of the formatting. + + For the argon2id case, the value of the algorithm in the first part of the digest is `argon2id`: + + `$argon2id$v=19$m=64,t=4,p=8$Z2liZXJyaXNo$iGXEpMBTDYQ8G/71tF0qGjxRHEmR3gpGULcE93zUJVU` + + **sha256** (insecure): The digest should be a 64-length hex string, e.g.: + + `9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08` + """ + ARGON2I = "argon2i" + ARGON2ID = "argon2id" + BCRYPT = "bcrypt" + BCRYPT_SHA256_DJANGO = "bcrypt_sha256_django" + MD5 = "md5" + PBKDF2_SHA256 = "pbkdf2_sha256" + PBKDF2_SHA512 = "pbkdf2_sha512" + PBKDF2_SHA256_DJANGO = "pbkdf2_sha256_django" + PBKDF2_SHA1 = "pbkdf2_sha1" + PHPASS = "phpass" + SCRYPT_FIREBASE = "scrypt_firebase" + SCRYPT_WERKZEUG = "scrypt_werkzeug" + SHA256 = "sha256" + + +class UpdateUserPublicMetadataTypedDict(TypedDict): + r"""Metadata saved on the user, that is visible to both your Frontend and Backend APIs""" + + + +class UpdateUserPublicMetadata(BaseModel): + r"""Metadata saved on the user, that is visible to both your Frontend and Backend APIs""" + + + +class UpdateUserPrivateMetadataTypedDict(TypedDict): + r"""Metadata saved on the user, that is only visible to your Backend API""" + + + +class UpdateUserPrivateMetadata(BaseModel): + r"""Metadata saved on the user, that is only visible to your Backend API""" + + + +class UpdateUserUnsafeMetadataTypedDict(TypedDict): + r"""Metadata saved on the user, that can be updated from both the Frontend and Backend APIs. + Note: Since this data can be modified from the frontend, it is not guaranteed to be safe. + """ + + + +class UpdateUserUnsafeMetadata(BaseModel): + r"""Metadata saved on the user, that can be updated from both the Frontend and Backend APIs. + Note: Since this data can be modified from the frontend, it is not guaranteed to be safe. + """ + + + +class UpdateUserRequestBodyTypedDict(TypedDict): + external_id: NotRequired[Nullable[str]] + r"""The ID of the user as used in your external systems or your previous authentication solution. + Must be unique across your instance. + """ + first_name: NotRequired[Nullable[str]] + r"""The first name to assign to the user""" + last_name: NotRequired[Nullable[str]] + r"""The last name to assign to the user""" + primary_email_address_id: NotRequired[str] + r"""The ID of the email address to set as primary. + It must be verified, and present on the current user. + """ + notify_primary_email_address_changed: NotRequired[bool] + r"""If set to `true`, the user will be notified that their primary email address has changed. + By default, no notification is sent. + """ + primary_phone_number_id: NotRequired[str] + r"""The ID of the phone number to set as primary. + It must be verified, and present on the current user. + """ + primary_web3_wallet_id: NotRequired[str] + r"""The ID of the web3 wallets to set as primary. + It must be verified, and present on the current user. + """ + username: NotRequired[Nullable[str]] + r"""The username to give to the user. + It must be unique across your instance. + """ + profile_image_id: NotRequired[Nullable[str]] + r"""The ID of the image to set as the user's profile image""" + password: NotRequired[Nullable[str]] + r"""The plaintext password to give the user. + Must be at least 8 characters long, and can not be in any list of hacked passwords. + """ + password_digest: NotRequired[str] + r"""In case you already have the password digests and not the passwords, you can use them for the newly created user via this property. + The digests should be generated with one of the supported algorithms. + The hashing algorithm can be specified using the `password_hasher` property. + """ + password_hasher: NotRequired[UpdateUserPasswordHasher] + r"""The hashing algorithm that was used to generate the password digest. + The algorithms we support at the moment are [bcrypt](https://en.wikipedia.org/wiki/Bcrypt), [bcrypt_sha256_django](https://docs.djangoproject.com/en/4.0/topics/auth/passwords/), + [md5](https://en.wikipedia.org/wiki/MD5), pbkdf2_sha256, pbkdf2_sha512, [pbkdf2_sha256_django](https://docs.djangoproject.com/en/4.0/topics/auth/passwords/), + [phpass](https://www.openwall.com/phpass/), [scrypt_firebase](https://firebaseopensource.com/projects/firebase/scrypt/), + [sha256](https://en.wikipedia.org/wiki/SHA-2), [scrypt_werkzeug](https://werkzeug.palletsprojects.com/en/3.0.x/utils/#werkzeug.security.generate_password_hash) + and the [argon2](https://argon2.online/) variants argon2i and argon2id. + + If you need support for any particular hashing algorithm, [please let us know](https://clerk.com/support). + + Note: for password hashers considered insecure (at this moment MD5 and SHA256), the corresponding user password hashes will be transparently migrated to Bcrypt (a secure hasher) upon the user's first successful password sign in. + Insecure schemes are marked with `(insecure)` in the list below. + + Each of the supported hashers expects the incoming digest to be in a particular format. Specifically: + + **bcrypt:** The digest should be of the following form: + + `$$$` + + **bcrypt_sha256_django:** This is the Django-specific variant of Bcrypt, using SHA256 hashing function. The format should be as follows (as exported from Django): + + `bcrypt_sha256$$$$` + + **md5** (insecure): The digest should follow the regular form e.g.: + + `5f4dcc3b5aa765d61d8327deb882cf99` + + **pbkdf2_sha256:** This is the PBKDF2 algorithm using the SHA256 hashing function. The format should be as follows: + + `pbkdf2_sha256$$$` + + Note: Both the salt and the hash are expected to be base64-encoded. + + **pbkdf2_sha512:** This is the PBKDF2 algorithm using the SHA512 hashing function. The format should be as follows: + + `pbkdf2_sha512$$$` + + _iterations:_ The number of iterations used. Must be an integer less than 420000. + _salt:_ The salt used when generating the hash. Must be less than bytes. + _hash:_ The hex-encoded hash. Must have been generated with a key length less than 1024 bytes. + + **pbkdf2_sha256_django:** This is the Django-specific variant of PBKDF2 and the digest should have the following format (as exported from Django): + + `pbkdf2_sha256$$$` + + Note: The salt is expected to be un-encoded, the hash is expected base64-encoded. + + **pbkdf2_sha1:** This is similar to pkbdf2_sha256_django, but with two differences: + 1. uses sha1 instead of sha256 + 2. accepts the hash as a hex-encoded string + + The format is the following: + + `pbkdf2_sha1$$$` + + **phpass:** Portable public domain password hashing framework for use in PHP applications. Digests hashed with phpass have the following sections: + + The format is the following: + + `$P$` + + - $P$ is the prefix used to identify phpass hashes. + - rounds is a single character encoding a 6-bit integer representing the number of rounds used. + - salt is eight characters drawn from [./0-9A-Za-z], providing a 48-bit salt. + - checksum is 22 characters drawn from the same set, encoding the 128-bit checksum with MD5. + + **scrypt_firebase:** The Firebase-specific variant of scrypt. + The value is expected to have 6 segments separated by the $ character and include the following information: + + _hash:_ The actual Base64 hash. This can be retrieved when exporting the user from Firebase. + _salt:_ The salt used to generate the above hash. Again, this is given when exporting the user. + _signer key:_ The base64 encoded signer key. + _salt separator:_ The base64 encoded salt separator. + _rounds:_ The number of rounds the algorithm needs to run. + _memory cost:_ The cost of the algorithm run + + The first 2 (hash and salt) are per user and can be retrieved when exporting the user from Firebase. + The other 4 values (signer key, salt separator, rounds and memory cost) are project-wide settings and can be retrieved from the project's password hash parameters. + + Once you have all these, you can combine it in the following format and send this as the digest in order for Clerk to accept it: + + `$$$$$` + + **scrypt_werkzeug:** The Werkzeug-specific variant of scrypt. + + The value is expected to have 3 segments separated by the $ character and include the following information: + + _algorithm args:_ The algorithm used to generate the hash. + _salt:_ The salt used to generate the above hash. + _hash:_ The actual Base64 hash. + + The algorithm args are the parameters used to generate the hash and are included in the digest. + + **argon2i:** Algorithms in the argon2 family generate digests that encode the following information: + + _version (v):_ The argon version, version 19 is assumed + _memory (m):_ The memory used by the algorithm (in kibibytes) + _iterations (t):_ The number of iterations to perform + _parallelism (p):_ The number of threads to use + + Parts are demarcated by the `$` character, with the first part identifying the algorithm variant. + The middle part is a comma-separated list of the encoding options (memory, iterations, parallelism). + The final part is the actual digest. + + `$argon2i$v=19$m=4096,t=3,p=1$4t6CL3P7YiHBtwESXawI8Hm20zJj4cs7/4/G3c187e0$m7RQFczcKr5bIR0IIxbpO2P0tyrLjf3eUW3M3QSwnLc` + + **argon2id:** See the previous algorithm for an explanation of the formatting. + + For the argon2id case, the value of the algorithm in the first part of the digest is `argon2id`: + + `$argon2id$v=19$m=64,t=4,p=8$Z2liZXJyaXNo$iGXEpMBTDYQ8G/71tF0qGjxRHEmR3gpGULcE93zUJVU` + + **sha256** (insecure): The digest should be a 64-length hex string, e.g.: + + `9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08` + """ + skip_password_checks: NotRequired[Nullable[bool]] + r"""Set it to `true` if you're updating the user's password and want to skip any password policy settings check. This parameter can only be used when providing a `password`.""" + sign_out_of_other_sessions: NotRequired[Nullable[bool]] + r"""Set to `true` to sign out the user from all their active sessions once their password is updated. This parameter can only be used when providing a `password`.""" + totp_secret: NotRequired[str] + r"""In case TOTP is configured on the instance, you can provide the secret to enable it on the specific user without the need to reset it. + Please note that currently the supported options are: + * Period: 30 seconds + * Code length: 6 digits + * Algorithm: SHA1 + """ + backup_codes: NotRequired[List[str]] + r"""If Backup Codes are configured on the instance, you can provide them to enable it on the specific user without the need to reset them. + You must provide the backup codes in plain format or the corresponding bcrypt digest. + """ + public_metadata: NotRequired[UpdateUserPublicMetadataTypedDict] + r"""Metadata saved on the user, that is visible to both your Frontend and Backend APIs""" + private_metadata: NotRequired[UpdateUserPrivateMetadataTypedDict] + r"""Metadata saved on the user, that is only visible to your Backend API""" + unsafe_metadata: NotRequired[UpdateUserUnsafeMetadataTypedDict] + r"""Metadata saved on the user, that can be updated from both the Frontend and Backend APIs. + Note: Since this data can be modified from the frontend, it is not guaranteed to be safe. + """ + delete_self_enabled: NotRequired[Nullable[bool]] + r"""If true, the user can delete themselves with the Frontend API.""" + create_organization_enabled: NotRequired[Nullable[bool]] + r"""If true, the user can create organizations with the Frontend API.""" + created_at: NotRequired[str] + r"""A custom date/time denoting _when_ the user signed up to the application, specified in RFC3339 format (e.g. `2012-10-20T07:15:20.902Z`).""" + + +class UpdateUserRequestBody(BaseModel): + external_id: Optional[Nullable[str]] = None + r"""The ID of the user as used in your external systems or your previous authentication solution. + Must be unique across your instance. + """ + first_name: Optional[Nullable[str]] = None + r"""The first name to assign to the user""" + last_name: Optional[Nullable[str]] = None + r"""The last name to assign to the user""" + primary_email_address_id: Optional[str] = None + r"""The ID of the email address to set as primary. + It must be verified, and present on the current user. + """ + notify_primary_email_address_changed: Optional[bool] = False + r"""If set to `true`, the user will be notified that their primary email address has changed. + By default, no notification is sent. + """ + primary_phone_number_id: Optional[str] = None + r"""The ID of the phone number to set as primary. + It must be verified, and present on the current user. + """ + primary_web3_wallet_id: Optional[str] = None + r"""The ID of the web3 wallets to set as primary. + It must be verified, and present on the current user. + """ + username: Optional[Nullable[str]] = None + r"""The username to give to the user. + It must be unique across your instance. + """ + profile_image_id: Optional[Nullable[str]] = None + r"""The ID of the image to set as the user's profile image""" + password: Optional[Nullable[str]] = None + r"""The plaintext password to give the user. + Must be at least 8 characters long, and can not be in any list of hacked passwords. + """ + password_digest: Optional[str] = None + r"""In case you already have the password digests and not the passwords, you can use them for the newly created user via this property. + The digests should be generated with one of the supported algorithms. + The hashing algorithm can be specified using the `password_hasher` property. + """ + password_hasher: Optional[UpdateUserPasswordHasher] = None + r"""The hashing algorithm that was used to generate the password digest. + The algorithms we support at the moment are [bcrypt](https://en.wikipedia.org/wiki/Bcrypt), [bcrypt_sha256_django](https://docs.djangoproject.com/en/4.0/topics/auth/passwords/), + [md5](https://en.wikipedia.org/wiki/MD5), pbkdf2_sha256, pbkdf2_sha512, [pbkdf2_sha256_django](https://docs.djangoproject.com/en/4.0/topics/auth/passwords/), + [phpass](https://www.openwall.com/phpass/), [scrypt_firebase](https://firebaseopensource.com/projects/firebase/scrypt/), + [sha256](https://en.wikipedia.org/wiki/SHA-2), [scrypt_werkzeug](https://werkzeug.palletsprojects.com/en/3.0.x/utils/#werkzeug.security.generate_password_hash) + and the [argon2](https://argon2.online/) variants argon2i and argon2id. + + If you need support for any particular hashing algorithm, [please let us know](https://clerk.com/support). + + Note: for password hashers considered insecure (at this moment MD5 and SHA256), the corresponding user password hashes will be transparently migrated to Bcrypt (a secure hasher) upon the user's first successful password sign in. + Insecure schemes are marked with `(insecure)` in the list below. + + Each of the supported hashers expects the incoming digest to be in a particular format. Specifically: + + **bcrypt:** The digest should be of the following form: + + `$$$` + + **bcrypt_sha256_django:** This is the Django-specific variant of Bcrypt, using SHA256 hashing function. The format should be as follows (as exported from Django): + + `bcrypt_sha256$$$$` + + **md5** (insecure): The digest should follow the regular form e.g.: + + `5f4dcc3b5aa765d61d8327deb882cf99` + + **pbkdf2_sha256:** This is the PBKDF2 algorithm using the SHA256 hashing function. The format should be as follows: + + `pbkdf2_sha256$$$` + + Note: Both the salt and the hash are expected to be base64-encoded. + + **pbkdf2_sha512:** This is the PBKDF2 algorithm using the SHA512 hashing function. The format should be as follows: + + `pbkdf2_sha512$$$` + + _iterations:_ The number of iterations used. Must be an integer less than 420000. + _salt:_ The salt used when generating the hash. Must be less than bytes. + _hash:_ The hex-encoded hash. Must have been generated with a key length less than 1024 bytes. + + **pbkdf2_sha256_django:** This is the Django-specific variant of PBKDF2 and the digest should have the following format (as exported from Django): + + `pbkdf2_sha256$$$` + + Note: The salt is expected to be un-encoded, the hash is expected base64-encoded. + + **pbkdf2_sha1:** This is similar to pkbdf2_sha256_django, but with two differences: + 1. uses sha1 instead of sha256 + 2. accepts the hash as a hex-encoded string + + The format is the following: + + `pbkdf2_sha1$$$` + + **phpass:** Portable public domain password hashing framework for use in PHP applications. Digests hashed with phpass have the following sections: + + The format is the following: + + `$P$` + + - $P$ is the prefix used to identify phpass hashes. + - rounds is a single character encoding a 6-bit integer representing the number of rounds used. + - salt is eight characters drawn from [./0-9A-Za-z], providing a 48-bit salt. + - checksum is 22 characters drawn from the same set, encoding the 128-bit checksum with MD5. + + **scrypt_firebase:** The Firebase-specific variant of scrypt. + The value is expected to have 6 segments separated by the $ character and include the following information: + + _hash:_ The actual Base64 hash. This can be retrieved when exporting the user from Firebase. + _salt:_ The salt used to generate the above hash. Again, this is given when exporting the user. + _signer key:_ The base64 encoded signer key. + _salt separator:_ The base64 encoded salt separator. + _rounds:_ The number of rounds the algorithm needs to run. + _memory cost:_ The cost of the algorithm run + + The first 2 (hash and salt) are per user and can be retrieved when exporting the user from Firebase. + The other 4 values (signer key, salt separator, rounds and memory cost) are project-wide settings and can be retrieved from the project's password hash parameters. + + Once you have all these, you can combine it in the following format and send this as the digest in order for Clerk to accept it: + + `$$$$$` + + **scrypt_werkzeug:** The Werkzeug-specific variant of scrypt. + + The value is expected to have 3 segments separated by the $ character and include the following information: + + _algorithm args:_ The algorithm used to generate the hash. + _salt:_ The salt used to generate the above hash. + _hash:_ The actual Base64 hash. + + The algorithm args are the parameters used to generate the hash and are included in the digest. + + **argon2i:** Algorithms in the argon2 family generate digests that encode the following information: + + _version (v):_ The argon version, version 19 is assumed + _memory (m):_ The memory used by the algorithm (in kibibytes) + _iterations (t):_ The number of iterations to perform + _parallelism (p):_ The number of threads to use + + Parts are demarcated by the `$` character, with the first part identifying the algorithm variant. + The middle part is a comma-separated list of the encoding options (memory, iterations, parallelism). + The final part is the actual digest. + + `$argon2i$v=19$m=4096,t=3,p=1$4t6CL3P7YiHBtwESXawI8Hm20zJj4cs7/4/G3c187e0$m7RQFczcKr5bIR0IIxbpO2P0tyrLjf3eUW3M3QSwnLc` + + **argon2id:** See the previous algorithm for an explanation of the formatting. + + For the argon2id case, the value of the algorithm in the first part of the digest is `argon2id`: + + `$argon2id$v=19$m=64,t=4,p=8$Z2liZXJyaXNo$iGXEpMBTDYQ8G/71tF0qGjxRHEmR3gpGULcE93zUJVU` + + **sha256** (insecure): The digest should be a 64-length hex string, e.g.: + + `9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08` + """ + skip_password_checks: Optional[Nullable[bool]] = None + r"""Set it to `true` if you're updating the user's password and want to skip any password policy settings check. This parameter can only be used when providing a `password`.""" + sign_out_of_other_sessions: Optional[Nullable[bool]] = None + r"""Set to `true` to sign out the user from all their active sessions once their password is updated. This parameter can only be used when providing a `password`.""" + totp_secret: Optional[str] = None + r"""In case TOTP is configured on the instance, you can provide the secret to enable it on the specific user without the need to reset it. + Please note that currently the supported options are: + * Period: 30 seconds + * Code length: 6 digits + * Algorithm: SHA1 + """ + backup_codes: Optional[List[str]] = None + r"""If Backup Codes are configured on the instance, you can provide them to enable it on the specific user without the need to reset them. + You must provide the backup codes in plain format or the corresponding bcrypt digest. + """ + public_metadata: Optional[UpdateUserPublicMetadata] = None + r"""Metadata saved on the user, that is visible to both your Frontend and Backend APIs""" + private_metadata: Optional[UpdateUserPrivateMetadata] = None + r"""Metadata saved on the user, that is only visible to your Backend API""" + unsafe_metadata: Optional[UpdateUserUnsafeMetadata] = None + r"""Metadata saved on the user, that can be updated from both the Frontend and Backend APIs. + Note: Since this data can be modified from the frontend, it is not guaranteed to be safe. + """ + delete_self_enabled: Optional[Nullable[bool]] = None + r"""If true, the user can delete themselves with the Frontend API.""" + create_organization_enabled: Optional[Nullable[bool]] = None + r"""If true, the user can create organizations with the Frontend API.""" + created_at: Optional[str] = None + r"""A custom date/time denoting _when_ the user signed up to the application, specified in RFC3339 format (e.g. `2012-10-20T07:15:20.902Z`).""" + + @model_serializer(mode="wrap") + def serialize_model(self, handler): + optional_fields = ["external_id", "first_name", "last_name", "primary_email_address_id", "notify_primary_email_address_changed", "primary_phone_number_id", "primary_web3_wallet_id", "username", "profile_image_id", "password", "password_digest", "password_hasher", "skip_password_checks", "sign_out_of_other_sessions", "totp_secret", "backup_codes", "public_metadata", "private_metadata", "unsafe_metadata", "delete_self_enabled", "create_organization_enabled", "created_at"] + nullable_fields = ["external_id", "first_name", "last_name", "username", "profile_image_id", "password", "skip_password_checks", "sign_out_of_other_sessions", "delete_self_enabled", "create_organization_enabled"] + null_default_fields = [] + + serialized = handler(self) + + m = {} + + for n, f in self.model_fields.items(): + k = f.alias or n + val = serialized.get(k) + + if val is not None: + m[k] = val + elif not k in optional_fields or ( + k in optional_fields + and k in nullable_fields + and (self.__pydantic_fields_set__.intersection({n}) or k in null_default_fields) # pylint: disable=no-member + ): + m[k] = val + + return m + + +class UpdateUserRequestTypedDict(TypedDict): + user_id: str + r"""The ID of the user to update""" + request_body: UpdateUserRequestBodyTypedDict + + +class UpdateUserRequest(BaseModel): + user_id: Annotated[str, FieldMetadata(path=PathParamMetadata(style="simple", explode=False))] + r"""The ID of the user to update""" + request_body: Annotated[UpdateUserRequestBody, FieldMetadata(request=RequestMetadata(media_type="application/json"))] + diff --git a/src/clerk/models/uploadorganizationlogoop.py b/src/clerk/models/uploadorganizationlogoop.py new file mode 100644 index 0000000..89098e3 --- /dev/null +++ b/src/clerk/models/uploadorganizationlogoop.py @@ -0,0 +1,46 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel +from clerk.utils import FieldMetadata, MultipartFormMetadata, PathParamMetadata, RequestMetadata +import io +import pydantic +from typing import IO, Optional, TypedDict, Union +from typing_extensions import Annotated, NotRequired + + +class UploadOrganizationLogoFileTypedDict(TypedDict): + file_name: str + content: Union[bytes, IO[bytes], io.BufferedReader] + content_type: NotRequired[str] + + +class UploadOrganizationLogoFile(BaseModel): + file_name: Annotated[str, pydantic.Field(alias="file"), FieldMetadata(multipart=True)] + content: Annotated[Union[bytes, IO[bytes], io.BufferedReader], pydantic.Field(alias=""), FieldMetadata(multipart=MultipartFormMetadata(content=True))] + content_type: Annotated[Optional[str], pydantic.Field(alias="Content-Type"), FieldMetadata(multipart=True)] = None + + +class UploadOrganizationLogoRequestBodyTypedDict(TypedDict): + uploader_user_id: str + r"""The ID of the user that will be credited with the image upload.""" + file: UploadOrganizationLogoFileTypedDict + + +class UploadOrganizationLogoRequestBody(BaseModel): + uploader_user_id: Annotated[str, FieldMetadata(multipart=True)] + r"""The ID of the user that will be credited with the image upload.""" + file: Annotated[UploadOrganizationLogoFile, pydantic.Field(alias=""), FieldMetadata(multipart=MultipartFormMetadata(file=True))] + + +class UploadOrganizationLogoRequestTypedDict(TypedDict): + organization_id: str + r"""The ID of the organization for which to upload a logo""" + request_body: NotRequired[UploadOrganizationLogoRequestBodyTypedDict] + + +class UploadOrganizationLogoRequest(BaseModel): + organization_id: Annotated[str, FieldMetadata(path=PathParamMetadata(style="simple", explode=False))] + r"""The ID of the organization for which to upload a logo""" + request_body: Annotated[Optional[UploadOrganizationLogoRequestBody], FieldMetadata(request=RequestMetadata(media_type="multipart/form-data"))] = None + diff --git a/src/clerk/models/upserttemplateop.py b/src/clerk/models/upserttemplateop.py new file mode 100644 index 0000000..305d1b3 --- /dev/null +++ b/src/clerk/models/upserttemplateop.py @@ -0,0 +1,107 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel, Nullable +from clerk.utils import FieldMetadata, PathParamMetadata, RequestMetadata +from enum import Enum +from pydantic import model_serializer +from typing import Optional, TypedDict +from typing_extensions import Annotated, NotRequired + + +class UpsertTemplatePathParamTemplateType(str, Enum): + r"""The type of template to update""" + EMAIL = "email" + SMS = "sms" + + +class UpsertTemplateRequestBodyTypedDict(TypedDict): + name: NotRequired[str] + r"""The user-friendly name of the template""" + subject: NotRequired[Nullable[str]] + r"""The email subject. + Applicable only to email templates. + """ + markup: NotRequired[Nullable[str]] + r"""The editor markup used to generate the body of the template""" + body: NotRequired[str] + r"""The template body before variable interpolation""" + delivered_by_clerk: NotRequired[Nullable[bool]] + r"""Whether Clerk should deliver emails or SMS messages based on the current template""" + from_email_name: NotRequired[str] + r"""The local part of the From email address that will be used for emails. + For example, in the address 'hello@example.com', the local part is 'hello'. + Applicable only to email templates. + """ + reply_to_email_name: NotRequired[str] + r"""The local part of the Reply To email address that will be used for emails. + For example, in the address 'hello@example.com', the local part is 'hello'. + Applicable only to email templates. + """ + + +class UpsertTemplateRequestBody(BaseModel): + name: Optional[str] = None + r"""The user-friendly name of the template""" + subject: Optional[Nullable[str]] = None + r"""The email subject. + Applicable only to email templates. + """ + markup: Optional[Nullable[str]] = None + r"""The editor markup used to generate the body of the template""" + body: Optional[str] = None + r"""The template body before variable interpolation""" + delivered_by_clerk: Optional[Nullable[bool]] = None + r"""Whether Clerk should deliver emails or SMS messages based on the current template""" + from_email_name: Optional[str] = None + r"""The local part of the From email address that will be used for emails. + For example, in the address 'hello@example.com', the local part is 'hello'. + Applicable only to email templates. + """ + reply_to_email_name: Optional[str] = None + r"""The local part of the Reply To email address that will be used for emails. + For example, in the address 'hello@example.com', the local part is 'hello'. + Applicable only to email templates. + """ + + @model_serializer(mode="wrap") + def serialize_model(self, handler): + optional_fields = ["name", "subject", "markup", "body", "delivered_by_clerk", "from_email_name", "reply_to_email_name"] + nullable_fields = ["subject", "markup", "delivered_by_clerk"] + null_default_fields = [] + + serialized = handler(self) + + m = {} + + for n, f in self.model_fields.items(): + k = f.alias or n + val = serialized.get(k) + + if val is not None: + m[k] = val + elif not k in optional_fields or ( + k in optional_fields + and k in nullable_fields + and (self.__pydantic_fields_set__.intersection({n}) or k in null_default_fields) # pylint: disable=no-member + ): + m[k] = val + + return m + + +class UpsertTemplateRequestTypedDict(TypedDict): + template_type: UpsertTemplatePathParamTemplateType + r"""The type of template to update""" + slug: str + r"""The slug of the template to update""" + request_body: NotRequired[UpsertTemplateRequestBodyTypedDict] + + +class UpsertTemplateRequest(BaseModel): + template_type: Annotated[UpsertTemplatePathParamTemplateType, FieldMetadata(path=PathParamMetadata(style="simple", explode=False))] + r"""The type of template to update""" + slug: Annotated[str, FieldMetadata(path=PathParamMetadata(style="simple", explode=False))] + r"""The slug of the template to update""" + request_body: Annotated[Optional[UpsertTemplateRequestBody], FieldMetadata(request=RequestMetadata(media_type="application/json"))] = None + diff --git a/src/clerk/models/user.py b/src/clerk/models/user.py new file mode 100644 index 0000000..b92628c --- /dev/null +++ b/src/clerk/models/user.py @@ -0,0 +1,237 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from .emailaddress import EmailAddress, EmailAddressTypedDict +from .phonenumber import PhoneNumber, PhoneNumberTypedDict +from .samlaccount import SAMLAccount, SAMLAccountTypedDict +from .schemas_passkey import SchemasPasskey, SchemasPasskeyTypedDict +from .web3wallet import Web3Wallet, Web3WalletTypedDict +from clerk.types import BaseModel, Nullable +from enum import Enum +import pydantic +from pydantic import model_serializer +from typing import List, Optional, TypedDict +from typing_extensions import Annotated, NotRequired + + +class UserObject(str, Enum): + r"""String representing the object's type. Objects of the same type share the same value. + + """ + USER = "user" + + +class PublicMetadataTypedDict(TypedDict): + pass + + +class PublicMetadata(BaseModel): + pass + + +class PrivateMetadataTypedDict(TypedDict): + pass + + +class PrivateMetadata(BaseModel): + pass + + +class UnsafeMetadataTypedDict(TypedDict): + pass + + +class UnsafeMetadata(BaseModel): + pass + + +class ExternalAccountsTypedDict(TypedDict): + pass + + +class ExternalAccounts(BaseModel): + pass + + +class UserTypedDict(TypedDict): + id: NotRequired[str] + object: NotRequired[UserObject] + r"""String representing the object's type. Objects of the same type share the same value. + + """ + external_id: NotRequired[Nullable[str]] + primary_email_address_id: NotRequired[Nullable[str]] + primary_phone_number_id: NotRequired[Nullable[str]] + primary_web3_wallet_id: NotRequired[Nullable[str]] + username: NotRequired[Nullable[str]] + first_name: NotRequired[Nullable[str]] + last_name: NotRequired[Nullable[str]] + profile_image_url: NotRequired[str] + image_url: NotRequired[str] + has_image: NotRequired[bool] + public_metadata: NotRequired[PublicMetadataTypedDict] + private_metadata: NotRequired[Nullable[PrivateMetadataTypedDict]] + unsafe_metadata: NotRequired[UnsafeMetadataTypedDict] + email_addresses: NotRequired[List[EmailAddressTypedDict]] + phone_numbers: NotRequired[List[PhoneNumberTypedDict]] + web3_wallets: NotRequired[List[Web3WalletTypedDict]] + passkeys: NotRequired[List[SchemasPasskeyTypedDict]] + password_enabled: NotRequired[bool] + two_factor_enabled: NotRequired[bool] + totp_enabled: NotRequired[bool] + backup_code_enabled: NotRequired[bool] + mfa_enabled_at: NotRequired[Nullable[int]] + r"""Unix timestamp of when MFA was last enabled for this user. It should be noted that this field is not nullified if MFA is disabled. + + """ + mfa_disabled_at: NotRequired[Nullable[int]] + r"""Unix timestamp of when MFA was last disabled for this user. It should be noted that this field is not nullified if MFA is enabled again. + + """ + external_accounts: NotRequired[List[ExternalAccountsTypedDict]] + saml_accounts: NotRequired[List[SAMLAccountTypedDict]] + last_sign_in_at: NotRequired[Nullable[int]] + r"""Unix timestamp of last sign-in. + + """ + banned: NotRequired[bool] + r"""Flag to denote whether user is banned or not. + + """ + locked: NotRequired[bool] + r"""Flag to denote whether user is currently locked, i.e. restricted from signing in or not. + + """ + lockout_expires_in_seconds: NotRequired[Nullable[int]] + r"""The number of seconds remaining until the lockout period expires for a locked user. A null value for a locked user indicates that lockout never expires. + + """ + verification_attempts_remaining: NotRequired[Nullable[int]] + r"""The number of verification attempts remaining until the user is locked. Null if account lockout is not enabled. Note: if a user is locked explicitly via the Backend API, they may still have verification attempts remaining. + + """ + updated_at: NotRequired[int] + r"""Unix timestamp of last update. + + """ + created_at: NotRequired[int] + r"""Unix timestamp of creation. + + """ + delete_self_enabled: NotRequired[bool] + r"""If enabled, user can delete themselves via FAPI. + + """ + create_organization_enabled: NotRequired[bool] + r"""If enabled, user can create organizations via FAPI. + + """ + last_active_at: NotRequired[Nullable[int]] + r"""Unix timestamp of the latest session activity, with day precision. + + """ + + +class User(BaseModel): + id: Optional[str] = None + object: Optional[UserObject] = None + r"""String representing the object's type. Objects of the same type share the same value. + + """ + external_id: Optional[Nullable[str]] = None + primary_email_address_id: Optional[Nullable[str]] = None + primary_phone_number_id: Optional[Nullable[str]] = None + primary_web3_wallet_id: Optional[Nullable[str]] = None + username: Optional[Nullable[str]] = None + first_name: Optional[Nullable[str]] = None + last_name: Optional[Nullable[str]] = None + profile_image_url: Annotated[Optional[str], pydantic.Field(deprecated="warning: ** DEPRECATED ** - This will be removed in a future release, please migrate away from it as soon as possible.")] = None + image_url: Optional[str] = None + has_image: Optional[bool] = None + public_metadata: Optional[PublicMetadata] = None + private_metadata: Optional[Nullable[PrivateMetadata]] = None + unsafe_metadata: Optional[UnsafeMetadata] = None + email_addresses: Optional[List[EmailAddress]] = None + phone_numbers: Optional[List[PhoneNumber]] = None + web3_wallets: Optional[List[Web3Wallet]] = None + passkeys: Optional[List[SchemasPasskey]] = None + password_enabled: Optional[bool] = None + two_factor_enabled: Optional[bool] = None + totp_enabled: Optional[bool] = None + backup_code_enabled: Optional[bool] = None + mfa_enabled_at: Optional[Nullable[int]] = None + r"""Unix timestamp of when MFA was last enabled for this user. It should be noted that this field is not nullified if MFA is disabled. + + """ + mfa_disabled_at: Optional[Nullable[int]] = None + r"""Unix timestamp of when MFA was last disabled for this user. It should be noted that this field is not nullified if MFA is enabled again. + + """ + external_accounts: Optional[List[ExternalAccounts]] = None + saml_accounts: Optional[List[SAMLAccount]] = None + last_sign_in_at: Optional[Nullable[int]] = None + r"""Unix timestamp of last sign-in. + + """ + banned: Optional[bool] = None + r"""Flag to denote whether user is banned or not. + + """ + locked: Optional[bool] = None + r"""Flag to denote whether user is currently locked, i.e. restricted from signing in or not. + + """ + lockout_expires_in_seconds: Optional[Nullable[int]] = None + r"""The number of seconds remaining until the lockout period expires for a locked user. A null value for a locked user indicates that lockout never expires. + + """ + verification_attempts_remaining: Optional[Nullable[int]] = None + r"""The number of verification attempts remaining until the user is locked. Null if account lockout is not enabled. Note: if a user is locked explicitly via the Backend API, they may still have verification attempts remaining. + + """ + updated_at: Optional[int] = None + r"""Unix timestamp of last update. + + """ + created_at: Optional[int] = None + r"""Unix timestamp of creation. + + """ + delete_self_enabled: Optional[bool] = None + r"""If enabled, user can delete themselves via FAPI. + + """ + create_organization_enabled: Optional[bool] = None + r"""If enabled, user can create organizations via FAPI. + + """ + last_active_at: Optional[Nullable[int]] = None + r"""Unix timestamp of the latest session activity, with day precision. + + """ + + @model_serializer(mode="wrap") + def serialize_model(self, handler): + optional_fields = ["id", "object", "external_id", "primary_email_address_id", "primary_phone_number_id", "primary_web3_wallet_id", "username", "first_name", "last_name", "profile_image_url", "image_url", "has_image", "public_metadata", "private_metadata", "unsafe_metadata", "email_addresses", "phone_numbers", "web3_wallets", "passkeys", "password_enabled", "two_factor_enabled", "totp_enabled", "backup_code_enabled", "mfa_enabled_at", "mfa_disabled_at", "external_accounts", "saml_accounts", "last_sign_in_at", "banned", "locked", "lockout_expires_in_seconds", "verification_attempts_remaining", "updated_at", "created_at", "delete_self_enabled", "create_organization_enabled", "last_active_at"] + nullable_fields = ["external_id", "primary_email_address_id", "primary_phone_number_id", "primary_web3_wallet_id", "username", "first_name", "last_name", "private_metadata", "mfa_enabled_at", "mfa_disabled_at", "last_sign_in_at", "lockout_expires_in_seconds", "verification_attempts_remaining", "last_active_at"] + null_default_fields = [] + + serialized = handler(self) + + m = {} + + for n, f in self.model_fields.items(): + k = f.alias or n + val = serialized.get(k) + + if val is not None: + m[k] = val + elif not k in optional_fields or ( + k in optional_fields + and k in nullable_fields + and (self.__pydantic_fields_set__.intersection({n}) or k in null_default_fields) # pylint: disable=no-member + ): + m[k] = val + + return m + diff --git a/src/clerk/models/usersgetorganizationmembershipsop.py b/src/clerk/models/usersgetorganizationmembershipsop.py new file mode 100644 index 0000000..4681a80 --- /dev/null +++ b/src/clerk/models/usersgetorganizationmembershipsop.py @@ -0,0 +1,47 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from .organizationmemberships import OrganizationMemberships, OrganizationMembershipsTypedDict +from clerk.types import BaseModel +from clerk.utils import FieldMetadata, PathParamMetadata, QueryParamMetadata +from typing import Callable, Optional, TypedDict +from typing_extensions import Annotated, NotRequired + + +class UsersGetOrganizationMembershipsRequestTypedDict(TypedDict): + user_id: str + r"""The ID of the user whose organization memberships we want to retrieve""" + limit: NotRequired[float] + r"""Applies a limit to the number of results returned. + Can be used for paginating the results together with `offset`. + """ + offset: NotRequired[float] + r"""Skip the first `offset` results when paginating. + Needs to be an integer greater or equal to zero. + To be used in conjunction with `limit`. + """ + + +class UsersGetOrganizationMembershipsRequest(BaseModel): + user_id: Annotated[str, FieldMetadata(path=PathParamMetadata(style="simple", explode=False))] + r"""The ID of the user whose organization memberships we want to retrieve""" + limit: Annotated[Optional[float], FieldMetadata(query=QueryParamMetadata(style="form", explode=True))] = 10 + r"""Applies a limit to the number of results returned. + Can be used for paginating the results together with `offset`. + """ + offset: Annotated[Optional[float], FieldMetadata(query=QueryParamMetadata(style="form", explode=True))] = 0 + r"""Skip the first `offset` results when paginating. + Needs to be an integer greater or equal to zero. + To be used in conjunction with `limit`. + """ + + +class UsersGetOrganizationMembershipsResponseTypedDict(TypedDict): + result: OrganizationMembershipsTypedDict + + +class UsersGetOrganizationMembershipsResponse(BaseModel): + next: Callable[[], Optional[UsersGetOrganizationMembershipsResponse]] + + result: OrganizationMemberships + diff --git a/src/clerk/models/verifyclientop.py b/src/clerk/models/verifyclientop.py new file mode 100644 index 0000000..0eaedda --- /dev/null +++ b/src/clerk/models/verifyclientop.py @@ -0,0 +1,21 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel +from typing import Optional, TypedDict +from typing_extensions import NotRequired + + +class VerifyClientRequestBodyTypedDict(TypedDict): + r"""Parameters.""" + + token: NotRequired[str] + r"""A JWT Token that represents the active client.""" + + +class VerifyClientRequestBody(BaseModel): + r"""Parameters.""" + + token: Optional[str] = None + r"""A JWT Token that represents the active client.""" + diff --git a/src/clerk/models/verifydomainproxyop.py b/src/clerk/models/verifydomainproxyop.py new file mode 100644 index 0000000..4b84647 --- /dev/null +++ b/src/clerk/models/verifydomainproxyop.py @@ -0,0 +1,21 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel +from typing import Optional, TypedDict +from typing_extensions import NotRequired + + +class VerifyDomainProxyRequestBodyTypedDict(TypedDict): + domain_id: NotRequired[str] + r"""The ID of the domain that will be updated.""" + proxy_url: NotRequired[str] + r"""The full URL of the proxy which will forward requests to the Clerk Frontend API for this domain. e.g. https://example.com/__clerk""" + + +class VerifyDomainProxyRequestBody(BaseModel): + domain_id: Optional[str] = None + r"""The ID of the domain that will be updated.""" + proxy_url: Optional[str] = None + r"""The full URL of the proxy which will forward requests to the Clerk Frontend API for this domain. e.g. https://example.com/__clerk""" + diff --git a/src/clerk/models/verifypasswordop.py b/src/clerk/models/verifypasswordop.py new file mode 100644 index 0000000..df22693 --- /dev/null +++ b/src/clerk/models/verifypasswordop.py @@ -0,0 +1,42 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel +from clerk.utils import FieldMetadata, PathParamMetadata, RequestMetadata +from typing import Optional, TypedDict +from typing_extensions import Annotated, NotRequired + + +class VerifyPasswordRequestBodyTypedDict(TypedDict): + password: str + r"""The user password to verify""" + + +class VerifyPasswordRequestBody(BaseModel): + password: str + r"""The user password to verify""" + + +class VerifyPasswordRequestTypedDict(TypedDict): + user_id: str + r"""The ID of the user for whom to verify the password""" + request_body: NotRequired[VerifyPasswordRequestBodyTypedDict] + + +class VerifyPasswordRequest(BaseModel): + user_id: Annotated[str, FieldMetadata(path=PathParamMetadata(style="simple", explode=False))] + r"""The ID of the user for whom to verify the password""" + request_body: Annotated[Optional[VerifyPasswordRequestBody], FieldMetadata(request=RequestMetadata(media_type="application/json"))] = None + + +class VerifyPasswordResponseBodyTypedDict(TypedDict): + r"""The provided password was correct.""" + + verified: NotRequired[bool] + + +class VerifyPasswordResponseBody(BaseModel): + r"""The provided password was correct.""" + + verified: Optional[bool] = None + diff --git a/src/clerk/models/verifysessionop.py b/src/clerk/models/verifysessionop.py new file mode 100644 index 0000000..91fda73 --- /dev/null +++ b/src/clerk/models/verifysessionop.py @@ -0,0 +1,40 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel +from clerk.utils import FieldMetadata, PathParamMetadata, RequestMetadata +from typing import Optional, TypedDict +from typing_extensions import Annotated, NotRequired + + +class VerifySessionRequestBodyTypedDict(TypedDict): + r"""Parameters.""" + + token: NotRequired[str] + r"""The JWT that is sent via the `__session` cookie from your frontend. + Note: this JWT must be associated with the supplied session ID. + """ + + +class VerifySessionRequestBody(BaseModel): + r"""Parameters.""" + + token: Optional[str] = None + r"""The JWT that is sent via the `__session` cookie from your frontend. + Note: this JWT must be associated with the supplied session ID. + """ + + +class VerifySessionRequestTypedDict(TypedDict): + session_id: str + r"""The ID of the session""" + request_body: NotRequired[VerifySessionRequestBodyTypedDict] + r"""Parameters.""" + + +class VerifySessionRequest(BaseModel): + session_id: Annotated[str, FieldMetadata(path=PathParamMetadata(style="simple", explode=False))] + r"""The ID of the session""" + request_body: Annotated[Optional[VerifySessionRequestBody], FieldMetadata(request=RequestMetadata(media_type="application/json"))] = None + r"""Parameters.""" + diff --git a/src/clerk/models/verifytotpop.py b/src/clerk/models/verifytotpop.py new file mode 100644 index 0000000..707f61d --- /dev/null +++ b/src/clerk/models/verifytotpop.py @@ -0,0 +1,50 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel +from clerk.utils import FieldMetadata, PathParamMetadata, RequestMetadata +from enum import Enum +from typing import Optional, TypedDict +from typing_extensions import Annotated, NotRequired + + +class VerifyTOTPRequestBodyTypedDict(TypedDict): + code: str + r"""The TOTP or backup code to verify""" + + +class VerifyTOTPRequestBody(BaseModel): + code: str + r"""The TOTP or backup code to verify""" + + +class VerifyTOTPRequestTypedDict(TypedDict): + user_id: str + r"""The ID of the user for whom to verify the TOTP""" + request_body: NotRequired[VerifyTOTPRequestBodyTypedDict] + + +class VerifyTOTPRequest(BaseModel): + user_id: Annotated[str, FieldMetadata(path=PathParamMetadata(style="simple", explode=False))] + r"""The ID of the user for whom to verify the TOTP""" + request_body: Annotated[Optional[VerifyTOTPRequestBody], FieldMetadata(request=RequestMetadata(media_type="application/json"))] = None + + +class CodeType(str, Enum): + TOTP = "totp" + BACKUP_CODE = "backup_code" + + +class VerifyTOTPResponseBodyTypedDict(TypedDict): + r"""The provided TOTP or backup code was correct.""" + + verified: NotRequired[bool] + code_type: NotRequired[CodeType] + + +class VerifyTOTPResponseBody(BaseModel): + r"""The provided TOTP or backup code was correct.""" + + verified: Optional[bool] = None + code_type: Optional[CodeType] = None + diff --git a/src/clerk/models/web3wallet.py b/src/clerk/models/web3wallet.py new file mode 100644 index 0000000..c86602f --- /dev/null +++ b/src/clerk/models/web3wallet.py @@ -0,0 +1,184 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk.types import BaseModel, Nullable +from enum import Enum +from pydantic import model_serializer +from typing import Optional, TypedDict, Union +from typing_extensions import NotRequired + + +class Web3WalletObject(str, Enum): + r"""String representing the object's type. Objects of the same type share the same value. + + """ + WEB3_WALLET = "web3_wallet" + + +class AdminVerificationWeb3WalletStatus(str, Enum): + VERIFIED = "verified" + + +class AdminVerificationWeb3WalletStrategy(str, Enum): + ADMIN = "admin" + FROM_OAUTH_DISCORD = "from_oauth_discord" + + +class Web3WalletVerificationAdminTypedDict(TypedDict): + status: AdminVerificationWeb3WalletStatus + strategy: AdminVerificationWeb3WalletStrategy + attempts: NotRequired[Nullable[int]] + expire_at: NotRequired[Nullable[int]] + + +class Web3WalletVerificationAdmin(BaseModel): + status: AdminVerificationWeb3WalletStatus + strategy: AdminVerificationWeb3WalletStrategy + attempts: Optional[Nullable[int]] = None + expire_at: Optional[Nullable[int]] = None + + @model_serializer(mode="wrap") + def serialize_model(self, handler): + optional_fields = ["attempts", "expire_at"] + nullable_fields = ["attempts", "expire_at"] + null_default_fields = [] + + serialized = handler(self) + + m = {} + + for n, f in self.model_fields.items(): + k = f.alias or n + val = serialized.get(k) + + if val is not None: + m[k] = val + elif not k in optional_fields or ( + k in optional_fields + and k in nullable_fields + and (self.__pydantic_fields_set__.intersection({n}) or k in null_default_fields) # pylint: disable=no-member + ): + m[k] = val + + return m + + +class Web3SignatureVerificationStatus(str, Enum): + VERIFIED = "verified" + + +class Web3SignatureVerificationStrategy(str, Enum): + WEB3_METAMASK_SIGNATURE = "web3_metamask_signature" + + +class Nonce(str, Enum): + NONCE = "nonce" + + +class Web3SignatureTypedDict(TypedDict): + status: Web3SignatureVerificationStatus + strategy: Web3SignatureVerificationStrategy + nonce: Nonce + attempts: NotRequired[Nullable[int]] + expire_at: NotRequired[Nullable[int]] + + +class Web3Signature(BaseModel): + status: Web3SignatureVerificationStatus + strategy: Web3SignatureVerificationStrategy + nonce: Nonce + attempts: Optional[Nullable[int]] = None + expire_at: Optional[Nullable[int]] = None + + @model_serializer(mode="wrap") + def serialize_model(self, handler): + optional_fields = ["attempts", "expire_at"] + nullable_fields = ["attempts", "expire_at"] + null_default_fields = [] + + serialized = handler(self) + + m = {} + + for n, f in self.model_fields.items(): + k = f.alias or n + val = serialized.get(k) + + if val is not None: + m[k] = val + elif not k in optional_fields or ( + k in optional_fields + and k in nullable_fields + and (self.__pydantic_fields_set__.intersection({n}) or k in null_default_fields) # pylint: disable=no-member + ): + m[k] = val + + return m + + +class Web3WalletTypedDict(TypedDict): + object: Web3WalletObject + r"""String representing the object's type. Objects of the same type share the same value. + + """ + web3_wallet: str + verification: Nullable[Web3WalletVerificationTypedDict] + created_at: int + r"""Unix timestamp of creation + + """ + updated_at: int + r"""Unix timestamp of creation + + """ + id: NotRequired[str] + + +class Web3Wallet(BaseModel): + object: Web3WalletObject + r"""String representing the object's type. Objects of the same type share the same value. + + """ + web3_wallet: str + verification: Nullable[Web3WalletVerification] + created_at: int + r"""Unix timestamp of creation + + """ + updated_at: int + r"""Unix timestamp of creation + + """ + id: Optional[str] = None + + @model_serializer(mode="wrap") + def serialize_model(self, handler): + optional_fields = ["id"] + nullable_fields = ["verification"] + null_default_fields = [] + + serialized = handler(self) + + m = {} + + for n, f in self.model_fields.items(): + k = f.alias or n + val = serialized.get(k) + + if val is not None: + m[k] = val + elif not k in optional_fields or ( + k in optional_fields + and k in nullable_fields + and (self.__pydantic_fields_set__.intersection({n}) or k in null_default_fields) # pylint: disable=no-member + ): + m[k] = val + + return m + + +Web3WalletVerificationTypedDict = Union[Web3WalletVerificationAdminTypedDict, Web3SignatureTypedDict] + + +Web3WalletVerification = Union[Web3WalletVerificationAdmin, Web3Signature] + diff --git a/src/clerk/oauthapplications_sdk.py b/src/clerk/oauthapplications_sdk.py new file mode 100644 index 0000000..b071dc7 --- /dev/null +++ b/src/clerk/oauthapplications_sdk.py @@ -0,0 +1,1046 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from .basesdk import BaseSDK +from clerk import models +from clerk._hooks import HookContext +from clerk.types import Nullable, UNSET +import clerk.utils as utils +from jsonpath import JSONPath +from typing import Any, Dict, Optional + +class OAuthApplicationsSDK(BaseSDK): + + + def list( + self, *, + limit: Optional[float] = None, + offset: Optional[float] = None, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.ListOAuthApplicationsResponse: + r"""Get a list of OAuth applications for an instance + + This request returns the list of OAuth applications for an instance. + Results can be paginated using the optional `limit` and `offset` query parameters. + The OAuth applications are ordered by descending creation date. + Most recent OAuth applications will be returned first. + + :param limit: Applies a limit to the number of results returned. Can be used for paginating the results together with `offset`. + :param offset: Skip the first `offset` results when paginating. Needs to be an integer greater or equal to zero. To be used in conjunction with `limit`. + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.ListOAuthApplicationsRequest( + limit=limit, + offset=offset, + ) + + req = self.build_request( + method="GET", + path="/oauth_applications", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=False, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="ListOAuthApplications", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","403","422","4XX","5XX"], + retry_config=retry_config + ) + + def next_func() -> Optional[models.ListOAuthApplicationsResponse]: + body = utils.unmarshal_json(http_res.text, Dict[Any, Any]) + offset = request.offset if not request.offset is None else 0 + + if not http_res.text: + return None + results = JSONPath("$").parse(body) + if len(results) == 0 or len(results[0]) == 0: + return None + limit = request.limit if not request.limit is None else 0 + if len(results[0]) < limit: + return None + next_offset = offset + len(results[0]) + + return self.list( + limit=limit, + offset=next_offset, + retries=retries, + ) + + res = models.ListOAuthApplicationsResponse(result=None, next=next_func) + + if utils.match_response(http_res, "200", "application/json"): + res.result = utils.unmarshal_json(http_res.text, Optional[models.OAuthApplications]) + elif utils.match_response(http_res, ["400","403","422"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + elif utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + else: + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + return res + + + async def list_async( + self, *, + limit: Optional[float] = None, + offset: Optional[float] = None, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.ListOAuthApplicationsResponse: + r"""Get a list of OAuth applications for an instance + + This request returns the list of OAuth applications for an instance. + Results can be paginated using the optional `limit` and `offset` query parameters. + The OAuth applications are ordered by descending creation date. + Most recent OAuth applications will be returned first. + + :param limit: Applies a limit to the number of results returned. Can be used for paginating the results together with `offset`. + :param offset: Skip the first `offset` results when paginating. Needs to be an integer greater or equal to zero. To be used in conjunction with `limit`. + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.ListOAuthApplicationsRequest( + limit=limit, + offset=offset, + ) + + req = self.build_request( + method="GET", + path="/oauth_applications", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=False, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="ListOAuthApplications", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","403","422","4XX","5XX"], + retry_config=retry_config + ) + + def next_func() -> Optional[models.ListOAuthApplicationsResponse]: + body = utils.unmarshal_json(http_res.text, Dict[Any, Any]) + offset = request.offset if not request.offset is None else 0 + + if not http_res.text: + return None + results = JSONPath("$").parse(body) + if len(results) == 0 or len(results[0]) == 0: + return None + limit = request.limit if not request.limit is None else 0 + if len(results[0]) < limit: + return None + next_offset = offset + len(results[0]) + + return self.list( + limit=limit, + offset=next_offset, + retries=retries, + ) + + res = models.ListOAuthApplicationsResponse(result=None, next=next_func) + + if utils.match_response(http_res, "200", "application/json"): + res.result = utils.unmarshal_json(http_res.text, Optional[models.OAuthApplications]) + elif utils.match_response(http_res, ["400","403","422"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + elif utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + else: + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + return res + + + def create( + self, *, + name: str, + callback_url: str, + scopes: Optional[str] = None, + public: Optional[bool] = None, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.OAuthApplicationWithSecret: + r"""Create an OAuth application + + Creates a new OAuth application with the given name and callback URL for an instance. + The callback URL must be a valid url. + All URL schemes are allowed such as `http://`, `https://`, `myapp://`, etc... + + :param name: The name of the new OAuth application + :param callback_url: The callback URL of the new OAuth application + :param scopes: Define the allowed scopes for the new OAuth applications that dictate the user payload of the OAuth user info endpoint. Available scopes are `profile`, `email`, `public_metadata`, `private_metadata`. Provide the requested scopes as a string, separated by spaces. + :param public: If true, this client is public and cannot securely store a client secret. Only the authorization code flow with proof key for code exchange (PKCE) may be used. Public clients cannot be updated to be confidential clients, and vice versa. + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.CreateOAuthApplicationRequestBody( + name=name, + callback_url=callback_url, + scopes=scopes, + public=public, + ) + + req = self.build_request( + method="POST", + path="/oauth_applications", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=False, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + get_serialized_body=lambda: utils.serialize_request_body(request, False, True, "json", Optional[models.CreateOAuthApplicationRequestBody]), + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="CreateOAuthApplication", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","403","422","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.OAuthApplicationWithSecret]) + if utils.match_response(http_res, ["400","403","422"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + async def create_async( + self, *, + name: str, + callback_url: str, + scopes: Optional[str] = None, + public: Optional[bool] = None, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.OAuthApplicationWithSecret: + r"""Create an OAuth application + + Creates a new OAuth application with the given name and callback URL for an instance. + The callback URL must be a valid url. + All URL schemes are allowed such as `http://`, `https://`, `myapp://`, etc... + + :param name: The name of the new OAuth application + :param callback_url: The callback URL of the new OAuth application + :param scopes: Define the allowed scopes for the new OAuth applications that dictate the user payload of the OAuth user info endpoint. Available scopes are `profile`, `email`, `public_metadata`, `private_metadata`. Provide the requested scopes as a string, separated by spaces. + :param public: If true, this client is public and cannot securely store a client secret. Only the authorization code flow with proof key for code exchange (PKCE) may be used. Public clients cannot be updated to be confidential clients, and vice versa. + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.CreateOAuthApplicationRequestBody( + name=name, + callback_url=callback_url, + scopes=scopes, + public=public, + ) + + req = self.build_request( + method="POST", + path="/oauth_applications", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=False, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + get_serialized_body=lambda: utils.serialize_request_body(request, False, True, "json", Optional[models.CreateOAuthApplicationRequestBody]), + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="CreateOAuthApplication", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","403","422","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.OAuthApplicationWithSecret]) + if utils.match_response(http_res, ["400","403","422"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + def get( + self, *, + oauth_application_id: str, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.OAuthApplication: + r"""Retrieve an OAuth application by ID + + Fetches the OAuth application whose ID matches the provided `id` in the path. + + :param oauth_application_id: The ID of the OAuth application + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.GetOAuthApplicationRequest( + oauth_application_id=oauth_application_id, + ) + + req = self.build_request( + method="GET", + path="/oauth_applications/{oauth_application_id}", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="GetOAuthApplication", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["403","404","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.OAuthApplication]) + if utils.match_response(http_res, ["403","404"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + async def get_async( + self, *, + oauth_application_id: str, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.OAuthApplication: + r"""Retrieve an OAuth application by ID + + Fetches the OAuth application whose ID matches the provided `id` in the path. + + :param oauth_application_id: The ID of the OAuth application + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.GetOAuthApplicationRequest( + oauth_application_id=oauth_application_id, + ) + + req = self.build_request( + method="GET", + path="/oauth_applications/{oauth_application_id}", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="GetOAuthApplication", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["403","404","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.OAuthApplication]) + if utils.match_response(http_res, ["403","404"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + def update( + self, *, + oauth_application_id: str, + name: Optional[str] = None, + callback_url: Optional[str] = None, + scopes: Optional[str] = None, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.OAuthApplication: + r"""Update an OAuth application + + Updates an existing OAuth application + + :param oauth_application_id: The ID of the OAuth application to update + :param name: The new name of the OAuth application + :param callback_url: The new callback URL of the OAuth application + :param scopes: Define the allowed scopes for the new OAuth applications that dictate the user payload of the OAuth user info endpoint. Available scopes are `profile`, `email`, `public_metadata`, `private_metadata`. Provide the requested scopes as a string, separated by spaces. + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.UpdateOAuthApplicationRequest( + oauth_application_id=oauth_application_id, + request_body=models.UpdateOAuthApplicationRequestBody( + name=name, + callback_url=callback_url, + scopes=scopes, + ), + ) + + req = self.build_request( + method="PATCH", + path="/oauth_applications/{oauth_application_id}", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=True, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + get_serialized_body=lambda: utils.serialize_request_body(request.request_body, False, False, "json", models.UpdateOAuthApplicationRequestBody), + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="UpdateOAuthApplication", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["403","404","422","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.OAuthApplication]) + if utils.match_response(http_res, ["403","404","422"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + async def update_async( + self, *, + oauth_application_id: str, + name: Optional[str] = None, + callback_url: Optional[str] = None, + scopes: Optional[str] = None, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.OAuthApplication: + r"""Update an OAuth application + + Updates an existing OAuth application + + :param oauth_application_id: The ID of the OAuth application to update + :param name: The new name of the OAuth application + :param callback_url: The new callback URL of the OAuth application + :param scopes: Define the allowed scopes for the new OAuth applications that dictate the user payload of the OAuth user info endpoint. Available scopes are `profile`, `email`, `public_metadata`, `private_metadata`. Provide the requested scopes as a string, separated by spaces. + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.UpdateOAuthApplicationRequest( + oauth_application_id=oauth_application_id, + request_body=models.UpdateOAuthApplicationRequestBody( + name=name, + callback_url=callback_url, + scopes=scopes, + ), + ) + + req = self.build_request( + method="PATCH", + path="/oauth_applications/{oauth_application_id}", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=True, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + get_serialized_body=lambda: utils.serialize_request_body(request.request_body, False, False, "json", models.UpdateOAuthApplicationRequestBody), + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="UpdateOAuthApplication", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["403","404","422","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.OAuthApplication]) + if utils.match_response(http_res, ["403","404","422"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + def delete( + self, *, + oauth_application_id: str, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.DeletedObject: + r"""Delete an OAuth application + + Deletes the given OAuth application. + This is not reversible. + + :param oauth_application_id: The ID of the OAuth application to delete + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.DeleteOAuthApplicationRequest( + oauth_application_id=oauth_application_id, + ) + + req = self.build_request( + method="DELETE", + path="/oauth_applications/{oauth_application_id}", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="DeleteOAuthApplication", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["403","404","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.DeletedObject]) + if utils.match_response(http_res, ["403","404"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + async def delete_async( + self, *, + oauth_application_id: str, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.DeletedObject: + r"""Delete an OAuth application + + Deletes the given OAuth application. + This is not reversible. + + :param oauth_application_id: The ID of the OAuth application to delete + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.DeleteOAuthApplicationRequest( + oauth_application_id=oauth_application_id, + ) + + req = self.build_request( + method="DELETE", + path="/oauth_applications/{oauth_application_id}", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="DeleteOAuthApplication", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["403","404","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.DeletedObject]) + if utils.match_response(http_res, ["403","404"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + def rotate_secret( + self, *, + oauth_application_id: str, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.OAuthApplicationWithSecret: + r"""Rotate the client secret of the given OAuth application + + Rotates the OAuth application's client secret. + When the client secret is rotated, make sure to update it in authorized OAuth clients. + + :param oauth_application_id: The ID of the OAuth application for which to rotate the client secret + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.RotateOAuthApplicationSecretRequest( + oauth_application_id=oauth_application_id, + ) + + req = self.build_request( + method="POST", + path="/oauth_applications/{oauth_application_id}/rotate_secret", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="RotateOAuthApplicationSecret", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["403","404","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.OAuthApplicationWithSecret]) + if utils.match_response(http_res, ["403","404"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + async def rotate_secret_async( + self, *, + oauth_application_id: str, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.OAuthApplicationWithSecret: + r"""Rotate the client secret of the given OAuth application + + Rotates the OAuth application's client secret. + When the client secret is rotated, make sure to update it in authorized OAuth clients. + + :param oauth_application_id: The ID of the OAuth application for which to rotate the client secret + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.RotateOAuthApplicationSecretRequest( + oauth_application_id=oauth_application_id, + ) + + req = self.build_request( + method="POST", + path="/oauth_applications/{oauth_application_id}/rotate_secret", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="RotateOAuthApplicationSecret", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["403","404","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.OAuthApplicationWithSecret]) + if utils.match_response(http_res, ["403","404"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + diff --git a/src/clerk/organizationinvitations_sdk.py b/src/clerk/organizationinvitations_sdk.py new file mode 100644 index 0000000..9a43801 --- /dev/null +++ b/src/clerk/organizationinvitations_sdk.py @@ -0,0 +1,1223 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from .basesdk import BaseSDK +from clerk import models +from clerk._hooks import HookContext +from clerk.types import BaseModel, Nullable, UNSET +import clerk.utils as utils +from jsonpath import JSONPath +from typing import Any, Dict, List, Optional, Union +from typing_extensions import deprecated + +class OrganizationInvitationsSDK(BaseSDK): + + + def create( + self, *, + organization_id: str, + email_address: str, + inviter_user_id: str, + role: str, + public_metadata: Optional[Union[models.CreateOrganizationInvitationPublicMetadata, models.CreateOrganizationInvitationPublicMetadataTypedDict]] = None, + private_metadata: Optional[Union[models.CreateOrganizationInvitationPrivateMetadata, models.CreateOrganizationInvitationPrivateMetadataTypedDict]] = None, + redirect_url: Optional[str] = None, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.OrganizationInvitation: + r"""Create and send an organization invitation + + Creates a new organization invitation and sends an email to the provided `email_address` with a link to accept the invitation and join the organization. + You can specify the `role` for the invited organization member. + + New organization invitations get a \"pending\" status until they are revoked by an organization administrator or accepted by the invitee. + + The request body supports passing an optional `redirect_url` parameter. + When the invited user clicks the link to accept the invitation, they will be redirected to the URL provided. + Use this parameter to implement a custom invitation acceptance flow. + + You must specify the ID of the user that will send the invitation with the `inviter_user_id` parameter. + That user must be a member with administrator privileges in the organization. + Only \"admin\" members can create organization invitations. + + You can optionally provide public and private metadata for the organization invitation. + The public metadata are visible by both the Frontend and the Backend whereas the private ones only by the Backend. + When the organization invitation is accepted, the metadata will be transferred to the newly created organization membership. + + :param organization_id: The ID of the organization for which to send the invitation + :param email_address: The email address of the new member that is going to be invited to the organization + :param inviter_user_id: The ID of the user that invites the new member to the organization. Must be an administrator in the organization. + :param role: The role of the new member in the organization + :param public_metadata: Metadata saved on the organization invitation, read-only from the Frontend API and fully accessible (read/write) from the Backend API. + :param private_metadata: Metadata saved on the organization invitation, fully accessible (read/write) from the Backend API but not visible from the Frontend API. + :param redirect_url: Optional URL that the invitee will be redirected to once they accept the invitation by clicking the join link in the invitation email. + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.CreateOrganizationInvitationRequest( + organization_id=organization_id, + request_body=models.CreateOrganizationInvitationRequestBody( + email_address=email_address, + inviter_user_id=inviter_user_id, + role=role, + public_metadata=utils.unmarshal(public_metadata, models.CreateOrganizationInvitationPublicMetadata) if not isinstance(public_metadata, BaseModel) and public_metadata is not None else public_metadata, + private_metadata=utils.unmarshal(private_metadata, models.CreateOrganizationInvitationPrivateMetadata) if not isinstance(private_metadata, BaseModel) and private_metadata is not None else private_metadata, + redirect_url=redirect_url, + ), + ) + + req = self.build_request( + method="POST", + path="/organizations/{organization_id}/invitations", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=True, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + get_serialized_body=lambda: utils.serialize_request_body(request.request_body, False, False, "json", models.CreateOrganizationInvitationRequestBody), + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="CreateOrganizationInvitation", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","403","404","422","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.OrganizationInvitation]) + if utils.match_response(http_res, ["400","403","404","422"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + async def create_async( + self, *, + organization_id: str, + email_address: str, + inviter_user_id: str, + role: str, + public_metadata: Optional[Union[models.CreateOrganizationInvitationPublicMetadata, models.CreateOrganizationInvitationPublicMetadataTypedDict]] = None, + private_metadata: Optional[Union[models.CreateOrganizationInvitationPrivateMetadata, models.CreateOrganizationInvitationPrivateMetadataTypedDict]] = None, + redirect_url: Optional[str] = None, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.OrganizationInvitation: + r"""Create and send an organization invitation + + Creates a new organization invitation and sends an email to the provided `email_address` with a link to accept the invitation and join the organization. + You can specify the `role` for the invited organization member. + + New organization invitations get a \"pending\" status until they are revoked by an organization administrator or accepted by the invitee. + + The request body supports passing an optional `redirect_url` parameter. + When the invited user clicks the link to accept the invitation, they will be redirected to the URL provided. + Use this parameter to implement a custom invitation acceptance flow. + + You must specify the ID of the user that will send the invitation with the `inviter_user_id` parameter. + That user must be a member with administrator privileges in the organization. + Only \"admin\" members can create organization invitations. + + You can optionally provide public and private metadata for the organization invitation. + The public metadata are visible by both the Frontend and the Backend whereas the private ones only by the Backend. + When the organization invitation is accepted, the metadata will be transferred to the newly created organization membership. + + :param organization_id: The ID of the organization for which to send the invitation + :param email_address: The email address of the new member that is going to be invited to the organization + :param inviter_user_id: The ID of the user that invites the new member to the organization. Must be an administrator in the organization. + :param role: The role of the new member in the organization + :param public_metadata: Metadata saved on the organization invitation, read-only from the Frontend API and fully accessible (read/write) from the Backend API. + :param private_metadata: Metadata saved on the organization invitation, fully accessible (read/write) from the Backend API but not visible from the Frontend API. + :param redirect_url: Optional URL that the invitee will be redirected to once they accept the invitation by clicking the join link in the invitation email. + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.CreateOrganizationInvitationRequest( + organization_id=organization_id, + request_body=models.CreateOrganizationInvitationRequestBody( + email_address=email_address, + inviter_user_id=inviter_user_id, + role=role, + public_metadata=utils.unmarshal(public_metadata, models.CreateOrganizationInvitationPublicMetadata) if not isinstance(public_metadata, BaseModel) and public_metadata is not None else public_metadata, + private_metadata=utils.unmarshal(private_metadata, models.CreateOrganizationInvitationPrivateMetadata) if not isinstance(private_metadata, BaseModel) and private_metadata is not None else private_metadata, + redirect_url=redirect_url, + ), + ) + + req = self.build_request( + method="POST", + path="/organizations/{organization_id}/invitations", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=True, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + get_serialized_body=lambda: utils.serialize_request_body(request.request_body, False, False, "json", models.CreateOrganizationInvitationRequestBody), + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="CreateOrganizationInvitation", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","403","404","422","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.OrganizationInvitation]) + if utils.match_response(http_res, ["400","403","404","422"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + def list( + self, *, + organization_id: str, + limit: Optional[float] = None, + offset: Optional[float] = None, + status: Optional[models.ListOrganizationInvitationsQueryParamStatus] = None, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.ListOrganizationInvitationsResponse: + r"""Get a list of organization invitations + + This request returns the list of organization invitations. + Results can be paginated using the optional `limit` and `offset` query parameters. + You can filter them by providing the 'status' query parameter, that accepts multiple values. + The organization invitations are ordered by descending creation date. + Most recent invitations will be returned first. + Any invitations created as a result of an Organization Domain are not included in the results. + + :param organization_id: The organization ID. + :param limit: Applies a limit to the number of results returned. Can be used for paginating the results together with `offset`. + :param offset: Skip the first `offset` results when paginating. Needs to be an integer greater or equal to zero. To be used in conjunction with `limit`. + :param status: Filter organization invitations based on their status + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.ListOrganizationInvitationsRequest( + organization_id=organization_id, + limit=limit, + offset=offset, + status=status, + ) + + req = self.build_request( + method="GET", + path="/organizations/{organization_id}/invitations", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="ListOrganizationInvitations", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","404","4XX","5XX"], + retry_config=retry_config + ) + + def next_func() -> Optional[models.ListOrganizationInvitationsResponse]: + body = utils.unmarshal_json(http_res.text, Dict[Any, Any]) + offset = request.offset if not request.offset is None else 0 + + if not http_res.text: + return None + results = JSONPath("$").parse(body) + if len(results) == 0 or len(results[0]) == 0: + return None + limit = request.limit if not request.limit is None else 0 + if len(results[0]) < limit: + return None + next_offset = offset + len(results[0]) + + return self.list( + organization_id=organization_id, + limit=limit, + offset=next_offset, + status=status, + retries=retries, + ) + + res = models.ListOrganizationInvitationsResponse(result=None, next=next_func) + + if utils.match_response(http_res, "200", "application/json"): + res.result = utils.unmarshal_json(http_res.text, Optional[models.OrganizationInvitations]) + elif utils.match_response(http_res, ["400","404"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + elif utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + else: + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + return res + + + async def list_async( + self, *, + organization_id: str, + limit: Optional[float] = None, + offset: Optional[float] = None, + status: Optional[models.ListOrganizationInvitationsQueryParamStatus] = None, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.ListOrganizationInvitationsResponse: + r"""Get a list of organization invitations + + This request returns the list of organization invitations. + Results can be paginated using the optional `limit` and `offset` query parameters. + You can filter them by providing the 'status' query parameter, that accepts multiple values. + The organization invitations are ordered by descending creation date. + Most recent invitations will be returned first. + Any invitations created as a result of an Organization Domain are not included in the results. + + :param organization_id: The organization ID. + :param limit: Applies a limit to the number of results returned. Can be used for paginating the results together with `offset`. + :param offset: Skip the first `offset` results when paginating. Needs to be an integer greater or equal to zero. To be used in conjunction with `limit`. + :param status: Filter organization invitations based on their status + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.ListOrganizationInvitationsRequest( + organization_id=organization_id, + limit=limit, + offset=offset, + status=status, + ) + + req = self.build_request( + method="GET", + path="/organizations/{organization_id}/invitations", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="ListOrganizationInvitations", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","404","4XX","5XX"], + retry_config=retry_config + ) + + def next_func() -> Optional[models.ListOrganizationInvitationsResponse]: + body = utils.unmarshal_json(http_res.text, Dict[Any, Any]) + offset = request.offset if not request.offset is None else 0 + + if not http_res.text: + return None + results = JSONPath("$").parse(body) + if len(results) == 0 or len(results[0]) == 0: + return None + limit = request.limit if not request.limit is None else 0 + if len(results[0]) < limit: + return None + next_offset = offset + len(results[0]) + + return self.list( + organization_id=organization_id, + limit=limit, + offset=next_offset, + status=status, + retries=retries, + ) + + res = models.ListOrganizationInvitationsResponse(result=None, next=next_func) + + if utils.match_response(http_res, "200", "application/json"): + res.result = utils.unmarshal_json(http_res.text, Optional[models.OrganizationInvitations]) + elif utils.match_response(http_res, ["400","404"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + elif utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + else: + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + return res + + + def create_bulk( + self, *, + organization_id: str, + request_body: Union[List[models.RequestBody], List[models.RequestBodyTypedDict]], + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.OrganizationInvitations: + r"""Bulk create and send organization invitations + + Creates new organization invitations in bulk and sends out emails to the provided email addresses with a link to accept the invitation and join the organization. + You can specify a different `role` for each invited organization member. + New organization invitations get a \"pending\" status until they are revoked by an organization administrator or accepted by the invitee. + The request body supports passing an optional `redirect_url` parameter for each invitation. + When the invited user clicks the link to accept the invitation, they will be redirected to the provided URL. + Use this parameter to implement a custom invitation acceptance flow. + You must specify the ID of the user that will send the invitation with the `inviter_user_id` parameter. Each invitation + can have a different inviter user. + Inviter users must be members with administrator privileges in the organization. + Only \"admin\" members can create organization invitations. + You can optionally provide public and private metadata for each organization invitation. The public metadata are visible + by both the Frontend and the Backend, whereas the private metadata are only visible by the Backend. + When the organization invitation is accepted, the metadata will be transferred to the newly created organization membership. + + :param organization_id: The organization ID. + :param request_body: + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.CreateOrganizationInvitationBulkRequest( + organization_id=organization_id, + request_body=utils.unmarshal(request_body, List[models.RequestBody]) if not isinstance(request_body, BaseModel) else request_body, + ) + + req = self.build_request( + method="POST", + path="/organizations/{organization_id}/invitations/bulk", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=True, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + get_serialized_body=lambda: utils.serialize_request_body(request.request_body, False, False, "json", List[models.RequestBody]), + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="CreateOrganizationInvitationBulk", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","403","404","422","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.OrganizationInvitations]) + if utils.match_response(http_res, ["400","403","404","422"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + async def create_bulk_async( + self, *, + organization_id: str, + request_body: Union[List[models.RequestBody], List[models.RequestBodyTypedDict]], + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.OrganizationInvitations: + r"""Bulk create and send organization invitations + + Creates new organization invitations in bulk and sends out emails to the provided email addresses with a link to accept the invitation and join the organization. + You can specify a different `role` for each invited organization member. + New organization invitations get a \"pending\" status until they are revoked by an organization administrator or accepted by the invitee. + The request body supports passing an optional `redirect_url` parameter for each invitation. + When the invited user clicks the link to accept the invitation, they will be redirected to the provided URL. + Use this parameter to implement a custom invitation acceptance flow. + You must specify the ID of the user that will send the invitation with the `inviter_user_id` parameter. Each invitation + can have a different inviter user. + Inviter users must be members with administrator privileges in the organization. + Only \"admin\" members can create organization invitations. + You can optionally provide public and private metadata for each organization invitation. The public metadata are visible + by both the Frontend and the Backend, whereas the private metadata are only visible by the Backend. + When the organization invitation is accepted, the metadata will be transferred to the newly created organization membership. + + :param organization_id: The organization ID. + :param request_body: + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.CreateOrganizationInvitationBulkRequest( + organization_id=organization_id, + request_body=utils.unmarshal(request_body, List[models.RequestBody]) if not isinstance(request_body, BaseModel) else request_body, + ) + + req = self.build_request( + method="POST", + path="/organizations/{organization_id}/invitations/bulk", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=True, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + get_serialized_body=lambda: utils.serialize_request_body(request.request_body, False, False, "json", List[models.RequestBody]), + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="CreateOrganizationInvitationBulk", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","403","404","422","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.OrganizationInvitations]) + if utils.match_response(http_res, ["400","403","404","422"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + @deprecated("warning: ** DEPRECATED ** - This will be removed in a future release, please migrate away from it as soon as possible.") + def list_pending( + self, *, + organization_id: str, + limit: Optional[float] = None, + offset: Optional[float] = None, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.ListPendingOrganizationInvitationsResponse: + r"""Get a list of pending organization invitations + + This request returns the list of organization invitations with \"pending\" status. + These are the organization invitations that can still be used to join the organization, but have not been accepted by the invited user yet. + Results can be paginated using the optional `limit` and `offset` query parameters. + The organization invitations are ordered by descending creation date. + Most recent invitations will be returned first. + Any invitations created as a result of an Organization Domain are not included in the results. + + :param organization_id: The organization ID. + :param limit: Applies a limit to the number of results returned. Can be used for paginating the results together with `offset`. + :param offset: Skip the first `offset` results when paginating. Needs to be an integer greater or equal to zero. To be used in conjunction with `limit`. + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.ListPendingOrganizationInvitationsRequest( + organization_id=organization_id, + limit=limit, + offset=offset, + ) + + req = self.build_request( + method="GET", + path="/organizations/{organization_id}/invitations/pending", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="ListPendingOrganizationInvitations", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","404","4XX","5XX"], + retry_config=retry_config + ) + + def next_func() -> Optional[models.ListPendingOrganizationInvitationsResponse]: + body = utils.unmarshal_json(http_res.text, Dict[Any, Any]) + offset = request.offset if not request.offset is None else 0 + + if not http_res.text: + return None + results = JSONPath("$").parse(body) + if len(results) == 0 or len(results[0]) == 0: + return None + limit = request.limit if not request.limit is None else 0 + if len(results[0]) < limit: + return None + next_offset = offset + len(results[0]) + + return self.list_pending( + organization_id=organization_id, + limit=limit, + offset=next_offset, + retries=retries, + ) + + res = models.ListPendingOrganizationInvitationsResponse(result=None, next=next_func) + + if utils.match_response(http_res, "200", "application/json"): + res.result = utils.unmarshal_json(http_res.text, Optional[models.OrganizationInvitations]) + elif utils.match_response(http_res, ["400","404"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + elif utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + else: + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + return res + + + @deprecated("warning: ** DEPRECATED ** - This will be removed in a future release, please migrate away from it as soon as possible.") + async def list_pending_async( + self, *, + organization_id: str, + limit: Optional[float] = None, + offset: Optional[float] = None, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.ListPendingOrganizationInvitationsResponse: + r"""Get a list of pending organization invitations + + This request returns the list of organization invitations with \"pending\" status. + These are the organization invitations that can still be used to join the organization, but have not been accepted by the invited user yet. + Results can be paginated using the optional `limit` and `offset` query parameters. + The organization invitations are ordered by descending creation date. + Most recent invitations will be returned first. + Any invitations created as a result of an Organization Domain are not included in the results. + + :param organization_id: The organization ID. + :param limit: Applies a limit to the number of results returned. Can be used for paginating the results together with `offset`. + :param offset: Skip the first `offset` results when paginating. Needs to be an integer greater or equal to zero. To be used in conjunction with `limit`. + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.ListPendingOrganizationInvitationsRequest( + organization_id=organization_id, + limit=limit, + offset=offset, + ) + + req = self.build_request( + method="GET", + path="/organizations/{organization_id}/invitations/pending", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="ListPendingOrganizationInvitations", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","404","4XX","5XX"], + retry_config=retry_config + ) + + def next_func() -> Optional[models.ListPendingOrganizationInvitationsResponse]: + body = utils.unmarshal_json(http_res.text, Dict[Any, Any]) + offset = request.offset if not request.offset is None else 0 + + if not http_res.text: + return None + results = JSONPath("$").parse(body) + if len(results) == 0 or len(results[0]) == 0: + return None + limit = request.limit if not request.limit is None else 0 + if len(results[0]) < limit: + return None + next_offset = offset + len(results[0]) + + return self.list_pending( + organization_id=organization_id, + limit=limit, + offset=next_offset, + retries=retries, + ) + + res = models.ListPendingOrganizationInvitationsResponse(result=None, next=next_func) + + if utils.match_response(http_res, "200", "application/json"): + res.result = utils.unmarshal_json(http_res.text, Optional[models.OrganizationInvitations]) + elif utils.match_response(http_res, ["400","404"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + elif utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + else: + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + return res + + + def get( + self, *, + organization_id: str, + invitation_id: str, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.OrganizationInvitation: + r"""Retrieve an organization invitation by ID + + Use this request to get an existing organization invitation by ID. + + :param organization_id: The organization ID. + :param invitation_id: The organization invitation ID. + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.GetOrganizationInvitationRequest( + organization_id=organization_id, + invitation_id=invitation_id, + ) + + req = self.build_request( + method="GET", + path="/organizations/{organization_id}/invitations/{invitation_id}", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="GetOrganizationInvitation", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","403","404","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.OrganizationInvitation]) + if utils.match_response(http_res, ["400","403","404"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + async def get_async( + self, *, + organization_id: str, + invitation_id: str, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.OrganizationInvitation: + r"""Retrieve an organization invitation by ID + + Use this request to get an existing organization invitation by ID. + + :param organization_id: The organization ID. + :param invitation_id: The organization invitation ID. + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.GetOrganizationInvitationRequest( + organization_id=organization_id, + invitation_id=invitation_id, + ) + + req = self.build_request( + method="GET", + path="/organizations/{organization_id}/invitations/{invitation_id}", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="GetOrganizationInvitation", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","403","404","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.OrganizationInvitation]) + if utils.match_response(http_res, ["400","403","404"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + def revoke( + self, *, + organization_id: str, + invitation_id: str, + requesting_user_id: str, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.OrganizationInvitation: + r"""Revoke a pending organization invitation + + Use this request to revoke a previously issued organization invitation. + Revoking an organization invitation makes it invalid; the invited user will no longer be able to join the organization with the revoked invitation. + Only organization invitations with \"pending\" status can be revoked. + The request needs the `requesting_user_id` parameter to specify the user which revokes the invitation. + Only users with \"admin\" role can revoke invitations. + + :param organization_id: The organization ID. + :param invitation_id: The organization invitation ID. + :param requesting_user_id: The ID of the user that revokes the invitation. Must be an administrator in the organization. + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.RevokeOrganizationInvitationRequest( + organization_id=organization_id, + invitation_id=invitation_id, + request_body=models.RevokeOrganizationInvitationRequestBody( + requesting_user_id=requesting_user_id, + ), + ) + + req = self.build_request( + method="POST", + path="/organizations/{organization_id}/invitations/{invitation_id}/revoke", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=True, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + get_serialized_body=lambda: utils.serialize_request_body(request.request_body, False, False, "json", models.RevokeOrganizationInvitationRequestBody), + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="RevokeOrganizationInvitation", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","403","404","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.OrganizationInvitation]) + if utils.match_response(http_res, ["400","403","404"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + async def revoke_async( + self, *, + organization_id: str, + invitation_id: str, + requesting_user_id: str, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.OrganizationInvitation: + r"""Revoke a pending organization invitation + + Use this request to revoke a previously issued organization invitation. + Revoking an organization invitation makes it invalid; the invited user will no longer be able to join the organization with the revoked invitation. + Only organization invitations with \"pending\" status can be revoked. + The request needs the `requesting_user_id` parameter to specify the user which revokes the invitation. + Only users with \"admin\" role can revoke invitations. + + :param organization_id: The organization ID. + :param invitation_id: The organization invitation ID. + :param requesting_user_id: The ID of the user that revokes the invitation. Must be an administrator in the organization. + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.RevokeOrganizationInvitationRequest( + organization_id=organization_id, + invitation_id=invitation_id, + request_body=models.RevokeOrganizationInvitationRequestBody( + requesting_user_id=requesting_user_id, + ), + ) + + req = self.build_request( + method="POST", + path="/organizations/{organization_id}/invitations/{invitation_id}/revoke", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=True, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + get_serialized_body=lambda: utils.serialize_request_body(request.request_body, False, False, "json", models.RevokeOrganizationInvitationRequestBody), + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="RevokeOrganizationInvitation", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","403","404","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.OrganizationInvitation]) + if utils.match_response(http_res, ["400","403","404"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + diff --git a/src/clerk/organizationmemberships_sdk.py b/src/clerk/organizationmemberships_sdk.py new file mode 100644 index 0000000..5e73108 --- /dev/null +++ b/src/clerk/organizationmemberships_sdk.py @@ -0,0 +1,920 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from .basesdk import BaseSDK +from clerk import models +from clerk._hooks import HookContext +from clerk.types import BaseModel, Nullable, UNSET +import clerk.utils as utils +from jsonpath import JSONPath +from typing import Any, Dict, Optional, Union + +class OrganizationMembershipsSDK(BaseSDK): + + + def create( + self, *, + organization_id: str, + user_id: str, + role: str, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.OrganizationMembership: + r"""Create a new organization membership + + Adds a user as a member to the given organization. + + :param organization_id: The ID of the organization where the new membership will be created + :param user_id: The ID of the user that will be added as a member in the organization. + :param role: The role that the new member will have in the organization. + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.CreateOrganizationMembershipRequest( + organization_id=organization_id, + request_body=models.CreateOrganizationMembershipRequestBody( + user_id=user_id, + role=role, + ), + ) + + req = self.build_request( + method="POST", + path="/organizations/{organization_id}/memberships", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=True, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + get_serialized_body=lambda: utils.serialize_request_body(request.request_body, False, False, "json", models.CreateOrganizationMembershipRequestBody), + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="CreateOrganizationMembership", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","403","404","422","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.OrganizationMembership]) + if utils.match_response(http_res, ["400","403","404","422"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + async def create_async( + self, *, + organization_id: str, + user_id: str, + role: str, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.OrganizationMembership: + r"""Create a new organization membership + + Adds a user as a member to the given organization. + + :param organization_id: The ID of the organization where the new membership will be created + :param user_id: The ID of the user that will be added as a member in the organization. + :param role: The role that the new member will have in the organization. + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.CreateOrganizationMembershipRequest( + organization_id=organization_id, + request_body=models.CreateOrganizationMembershipRequestBody( + user_id=user_id, + role=role, + ), + ) + + req = self.build_request( + method="POST", + path="/organizations/{organization_id}/memberships", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=True, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + get_serialized_body=lambda: utils.serialize_request_body(request.request_body, False, False, "json", models.CreateOrganizationMembershipRequestBody), + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="CreateOrganizationMembership", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","403","404","422","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.OrganizationMembership]) + if utils.match_response(http_res, ["400","403","404","422"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + def list( + self, *, + organization_id: str, + limit: Optional[float] = None, + offset: Optional[float] = None, + order_by: Optional[str] = None, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.ListOrganizationMembershipsResponse: + r"""Get a list of all members of an organization + + Retrieves all user memberships for the given organization + + :param organization_id: The organization ID. + :param limit: Applies a limit to the number of results returned. Can be used for paginating the results together with `offset`. + :param offset: Skip the first `offset` results when paginating. Needs to be an integer greater or equal to zero. To be used in conjunction with `limit`. + :param order_by: Sorts organizations memberships by phone_number, email_address, created_at, first_name, last_name or username. By prepending one of those values with + or -, we can choose to sort in ascending (ASC) or descending (DESC) order.\" + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.ListOrganizationMembershipsRequest( + organization_id=organization_id, + limit=limit, + offset=offset, + order_by=order_by, + ) + + req = self.build_request( + method="GET", + path="/organizations/{organization_id}/memberships", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="ListOrganizationMemberships", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["401","422","4XX","5XX"], + retry_config=retry_config + ) + + def next_func() -> Optional[models.ListOrganizationMembershipsResponse]: + body = utils.unmarshal_json(http_res.text, Dict[Any, Any]) + offset = request.offset if not request.offset is None else 0 + + if not http_res.text: + return None + results = JSONPath("$").parse(body) + if len(results) == 0 or len(results[0]) == 0: + return None + limit = request.limit if not request.limit is None else 0 + if len(results[0]) < limit: + return None + next_offset = offset + len(results[0]) + + return self.list( + organization_id=organization_id, + limit=limit, + offset=next_offset, + order_by=order_by, + retries=retries, + ) + + res = models.ListOrganizationMembershipsResponse(result=None, next=next_func) + + if utils.match_response(http_res, "200", "application/json"): + res.result = utils.unmarshal_json(http_res.text, Optional[models.OrganizationMemberships]) + elif utils.match_response(http_res, ["401","422"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + elif utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + else: + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + return res + + + async def list_async( + self, *, + organization_id: str, + limit: Optional[float] = None, + offset: Optional[float] = None, + order_by: Optional[str] = None, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.ListOrganizationMembershipsResponse: + r"""Get a list of all members of an organization + + Retrieves all user memberships for the given organization + + :param organization_id: The organization ID. + :param limit: Applies a limit to the number of results returned. Can be used for paginating the results together with `offset`. + :param offset: Skip the first `offset` results when paginating. Needs to be an integer greater or equal to zero. To be used in conjunction with `limit`. + :param order_by: Sorts organizations memberships by phone_number, email_address, created_at, first_name, last_name or username. By prepending one of those values with + or -, we can choose to sort in ascending (ASC) or descending (DESC) order.\" + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.ListOrganizationMembershipsRequest( + organization_id=organization_id, + limit=limit, + offset=offset, + order_by=order_by, + ) + + req = self.build_request( + method="GET", + path="/organizations/{organization_id}/memberships", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="ListOrganizationMemberships", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["401","422","4XX","5XX"], + retry_config=retry_config + ) + + def next_func() -> Optional[models.ListOrganizationMembershipsResponse]: + body = utils.unmarshal_json(http_res.text, Dict[Any, Any]) + offset = request.offset if not request.offset is None else 0 + + if not http_res.text: + return None + results = JSONPath("$").parse(body) + if len(results) == 0 or len(results[0]) == 0: + return None + limit = request.limit if not request.limit is None else 0 + if len(results[0]) < limit: + return None + next_offset = offset + len(results[0]) + + return self.list( + organization_id=organization_id, + limit=limit, + offset=next_offset, + order_by=order_by, + retries=retries, + ) + + res = models.ListOrganizationMembershipsResponse(result=None, next=next_func) + + if utils.match_response(http_res, "200", "application/json"): + res.result = utils.unmarshal_json(http_res.text, Optional[models.OrganizationMemberships]) + elif utils.match_response(http_res, ["401","422"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + elif utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + else: + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + return res + + + def update( + self, *, + organization_id: str, + user_id: str, + role: str, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.OrganizationMembership: + r"""Update an organization membership + + Updates the properties of an existing organization membership + + :param organization_id: The ID of the organization the membership belongs to + :param user_id: The ID of the user that this membership belongs to + :param role: The new role of the given membership. + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.UpdateOrganizationMembershipRequest( + organization_id=organization_id, + user_id=user_id, + request_body=models.UpdateOrganizationMembershipRequestBody( + role=role, + ), + ) + + req = self.build_request( + method="PATCH", + path="/organizations/{organization_id}/memberships/{user_id}", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=True, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + get_serialized_body=lambda: utils.serialize_request_body(request.request_body, False, False, "json", models.UpdateOrganizationMembershipRequestBody), + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="UpdateOrganizationMembership", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","404","422","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.OrganizationMembership]) + if utils.match_response(http_res, ["400","404","422"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + async def update_async( + self, *, + organization_id: str, + user_id: str, + role: str, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.OrganizationMembership: + r"""Update an organization membership + + Updates the properties of an existing organization membership + + :param organization_id: The ID of the organization the membership belongs to + :param user_id: The ID of the user that this membership belongs to + :param role: The new role of the given membership. + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.UpdateOrganizationMembershipRequest( + organization_id=organization_id, + user_id=user_id, + request_body=models.UpdateOrganizationMembershipRequestBody( + role=role, + ), + ) + + req = self.build_request( + method="PATCH", + path="/organizations/{organization_id}/memberships/{user_id}", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=True, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + get_serialized_body=lambda: utils.serialize_request_body(request.request_body, False, False, "json", models.UpdateOrganizationMembershipRequestBody), + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="UpdateOrganizationMembership", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","404","422","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.OrganizationMembership]) + if utils.match_response(http_res, ["400","404","422"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + def delete( + self, *, + organization_id: str, + user_id: str, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.OrganizationMembership: + r"""Remove a member from an organization + + Removes the given membership from the organization + + :param organization_id: The ID of the organization the membership belongs to + :param user_id: The ID of the user that this membership belongs to + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.DeleteOrganizationMembershipRequest( + organization_id=organization_id, + user_id=user_id, + ) + + req = self.build_request( + method="DELETE", + path="/organizations/{organization_id}/memberships/{user_id}", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="DeleteOrganizationMembership", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","401","404","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.OrganizationMembership]) + if utils.match_response(http_res, ["400","401","404"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + async def delete_async( + self, *, + organization_id: str, + user_id: str, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.OrganizationMembership: + r"""Remove a member from an organization + + Removes the given membership from the organization + + :param organization_id: The ID of the organization the membership belongs to + :param user_id: The ID of the user that this membership belongs to + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.DeleteOrganizationMembershipRequest( + organization_id=organization_id, + user_id=user_id, + ) + + req = self.build_request( + method="DELETE", + path="/organizations/{organization_id}/memberships/{user_id}", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="DeleteOrganizationMembership", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","401","404","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.OrganizationMembership]) + if utils.match_response(http_res, ["400","401","404"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + def update_metadata( + self, *, + organization_id: str, + user_id: str, + public_metadata: Optional[Union[models.UpdateOrganizationMembershipMetadataPublicMetadata, models.UpdateOrganizationMembershipMetadataPublicMetadataTypedDict]] = None, + private_metadata: Optional[Union[models.UpdateOrganizationMembershipMetadataPrivateMetadata, models.UpdateOrganizationMembershipMetadataPrivateMetadataTypedDict]] = None, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.OrganizationMembership: + r"""Merge and update organization membership metadata + + Update an organization membership's metadata attributes by merging existing values with the provided parameters. + Metadata values will be updated via a deep merge. Deep means that any nested JSON objects will be merged as well. + You can remove metadata keys at any level by setting their value to `null`. + + :param organization_id: The ID of the organization the membership belongs to + :param user_id: The ID of the user that this membership belongs to + :param public_metadata: Metadata saved on the organization membership, that is visible to both your frontend and backend. The new object will be merged with the existing value. + :param private_metadata: Metadata saved on the organization membership that is only visible to your backend. The new object will be merged with the existing value. + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.UpdateOrganizationMembershipMetadataRequest( + organization_id=organization_id, + user_id=user_id, + request_body=models.UpdateOrganizationMembershipMetadataRequestBody( + public_metadata=utils.unmarshal(public_metadata, models.UpdateOrganizationMembershipMetadataPublicMetadata) if not isinstance(public_metadata, BaseModel) and public_metadata is not None else public_metadata, + private_metadata=utils.unmarshal(private_metadata, models.UpdateOrganizationMembershipMetadataPrivateMetadata) if not isinstance(private_metadata, BaseModel) and private_metadata is not None else private_metadata, + ), + ) + + req = self.build_request( + method="PATCH", + path="/organizations/{organization_id}/memberships/{user_id}/metadata", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=True, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + get_serialized_body=lambda: utils.serialize_request_body(request.request_body, False, False, "json", models.UpdateOrganizationMembershipMetadataRequestBody), + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="UpdateOrganizationMembershipMetadata", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","404","422","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.OrganizationMembership]) + if utils.match_response(http_res, ["400","404","422"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + async def update_metadata_async( + self, *, + organization_id: str, + user_id: str, + public_metadata: Optional[Union[models.UpdateOrganizationMembershipMetadataPublicMetadata, models.UpdateOrganizationMembershipMetadataPublicMetadataTypedDict]] = None, + private_metadata: Optional[Union[models.UpdateOrganizationMembershipMetadataPrivateMetadata, models.UpdateOrganizationMembershipMetadataPrivateMetadataTypedDict]] = None, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.OrganizationMembership: + r"""Merge and update organization membership metadata + + Update an organization membership's metadata attributes by merging existing values with the provided parameters. + Metadata values will be updated via a deep merge. Deep means that any nested JSON objects will be merged as well. + You can remove metadata keys at any level by setting their value to `null`. + + :param organization_id: The ID of the organization the membership belongs to + :param user_id: The ID of the user that this membership belongs to + :param public_metadata: Metadata saved on the organization membership, that is visible to both your frontend and backend. The new object will be merged with the existing value. + :param private_metadata: Metadata saved on the organization membership that is only visible to your backend. The new object will be merged with the existing value. + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.UpdateOrganizationMembershipMetadataRequest( + organization_id=organization_id, + user_id=user_id, + request_body=models.UpdateOrganizationMembershipMetadataRequestBody( + public_metadata=utils.unmarshal(public_metadata, models.UpdateOrganizationMembershipMetadataPublicMetadata) if not isinstance(public_metadata, BaseModel) and public_metadata is not None else public_metadata, + private_metadata=utils.unmarshal(private_metadata, models.UpdateOrganizationMembershipMetadataPrivateMetadata) if not isinstance(private_metadata, BaseModel) and private_metadata is not None else private_metadata, + ), + ) + + req = self.build_request( + method="PATCH", + path="/organizations/{organization_id}/memberships/{user_id}/metadata", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=True, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + get_serialized_body=lambda: utils.serialize_request_body(request.request_body, False, False, "json", models.UpdateOrganizationMembershipMetadataRequestBody), + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="UpdateOrganizationMembershipMetadata", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","404","422","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.OrganizationMembership]) + if utils.match_response(http_res, ["400","404","422"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + diff --git a/src/clerk/organizations_sdk.py b/src/clerk/organizations_sdk.py new file mode 100644 index 0000000..4caa2d5 --- /dev/null +++ b/src/clerk/organizations_sdk.py @@ -0,0 +1,1411 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from .basesdk import BaseSDK +from clerk import models +from clerk._hooks import HookContext +from clerk.types import BaseModel, Nullable, UNSET +import clerk.utils as utils +from typing import Optional, Union + +class OrganizationsSDK(BaseSDK): + + + def list( + self, *, + limit: Optional[float] = None, + offset: Optional[float] = None, + include_members_count: Optional[bool] = None, + query: Optional[str] = None, + order_by: Optional[str] = None, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.Organizations: + r"""Get a list of organizations for an instance + + This request returns the list of organizations for an instance. + Results can be paginated using the optional `limit` and `offset` query parameters. + The organizations are ordered by descending creation date. + Most recent organizations will be returned first. + + :param limit: Applies a limit to the number of results returned. Can be used for paginating the results together with `offset`. + :param offset: Skip the first `offset` results when paginating. Needs to be an integer greater or equal to zero. To be used in conjunction with `limit`. + :param include_members_count: Flag to denote whether the member counts of each organization should be included in the response or not. + :param query: Returns organizations with ID, name, or slug that match the given query. Uses exact match for organization ID and partial match for name and slug. + :param order_by: Allows to return organizations in a particular order. At the moment, you can order the returned organizations either by their `name`, `created_at` or `members_count`. In order to specify the direction, you can use the `+/-` symbols prepended in the property to order by. For example, if you want organizations to be returned in descending order according to their `created_at` property, you can use `-created_at`. If you don't use `+` or `-`, then `+` is implied. Defaults to `-created_at`. + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.ListOrganizationsRequest( + limit=limit, + offset=offset, + include_members_count=include_members_count, + query=query, + order_by=order_by, + ) + + req = self.build_request( + method="GET", + path="/organizations", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=False, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="ListOrganizations", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","403","422","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.Organizations]) + if utils.match_response(http_res, ["400","403","422"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + async def list_async( + self, *, + limit: Optional[float] = None, + offset: Optional[float] = None, + include_members_count: Optional[bool] = None, + query: Optional[str] = None, + order_by: Optional[str] = None, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.Organizations: + r"""Get a list of organizations for an instance + + This request returns the list of organizations for an instance. + Results can be paginated using the optional `limit` and `offset` query parameters. + The organizations are ordered by descending creation date. + Most recent organizations will be returned first. + + :param limit: Applies a limit to the number of results returned. Can be used for paginating the results together with `offset`. + :param offset: Skip the first `offset` results when paginating. Needs to be an integer greater or equal to zero. To be used in conjunction with `limit`. + :param include_members_count: Flag to denote whether the member counts of each organization should be included in the response or not. + :param query: Returns organizations with ID, name, or slug that match the given query. Uses exact match for organization ID and partial match for name and slug. + :param order_by: Allows to return organizations in a particular order. At the moment, you can order the returned organizations either by their `name`, `created_at` or `members_count`. In order to specify the direction, you can use the `+/-` symbols prepended in the property to order by. For example, if you want organizations to be returned in descending order according to their `created_at` property, you can use `-created_at`. If you don't use `+` or `-`, then `+` is implied. Defaults to `-created_at`. + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.ListOrganizationsRequest( + limit=limit, + offset=offset, + include_members_count=include_members_count, + query=query, + order_by=order_by, + ) + + req = self.build_request( + method="GET", + path="/organizations", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=False, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="ListOrganizations", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","403","422","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.Organizations]) + if utils.match_response(http_res, ["400","403","422"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + def create( + self, *, + name: str, + created_by: str, + private_metadata: Optional[Union[models.CreateOrganizationPrivateMetadata, models.CreateOrganizationPrivateMetadataTypedDict]] = None, + public_metadata: Optional[Union[models.CreateOrganizationPublicMetadata, models.CreateOrganizationPublicMetadataTypedDict]] = None, + slug: Optional[str] = None, + max_allowed_memberships: Optional[int] = None, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.Organization: + r"""Create an organization + + Creates a new organization with the given name for an instance. + In order to successfully create an organization you need to provide the ID of the User who will become the organization administrator. + You can specify an optional slug for the new organization. + If provided, the organization slug can contain only lowercase alphanumeric characters (letters and digits) and the dash \"-\". + Organization slugs must be unique for the instance. + You can provide additional metadata for the organization and set any custom attribute you want. + Organizations support private and public metadata. + Private metadata can only be accessed from the Backend API. + Public metadata can be accessed from the Backend API, and are read-only from the Frontend API. + + :param name: The name of the new organization + :param created_by: The ID of the User who will become the administrator for the new organization + :param private_metadata: Metadata saved on the organization, accessible only from the Backend API + :param public_metadata: Metadata saved on the organization, read-only from the Frontend API and fully accessible (read/write) from the Backend API + :param slug: A slug for the new organization. Can contain only lowercase alphanumeric characters and the dash \"-\". Must be unique for the instance. + :param max_allowed_memberships: The maximum number of memberships allowed for this organization + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.CreateOrganizationRequestBody( + name=name, + created_by=created_by, + private_metadata=utils.unmarshal(private_metadata, models.CreateOrganizationPrivateMetadata) if not isinstance(private_metadata, BaseModel) and private_metadata is not None else private_metadata, + public_metadata=utils.unmarshal(public_metadata, models.CreateOrganizationPublicMetadata) if not isinstance(public_metadata, BaseModel) and public_metadata is not None else public_metadata, + slug=slug, + max_allowed_memberships=max_allowed_memberships, + ) + + req = self.build_request( + method="POST", + path="/organizations", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=False, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + get_serialized_body=lambda: utils.serialize_request_body(request, False, True, "json", Optional[models.CreateOrganizationRequestBody]), + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="CreateOrganization", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","403","422","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.Organization]) + if utils.match_response(http_res, ["400","403","422"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + async def create_async( + self, *, + name: str, + created_by: str, + private_metadata: Optional[Union[models.CreateOrganizationPrivateMetadata, models.CreateOrganizationPrivateMetadataTypedDict]] = None, + public_metadata: Optional[Union[models.CreateOrganizationPublicMetadata, models.CreateOrganizationPublicMetadataTypedDict]] = None, + slug: Optional[str] = None, + max_allowed_memberships: Optional[int] = None, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.Organization: + r"""Create an organization + + Creates a new organization with the given name for an instance. + In order to successfully create an organization you need to provide the ID of the User who will become the organization administrator. + You can specify an optional slug for the new organization. + If provided, the organization slug can contain only lowercase alphanumeric characters (letters and digits) and the dash \"-\". + Organization slugs must be unique for the instance. + You can provide additional metadata for the organization and set any custom attribute you want. + Organizations support private and public metadata. + Private metadata can only be accessed from the Backend API. + Public metadata can be accessed from the Backend API, and are read-only from the Frontend API. + + :param name: The name of the new organization + :param created_by: The ID of the User who will become the administrator for the new organization + :param private_metadata: Metadata saved on the organization, accessible only from the Backend API + :param public_metadata: Metadata saved on the organization, read-only from the Frontend API and fully accessible (read/write) from the Backend API + :param slug: A slug for the new organization. Can contain only lowercase alphanumeric characters and the dash \"-\". Must be unique for the instance. + :param max_allowed_memberships: The maximum number of memberships allowed for this organization + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.CreateOrganizationRequestBody( + name=name, + created_by=created_by, + private_metadata=utils.unmarshal(private_metadata, models.CreateOrganizationPrivateMetadata) if not isinstance(private_metadata, BaseModel) and private_metadata is not None else private_metadata, + public_metadata=utils.unmarshal(public_metadata, models.CreateOrganizationPublicMetadata) if not isinstance(public_metadata, BaseModel) and public_metadata is not None else public_metadata, + slug=slug, + max_allowed_memberships=max_allowed_memberships, + ) + + req = self.build_request( + method="POST", + path="/organizations", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=False, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + get_serialized_body=lambda: utils.serialize_request_body(request, False, True, "json", Optional[models.CreateOrganizationRequestBody]), + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="CreateOrganization", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","403","422","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.Organization]) + if utils.match_response(http_res, ["400","403","422"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + def get( + self, *, + organization_id: str, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.Organization: + r"""Retrieve an organization by ID or slug + + Fetches the organization whose ID or slug matches the provided `id_or_slug` URL query parameter. + + :param organization_id: The ID or slug of the organization + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.GetOrganizationRequest( + organization_id=organization_id, + ) + + req = self.build_request( + method="GET", + path="/organizations/{organization_id}", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="GetOrganization", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["403","404","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.Organization]) + if utils.match_response(http_res, ["403","404"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + async def get_async( + self, *, + organization_id: str, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.Organization: + r"""Retrieve an organization by ID or slug + + Fetches the organization whose ID or slug matches the provided `id_or_slug` URL query parameter. + + :param organization_id: The ID or slug of the organization + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.GetOrganizationRequest( + organization_id=organization_id, + ) + + req = self.build_request( + method="GET", + path="/organizations/{organization_id}", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="GetOrganization", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["403","404","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.Organization]) + if utils.match_response(http_res, ["403","404"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + def update( + self, *, + organization_id: str, + public_metadata: Optional[Union[models.UpdateOrganizationPublicMetadata, models.UpdateOrganizationPublicMetadataTypedDict]] = None, + private_metadata: Optional[Union[models.UpdateOrganizationPrivateMetadata, models.UpdateOrganizationPrivateMetadataTypedDict]] = None, + name: Optional[Nullable[str]] = None, + slug: Optional[Nullable[str]] = None, + max_allowed_memberships: Optional[Nullable[int]] = None, + admin_delete_enabled: Optional[Nullable[bool]] = None, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.Organization: + r"""Update an organization + + Updates an existing organization + + :param organization_id: The ID of the organization to update + :param public_metadata: Metadata saved on the organization, that is visible to both your frontend and backend. + :param private_metadata: Metadata saved on the organization that is only visible to your backend. + :param name: The new name of the organization + :param slug: The new slug of the organization, which needs to be unique in the instance + :param max_allowed_memberships: The maximum number of memberships allowed for this organization + :param admin_delete_enabled: If true, an admin can delete this organization with the Frontend API. + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.UpdateOrganizationRequest( + organization_id=organization_id, + request_body=models.UpdateOrganizationRequestBody( + public_metadata=utils.unmarshal(public_metadata, models.UpdateOrganizationPublicMetadata) if not isinstance(public_metadata, BaseModel) and public_metadata is not None else public_metadata, + private_metadata=utils.unmarshal(private_metadata, models.UpdateOrganizationPrivateMetadata) if not isinstance(private_metadata, BaseModel) and private_metadata is not None else private_metadata, + name=name, + slug=slug, + max_allowed_memberships=max_allowed_memberships, + admin_delete_enabled=admin_delete_enabled, + ), + ) + + req = self.build_request( + method="PATCH", + path="/organizations/{organization_id}", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=True, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + get_serialized_body=lambda: utils.serialize_request_body(request.request_body, False, False, "json", models.UpdateOrganizationRequestBody), + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="UpdateOrganization", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["402","404","422","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.Organization]) + if utils.match_response(http_res, ["402","404","422"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + async def update_async( + self, *, + organization_id: str, + public_metadata: Optional[Union[models.UpdateOrganizationPublicMetadata, models.UpdateOrganizationPublicMetadataTypedDict]] = None, + private_metadata: Optional[Union[models.UpdateOrganizationPrivateMetadata, models.UpdateOrganizationPrivateMetadataTypedDict]] = None, + name: Optional[Nullable[str]] = None, + slug: Optional[Nullable[str]] = None, + max_allowed_memberships: Optional[Nullable[int]] = None, + admin_delete_enabled: Optional[Nullable[bool]] = None, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.Organization: + r"""Update an organization + + Updates an existing organization + + :param organization_id: The ID of the organization to update + :param public_metadata: Metadata saved on the organization, that is visible to both your frontend and backend. + :param private_metadata: Metadata saved on the organization that is only visible to your backend. + :param name: The new name of the organization + :param slug: The new slug of the organization, which needs to be unique in the instance + :param max_allowed_memberships: The maximum number of memberships allowed for this organization + :param admin_delete_enabled: If true, an admin can delete this organization with the Frontend API. + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.UpdateOrganizationRequest( + organization_id=organization_id, + request_body=models.UpdateOrganizationRequestBody( + public_metadata=utils.unmarshal(public_metadata, models.UpdateOrganizationPublicMetadata) if not isinstance(public_metadata, BaseModel) and public_metadata is not None else public_metadata, + private_metadata=utils.unmarshal(private_metadata, models.UpdateOrganizationPrivateMetadata) if not isinstance(private_metadata, BaseModel) and private_metadata is not None else private_metadata, + name=name, + slug=slug, + max_allowed_memberships=max_allowed_memberships, + admin_delete_enabled=admin_delete_enabled, + ), + ) + + req = self.build_request( + method="PATCH", + path="/organizations/{organization_id}", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=True, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + get_serialized_body=lambda: utils.serialize_request_body(request.request_body, False, False, "json", models.UpdateOrganizationRequestBody), + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="UpdateOrganization", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["402","404","422","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.Organization]) + if utils.match_response(http_res, ["402","404","422"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + def delete( + self, *, + organization_id: str, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.DeletedObject: + r"""Delete an organization + + Deletes the given organization. + Please note that deleting an organization will also delete all memberships and invitations. + This is not reversible. + + :param organization_id: The ID of the organization to delete + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.DeleteOrganizationRequest( + organization_id=organization_id, + ) + + req = self.build_request( + method="DELETE", + path="/organizations/{organization_id}", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="DeleteOrganization", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["404","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.DeletedObject]) + if utils.match_response(http_res, "404", "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + async def delete_async( + self, *, + organization_id: str, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.DeletedObject: + r"""Delete an organization + + Deletes the given organization. + Please note that deleting an organization will also delete all memberships and invitations. + This is not reversible. + + :param organization_id: The ID of the organization to delete + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.DeleteOrganizationRequest( + organization_id=organization_id, + ) + + req = self.build_request( + method="DELETE", + path="/organizations/{organization_id}", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="DeleteOrganization", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["404","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.DeletedObject]) + if utils.match_response(http_res, "404", "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + def merge_metadata( + self, *, + organization_id: str, + public_metadata: Optional[Union[models.MergeOrganizationMetadataPublicMetadata, models.MergeOrganizationMetadataPublicMetadataTypedDict]] = None, + private_metadata: Optional[Union[models.MergeOrganizationMetadataPrivateMetadata, models.MergeOrganizationMetadataPrivateMetadataTypedDict]] = None, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.Organization: + r"""Merge and update metadata for an organization + + Update organization metadata attributes by merging existing values with the provided parameters. + Metadata values will be updated via a deep merge. + Deep meaning that any nested JSON objects will be merged as well. + You can remove metadata keys at any level by setting their value to `null`. + + :param organization_id: The ID of the organization for which metadata will be merged or updated + :param public_metadata: Metadata saved on the organization, that is visible to both your frontend and backend. The new object will be merged with the existing value. + :param private_metadata: Metadata saved on the organization that is only visible to your backend. The new object will be merged with the existing value. + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.MergeOrganizationMetadataRequest( + organization_id=organization_id, + request_body=models.MergeOrganizationMetadataRequestBody( + public_metadata=utils.unmarshal(public_metadata, models.MergeOrganizationMetadataPublicMetadata) if not isinstance(public_metadata, BaseModel) and public_metadata is not None else public_metadata, + private_metadata=utils.unmarshal(private_metadata, models.MergeOrganizationMetadataPrivateMetadata) if not isinstance(private_metadata, BaseModel) and private_metadata is not None else private_metadata, + ), + ) + + req = self.build_request( + method="PATCH", + path="/organizations/{organization_id}/metadata", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=True, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + get_serialized_body=lambda: utils.serialize_request_body(request.request_body, False, False, "json", models.MergeOrganizationMetadataRequestBody), + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="MergeOrganizationMetadata", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","401","404","422","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.Organization]) + if utils.match_response(http_res, ["400","401","404","422"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + async def merge_metadata_async( + self, *, + organization_id: str, + public_metadata: Optional[Union[models.MergeOrganizationMetadataPublicMetadata, models.MergeOrganizationMetadataPublicMetadataTypedDict]] = None, + private_metadata: Optional[Union[models.MergeOrganizationMetadataPrivateMetadata, models.MergeOrganizationMetadataPrivateMetadataTypedDict]] = None, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.Organization: + r"""Merge and update metadata for an organization + + Update organization metadata attributes by merging existing values with the provided parameters. + Metadata values will be updated via a deep merge. + Deep meaning that any nested JSON objects will be merged as well. + You can remove metadata keys at any level by setting their value to `null`. + + :param organization_id: The ID of the organization for which metadata will be merged or updated + :param public_metadata: Metadata saved on the organization, that is visible to both your frontend and backend. The new object will be merged with the existing value. + :param private_metadata: Metadata saved on the organization that is only visible to your backend. The new object will be merged with the existing value. + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.MergeOrganizationMetadataRequest( + organization_id=organization_id, + request_body=models.MergeOrganizationMetadataRequestBody( + public_metadata=utils.unmarshal(public_metadata, models.MergeOrganizationMetadataPublicMetadata) if not isinstance(public_metadata, BaseModel) and public_metadata is not None else public_metadata, + private_metadata=utils.unmarshal(private_metadata, models.MergeOrganizationMetadataPrivateMetadata) if not isinstance(private_metadata, BaseModel) and private_metadata is not None else private_metadata, + ), + ) + + req = self.build_request( + method="PATCH", + path="/organizations/{organization_id}/metadata", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=True, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + get_serialized_body=lambda: utils.serialize_request_body(request.request_body, False, False, "json", models.MergeOrganizationMetadataRequestBody), + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="MergeOrganizationMetadata", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","401","404","422","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.Organization]) + if utils.match_response(http_res, ["400","401","404","422"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + def upload_logo( + self, *, + organization_id: str, + uploader_user_id: str, + file: Union[models.UploadOrganizationLogoFile, models.UploadOrganizationLogoFileTypedDict], + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.OrganizationWithLogo: + r"""Upload a logo for the organization + + Set or replace an organization's logo, by uploading an image file. + This endpoint uses the `multipart/form-data` request content type and accepts a file of image type. + The file size cannot exceed 10MB. + Only the following file content types are supported: `image/jpeg`, `image/png`, `image/gif`, `image/webp`, `image/x-icon`, `image/vnd.microsoft.icon`. + + :param organization_id: The ID of the organization for which to upload a logo + :param uploader_user_id: The ID of the user that will be credited with the image upload. + :param file: + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.UploadOrganizationLogoRequest( + organization_id=organization_id, + request_body=models.UploadOrganizationLogoRequestBody( + uploader_user_id=uploader_user_id, + file=utils.unmarshal(file, models.UploadOrganizationLogoFile) if not isinstance(file, BaseModel) else file, + ), + ) + + req = self.build_request( + method="PUT", + path="/organizations/{organization_id}/logo", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + get_serialized_body=lambda: utils.serialize_request_body(request.request_body, False, True, "multipart", Optional[models.UploadOrganizationLogoRequestBody]), + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="UploadOrganizationLogo", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","403","404","413","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.OrganizationWithLogo]) + if utils.match_response(http_res, ["400","403","404","413"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + async def upload_logo_async( + self, *, + organization_id: str, + uploader_user_id: str, + file: Union[models.UploadOrganizationLogoFile, models.UploadOrganizationLogoFileTypedDict], + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.OrganizationWithLogo: + r"""Upload a logo for the organization + + Set or replace an organization's logo, by uploading an image file. + This endpoint uses the `multipart/form-data` request content type and accepts a file of image type. + The file size cannot exceed 10MB. + Only the following file content types are supported: `image/jpeg`, `image/png`, `image/gif`, `image/webp`, `image/x-icon`, `image/vnd.microsoft.icon`. + + :param organization_id: The ID of the organization for which to upload a logo + :param uploader_user_id: The ID of the user that will be credited with the image upload. + :param file: + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.UploadOrganizationLogoRequest( + organization_id=organization_id, + request_body=models.UploadOrganizationLogoRequestBody( + uploader_user_id=uploader_user_id, + file=utils.unmarshal(file, models.UploadOrganizationLogoFile) if not isinstance(file, BaseModel) else file, + ), + ) + + req = self.build_request( + method="PUT", + path="/organizations/{organization_id}/logo", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + get_serialized_body=lambda: utils.serialize_request_body(request.request_body, False, True, "multipart", Optional[models.UploadOrganizationLogoRequestBody]), + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="UploadOrganizationLogo", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","403","404","413","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.OrganizationWithLogo]) + if utils.match_response(http_res, ["400","403","404","413"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + def delete_logo( + self, *, + organization_id: str, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.Organization: + r"""Delete the organization's logo. + + :param organization_id: The ID of the organization for which the logo will be deleted. + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.DeleteOrganizationLogoRequest( + organization_id=organization_id, + ) + + req = self.build_request( + method="DELETE", + path="/organizations/{organization_id}/logo", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="DeleteOrganizationLogo", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["404","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.Organization]) + if utils.match_response(http_res, "404", "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + async def delete_logo_async( + self, *, + organization_id: str, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.Organization: + r"""Delete the organization's logo. + + :param organization_id: The ID of the organization for which the logo will be deleted. + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.DeleteOrganizationLogoRequest( + organization_id=organization_id, + ) + + req = self.build_request( + method="DELETE", + path="/organizations/{organization_id}/logo", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="DeleteOrganizationLogo", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["404","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.Organization]) + if utils.match_response(http_res, "404", "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + diff --git a/src/clerk/phonenumbers.py b/src/clerk/phonenumbers.py new file mode 100644 index 0000000..2fefcf8 --- /dev/null +++ b/src/clerk/phonenumbers.py @@ -0,0 +1,677 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from .basesdk import BaseSDK +from clerk import models +from clerk._hooks import HookContext +from clerk.types import Nullable, UNSET +import clerk.utils as utils +from typing import Optional + +class PhoneNumbers(BaseSDK): + + + def create( + self, *, + user_id: Optional[str] = None, + phone_number: Optional[str] = None, + verified: Optional[Nullable[bool]] = None, + primary: Optional[Nullable[bool]] = None, + reserved_for_second_factor: Optional[Nullable[bool]] = None, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.PhoneNumber: + r"""Create a phone number + + Create a new phone number + + :param user_id: The ID representing the user + :param phone_number: The new phone number. Must adhere to the E.164 standard for phone number format. + :param verified: When created, the phone number will be marked as verified. + :param primary: Create this phone number as the primary phone number for the user. Default: false, unless it is the first phone number. + :param reserved_for_second_factor: Create this phone number as reserved for multi-factor authentication. The phone number must also be verified. If there are no other reserved second factors, the phone number will be set as the default second factor. + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.CreatePhoneNumberRequestBody( + user_id=user_id, + phone_number=phone_number, + verified=verified, + primary=primary, + reserved_for_second_factor=reserved_for_second_factor, + ) + + req = self.build_request( + method="POST", + path="/phone_numbers", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=False, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + get_serialized_body=lambda: utils.serialize_request_body(request, False, True, "json", Optional[models.CreatePhoneNumberRequestBody]), + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="CreatePhoneNumber", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","401","403","404","422","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.PhoneNumber]) + if utils.match_response(http_res, ["400","401","403","404","422"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + async def create_async( + self, *, + user_id: Optional[str] = None, + phone_number: Optional[str] = None, + verified: Optional[Nullable[bool]] = None, + primary: Optional[Nullable[bool]] = None, + reserved_for_second_factor: Optional[Nullable[bool]] = None, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.PhoneNumber: + r"""Create a phone number + + Create a new phone number + + :param user_id: The ID representing the user + :param phone_number: The new phone number. Must adhere to the E.164 standard for phone number format. + :param verified: When created, the phone number will be marked as verified. + :param primary: Create this phone number as the primary phone number for the user. Default: false, unless it is the first phone number. + :param reserved_for_second_factor: Create this phone number as reserved for multi-factor authentication. The phone number must also be verified. If there are no other reserved second factors, the phone number will be set as the default second factor. + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.CreatePhoneNumberRequestBody( + user_id=user_id, + phone_number=phone_number, + verified=verified, + primary=primary, + reserved_for_second_factor=reserved_for_second_factor, + ) + + req = self.build_request( + method="POST", + path="/phone_numbers", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=False, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + get_serialized_body=lambda: utils.serialize_request_body(request, False, True, "json", Optional[models.CreatePhoneNumberRequestBody]), + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="CreatePhoneNumber", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","401","403","404","422","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.PhoneNumber]) + if utils.match_response(http_res, ["400","401","403","404","422"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + def get( + self, *, + phone_number_id: str, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.PhoneNumber: + r"""Retrieve a phone number + + Returns the details of a phone number + + :param phone_number_id: The ID of the phone number to retrieve + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.GetPhoneNumberRequest( + phone_number_id=phone_number_id, + ) + + req = self.build_request( + method="GET", + path="/phone_numbers/{phone_number_id}", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="GetPhoneNumber", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","401","403","404","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.PhoneNumber]) + if utils.match_response(http_res, ["400","401","403","404"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + async def get_async( + self, *, + phone_number_id: str, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.PhoneNumber: + r"""Retrieve a phone number + + Returns the details of a phone number + + :param phone_number_id: The ID of the phone number to retrieve + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.GetPhoneNumberRequest( + phone_number_id=phone_number_id, + ) + + req = self.build_request( + method="GET", + path="/phone_numbers/{phone_number_id}", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="GetPhoneNumber", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","401","403","404","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.PhoneNumber]) + if utils.match_response(http_res, ["400","401","403","404"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + def delete( + self, *, + phone_number_id: str, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.DeletedObject: + r"""Delete a phone number + + Delete the phone number with the given ID + + :param phone_number_id: The ID of the phone number to delete + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.DeletePhoneNumberRequest( + phone_number_id=phone_number_id, + ) + + req = self.build_request( + method="DELETE", + path="/phone_numbers/{phone_number_id}", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="DeletePhoneNumber", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","401","403","404","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.DeletedObject]) + if utils.match_response(http_res, ["400","401","403","404"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + async def delete_async( + self, *, + phone_number_id: str, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.DeletedObject: + r"""Delete a phone number + + Delete the phone number with the given ID + + :param phone_number_id: The ID of the phone number to delete + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.DeletePhoneNumberRequest( + phone_number_id=phone_number_id, + ) + + req = self.build_request( + method="DELETE", + path="/phone_numbers/{phone_number_id}", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="DeletePhoneNumber", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","401","403","404","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.DeletedObject]) + if utils.match_response(http_res, ["400","401","403","404"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + def update( + self, *, + phone_number_id: str, + verified: Optional[Nullable[bool]] = None, + primary: Optional[Nullable[bool]] = None, + reserved_for_second_factor: Optional[Nullable[bool]] = None, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.PhoneNumber: + r"""Update a phone number + + Updates a phone number + + :param phone_number_id: The ID of the phone number to update + :param verified: The phone number will be marked as verified. + :param primary: Set this phone number as the primary phone number for the user. + :param reserved_for_second_factor: Set this phone number as reserved for multi-factor authentication. The phone number must also be verified. If there are no other reserved second factors, the phone number will be set as the default second factor. + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.UpdatePhoneNumberRequest( + phone_number_id=phone_number_id, + request_body=models.UpdatePhoneNumberRequestBody( + verified=verified, + primary=primary, + reserved_for_second_factor=reserved_for_second_factor, + ), + ) + + req = self.build_request( + method="PATCH", + path="/phone_numbers/{phone_number_id}", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + get_serialized_body=lambda: utils.serialize_request_body(request.request_body, False, True, "json", Optional[models.UpdatePhoneNumberRequestBody]), + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="UpdatePhoneNumber", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","401","403","404","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.PhoneNumber]) + if utils.match_response(http_res, ["400","401","403","404"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + async def update_async( + self, *, + phone_number_id: str, + verified: Optional[Nullable[bool]] = None, + primary: Optional[Nullable[bool]] = None, + reserved_for_second_factor: Optional[Nullable[bool]] = None, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.PhoneNumber: + r"""Update a phone number + + Updates a phone number + + :param phone_number_id: The ID of the phone number to update + :param verified: The phone number will be marked as verified. + :param primary: Set this phone number as the primary phone number for the user. + :param reserved_for_second_factor: Set this phone number as reserved for multi-factor authentication. The phone number must also be verified. If there are no other reserved second factors, the phone number will be set as the default second factor. + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.UpdatePhoneNumberRequest( + phone_number_id=phone_number_id, + request_body=models.UpdatePhoneNumberRequestBody( + verified=verified, + primary=primary, + reserved_for_second_factor=reserved_for_second_factor, + ), + ) + + req = self.build_request( + method="PATCH", + path="/phone_numbers/{phone_number_id}", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + get_serialized_body=lambda: utils.serialize_request_body(request.request_body, False, True, "json", Optional[models.UpdatePhoneNumberRequestBody]), + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="UpdatePhoneNumber", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","401","403","404","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.PhoneNumber]) + if utils.match_response(http_res, ["400","401","403","404"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + diff --git a/src/clerk/proxychecks.py b/src/clerk/proxychecks.py new file mode 100644 index 0000000..71b5bc4 --- /dev/null +++ b/src/clerk/proxychecks.py @@ -0,0 +1,187 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from .basesdk import BaseSDK +from clerk import models +from clerk._hooks import HookContext +from clerk.types import Nullable, UNSET +import clerk.utils as utils +from typing import Optional + +class ProxyChecks(BaseSDK): + + + def verify( + self, *, + domain_id: Optional[str] = None, + proxy_url: Optional[str] = None, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.ProxyCheck: + r"""Verify the proxy configuration for your domain + + This endpoint can be used to validate that a proxy-enabled domain is operational. + It tries to verify that the proxy URL provided in the parameters maps to a functional proxy that can reach the Clerk Frontend API. + + You can use this endpoint before you set a proxy URL for a domain. This way you can ensure that switching to proxy-based + configuration will not lead to downtime for your instance. + + The `proxy_url` parameter allows for testing proxy configurations for domains that don't have a proxy URL yet, or operate on + a different proxy URL than the one provided. It can also be used to re-validate a domain that is already configured to work with a proxy. + + :param domain_id: The ID of the domain that will be updated. + :param proxy_url: The full URL of the proxy which will forward requests to the Clerk Frontend API for this domain. e.g. https://example.com/__clerk + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.VerifyDomainProxyRequestBody( + domain_id=domain_id, + proxy_url=proxy_url, + ) + + req = self.build_request( + method="POST", + path="/proxy_checks", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=False, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + get_serialized_body=lambda: utils.serialize_request_body(request, False, True, "json", Optional[models.VerifyDomainProxyRequestBody]), + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="VerifyDomainProxy", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","422","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.ProxyCheck]) + if utils.match_response(http_res, ["400","422"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + async def verify_async( + self, *, + domain_id: Optional[str] = None, + proxy_url: Optional[str] = None, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.ProxyCheck: + r"""Verify the proxy configuration for your domain + + This endpoint can be used to validate that a proxy-enabled domain is operational. + It tries to verify that the proxy URL provided in the parameters maps to a functional proxy that can reach the Clerk Frontend API. + + You can use this endpoint before you set a proxy URL for a domain. This way you can ensure that switching to proxy-based + configuration will not lead to downtime for your instance. + + The `proxy_url` parameter allows for testing proxy configurations for domains that don't have a proxy URL yet, or operate on + a different proxy URL than the one provided. It can also be used to re-validate a domain that is already configured to work with a proxy. + + :param domain_id: The ID of the domain that will be updated. + :param proxy_url: The full URL of the proxy which will forward requests to the Clerk Frontend API for this domain. e.g. https://example.com/__clerk + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.VerifyDomainProxyRequestBody( + domain_id=domain_id, + proxy_url=proxy_url, + ) + + req = self.build_request( + method="POST", + path="/proxy_checks", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=False, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + get_serialized_body=lambda: utils.serialize_request_body(request, False, True, "json", Optional[models.VerifyDomainProxyRequestBody]), + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="VerifyDomainProxy", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","422","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.ProxyCheck]) + if utils.match_response(http_res, ["400","422"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + diff --git a/src/clerk/redirecturls.py b/src/clerk/redirecturls.py new file mode 100644 index 0000000..546447b --- /dev/null +++ b/src/clerk/redirecturls.py @@ -0,0 +1,609 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from .basesdk import BaseSDK +from clerk import models +from clerk._hooks import HookContext +from clerk.types import Nullable, UNSET +import clerk.utils as utils +from typing import List, Optional + +class RedirectUrls(BaseSDK): + + + def list( + self, *, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> List[models.RedirectURL]: + r"""List all redirect URLs + + Lists all whitelisted redirect_urls for the instance + + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + req = self.build_request( + method="GET", + path="/redirect_urls", + base_url=base_url, + url_variables=url_variables, + request=None, + request_body_required=False, + request_has_path_params=False, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="ListRedirectURLs", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[List[models.RedirectURL]]) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + async def list_async( + self, *, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> List[models.RedirectURL]: + r"""List all redirect URLs + + Lists all whitelisted redirect_urls for the instance + + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + req = self.build_request( + method="GET", + path="/redirect_urls", + base_url=base_url, + url_variables=url_variables, + request=None, + request_body_required=False, + request_has_path_params=False, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="ListRedirectURLs", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[List[models.RedirectURL]]) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + def create( + self, *, + url: Optional[str] = None, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.RedirectURL: + r"""Create a redirect URL + + Create a redirect URL + + :param url: The full url value prefixed with `https://` or a custom scheme e.g. `\"https://my-app.com/oauth-callback\"` or `\"my-app://oauth-callback\"` + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.CreateRedirectURLRequestBody( + url=url, + ) + + req = self.build_request( + method="POST", + path="/redirect_urls", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=False, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + get_serialized_body=lambda: utils.serialize_request_body(request, False, True, "json", Optional[models.CreateRedirectURLRequestBody]), + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="CreateRedirectURL", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","422","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.RedirectURL]) + if utils.match_response(http_res, ["400","422"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + async def create_async( + self, *, + url: Optional[str] = None, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.RedirectURL: + r"""Create a redirect URL + + Create a redirect URL + + :param url: The full url value prefixed with `https://` or a custom scheme e.g. `\"https://my-app.com/oauth-callback\"` or `\"my-app://oauth-callback\"` + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.CreateRedirectURLRequestBody( + url=url, + ) + + req = self.build_request( + method="POST", + path="/redirect_urls", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=False, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + get_serialized_body=lambda: utils.serialize_request_body(request, False, True, "json", Optional[models.CreateRedirectURLRequestBody]), + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="CreateRedirectURL", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","422","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.RedirectURL]) + if utils.match_response(http_res, ["400","422"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + def get( + self, *, + id: str, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.RedirectURL: + r"""Retrieve a redirect URL + + Retrieve the details of the redirect URL with the given ID + + :param id: The ID of the redirect URL + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.GetRedirectURLRequest( + id=id, + ) + + req = self.build_request( + method="GET", + path="/redirect_urls/{id}", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="GetRedirectURL", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["404","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.RedirectURL]) + if utils.match_response(http_res, "404", "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + async def get_async( + self, *, + id: str, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.RedirectURL: + r"""Retrieve a redirect URL + + Retrieve the details of the redirect URL with the given ID + + :param id: The ID of the redirect URL + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.GetRedirectURLRequest( + id=id, + ) + + req = self.build_request( + method="GET", + path="/redirect_urls/{id}", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="GetRedirectURL", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["404","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.RedirectURL]) + if utils.match_response(http_res, "404", "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + def delete( + self, *, + id: str, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.DeletedObject: + r"""Delete a redirect URL + + Remove the selected redirect URL from the whitelist of the instance + + :param id: The ID of the redirect URL + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.DeleteRedirectURLRequest( + id=id, + ) + + req = self.build_request( + method="DELETE", + path="/redirect_urls/{id}", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="DeleteRedirectURL", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["404","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.DeletedObject]) + if utils.match_response(http_res, "404", "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + async def delete_async( + self, *, + id: str, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.DeletedObject: + r"""Delete a redirect URL + + Remove the selected redirect URL from the whitelist of the instance + + :param id: The ID of the redirect URL + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.DeleteRedirectURLRequest( + id=id, + ) + + req = self.build_request( + method="DELETE", + path="/redirect_urls/{id}", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="DeleteRedirectURL", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["404","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.DeletedObject]) + if utils.match_response(http_res, "404", "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + diff --git a/src/clerk/samlconnections_sdk.py b/src/clerk/samlconnections_sdk.py new file mode 100644 index 0000000..596a524 --- /dev/null +++ b/src/clerk/samlconnections_sdk.py @@ -0,0 +1,966 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from .basesdk import BaseSDK +from clerk import models +from clerk._hooks import HookContext +from clerk.types import BaseModel, Nullable, UNSET +import clerk.utils as utils +from jsonpath import JSONPath +from typing import Any, Dict, Optional, Union + +class SamlConnectionsSDK(BaseSDK): + + + def list( + self, *, + limit: Optional[float] = None, + offset: Optional[float] = None, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.ListSAMLConnectionsResponse: + r"""Get a list of SAML Connections for an instance + + Returns the list of SAML Connections for an instance. + Results can be paginated using the optional `limit` and `offset` query parameters. + The SAML Connections are ordered by descending creation date and the most recent will be returned first. + + :param limit: Applies a limit to the number of results returned. Can be used for paginating the results together with `offset`. + :param offset: Skip the first `offset` results when paginating. Needs to be an integer greater or equal to zero. To be used in conjunction with `limit`. + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.ListSAMLConnectionsRequest( + limit=limit, + offset=offset, + ) + + req = self.build_request( + method="GET", + path="/saml_connections", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=False, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="ListSAMLConnections", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["402","403","422","4XX","5XX"], + retry_config=retry_config + ) + + def next_func() -> Optional[models.ListSAMLConnectionsResponse]: + body = utils.unmarshal_json(http_res.text, Dict[Any, Any]) + offset = request.offset if not request.offset is None else 0 + + if not http_res.text: + return None + results = JSONPath("$").parse(body) + if len(results) == 0 or len(results[0]) == 0: + return None + limit = request.limit if not request.limit is None else 0 + if len(results[0]) < limit: + return None + next_offset = offset + len(results[0]) + + return self.list( + limit=limit, + offset=next_offset, + retries=retries, + ) + + res = models.ListSAMLConnectionsResponse(result=None, next=next_func) + + if utils.match_response(http_res, "200", "application/json"): + res.result = utils.unmarshal_json(http_res.text, Optional[models.SAMLConnections]) + elif utils.match_response(http_res, ["402","403","422"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + elif utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + else: + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + return res + + + async def list_async( + self, *, + limit: Optional[float] = None, + offset: Optional[float] = None, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.ListSAMLConnectionsResponse: + r"""Get a list of SAML Connections for an instance + + Returns the list of SAML Connections for an instance. + Results can be paginated using the optional `limit` and `offset` query parameters. + The SAML Connections are ordered by descending creation date and the most recent will be returned first. + + :param limit: Applies a limit to the number of results returned. Can be used for paginating the results together with `offset`. + :param offset: Skip the first `offset` results when paginating. Needs to be an integer greater or equal to zero. To be used in conjunction with `limit`. + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.ListSAMLConnectionsRequest( + limit=limit, + offset=offset, + ) + + req = self.build_request( + method="GET", + path="/saml_connections", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=False, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="ListSAMLConnections", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["402","403","422","4XX","5XX"], + retry_config=retry_config + ) + + def next_func() -> Optional[models.ListSAMLConnectionsResponse]: + body = utils.unmarshal_json(http_res.text, Dict[Any, Any]) + offset = request.offset if not request.offset is None else 0 + + if not http_res.text: + return None + results = JSONPath("$").parse(body) + if len(results) == 0 or len(results[0]) == 0: + return None + limit = request.limit if not request.limit is None else 0 + if len(results[0]) < limit: + return None + next_offset = offset + len(results[0]) + + return self.list( + limit=limit, + offset=next_offset, + retries=retries, + ) + + res = models.ListSAMLConnectionsResponse(result=None, next=next_func) + + if utils.match_response(http_res, "200", "application/json"): + res.result = utils.unmarshal_json(http_res.text, Optional[models.SAMLConnections]) + elif utils.match_response(http_res, ["402","403","422"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + elif utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + else: + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + return res + + + def create( + self, *, + name: str, + domain: str, + provider: models.Provider, + idp_entity_id: Optional[Nullable[str]] = None, + idp_sso_url: Optional[Nullable[str]] = None, + idp_certificate: Optional[Nullable[str]] = None, + idp_metadata_url: Optional[Nullable[str]] = None, + idp_metadata: Optional[Nullable[str]] = None, + attribute_mapping: Optional[Union[Nullable[models.CreateSAMLConnectionAttributeMapping], Nullable[models.CreateSAMLConnectionAttributeMappingTypedDict]]] = None, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.SAMLConnection: + r"""Create a SAML Connection + + Create a new SAML Connection. + + :param name: The name to use as a label for this SAML Connection + :param domain: The domain of your organization. Sign in flows using an email with this domain, will use this SAML Connection. + :param provider: The IdP provider of the connection. + :param idp_entity_id: The Entity ID as provided by the IdP + :param idp_sso_url: The Single-Sign On URL as provided by the IdP + :param idp_certificate: The X.509 certificate as provided by the IdP + :param idp_metadata_url: The URL which serves the IdP metadata. If present, it takes priority over the corresponding individual properties + :param idp_metadata: The XML content of the IdP metadata file. If present, it takes priority over the corresponding individual properties + :param attribute_mapping: Define the attribute name mapping between Identity Provider and Clerk's user properties + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.CreateSAMLConnectionRequestBody( + name=name, + domain=domain, + provider=provider, + idp_entity_id=idp_entity_id, + idp_sso_url=idp_sso_url, + idp_certificate=idp_certificate, + idp_metadata_url=idp_metadata_url, + idp_metadata=idp_metadata, + attribute_mapping=utils.unmarshal(attribute_mapping, models.CreateSAMLConnectionAttributeMapping) if not isinstance(attribute_mapping, BaseModel) and attribute_mapping is not None else attribute_mapping, + ) + + req = self.build_request( + method="POST", + path="/saml_connections", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=False, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + get_serialized_body=lambda: utils.serialize_request_body(request, False, True, "json", Optional[models.CreateSAMLConnectionRequestBody]), + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="CreateSAMLConnection", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["402","403","422","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.SAMLConnection]) + if utils.match_response(http_res, ["402","403","422"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + async def create_async( + self, *, + name: str, + domain: str, + provider: models.Provider, + idp_entity_id: Optional[Nullable[str]] = None, + idp_sso_url: Optional[Nullable[str]] = None, + idp_certificate: Optional[Nullable[str]] = None, + idp_metadata_url: Optional[Nullable[str]] = None, + idp_metadata: Optional[Nullable[str]] = None, + attribute_mapping: Optional[Union[Nullable[models.CreateSAMLConnectionAttributeMapping], Nullable[models.CreateSAMLConnectionAttributeMappingTypedDict]]] = None, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.SAMLConnection: + r"""Create a SAML Connection + + Create a new SAML Connection. + + :param name: The name to use as a label for this SAML Connection + :param domain: The domain of your organization. Sign in flows using an email with this domain, will use this SAML Connection. + :param provider: The IdP provider of the connection. + :param idp_entity_id: The Entity ID as provided by the IdP + :param idp_sso_url: The Single-Sign On URL as provided by the IdP + :param idp_certificate: The X.509 certificate as provided by the IdP + :param idp_metadata_url: The URL which serves the IdP metadata. If present, it takes priority over the corresponding individual properties + :param idp_metadata: The XML content of the IdP metadata file. If present, it takes priority over the corresponding individual properties + :param attribute_mapping: Define the attribute name mapping between Identity Provider and Clerk's user properties + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.CreateSAMLConnectionRequestBody( + name=name, + domain=domain, + provider=provider, + idp_entity_id=idp_entity_id, + idp_sso_url=idp_sso_url, + idp_certificate=idp_certificate, + idp_metadata_url=idp_metadata_url, + idp_metadata=idp_metadata, + attribute_mapping=utils.unmarshal(attribute_mapping, models.CreateSAMLConnectionAttributeMapping) if not isinstance(attribute_mapping, BaseModel) and attribute_mapping is not None else attribute_mapping, + ) + + req = self.build_request( + method="POST", + path="/saml_connections", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=False, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + get_serialized_body=lambda: utils.serialize_request_body(request, False, True, "json", Optional[models.CreateSAMLConnectionRequestBody]), + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="CreateSAMLConnection", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["402","403","422","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.SAMLConnection]) + if utils.match_response(http_res, ["402","403","422"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + def get( + self, *, + saml_connection_id: str, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.SAMLConnection: + r"""Retrieve a SAML Connection by ID + + Fetches the SAML Connection whose ID matches the provided `saml_connection_id` in the path. + + :param saml_connection_id: The ID of the SAML Connection + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.GetSAMLConnectionRequest( + saml_connection_id=saml_connection_id, + ) + + req = self.build_request( + method="GET", + path="/saml_connections/{saml_connection_id}", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="GetSAMLConnection", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["402","403","404","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.SAMLConnection]) + if utils.match_response(http_res, ["402","403","404"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + async def get_async( + self, *, + saml_connection_id: str, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.SAMLConnection: + r"""Retrieve a SAML Connection by ID + + Fetches the SAML Connection whose ID matches the provided `saml_connection_id` in the path. + + :param saml_connection_id: The ID of the SAML Connection + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.GetSAMLConnectionRequest( + saml_connection_id=saml_connection_id, + ) + + req = self.build_request( + method="GET", + path="/saml_connections/{saml_connection_id}", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="GetSAMLConnection", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["402","403","404","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.SAMLConnection]) + if utils.match_response(http_res, ["402","403","404"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + def update( + self, *, + saml_connection_id: str, + name: Optional[Nullable[str]] = None, + domain: Optional[Nullable[str]] = None, + idp_entity_id: Optional[Nullable[str]] = None, + idp_sso_url: Optional[Nullable[str]] = None, + idp_certificate: Optional[Nullable[str]] = None, + idp_metadata_url: Optional[Nullable[str]] = None, + idp_metadata: Optional[Nullable[str]] = None, + attribute_mapping: Optional[Union[Nullable[models.UpdateSAMLConnectionAttributeMapping], Nullable[models.UpdateSAMLConnectionAttributeMappingTypedDict]]] = None, + active: Optional[Nullable[bool]] = None, + sync_user_attributes: Optional[Nullable[bool]] = None, + allow_subdomains: Optional[Nullable[bool]] = None, + allow_idp_initiated: Optional[Nullable[bool]] = None, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.SAMLConnection: + r"""Update a SAML Connection + + Updates the SAML Connection whose ID matches the provided `id` in the path. + + :param saml_connection_id: The ID of the SAML Connection to update + :param name: The name of the new SAML Connection + :param domain: The domain to use for the new SAML Connection + :param idp_entity_id: The entity id as provided by the IdP + :param idp_sso_url: The SSO url as provided by the IdP + :param idp_certificate: The x509 certificated as provided by the IdP + :param idp_metadata_url: The URL which serves the IdP metadata. If present, it takes priority over the corresponding individual properties and replaces them + :param idp_metadata: The XML content of the IdP metadata file. If present, it takes priority over the corresponding individual properties + :param attribute_mapping: Define the atrtibute name mapping between Identity Provider and Clerk's user properties + :param active: Activate or de-activate the SAML Connection + :param sync_user_attributes: Controls whether to update the user's attributes in each sign-in + :param allow_subdomains: Allow users with an email address subdomain to use this connection in order to authenticate + :param allow_idp_initiated: Enable or deactivate IdP-initiated flows + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.UpdateSAMLConnectionRequest( + saml_connection_id=saml_connection_id, + request_body=models.UpdateSAMLConnectionRequestBody( + name=name, + domain=domain, + idp_entity_id=idp_entity_id, + idp_sso_url=idp_sso_url, + idp_certificate=idp_certificate, + idp_metadata_url=idp_metadata_url, + idp_metadata=idp_metadata, + attribute_mapping=utils.unmarshal(attribute_mapping, models.UpdateSAMLConnectionAttributeMapping) if not isinstance(attribute_mapping, BaseModel) and attribute_mapping is not None else attribute_mapping, + active=active, + sync_user_attributes=sync_user_attributes, + allow_subdomains=allow_subdomains, + allow_idp_initiated=allow_idp_initiated, + ), + ) + + req = self.build_request( + method="PATCH", + path="/saml_connections/{saml_connection_id}", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=True, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + get_serialized_body=lambda: utils.serialize_request_body(request.request_body, False, False, "json", models.UpdateSAMLConnectionRequestBody), + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="UpdateSAMLConnection", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["402","403","404","422","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.SAMLConnection]) + if utils.match_response(http_res, ["402","403","404","422"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + async def update_async( + self, *, + saml_connection_id: str, + name: Optional[Nullable[str]] = None, + domain: Optional[Nullable[str]] = None, + idp_entity_id: Optional[Nullable[str]] = None, + idp_sso_url: Optional[Nullable[str]] = None, + idp_certificate: Optional[Nullable[str]] = None, + idp_metadata_url: Optional[Nullable[str]] = None, + idp_metadata: Optional[Nullable[str]] = None, + attribute_mapping: Optional[Union[Nullable[models.UpdateSAMLConnectionAttributeMapping], Nullable[models.UpdateSAMLConnectionAttributeMappingTypedDict]]] = None, + active: Optional[Nullable[bool]] = None, + sync_user_attributes: Optional[Nullable[bool]] = None, + allow_subdomains: Optional[Nullable[bool]] = None, + allow_idp_initiated: Optional[Nullable[bool]] = None, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.SAMLConnection: + r"""Update a SAML Connection + + Updates the SAML Connection whose ID matches the provided `id` in the path. + + :param saml_connection_id: The ID of the SAML Connection to update + :param name: The name of the new SAML Connection + :param domain: The domain to use for the new SAML Connection + :param idp_entity_id: The entity id as provided by the IdP + :param idp_sso_url: The SSO url as provided by the IdP + :param idp_certificate: The x509 certificated as provided by the IdP + :param idp_metadata_url: The URL which serves the IdP metadata. If present, it takes priority over the corresponding individual properties and replaces them + :param idp_metadata: The XML content of the IdP metadata file. If present, it takes priority over the corresponding individual properties + :param attribute_mapping: Define the atrtibute name mapping between Identity Provider and Clerk's user properties + :param active: Activate or de-activate the SAML Connection + :param sync_user_attributes: Controls whether to update the user's attributes in each sign-in + :param allow_subdomains: Allow users with an email address subdomain to use this connection in order to authenticate + :param allow_idp_initiated: Enable or deactivate IdP-initiated flows + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.UpdateSAMLConnectionRequest( + saml_connection_id=saml_connection_id, + request_body=models.UpdateSAMLConnectionRequestBody( + name=name, + domain=domain, + idp_entity_id=idp_entity_id, + idp_sso_url=idp_sso_url, + idp_certificate=idp_certificate, + idp_metadata_url=idp_metadata_url, + idp_metadata=idp_metadata, + attribute_mapping=utils.unmarshal(attribute_mapping, models.UpdateSAMLConnectionAttributeMapping) if not isinstance(attribute_mapping, BaseModel) and attribute_mapping is not None else attribute_mapping, + active=active, + sync_user_attributes=sync_user_attributes, + allow_subdomains=allow_subdomains, + allow_idp_initiated=allow_idp_initiated, + ), + ) + + req = self.build_request( + method="PATCH", + path="/saml_connections/{saml_connection_id}", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=True, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + get_serialized_body=lambda: utils.serialize_request_body(request.request_body, False, False, "json", models.UpdateSAMLConnectionRequestBody), + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="UpdateSAMLConnection", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["402","403","404","422","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.SAMLConnection]) + if utils.match_response(http_res, ["402","403","404","422"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + def delete( + self, *, + saml_connection_id: str, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.DeletedObject: + r"""Delete a SAML Connection + + Deletes the SAML Connection whose ID matches the provided `id` in the path. + + :param saml_connection_id: The ID of the SAML Connection to delete + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.DeleteSAMLConnectionRequest( + saml_connection_id=saml_connection_id, + ) + + req = self.build_request( + method="DELETE", + path="/saml_connections/{saml_connection_id}", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="DeleteSAMLConnection", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["402","403","404","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.DeletedObject]) + if utils.match_response(http_res, ["402","403","404"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + async def delete_async( + self, *, + saml_connection_id: str, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.DeletedObject: + r"""Delete a SAML Connection + + Deletes the SAML Connection whose ID matches the provided `id` in the path. + + :param saml_connection_id: The ID of the SAML Connection to delete + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.DeleteSAMLConnectionRequest( + saml_connection_id=saml_connection_id, + ) + + req = self.build_request( + method="DELETE", + path="/saml_connections/{saml_connection_id}", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="DeleteSAMLConnection", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["402","403","404","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.DeletedObject]) + if utils.match_response(http_res, ["402","403","404"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + diff --git a/src/clerk/sdk.py b/src/clerk/sdk.py new file mode 100644 index 0000000..d709aff --- /dev/null +++ b/src/clerk/sdk.py @@ -0,0 +1,179 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from .basesdk import BaseSDK +from .httpclient import AsyncHttpClient, HttpClient +from .sdkconfiguration import SDKConfiguration +from .utils.retries import RetryConfig +from clerk import models +from clerk._hooks import SDKHooks +from clerk.actortokens import ActorTokens +from clerk.allowlistidentifiers import AllowlistIdentifiers +from clerk.betafeatures import BetaFeatures +from clerk.blocklistidentifiers_sdk import BlocklistIdentifiersSDK +from clerk.clients import Clients +from clerk.domains_sdk import DomainsSDK +from clerk.emailaddresses import EmailAddresses +from clerk.instancesettings_sdk import InstanceSettingsSDK +from clerk.invitations import Invitations +from clerk.jwks import Jwks +from clerk.jwttemplates import JwtTemplates +from clerk.misc import Misc +from clerk.oauthapplications_sdk import OAuthApplicationsSDK +from clerk.organizationinvitations_sdk import OrganizationInvitationsSDK +from clerk.organizationmemberships_sdk import OrganizationMembershipsSDK +from clerk.organizations_sdk import OrganizationsSDK +from clerk.phonenumbers import PhoneNumbers +from clerk.proxychecks import ProxyChecks +from clerk.redirecturls import RedirectUrls +from clerk.samlconnections_sdk import SamlConnectionsSDK +from clerk.sessions import Sessions +from clerk.signintokens import SignInTokens +from clerk.signups import SignUps +from clerk.templates import Templates +from clerk.testingtokens import TestingTokens +from clerk.types import Nullable, UNSET +from clerk.users import Users +import clerk.utils as utils +from clerk.webhooks import Webhooks +import httpx +from typing import Callable, Dict, Optional, Union + +class Clerk(BaseSDK): + r"""Clerk Backend API: The Clerk REST Backend API, meant to be accessed by backend + servers. + + ### Versions + + When the API changes in a way that isn't compatible with older versions, a new version is released. + Each version is identified by its release date, e.g. `2021-02-05`. For more information, please see [Clerk API Versions](https://clerk.com/docs/backend-requests/versioning/overview). + + + Please see https://clerk.com/docs for more information. + https://clerk.com/docs + """ + misc: Misc + jwks: Jwks + clients: Clients + email_addresses: EmailAddresses + phone_numbers: PhoneNumbers + sessions: Sessions + templates: Templates + users: Users + invitations: Invitations + allowlist_identifiers: AllowlistIdentifiers + blocklist_identifiers: BlocklistIdentifiersSDK + beta_features: BetaFeatures + actor_tokens: ActorTokens + domains: DomainsSDK + instance_settings: InstanceSettingsSDK + webhooks: Webhooks + jwt_templates: JwtTemplates + organizations: OrganizationsSDK + organization_invitations: OrganizationInvitationsSDK + organization_memberships: OrganizationMembershipsSDK + proxy_checks: ProxyChecks + redirect_urls: RedirectUrls + sign_in_tokens: SignInTokens + sign_ups: SignUps + o_auth_applications: OAuthApplicationsSDK + saml_connections: SamlConnectionsSDK + testing_tokens: TestingTokens + def __init__( + self, + bearer_auth: Union[str, Callable[[], str]], + server_idx: Optional[int] = None, + server_url: Optional[str] = None, + url_params: Optional[Dict[str, str]] = None, + client: Optional[HttpClient] = None, + async_client: Optional[AsyncHttpClient] = None, + retry_config: Optional[Nullable[RetryConfig]] = UNSET, + timeout_config: Optional[int] = None + ) -> None: + r"""Instantiates the SDK configuring it with the provided parameters. + + :param bearer_auth: The bearer_auth required for authentication + :param server_idx: The index of the server to use for all methods + :param server_url: The server URL to use for all methods + :param url_params: Parameters to optionally template the server URL with + :param client: The HTTP client to use for all synchronous methods + :param async_client: The Async HTTP client to use for all asynchronous methods + :param retry_config: The retry configuration to use for all supported methods + :param timeout_config: Optional request timeout applied to each operation in milliseconds + """ + if client is None: + client = httpx.Client() + + assert issubclass( + type(client), HttpClient + ), "The provided client must implement the HttpClient protocol." + + if async_client is None: + async_client = httpx.AsyncClient() + + assert issubclass( + type(async_client), AsyncHttpClient + ), "The provided async_client must implement the AsyncHttpClient protocol." + + security = None + if callable(bearer_auth): + security = lambda: models.Security(bearer_auth = bearer_auth()) # pylint: disable=unnecessary-lambda-assignment + else: + security = models.Security(bearer_auth = bearer_auth) + + if server_url is not None: + if url_params is not None: + server_url = utils.template_url(server_url, url_params) + + + BaseSDK.__init__(self, SDKConfiguration( + client=client, + async_client=async_client, + security=security, + server_url=server_url, + server_idx=server_idx, + retry_config=retry_config, + timeout_config=timeout_config + )) + + hooks = SDKHooks() + + current_server_url, *_ = self.sdk_configuration.get_server_details() + server_url, self.sdk_configuration.client = hooks.sdk_init(current_server_url, self.sdk_configuration.client) + if current_server_url != server_url: + self.sdk_configuration.server_url = server_url + + # pylint: disable=protected-access + self.sdk_configuration.__dict__["_hooks"] = hooks + + self._init_sdks() + + + def _init_sdks(self): + self.misc = Misc(self.sdk_configuration) + self.jwks = Jwks(self.sdk_configuration) + self.clients = Clients(self.sdk_configuration) + self.email_addresses = EmailAddresses(self.sdk_configuration) + self.phone_numbers = PhoneNumbers(self.sdk_configuration) + self.sessions = Sessions(self.sdk_configuration) + self.templates = Templates(self.sdk_configuration) + self.users = Users(self.sdk_configuration) + self.invitations = Invitations(self.sdk_configuration) + self.allowlist_identifiers = AllowlistIdentifiers(self.sdk_configuration) + self.blocklist_identifiers = BlocklistIdentifiersSDK(self.sdk_configuration) + self.beta_features = BetaFeatures(self.sdk_configuration) + self.actor_tokens = ActorTokens(self.sdk_configuration) + self.domains = DomainsSDK(self.sdk_configuration) + self.instance_settings = InstanceSettingsSDK(self.sdk_configuration) + self.webhooks = Webhooks(self.sdk_configuration) + self.jwt_templates = JwtTemplates(self.sdk_configuration) + self.organizations = OrganizationsSDK(self.sdk_configuration) + self.organization_invitations = OrganizationInvitationsSDK(self.sdk_configuration) + self.organization_memberships = OrganizationMembershipsSDK(self.sdk_configuration) + self.proxy_checks = ProxyChecks(self.sdk_configuration) + self.redirect_urls = RedirectUrls(self.sdk_configuration) + self.sign_in_tokens = SignInTokens(self.sdk_configuration) + self.sign_ups = SignUps(self.sdk_configuration) + self.o_auth_applications = OAuthApplicationsSDK(self.sdk_configuration) + self.saml_connections = SamlConnectionsSDK(self.sdk_configuration) + self.testing_tokens = TestingTokens(self.sdk_configuration) + diff --git a/src/clerk/sdkconfiguration.py b/src/clerk/sdkconfiguration.py new file mode 100644 index 0000000..5fe25c2 --- /dev/null +++ b/src/clerk/sdkconfiguration.py @@ -0,0 +1,46 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + + +from ._hooks import SDKHooks +from .httpclient import AsyncHttpClient, HttpClient +from .utils import RetryConfig, remove_suffix +from clerk import models +from clerk.types import Nullable, UNSET +from dataclasses import dataclass +from typing import Callable, Dict, Optional, Tuple, Union + + +SERVERS = [ + "https://api.clerk.com/v1", +] +"""Contains the list of servers available to the SDK""" + +@dataclass +class SDKConfiguration: + client: HttpClient + async_client: AsyncHttpClient + security: Optional[Union[models.Security,Callable[[], models.Security]]] = None + server_url: Optional[str] = "" + server_idx: Optional[int] = 0 + language: str = "python" + openapi_doc_version: str = "v1" + sdk_version: str = "0.5.0-alpha.5" + gen_version: str = "2.366.1" + user_agent: str = "speakeasy-sdk/python 0.5.0-alpha.5 2.366.1 v1 clerk" + retry_config: Optional[Nullable[RetryConfig]] = UNSET + timeout_config: Optional[int] = None + + def __post_init__(self): + self._hooks = SDKHooks() + + def get_server_details(self) -> Tuple[str, Dict[str, str]]: + if self.server_url is not None and self.server_url: + return remove_suffix(self.server_url, "/"), {} + if self.server_idx is None: + self.server_idx = 0 + + return SERVERS[self.server_idx], {} + + + def get_hooks(self) -> SDKHooks: + return self._hooks diff --git a/src/clerk/sessions.py b/src/clerk/sessions.py new file mode 100644 index 0000000..5c9426e --- /dev/null +++ b/src/clerk/sessions.py @@ -0,0 +1,840 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from .basesdk import BaseSDK +from clerk import models +from clerk._hooks import HookContext +from clerk.types import Nullable, UNSET +import clerk.utils as utils +from typing import List, Optional +from typing_extensions import deprecated + +class Sessions(BaseSDK): + + + def list( + self, *, + client_id: Optional[str] = None, + user_id: Optional[str] = None, + status: Optional[models.QueryParamStatus] = None, + limit: Optional[float] = None, + offset: Optional[float] = None, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> List[models.Session]: + r"""List all sessions + + Returns a list of all sessions. + The sessions are returned sorted by creation date, with the newest sessions appearing first. + **Deprecation Notice (2024-01-01):** All parameters were initially considered optional, however + moving forward at least one of `client_id` or `user_id` parameters should be provided. + + :param client_id: List sessions for the given client + :param user_id: List sessions for the given user + :param status: Filter sessions by the provided status + :param limit: Applies a limit to the number of results returned. Can be used for paginating the results together with `offset`. + :param offset: Skip the first `offset` results when paginating. Needs to be an integer greater or equal to zero. To be used in conjunction with `limit`. + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.GetSessionListRequest( + client_id=client_id, + user_id=user_id, + status=status, + limit=limit, + offset=offset, + ) + + req = self.build_request( + method="GET", + path="/sessions", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=False, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="GetSessionList", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","401","422","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[List[models.Session]]) + if utils.match_response(http_res, ["400","401","422"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + async def list_async( + self, *, + client_id: Optional[str] = None, + user_id: Optional[str] = None, + status: Optional[models.QueryParamStatus] = None, + limit: Optional[float] = None, + offset: Optional[float] = None, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> List[models.Session]: + r"""List all sessions + + Returns a list of all sessions. + The sessions are returned sorted by creation date, with the newest sessions appearing first. + **Deprecation Notice (2024-01-01):** All parameters were initially considered optional, however + moving forward at least one of `client_id` or `user_id` parameters should be provided. + + :param client_id: List sessions for the given client + :param user_id: List sessions for the given user + :param status: Filter sessions by the provided status + :param limit: Applies a limit to the number of results returned. Can be used for paginating the results together with `offset`. + :param offset: Skip the first `offset` results when paginating. Needs to be an integer greater or equal to zero. To be used in conjunction with `limit`. + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.GetSessionListRequest( + client_id=client_id, + user_id=user_id, + status=status, + limit=limit, + offset=offset, + ) + + req = self.build_request( + method="GET", + path="/sessions", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=False, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="GetSessionList", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","401","422","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[List[models.Session]]) + if utils.match_response(http_res, ["400","401","422"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + def get( + self, *, + session_id: str, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.Session: + r"""Retrieve a session + + Retrieve the details of a session + + :param session_id: The ID of the session + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.GetSessionRequest( + session_id=session_id, + ) + + req = self.build_request( + method="GET", + path="/sessions/{session_id}", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="GetSession", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","401","404","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.Session]) + if utils.match_response(http_res, ["400","401","404"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + async def get_async( + self, *, + session_id: str, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.Session: + r"""Retrieve a session + + Retrieve the details of a session + + :param session_id: The ID of the session + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.GetSessionRequest( + session_id=session_id, + ) + + req = self.build_request( + method="GET", + path="/sessions/{session_id}", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="GetSession", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","401","404","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.Session]) + if utils.match_response(http_res, ["400","401","404"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + def revoke( + self, *, + session_id: str, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.Session: + r"""Revoke a session + + Sets the status of a session as \"revoked\", which is an unauthenticated state. + In multi-session mode, a revoked session will still be returned along with its client object, however the user will need to sign in again. + + :param session_id: The ID of the session + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.RevokeSessionRequest( + session_id=session_id, + ) + + req = self.build_request( + method="POST", + path="/sessions/{session_id}/revoke", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="RevokeSession", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","401","404","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.Session]) + if utils.match_response(http_res, ["400","401","404"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + async def revoke_async( + self, *, + session_id: str, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.Session: + r"""Revoke a session + + Sets the status of a session as \"revoked\", which is an unauthenticated state. + In multi-session mode, a revoked session will still be returned along with its client object, however the user will need to sign in again. + + :param session_id: The ID of the session + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.RevokeSessionRequest( + session_id=session_id, + ) + + req = self.build_request( + method="POST", + path="/sessions/{session_id}/revoke", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="RevokeSession", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","401","404","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.Session]) + if utils.match_response(http_res, ["400","401","404"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + @deprecated("warning: ** DEPRECATED ** - This will be removed in a future release, please migrate away from it as soon as possible.") + def verify( + self, *, + session_id: str, + token: Optional[str] = None, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.Session: + r"""Verify a session + + Returns the session if it is authenticated, otherwise returns an error. + WARNING: This endpoint is deprecated and will be removed in future versions. We strongly recommend switching to networkless verification using short-lived session tokens, + which is implemented transparently in all recent SDK versions (e.g. [NodeJS SDK](https://clerk.com/docs/backend-requests/handling/nodejs#clerk-express-require-auth)). + For more details on how networkless verification works, refer to our [Session Tokens documentation](https://clerk.com/docs/backend-requests/resources/session-tokens). + + :param session_id: The ID of the session + :param token: The JWT that is sent via the `__session` cookie from your frontend. Note: this JWT must be associated with the supplied session ID. + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.VerifySessionRequest( + session_id=session_id, + request_body=models.VerifySessionRequestBody( + token=token, + ), + ) + + req = self.build_request( + method="POST", + path="/sessions/{session_id}/verify", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + get_serialized_body=lambda: utils.serialize_request_body(request.request_body, False, True, "json", Optional[models.VerifySessionRequestBody]), + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="VerifySession", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","401","404","410","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.Session]) + if utils.match_response(http_res, ["400","401","404","410"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + @deprecated("warning: ** DEPRECATED ** - This will be removed in a future release, please migrate away from it as soon as possible.") + async def verify_async( + self, *, + session_id: str, + token: Optional[str] = None, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.Session: + r"""Verify a session + + Returns the session if it is authenticated, otherwise returns an error. + WARNING: This endpoint is deprecated and will be removed in future versions. We strongly recommend switching to networkless verification using short-lived session tokens, + which is implemented transparently in all recent SDK versions (e.g. [NodeJS SDK](https://clerk.com/docs/backend-requests/handling/nodejs#clerk-express-require-auth)). + For more details on how networkless verification works, refer to our [Session Tokens documentation](https://clerk.com/docs/backend-requests/resources/session-tokens). + + :param session_id: The ID of the session + :param token: The JWT that is sent via the `__session` cookie from your frontend. Note: this JWT must be associated with the supplied session ID. + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.VerifySessionRequest( + session_id=session_id, + request_body=models.VerifySessionRequestBody( + token=token, + ), + ) + + req = self.build_request( + method="POST", + path="/sessions/{session_id}/verify", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + get_serialized_body=lambda: utils.serialize_request_body(request.request_body, False, True, "json", Optional[models.VerifySessionRequestBody]), + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="VerifySession", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","401","404","410","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.Session]) + if utils.match_response(http_res, ["400","401","404","410"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + def create_token_from_template( + self, *, + session_id: str, + template_name: str, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.CreateSessionTokenFromTemplateResponseBody: + r"""Create a session token from a jwt template + + Creates a JSON Web Token(JWT) based on a session and a JWT Template name defined for your instance + + :param session_id: The ID of the session + :param template_name: The name of the JWT Template defined in your instance (e.g. `custom_hasura`). + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.CreateSessionTokenFromTemplateRequest( + session_id=session_id, + template_name=template_name, + ) + + req = self.build_request( + method="POST", + path="/sessions/{session_id}/tokens/{template_name}", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="CreateSessionTokenFromTemplate", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["401","404","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.CreateSessionTokenFromTemplateResponseBody]) + if utils.match_response(http_res, ["401","404"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + async def create_token_from_template_async( + self, *, + session_id: str, + template_name: str, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.CreateSessionTokenFromTemplateResponseBody: + r"""Create a session token from a jwt template + + Creates a JSON Web Token(JWT) based on a session and a JWT Template name defined for your instance + + :param session_id: The ID of the session + :param template_name: The name of the JWT Template defined in your instance (e.g. `custom_hasura`). + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.CreateSessionTokenFromTemplateRequest( + session_id=session_id, + template_name=template_name, + ) + + req = self.build_request( + method="POST", + path="/sessions/{session_id}/tokens/{template_name}", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="CreateSessionTokenFromTemplate", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["401","404","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.CreateSessionTokenFromTemplateResponseBody]) + if utils.match_response(http_res, ["401","404"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + diff --git a/src/clerk/signintokens.py b/src/clerk/signintokens.py new file mode 100644 index 0000000..a6f2c89 --- /dev/null +++ b/src/clerk/signintokens.py @@ -0,0 +1,331 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from .basesdk import BaseSDK +from clerk import models +from clerk._hooks import HookContext +from clerk.types import Nullable, UNSET +import clerk.utils as utils +from typing import Optional + +class SignInTokens(BaseSDK): + + + def create( + self, *, + user_id: Optional[str] = None, + expires_in_seconds: Optional[int] = None, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.SignInToken: + r"""Create sign-in token + + Creates a new sign-in token and associates it with the given user. + By default, sign-in tokens expire in 30 days. + You can optionally supply a different duration in seconds using the `expires_in_seconds` property. + + :param user_id: The ID of the user that can use the newly created sign in token + :param expires_in_seconds: Optional parameter to specify the life duration of the sign in token in seconds. By default, the duration is 30 days. + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.CreateSignInTokenRequestBody( + user_id=user_id, + expires_in_seconds=expires_in_seconds, + ) + + req = self.build_request( + method="POST", + path="/sign_in_tokens", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=False, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + get_serialized_body=lambda: utils.serialize_request_body(request, False, True, "json", Optional[models.CreateSignInTokenRequestBody]), + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="CreateSignInToken", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["404","422","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.SignInToken]) + if utils.match_response(http_res, ["404","422"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + async def create_async( + self, *, + user_id: Optional[str] = None, + expires_in_seconds: Optional[int] = None, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.SignInToken: + r"""Create sign-in token + + Creates a new sign-in token and associates it with the given user. + By default, sign-in tokens expire in 30 days. + You can optionally supply a different duration in seconds using the `expires_in_seconds` property. + + :param user_id: The ID of the user that can use the newly created sign in token + :param expires_in_seconds: Optional parameter to specify the life duration of the sign in token in seconds. By default, the duration is 30 days. + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.CreateSignInTokenRequestBody( + user_id=user_id, + expires_in_seconds=expires_in_seconds, + ) + + req = self.build_request( + method="POST", + path="/sign_in_tokens", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=False, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + get_serialized_body=lambda: utils.serialize_request_body(request, False, True, "json", Optional[models.CreateSignInTokenRequestBody]), + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="CreateSignInToken", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["404","422","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.SignInToken]) + if utils.match_response(http_res, ["404","422"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + def revoke( + self, *, + sign_in_token_id: str, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.SignInToken: + r"""Revoke the given sign-in token + + Revokes a pending sign-in token + + :param sign_in_token_id: The ID of the sign-in token to be revoked + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.RevokeSignInTokenRequest( + sign_in_token_id=sign_in_token_id, + ) + + req = self.build_request( + method="POST", + path="/sign_in_tokens/{sign_in_token_id}/revoke", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="RevokeSignInToken", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","404","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.SignInToken]) + if utils.match_response(http_res, ["400","404"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + async def revoke_async( + self, *, + sign_in_token_id: str, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.SignInToken: + r"""Revoke the given sign-in token + + Revokes a pending sign-in token + + :param sign_in_token_id: The ID of the sign-in token to be revoked + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.RevokeSignInTokenRequest( + sign_in_token_id=sign_in_token_id, + ) + + req = self.build_request( + method="POST", + path="/sign_in_tokens/{sign_in_token_id}/revoke", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="RevokeSignInToken", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","404","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.SignInToken]) + if utils.match_response(http_res, ["400","404"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + diff --git a/src/clerk/signups.py b/src/clerk/signups.py new file mode 100644 index 0000000..468c08e --- /dev/null +++ b/src/clerk/signups.py @@ -0,0 +1,183 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from .basesdk import BaseSDK +from clerk import models +from clerk._hooks import HookContext +from clerk.types import Nullable, UNSET +import clerk.utils as utils +from typing import Optional + +class SignUps(BaseSDK): + + + def update( + self, *, + id: str, + custom_action: Optional[bool] = None, + external_id: Optional[Nullable[str]] = None, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.SignUp: + r"""Update a sign-up + + Update the sign-up with the given ID + + :param id: The ID of the sign-up to update + :param custom_action: Specifies whether a custom action has run for this sign-up attempt. This is important when your instance has been configured to require a custom action to run before converting a sign-up into a user. After executing any external business logic you deem necessary, you can mark the sign-up as ready-to-convert by setting `custom_action` to `true`. + :param external_id: The ID of the guest attempting to sign up as used in your external systems or your previous authentication solution. This will be copied to the resulting user when the sign-up is completed. + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.UpdateSignUpRequest( + id=id, + request_body=models.UpdateSignUpRequestBody( + custom_action=custom_action, + external_id=external_id, + ), + ) + + req = self.build_request( + method="PATCH", + path="/sign_ups/{id}", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + get_serialized_body=lambda: utils.serialize_request_body(request.request_body, False, True, "json", Optional[models.UpdateSignUpRequestBody]), + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="UpdateSignUp", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["403","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.SignUp]) + if utils.match_response(http_res, "403", "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + async def update_async( + self, *, + id: str, + custom_action: Optional[bool] = None, + external_id: Optional[Nullable[str]] = None, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.SignUp: + r"""Update a sign-up + + Update the sign-up with the given ID + + :param id: The ID of the sign-up to update + :param custom_action: Specifies whether a custom action has run for this sign-up attempt. This is important when your instance has been configured to require a custom action to run before converting a sign-up into a user. After executing any external business logic you deem necessary, you can mark the sign-up as ready-to-convert by setting `custom_action` to `true`. + :param external_id: The ID of the guest attempting to sign up as used in your external systems or your previous authentication solution. This will be copied to the resulting user when the sign-up is completed. + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.UpdateSignUpRequest( + id=id, + request_body=models.UpdateSignUpRequestBody( + custom_action=custom_action, + external_id=external_id, + ), + ) + + req = self.build_request( + method="PATCH", + path="/sign_ups/{id}", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + get_serialized_body=lambda: utils.serialize_request_body(request.request_body, False, True, "json", Optional[models.UpdateSignUpRequestBody]), + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="UpdateSignUp", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["403","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.SignUp]) + if utils.match_response(http_res, "403", "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + diff --git a/src/clerk/templates.py b/src/clerk/templates.py new file mode 100644 index 0000000..b59d752 --- /dev/null +++ b/src/clerk/templates.py @@ -0,0 +1,1061 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from .basesdk import BaseSDK +from clerk import models +from clerk._hooks import HookContext +from clerk.types import Nullable, UNSET +import clerk.utils as utils +from typing import List, Optional + +class Templates(BaseSDK): + + + def list( + self, *, + template_type: models.TemplateType, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> List[models.Template]: + r"""List all templates + + Returns a list of all templates. + The templates are returned sorted by position. + + :param template_type: The type of templates to list (email or SMS) + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.GetTemplateListRequest( + template_type=template_type, + ) + + req = self.build_request( + method="GET", + path="/templates/{template_type}", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="GetTemplateList", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","401","422","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[List[models.Template]]) + if utils.match_response(http_res, ["400","401","422"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + async def list_async( + self, *, + template_type: models.TemplateType, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> List[models.Template]: + r"""List all templates + + Returns a list of all templates. + The templates are returned sorted by position. + + :param template_type: The type of templates to list (email or SMS) + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.GetTemplateListRequest( + template_type=template_type, + ) + + req = self.build_request( + method="GET", + path="/templates/{template_type}", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="GetTemplateList", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","401","422","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[List[models.Template]]) + if utils.match_response(http_res, ["400","401","422"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + def get( + self, *, + template_type: models.PathParamTemplateType, + slug: str, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.Template: + r"""Retrieve a template + + Returns the details of a template + + :param template_type: The type of templates to retrieve (email or SMS) + :param slug: The slug (i.e. machine-friendly name) of the template to retrieve + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.GetTemplateRequest( + template_type=template_type, + slug=slug, + ) + + req = self.build_request( + method="GET", + path="/templates/{template_type}/{slug}", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="GetTemplate", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","401","404","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.Template]) + if utils.match_response(http_res, ["400","401","404"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + async def get_async( + self, *, + template_type: models.PathParamTemplateType, + slug: str, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.Template: + r"""Retrieve a template + + Returns the details of a template + + :param template_type: The type of templates to retrieve (email or SMS) + :param slug: The slug (i.e. machine-friendly name) of the template to retrieve + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.GetTemplateRequest( + template_type=template_type, + slug=slug, + ) + + req = self.build_request( + method="GET", + path="/templates/{template_type}/{slug}", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="GetTemplate", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","401","404","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.Template]) + if utils.match_response(http_res, ["400","401","404"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + def upsert( + self, *, + template_type: models.UpsertTemplatePathParamTemplateType, + slug: str, + name: Optional[str] = None, + subject: Optional[Nullable[str]] = None, + markup: Optional[Nullable[str]] = None, + body: Optional[str] = None, + delivered_by_clerk: Optional[Nullable[bool]] = None, + from_email_name: Optional[str] = None, + reply_to_email_name: Optional[str] = None, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.Template: + r"""Update a template for a given type and slug + + Updates the existing template of the given type and slug + + :param template_type: The type of template to update + :param slug: The slug of the template to update + :param name: The user-friendly name of the template + :param subject: The email subject. Applicable only to email templates. + :param markup: The editor markup used to generate the body of the template + :param body: The template body before variable interpolation + :param delivered_by_clerk: Whether Clerk should deliver emails or SMS messages based on the current template + :param from_email_name: The local part of the From email address that will be used for emails. For example, in the address 'hello@example.com', the local part is 'hello'. Applicable only to email templates. + :param reply_to_email_name: The local part of the Reply To email address that will be used for emails. For example, in the address 'hello@example.com', the local part is 'hello'. Applicable only to email templates. + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.UpsertTemplateRequest( + template_type=template_type, + slug=slug, + request_body=models.UpsertTemplateRequestBody( + name=name, + subject=subject, + markup=markup, + body=body, + delivered_by_clerk=delivered_by_clerk, + from_email_name=from_email_name, + reply_to_email_name=reply_to_email_name, + ), + ) + + req = self.build_request( + method="PUT", + path="/templates/{template_type}/{slug}", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + get_serialized_body=lambda: utils.serialize_request_body(request.request_body, False, True, "json", Optional[models.UpsertTemplateRequestBody]), + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="UpsertTemplate", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","401","402","403","404","422","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.Template]) + if utils.match_response(http_res, ["400","401","402","403","404","422"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + async def upsert_async( + self, *, + template_type: models.UpsertTemplatePathParamTemplateType, + slug: str, + name: Optional[str] = None, + subject: Optional[Nullable[str]] = None, + markup: Optional[Nullable[str]] = None, + body: Optional[str] = None, + delivered_by_clerk: Optional[Nullable[bool]] = None, + from_email_name: Optional[str] = None, + reply_to_email_name: Optional[str] = None, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.Template: + r"""Update a template for a given type and slug + + Updates the existing template of the given type and slug + + :param template_type: The type of template to update + :param slug: The slug of the template to update + :param name: The user-friendly name of the template + :param subject: The email subject. Applicable only to email templates. + :param markup: The editor markup used to generate the body of the template + :param body: The template body before variable interpolation + :param delivered_by_clerk: Whether Clerk should deliver emails or SMS messages based on the current template + :param from_email_name: The local part of the From email address that will be used for emails. For example, in the address 'hello@example.com', the local part is 'hello'. Applicable only to email templates. + :param reply_to_email_name: The local part of the Reply To email address that will be used for emails. For example, in the address 'hello@example.com', the local part is 'hello'. Applicable only to email templates. + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.UpsertTemplateRequest( + template_type=template_type, + slug=slug, + request_body=models.UpsertTemplateRequestBody( + name=name, + subject=subject, + markup=markup, + body=body, + delivered_by_clerk=delivered_by_clerk, + from_email_name=from_email_name, + reply_to_email_name=reply_to_email_name, + ), + ) + + req = self.build_request( + method="PUT", + path="/templates/{template_type}/{slug}", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + get_serialized_body=lambda: utils.serialize_request_body(request.request_body, False, True, "json", Optional[models.UpsertTemplateRequestBody]), + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="UpsertTemplate", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","401","402","403","404","422","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.Template]) + if utils.match_response(http_res, ["400","401","402","403","404","422"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + def revert( + self, *, + template_type: models.RevertTemplatePathParamTemplateType, + slug: str, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.Template: + r"""Revert a template + + Reverts an updated template to its default state + + :param template_type: The type of template to revert + :param slug: The slug of the template to revert + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.RevertTemplateRequest( + template_type=template_type, + slug=slug, + ) + + req = self.build_request( + method="POST", + path="/templates/{template_type}/{slug}/revert", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="RevertTemplate", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","401","402","404","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.Template]) + if utils.match_response(http_res, ["400","401","402","404"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + async def revert_async( + self, *, + template_type: models.RevertTemplatePathParamTemplateType, + slug: str, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.Template: + r"""Revert a template + + Reverts an updated template to its default state + + :param template_type: The type of template to revert + :param slug: The slug of the template to revert + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.RevertTemplateRequest( + template_type=template_type, + slug=slug, + ) + + req = self.build_request( + method="POST", + path="/templates/{template_type}/{slug}/revert", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="RevertTemplate", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","401","402","404","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.Template]) + if utils.match_response(http_res, ["400","401","402","404"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + def preview( + self, *, + template_type: str, + slug: str, + subject: Optional[Nullable[str]] = None, + body: Optional[str] = None, + from_email_name: Optional[str] = None, + reply_to_email_name: Optional[str] = None, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.PreviewTemplateResponseBody: + r"""Preview changes to a template + + Returns a preview of a template for a given template_type, slug and body + + :param template_type: The type of template to preview + :param slug: The slug of the template to preview + :param subject: The email subject. Applicable only to email templates. + :param body: The template body before variable interpolation + :param from_email_name: The local part of the From email address that will be used for emails. For example, in the address 'hello@example.com', the local part is 'hello'. Applicable only to email templates. + :param reply_to_email_name: The local part of the Reply To email address that will be used for emails. For example, in the address 'hello@example.com', the local part is 'hello'. Applicable only to email templates. + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.PreviewTemplateRequest( + template_type=template_type, + slug=slug, + request_body=models.PreviewTemplateRequestBody( + subject=subject, + body=body, + from_email_name=from_email_name, + reply_to_email_name=reply_to_email_name, + ), + ) + + req = self.build_request( + method="POST", + path="/templates/{template_type}/{slug}/preview", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + get_serialized_body=lambda: utils.serialize_request_body(request.request_body, False, True, "json", Optional[models.PreviewTemplateRequestBody]), + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="PreviewTemplate", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","401","404","422","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.PreviewTemplateResponseBody]) + if utils.match_response(http_res, ["400","401","404","422"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + async def preview_async( + self, *, + template_type: str, + slug: str, + subject: Optional[Nullable[str]] = None, + body: Optional[str] = None, + from_email_name: Optional[str] = None, + reply_to_email_name: Optional[str] = None, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.PreviewTemplateResponseBody: + r"""Preview changes to a template + + Returns a preview of a template for a given template_type, slug and body + + :param template_type: The type of template to preview + :param slug: The slug of the template to preview + :param subject: The email subject. Applicable only to email templates. + :param body: The template body before variable interpolation + :param from_email_name: The local part of the From email address that will be used for emails. For example, in the address 'hello@example.com', the local part is 'hello'. Applicable only to email templates. + :param reply_to_email_name: The local part of the Reply To email address that will be used for emails. For example, in the address 'hello@example.com', the local part is 'hello'. Applicable only to email templates. + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.PreviewTemplateRequest( + template_type=template_type, + slug=slug, + request_body=models.PreviewTemplateRequestBody( + subject=subject, + body=body, + from_email_name=from_email_name, + reply_to_email_name=reply_to_email_name, + ), + ) + + req = self.build_request( + method="POST", + path="/templates/{template_type}/{slug}/preview", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + get_serialized_body=lambda: utils.serialize_request_body(request.request_body, False, True, "json", Optional[models.PreviewTemplateRequestBody]), + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="PreviewTemplate", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","401","404","422","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.PreviewTemplateResponseBody]) + if utils.match_response(http_res, ["400","401","404","422"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + def toggle_delivery( + self, *, + template_type: models.ToggleTemplateDeliveryPathParamTemplateType, + slug: str, + delivered_by_clerk: Optional[Nullable[bool]] = None, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.Template: + r"""Toggle the delivery by Clerk for a template of a given type and slug + + Toggles the delivery by Clerk for a template of a given type and slug. + If disabled, Clerk will not deliver the resulting email or SMS. + The app developer will need to listen to the `email.created` or `sms.created` webhooks in order to handle delivery themselves. + + :param template_type: The type of template to toggle delivery for + :param slug: The slug of the template for which to toggle delivery + :param delivered_by_clerk: Whether Clerk should deliver emails or SMS messages based on the current template + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.ToggleTemplateDeliveryRequest( + template_type=template_type, + slug=slug, + request_body=models.ToggleTemplateDeliveryRequestBody( + delivered_by_clerk=delivered_by_clerk, + ), + ) + + req = self.build_request( + method="POST", + path="/templates/{template_type}/{slug}/toggle_delivery", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + get_serialized_body=lambda: utils.serialize_request_body(request.request_body, False, True, "json", Optional[models.ToggleTemplateDeliveryRequestBody]), + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="ToggleTemplateDelivery", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","401","404","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.Template]) + if utils.match_response(http_res, ["400","401","404"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + async def toggle_delivery_async( + self, *, + template_type: models.ToggleTemplateDeliveryPathParamTemplateType, + slug: str, + delivered_by_clerk: Optional[Nullable[bool]] = None, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.Template: + r"""Toggle the delivery by Clerk for a template of a given type and slug + + Toggles the delivery by Clerk for a template of a given type and slug. + If disabled, Clerk will not deliver the resulting email or SMS. + The app developer will need to listen to the `email.created` or `sms.created` webhooks in order to handle delivery themselves. + + :param template_type: The type of template to toggle delivery for + :param slug: The slug of the template for which to toggle delivery + :param delivered_by_clerk: Whether Clerk should deliver emails or SMS messages based on the current template + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.ToggleTemplateDeliveryRequest( + template_type=template_type, + slug=slug, + request_body=models.ToggleTemplateDeliveryRequestBody( + delivered_by_clerk=delivered_by_clerk, + ), + ) + + req = self.build_request( + method="POST", + path="/templates/{template_type}/{slug}/toggle_delivery", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + get_serialized_body=lambda: utils.serialize_request_body(request.request_body, False, True, "json", Optional[models.ToggleTemplateDeliveryRequestBody]), + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="ToggleTemplateDelivery", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","401","404","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.Template]) + if utils.match_response(http_res, ["400","401","404"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + diff --git a/src/clerk/testingtokens.py b/src/clerk/testingtokens.py new file mode 100644 index 0000000..72011f6 --- /dev/null +++ b/src/clerk/testingtokens.py @@ -0,0 +1,145 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from .basesdk import BaseSDK +from clerk import models +from clerk._hooks import HookContext +from clerk.types import Nullable, UNSET +import clerk.utils as utils +from typing import Optional + +class TestingTokens(BaseSDK): + + + def create( + self, *, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.TestingToken: + r"""Retrieve a new testing token + + Retrieve a new testing token. Only available for development instances. + + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + req = self.build_request( + method="POST", + path="/testing_tokens", + base_url=base_url, + url_variables=url_variables, + request=None, + request_body_required=False, + request_has_path_params=False, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="CreateTestingToken", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.TestingToken]) + if utils.match_response(http_res, ["400","4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + async def create_async( + self, *, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.TestingToken: + r"""Retrieve a new testing token + + Retrieve a new testing token. Only available for development instances. + + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + req = self.build_request( + method="POST", + path="/testing_tokens", + base_url=base_url, + url_variables=url_variables, + request=None, + request_body_required=False, + request_has_path_params=False, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="CreateTestingToken", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.TestingToken]) + if utils.match_response(http_res, ["400","4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + diff --git a/src/clerk/types/__init__.py b/src/clerk/types/__init__.py new file mode 100644 index 0000000..f2314e9 --- /dev/null +++ b/src/clerk/types/__init__.py @@ -0,0 +1,9 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from .basemodel import UNSET, Nullable, BaseModel + +__all__ = [ + "UNSET", + "Nullable", + "BaseModel", +] diff --git a/src/clerk/types/basemodel.py b/src/clerk/types/basemodel.py new file mode 100644 index 0000000..969e85a --- /dev/null +++ b/src/clerk/types/basemodel.py @@ -0,0 +1,18 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from pydantic import ConfigDict +from pydantic import BaseModel as PydanticBaseModel +from typing import TypeVar, Union +from typing_extensions import TypeAliasType + + +class UNSET: + pass + + +T = TypeVar("T") +Nullable = TypeAliasType("Nullable", Union[T, None], type_params=(T,)) + + +class BaseModel(PydanticBaseModel): + model_config = ConfigDict(populate_by_name=True, arbitrary_types_allowed=True) diff --git a/src/clerk/users.py b/src/clerk/users.py new file mode 100644 index 0000000..73e9196 --- /dev/null +++ b/src/clerk/users.py @@ -0,0 +1,3316 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from .basesdk import BaseSDK +from clerk import models +from clerk._hooks import HookContext +from clerk.types import BaseModel, Nullable, UNSET +import clerk.utils as utils +from jsonpath import JSONPath +from typing import Any, Dict, List, Optional, Union + +class Users(BaseSDK): + + + def list( + self, *, + email_address: Optional[List[str]] = None, + phone_number: Optional[List[str]] = None, + external_id: Optional[List[str]] = None, + username: Optional[List[str]] = None, + web3_wallet: Optional[List[str]] = None, + user_id: Optional[List[str]] = None, + organization_id: Optional[List[str]] = None, + query: Optional[str] = None, + last_active_at_since: Optional[int] = None, + limit: Optional[float] = None, + offset: Optional[float] = None, + order_by: Optional[str] = None, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> List[models.User]: + r"""List all users + + Returns a list of all users. + The users are returned sorted by creation date, with the newest users appearing first. + + :param email_address: Returns users with the specified email addresses. Accepts up to 100 email addresses. Any email addresses not found are ignored. + :param phone_number: Returns users with the specified phone numbers. Accepts up to 100 phone numbers. Any phone numbers not found are ignored. + :param external_id: Returns users with the specified external ids. For each external id, the `+` and `-` can be prepended to the id, which denote whether the respective external id should be included or excluded from the result set. Accepts up to 100 external ids. Any external ids not found are ignored. + :param username: Returns users with the specified usernames. Accepts up to 100 usernames. Any usernames not found are ignored. + :param web3_wallet: Returns users with the specified web3 wallet addresses. Accepts up to 100 web3 wallet addresses. Any web3 wallet addressed not found are ignored. + :param user_id: Returns users with the user ids specified. For each user id, the `+` and `-` can be prepended to the id, which denote whether the respective user id should be included or excluded from the result set. Accepts up to 100 user ids. Any user ids not found are ignored. + :param organization_id: Returns users that have memberships to the given organizations. For each organization id, the `+` and `-` can be prepended to the id, which denote whether the respective organization should be included or excluded from the result set. Accepts up to 100 organization ids. + :param query: Returns users that match the given query. For possible matches, we check the email addresses, phone numbers, usernames, web3 wallets, user ids, first and last names. The query value doesn't need to match the exact value you are looking for, it is capable of partial matches as well. + :param last_active_at_since: Returns users that had session activity since the given date, with day precision. Providing a value with higher precision than day will result in an error. Example: use 1700690400000 to retrieve users that had session activity from 2023-11-23 until the current day. + :param limit: Applies a limit to the number of results returned. Can be used for paginating the results together with `offset`. + :param offset: Skip the first `offset` results when paginating. Needs to be an integer greater or equal to zero. To be used in conjunction with `limit`. + :param order_by: Allows to return users in a particular order. At the moment, you can order the returned users by their `created_at`,`updated_at`,`email_address`,`web3wallet`,`first_name`,`last_name`,`phone_number`,`username`,`last_active_at`,`last_sign_in_at`. In order to specify the direction, you can use the `+/-` symbols prepended in the property to order by. For example, if you want users to be returned in descending order according to their `created_at` property, you can use `-created_at`. If you don't use `+` or `-`, then `+` is implied. We only support one `order_by` parameter, and if multiple `order_by` parameters are provided, we will only keep the first one. For example, if you pass `order_by=username&order_by=created_at`, we will consider only the first `order_by` parameter, which is `username`. The `created_at` parameter will be ignored in this case. + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.GetUserListRequest( + email_address=email_address, + phone_number=phone_number, + external_id=external_id, + username=username, + web3_wallet=web3_wallet, + user_id=user_id, + organization_id=organization_id, + query=query, + last_active_at_since=last_active_at_since, + limit=limit, + offset=offset, + order_by=order_by, + ) + + req = self.build_request( + method="GET", + path="/users", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=False, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="GetUserList", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","401","422","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[List[models.User]]) + if utils.match_response(http_res, ["400","401","422"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + async def list_async( + self, *, + email_address: Optional[List[str]] = None, + phone_number: Optional[List[str]] = None, + external_id: Optional[List[str]] = None, + username: Optional[List[str]] = None, + web3_wallet: Optional[List[str]] = None, + user_id: Optional[List[str]] = None, + organization_id: Optional[List[str]] = None, + query: Optional[str] = None, + last_active_at_since: Optional[int] = None, + limit: Optional[float] = None, + offset: Optional[float] = None, + order_by: Optional[str] = None, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> List[models.User]: + r"""List all users + + Returns a list of all users. + The users are returned sorted by creation date, with the newest users appearing first. + + :param email_address: Returns users with the specified email addresses. Accepts up to 100 email addresses. Any email addresses not found are ignored. + :param phone_number: Returns users with the specified phone numbers. Accepts up to 100 phone numbers. Any phone numbers not found are ignored. + :param external_id: Returns users with the specified external ids. For each external id, the `+` and `-` can be prepended to the id, which denote whether the respective external id should be included or excluded from the result set. Accepts up to 100 external ids. Any external ids not found are ignored. + :param username: Returns users with the specified usernames. Accepts up to 100 usernames. Any usernames not found are ignored. + :param web3_wallet: Returns users with the specified web3 wallet addresses. Accepts up to 100 web3 wallet addresses. Any web3 wallet addressed not found are ignored. + :param user_id: Returns users with the user ids specified. For each user id, the `+` and `-` can be prepended to the id, which denote whether the respective user id should be included or excluded from the result set. Accepts up to 100 user ids. Any user ids not found are ignored. + :param organization_id: Returns users that have memberships to the given organizations. For each organization id, the `+` and `-` can be prepended to the id, which denote whether the respective organization should be included or excluded from the result set. Accepts up to 100 organization ids. + :param query: Returns users that match the given query. For possible matches, we check the email addresses, phone numbers, usernames, web3 wallets, user ids, first and last names. The query value doesn't need to match the exact value you are looking for, it is capable of partial matches as well. + :param last_active_at_since: Returns users that had session activity since the given date, with day precision. Providing a value with higher precision than day will result in an error. Example: use 1700690400000 to retrieve users that had session activity from 2023-11-23 until the current day. + :param limit: Applies a limit to the number of results returned. Can be used for paginating the results together with `offset`. + :param offset: Skip the first `offset` results when paginating. Needs to be an integer greater or equal to zero. To be used in conjunction with `limit`. + :param order_by: Allows to return users in a particular order. At the moment, you can order the returned users by their `created_at`,`updated_at`,`email_address`,`web3wallet`,`first_name`,`last_name`,`phone_number`,`username`,`last_active_at`,`last_sign_in_at`. In order to specify the direction, you can use the `+/-` symbols prepended in the property to order by. For example, if you want users to be returned in descending order according to their `created_at` property, you can use `-created_at`. If you don't use `+` or `-`, then `+` is implied. We only support one `order_by` parameter, and if multiple `order_by` parameters are provided, we will only keep the first one. For example, if you pass `order_by=username&order_by=created_at`, we will consider only the first `order_by` parameter, which is `username`. The `created_at` parameter will be ignored in this case. + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.GetUserListRequest( + email_address=email_address, + phone_number=phone_number, + external_id=external_id, + username=username, + web3_wallet=web3_wallet, + user_id=user_id, + organization_id=organization_id, + query=query, + last_active_at_since=last_active_at_since, + limit=limit, + offset=offset, + order_by=order_by, + ) + + req = self.build_request( + method="GET", + path="/users", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=False, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="GetUserList", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","401","422","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[List[models.User]]) + if utils.match_response(http_res, ["400","401","422"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + def create( + self, *, + external_id: Optional[Nullable[str]] = None, + first_name: Optional[Nullable[str]] = None, + last_name: Optional[Nullable[str]] = None, + email_address: Optional[List[str]] = None, + phone_number: Optional[List[str]] = None, + web3_wallet: Optional[List[str]] = None, + username: Optional[Nullable[str]] = None, + password: Optional[Nullable[str]] = None, + password_digest: Optional[str] = None, + password_hasher: Optional[models.PasswordHasher] = None, + skip_password_checks: Optional[bool] = None, + skip_password_requirement: Optional[bool] = None, + totp_secret: Optional[str] = None, + backup_codes: Optional[List[str]] = None, + public_metadata: Optional[Union[models.CreateUserPublicMetadata, models.CreateUserPublicMetadataTypedDict]] = None, + private_metadata: Optional[Union[models.CreateUserPrivateMetadata, models.CreateUserPrivateMetadataTypedDict]] = None, + unsafe_metadata: Optional[Union[models.CreateUserUnsafeMetadata, models.CreateUserUnsafeMetadataTypedDict]] = None, + created_at: Optional[str] = None, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.User: + r"""Create a new user + + Creates a new user. Your user management settings determine how you should setup your user model. + + Any email address and phone number created using this method will be marked as verified. + + Note: If you are performing a migration, check out our guide on [zero downtime migrations](https://clerk.com/docs/deployments/migrate-overview). + + A rate limit rule of 20 requests per 10 seconds is applied to this endpoint. + + :param external_id: The ID of the user as used in your external systems or your previous authentication solution. Must be unique across your instance. + :param first_name: The first name to assign to the user + :param last_name: The last name to assign to the user + :param email_address: Email addresses to add to the user. Must be unique across your instance. The first email address will be set as the user's primary email address. + :param phone_number: Phone numbers to add to the user. Must be unique across your instance. The first phone number will be set as the user's primary phone number. + :param web3_wallet: Web3 wallets to add to the user. Must be unique across your instance. The first wallet will be set as the user's primary wallet. + :param username: The username to give to the user. It must be unique across your instance. + :param password: The plaintext password to give the user. Must be at least 8 characters long, and can not be in any list of hacked passwords. + :param password_digest: In case you already have the password digests and not the passwords, you can use them for the newly created user via this property. The digests should be generated with one of the supported algorithms. The hashing algorithm can be specified using the `password_hasher` property. + :param password_hasher: The hashing algorithm that was used to generate the password digest. The algorithms we support at the moment are [bcrypt](https://en.wikipedia.org/wiki/Bcrypt), [bcrypt_sha256_django](https://docs.djangoproject.com/en/4.0/topics/auth/passwords/), [md5](https://en.wikipedia.org/wiki/MD5), pbkdf2_sha256, pbkdf2_sha512, [pbkdf2_sha256_django](https://docs.djangoproject.com/en/4.0/topics/auth/passwords/), [phpass](https://www.openwall.com/phpass/), [scrypt_firebase](https://firebaseopensource.com/projects/firebase/scrypt/), [scrypt_werkzeug](https://werkzeug.palletsprojects.com/en/3.0.x/utils/#werkzeug.security.generate_password_hash), [sha256](https://en.wikipedia.org/wiki/SHA-2) and the [argon2](https://argon2.online/) variants argon2i and argon2id. If you need support for any particular hashing algorithm, [please let us know](https://clerk.com/support). Note: for password hashers considered insecure (at this moment MD5 and SHA256), the corresponding user password hashes will be transparently migrated to Bcrypt (a secure hasher) upon the user's first successful password sign in. Insecure schemes are marked with `(insecure)` in the list below. Each of the supported hashers expects the incoming digest to be in a particular format. Specifically: **bcrypt:** The digest should be of the following form: `$$$` **bcrypt_sha256_django:** This is the Django-specific variant of Bcrypt, using SHA256 hashing function. The format should be as follows (as exported from Django): `bcrypt_sha256$$$$` **md5** (insecure): The digest should follow the regular form e.g.: `5f4dcc3b5aa765d61d8327deb882cf99` **pbkdf2_sha256:** This is the PBKDF2 algorithm using the SHA256 hashing function. The format should be as follows: `pbkdf2_sha256$$$` Note: Both the salt and the hash are expected to be base64-encoded. **pbkdf2_sha512:** This is the PBKDF2 algorithm using the SHA512 hashing function. The format should be as follows: `pbkdf2_sha512$$$` _iterations:_ The number of iterations used. Must be an integer less than 420000. _salt:_ The salt used when generating the hash. Must be less than 1024 bytes. _hash:_ The hex-encoded hash. Must have been generated with a key length less than 1024 bytes. **pbkdf2_sha256_django:** This is the Django-specific variant of PBKDF2 and the digest should have the following format (as exported from Django): `pbkdf2_sha256$$$` Note: The salt is expected to be un-encoded, the hash is expected base64-encoded. **pbkdf2_sha1:** This is similar to pkbdf2_sha256_django, but with two differences: 1. uses sha1 instead of sha256 2. accepts the hash as a hex-encoded string The format is the following: `pbkdf2_sha1$$$` **phpass:** Portable public domain password hashing framework for use in PHP applications. Digests hashed with phpass have the following sections: The format is the following: `$P$` - $P$ is the prefix used to identify phpass hashes. - rounds is a single character encoding a 6-bit integer representing the number of rounds used. - salt is eight characters drawn from [./0-9A-Za-z], providing a 48-bit salt. - checksum is 22 characters drawn from the same set, encoding the 128-bit checksum with MD5. **scrypt_firebase:** The Firebase-specific variant of scrypt. The value is expected to have 6 segments separated by the $ character and include the following information: _hash:_ The actual Base64 hash. This can be retrieved when exporting the user from Firebase. _salt:_ The salt used to generate the above hash. Again, this is given when exporting the user. _signer key:_ The base64 encoded signer key. _salt separator:_ The base64 encoded salt separator. _rounds:_ The number of rounds the algorithm needs to run. _memory cost:_ The cost of the algorithm run The first 2 (hash and salt) are per user and can be retrieved when exporting the user from Firebase. The other 4 values (signer key, salt separator, rounds and memory cost) are project-wide settings and can be retrieved from the project's password hash parameters. Once you have all these, you can combine it in the following format and send this as the digest in order for Clerk to accept it: `$$$$$` **scrypt_werkzeug:** The Werkzeug-specific variant of scrypt. The value is expected to have 3 segments separated by the $ character and include the following information: _algorithm args:_ The algorithm used to generate the hash. _salt:_ The salt used to generate the above hash. _hash:_ The actual Base64 hash. The algorithm args are the parameters used to generate the hash and are included in the digest. **argon2i:** Algorithms in the argon2 family generate digests that encode the following information: _version (v):_ The argon version, version 19 is assumed _memory (m):_ The memory used by the algorithm (in kibibytes) _iterations (t):_ The number of iterations to perform _parallelism (p):_ The number of threads to use Parts are demarcated by the `$` character, with the first part identifying the algorithm variant. The middle part is a comma-separated list of the encoding options (memory, iterations, parallelism). The final part is the actual digest. `$argon2i$v=19$m=4096,t=3,p=1$4t6CL3P7YiHBtwESXawI8Hm20zJj4cs7/4/G3c187e0$m7RQFczcKr5bIR0IIxbpO2P0tyrLjf3eUW3M3QSwnLc` **argon2id:** See the previous algorithm for an explanation of the formatting. For the argon2id case, the value of the algorithm in the first part of the digest is `argon2id`: `$argon2id$v=19$m=64,t=4,p=8$Z2liZXJyaXNo$iGXEpMBTDYQ8G/71tF0qGjxRHEmR3gpGULcE93zUJVU` **sha256** (insecure): The digest should be a 64-length hex string, e.g.: `9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08` **sha256_salted** (insecure): The digest should be a 64-length hex string with a salt. The format is the following: `$` The value is expected to have 2 segments separated by the $ character and include the following information: _hash:_ The sha256 hash, a 64-length hex string. _salt:_ The salt used to generate the above hash. Must be between 1 and 1024 bits. + :param skip_password_checks: When set to `true` all password checks are skipped. It is recommended to use this method only when migrating plaintext passwords to Clerk. Upon migration the user base should be prompted to pick stronger password. + :param skip_password_requirement: When set to `true`, `password` is not required anymore when creating the user and can be omitted. This is useful when you are trying to create a user that doesn't have a password, in an instance that is using passwords. Please note that you cannot use this flag if password is the only way for a user to sign into your instance. + :param totp_secret: In case TOTP is configured on the instance, you can provide the secret to enable it on the newly created user without the need to reset it. Please note that currently the supported options are: * Period: 30 seconds * Code length: 6 digits * Algorithm: SHA1 + :param backup_codes: If Backup Codes are configured on the instance, you can provide them to enable it on the newly created user without the need to reset them. You must provide the backup codes in plain format or the corresponding bcrypt digest. + :param public_metadata: Metadata saved on the user, that is visible to both your Frontend and Backend APIs + :param private_metadata: Metadata saved on the user, that is only visible to your Backend API + :param unsafe_metadata: Metadata saved on the user, that can be updated from both the Frontend and Backend APIs. Note: Since this data can be modified from the frontend, it is not guaranteed to be safe. + :param created_at: A custom date/time denoting _when_ the user signed up to the application, specified in RFC3339 format (e.g. `2012-10-20T07:15:20.902Z`). + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.CreateUserRequestBody( + external_id=external_id, + first_name=first_name, + last_name=last_name, + email_address=email_address, + phone_number=phone_number, + web3_wallet=web3_wallet, + username=username, + password=password, + password_digest=password_digest, + password_hasher=password_hasher, + skip_password_checks=skip_password_checks, + skip_password_requirement=skip_password_requirement, + totp_secret=totp_secret, + backup_codes=backup_codes, + public_metadata=utils.unmarshal(public_metadata, models.CreateUserPublicMetadata) if not isinstance(public_metadata, BaseModel) and public_metadata is not None else public_metadata, + private_metadata=utils.unmarshal(private_metadata, models.CreateUserPrivateMetadata) if not isinstance(private_metadata, BaseModel) and private_metadata is not None else private_metadata, + unsafe_metadata=utils.unmarshal(unsafe_metadata, models.CreateUserUnsafeMetadata) if not isinstance(unsafe_metadata, BaseModel) and unsafe_metadata is not None else unsafe_metadata, + created_at=created_at, + ) + + req = self.build_request( + method="POST", + path="/users", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=True, + request_has_path_params=False, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + get_serialized_body=lambda: utils.serialize_request_body(request, False, False, "json", models.CreateUserRequestBody), + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="CreateUser", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","401","403","422","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.User]) + if utils.match_response(http_res, ["400","401","403","422"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + async def create_async( + self, *, + external_id: Optional[Nullable[str]] = None, + first_name: Optional[Nullable[str]] = None, + last_name: Optional[Nullable[str]] = None, + email_address: Optional[List[str]] = None, + phone_number: Optional[List[str]] = None, + web3_wallet: Optional[List[str]] = None, + username: Optional[Nullable[str]] = None, + password: Optional[Nullable[str]] = None, + password_digest: Optional[str] = None, + password_hasher: Optional[models.PasswordHasher] = None, + skip_password_checks: Optional[bool] = None, + skip_password_requirement: Optional[bool] = None, + totp_secret: Optional[str] = None, + backup_codes: Optional[List[str]] = None, + public_metadata: Optional[Union[models.CreateUserPublicMetadata, models.CreateUserPublicMetadataTypedDict]] = None, + private_metadata: Optional[Union[models.CreateUserPrivateMetadata, models.CreateUserPrivateMetadataTypedDict]] = None, + unsafe_metadata: Optional[Union[models.CreateUserUnsafeMetadata, models.CreateUserUnsafeMetadataTypedDict]] = None, + created_at: Optional[str] = None, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.User: + r"""Create a new user + + Creates a new user. Your user management settings determine how you should setup your user model. + + Any email address and phone number created using this method will be marked as verified. + + Note: If you are performing a migration, check out our guide on [zero downtime migrations](https://clerk.com/docs/deployments/migrate-overview). + + A rate limit rule of 20 requests per 10 seconds is applied to this endpoint. + + :param external_id: The ID of the user as used in your external systems or your previous authentication solution. Must be unique across your instance. + :param first_name: The first name to assign to the user + :param last_name: The last name to assign to the user + :param email_address: Email addresses to add to the user. Must be unique across your instance. The first email address will be set as the user's primary email address. + :param phone_number: Phone numbers to add to the user. Must be unique across your instance. The first phone number will be set as the user's primary phone number. + :param web3_wallet: Web3 wallets to add to the user. Must be unique across your instance. The first wallet will be set as the user's primary wallet. + :param username: The username to give to the user. It must be unique across your instance. + :param password: The plaintext password to give the user. Must be at least 8 characters long, and can not be in any list of hacked passwords. + :param password_digest: In case you already have the password digests and not the passwords, you can use them for the newly created user via this property. The digests should be generated with one of the supported algorithms. The hashing algorithm can be specified using the `password_hasher` property. + :param password_hasher: The hashing algorithm that was used to generate the password digest. The algorithms we support at the moment are [bcrypt](https://en.wikipedia.org/wiki/Bcrypt), [bcrypt_sha256_django](https://docs.djangoproject.com/en/4.0/topics/auth/passwords/), [md5](https://en.wikipedia.org/wiki/MD5), pbkdf2_sha256, pbkdf2_sha512, [pbkdf2_sha256_django](https://docs.djangoproject.com/en/4.0/topics/auth/passwords/), [phpass](https://www.openwall.com/phpass/), [scrypt_firebase](https://firebaseopensource.com/projects/firebase/scrypt/), [scrypt_werkzeug](https://werkzeug.palletsprojects.com/en/3.0.x/utils/#werkzeug.security.generate_password_hash), [sha256](https://en.wikipedia.org/wiki/SHA-2) and the [argon2](https://argon2.online/) variants argon2i and argon2id. If you need support for any particular hashing algorithm, [please let us know](https://clerk.com/support). Note: for password hashers considered insecure (at this moment MD5 and SHA256), the corresponding user password hashes will be transparently migrated to Bcrypt (a secure hasher) upon the user's first successful password sign in. Insecure schemes are marked with `(insecure)` in the list below. Each of the supported hashers expects the incoming digest to be in a particular format. Specifically: **bcrypt:** The digest should be of the following form: `$$$` **bcrypt_sha256_django:** This is the Django-specific variant of Bcrypt, using SHA256 hashing function. The format should be as follows (as exported from Django): `bcrypt_sha256$$$$` **md5** (insecure): The digest should follow the regular form e.g.: `5f4dcc3b5aa765d61d8327deb882cf99` **pbkdf2_sha256:** This is the PBKDF2 algorithm using the SHA256 hashing function. The format should be as follows: `pbkdf2_sha256$$$` Note: Both the salt and the hash are expected to be base64-encoded. **pbkdf2_sha512:** This is the PBKDF2 algorithm using the SHA512 hashing function. The format should be as follows: `pbkdf2_sha512$$$` _iterations:_ The number of iterations used. Must be an integer less than 420000. _salt:_ The salt used when generating the hash. Must be less than 1024 bytes. _hash:_ The hex-encoded hash. Must have been generated with a key length less than 1024 bytes. **pbkdf2_sha256_django:** This is the Django-specific variant of PBKDF2 and the digest should have the following format (as exported from Django): `pbkdf2_sha256$$$` Note: The salt is expected to be un-encoded, the hash is expected base64-encoded. **pbkdf2_sha1:** This is similar to pkbdf2_sha256_django, but with two differences: 1. uses sha1 instead of sha256 2. accepts the hash as a hex-encoded string The format is the following: `pbkdf2_sha1$$$` **phpass:** Portable public domain password hashing framework for use in PHP applications. Digests hashed with phpass have the following sections: The format is the following: `$P$` - $P$ is the prefix used to identify phpass hashes. - rounds is a single character encoding a 6-bit integer representing the number of rounds used. - salt is eight characters drawn from [./0-9A-Za-z], providing a 48-bit salt. - checksum is 22 characters drawn from the same set, encoding the 128-bit checksum with MD5. **scrypt_firebase:** The Firebase-specific variant of scrypt. The value is expected to have 6 segments separated by the $ character and include the following information: _hash:_ The actual Base64 hash. This can be retrieved when exporting the user from Firebase. _salt:_ The salt used to generate the above hash. Again, this is given when exporting the user. _signer key:_ The base64 encoded signer key. _salt separator:_ The base64 encoded salt separator. _rounds:_ The number of rounds the algorithm needs to run. _memory cost:_ The cost of the algorithm run The first 2 (hash and salt) are per user and can be retrieved when exporting the user from Firebase. The other 4 values (signer key, salt separator, rounds and memory cost) are project-wide settings and can be retrieved from the project's password hash parameters. Once you have all these, you can combine it in the following format and send this as the digest in order for Clerk to accept it: `$$$$$` **scrypt_werkzeug:** The Werkzeug-specific variant of scrypt. The value is expected to have 3 segments separated by the $ character and include the following information: _algorithm args:_ The algorithm used to generate the hash. _salt:_ The salt used to generate the above hash. _hash:_ The actual Base64 hash. The algorithm args are the parameters used to generate the hash and are included in the digest. **argon2i:** Algorithms in the argon2 family generate digests that encode the following information: _version (v):_ The argon version, version 19 is assumed _memory (m):_ The memory used by the algorithm (in kibibytes) _iterations (t):_ The number of iterations to perform _parallelism (p):_ The number of threads to use Parts are demarcated by the `$` character, with the first part identifying the algorithm variant. The middle part is a comma-separated list of the encoding options (memory, iterations, parallelism). The final part is the actual digest. `$argon2i$v=19$m=4096,t=3,p=1$4t6CL3P7YiHBtwESXawI8Hm20zJj4cs7/4/G3c187e0$m7RQFczcKr5bIR0IIxbpO2P0tyrLjf3eUW3M3QSwnLc` **argon2id:** See the previous algorithm for an explanation of the formatting. For the argon2id case, the value of the algorithm in the first part of the digest is `argon2id`: `$argon2id$v=19$m=64,t=4,p=8$Z2liZXJyaXNo$iGXEpMBTDYQ8G/71tF0qGjxRHEmR3gpGULcE93zUJVU` **sha256** (insecure): The digest should be a 64-length hex string, e.g.: `9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08` **sha256_salted** (insecure): The digest should be a 64-length hex string with a salt. The format is the following: `$` The value is expected to have 2 segments separated by the $ character and include the following information: _hash:_ The sha256 hash, a 64-length hex string. _salt:_ The salt used to generate the above hash. Must be between 1 and 1024 bits. + :param skip_password_checks: When set to `true` all password checks are skipped. It is recommended to use this method only when migrating plaintext passwords to Clerk. Upon migration the user base should be prompted to pick stronger password. + :param skip_password_requirement: When set to `true`, `password` is not required anymore when creating the user and can be omitted. This is useful when you are trying to create a user that doesn't have a password, in an instance that is using passwords. Please note that you cannot use this flag if password is the only way for a user to sign into your instance. + :param totp_secret: In case TOTP is configured on the instance, you can provide the secret to enable it on the newly created user without the need to reset it. Please note that currently the supported options are: * Period: 30 seconds * Code length: 6 digits * Algorithm: SHA1 + :param backup_codes: If Backup Codes are configured on the instance, you can provide them to enable it on the newly created user without the need to reset them. You must provide the backup codes in plain format or the corresponding bcrypt digest. + :param public_metadata: Metadata saved on the user, that is visible to both your Frontend and Backend APIs + :param private_metadata: Metadata saved on the user, that is only visible to your Backend API + :param unsafe_metadata: Metadata saved on the user, that can be updated from both the Frontend and Backend APIs. Note: Since this data can be modified from the frontend, it is not guaranteed to be safe. + :param created_at: A custom date/time denoting _when_ the user signed up to the application, specified in RFC3339 format (e.g. `2012-10-20T07:15:20.902Z`). + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.CreateUserRequestBody( + external_id=external_id, + first_name=first_name, + last_name=last_name, + email_address=email_address, + phone_number=phone_number, + web3_wallet=web3_wallet, + username=username, + password=password, + password_digest=password_digest, + password_hasher=password_hasher, + skip_password_checks=skip_password_checks, + skip_password_requirement=skip_password_requirement, + totp_secret=totp_secret, + backup_codes=backup_codes, + public_metadata=utils.unmarshal(public_metadata, models.CreateUserPublicMetadata) if not isinstance(public_metadata, BaseModel) and public_metadata is not None else public_metadata, + private_metadata=utils.unmarshal(private_metadata, models.CreateUserPrivateMetadata) if not isinstance(private_metadata, BaseModel) and private_metadata is not None else private_metadata, + unsafe_metadata=utils.unmarshal(unsafe_metadata, models.CreateUserUnsafeMetadata) if not isinstance(unsafe_metadata, BaseModel) and unsafe_metadata is not None else unsafe_metadata, + created_at=created_at, + ) + + req = self.build_request( + method="POST", + path="/users", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=True, + request_has_path_params=False, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + get_serialized_body=lambda: utils.serialize_request_body(request, False, False, "json", models.CreateUserRequestBody), + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="CreateUser", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","401","403","422","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.User]) + if utils.match_response(http_res, ["400","401","403","422"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + def count( + self, *, + email_address: Optional[List[str]] = None, + phone_number: Optional[List[str]] = None, + external_id: Optional[List[str]] = None, + username: Optional[List[str]] = None, + web3_wallet: Optional[List[str]] = None, + user_id: Optional[List[str]] = None, + query: Optional[str] = None, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.TotalCount: + r"""Count users + + Returns a total count of all users that match the given filtering criteria. + + :param email_address: Counts users with the specified email addresses. Accepts up to 100 email addresses. Any email addresses not found are ignored. + :param phone_number: Counts users with the specified phone numbers. Accepts up to 100 phone numbers. Any phone numbers not found are ignored. + :param external_id: Counts users with the specified external ids. Accepts up to 100 external ids. Any external ids not found are ignored. + :param username: Counts users with the specified usernames. Accepts up to 100 usernames. Any usernames not found are ignored. + :param web3_wallet: Counts users with the specified web3 wallet addresses. Accepts up to 100 web3 wallet addresses. Any web3 wallet addressed not found are ignored. + :param user_id: Counts users with the user ids specified. Accepts up to 100 user ids. Any user ids not found are ignored. + :param query: Counts users that match the given query. For possible matches, we check the email addresses, phone numbers, usernames, web3 wallets, user ids, first and last names. The query value doesn't need to match the exact value you are looking for, it is capable of partial matches as well. + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.GetUsersCountRequest( + email_address=email_address, + phone_number=phone_number, + external_id=external_id, + username=username, + web3_wallet=web3_wallet, + user_id=user_id, + query=query, + ) + + req = self.build_request( + method="GET", + path="/users/count", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=False, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="GetUsersCount", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["422","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.TotalCount]) + if utils.match_response(http_res, "422", "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + async def count_async( + self, *, + email_address: Optional[List[str]] = None, + phone_number: Optional[List[str]] = None, + external_id: Optional[List[str]] = None, + username: Optional[List[str]] = None, + web3_wallet: Optional[List[str]] = None, + user_id: Optional[List[str]] = None, + query: Optional[str] = None, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.TotalCount: + r"""Count users + + Returns a total count of all users that match the given filtering criteria. + + :param email_address: Counts users with the specified email addresses. Accepts up to 100 email addresses. Any email addresses not found are ignored. + :param phone_number: Counts users with the specified phone numbers. Accepts up to 100 phone numbers. Any phone numbers not found are ignored. + :param external_id: Counts users with the specified external ids. Accepts up to 100 external ids. Any external ids not found are ignored. + :param username: Counts users with the specified usernames. Accepts up to 100 usernames. Any usernames not found are ignored. + :param web3_wallet: Counts users with the specified web3 wallet addresses. Accepts up to 100 web3 wallet addresses. Any web3 wallet addressed not found are ignored. + :param user_id: Counts users with the user ids specified. Accepts up to 100 user ids. Any user ids not found are ignored. + :param query: Counts users that match the given query. For possible matches, we check the email addresses, phone numbers, usernames, web3 wallets, user ids, first and last names. The query value doesn't need to match the exact value you are looking for, it is capable of partial matches as well. + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.GetUsersCountRequest( + email_address=email_address, + phone_number=phone_number, + external_id=external_id, + username=username, + web3_wallet=web3_wallet, + user_id=user_id, + query=query, + ) + + req = self.build_request( + method="GET", + path="/users/count", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=False, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="GetUsersCount", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["422","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.TotalCount]) + if utils.match_response(http_res, "422", "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + def get( + self, *, + user_id: str, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.User: + r"""Retrieve a user + + Retrieve the details of a user + + :param user_id: The ID of the user to retrieve + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.GetUserRequest( + user_id=user_id, + ) + + req = self.build_request( + method="GET", + path="/users/{user_id}", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="GetUser", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","401","404","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.User]) + if utils.match_response(http_res, ["400","401","404"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + async def get_async( + self, *, + user_id: str, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.User: + r"""Retrieve a user + + Retrieve the details of a user + + :param user_id: The ID of the user to retrieve + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.GetUserRequest( + user_id=user_id, + ) + + req = self.build_request( + method="GET", + path="/users/{user_id}", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="GetUser", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","401","404","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.User]) + if utils.match_response(http_res, ["400","401","404"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + def update( + self, *, + user_id: str, + external_id: Optional[Nullable[str]] = None, + first_name: Optional[Nullable[str]] = None, + last_name: Optional[Nullable[str]] = None, + primary_email_address_id: Optional[str] = None, + notify_primary_email_address_changed: Optional[bool] = None, + primary_phone_number_id: Optional[str] = None, + primary_web3_wallet_id: Optional[str] = None, + username: Optional[Nullable[str]] = None, + profile_image_id: Optional[Nullable[str]] = None, + password: Optional[Nullable[str]] = None, + password_digest: Optional[str] = None, + password_hasher: Optional[models.UpdateUserPasswordHasher] = None, + skip_password_checks: Optional[Nullable[bool]] = None, + sign_out_of_other_sessions: Optional[Nullable[bool]] = None, + totp_secret: Optional[str] = None, + backup_codes: Optional[List[str]] = None, + public_metadata: Optional[Union[models.UpdateUserPublicMetadata, models.UpdateUserPublicMetadataTypedDict]] = None, + private_metadata: Optional[Union[models.UpdateUserPrivateMetadata, models.UpdateUserPrivateMetadataTypedDict]] = None, + unsafe_metadata: Optional[Union[models.UpdateUserUnsafeMetadata, models.UpdateUserUnsafeMetadataTypedDict]] = None, + delete_self_enabled: Optional[Nullable[bool]] = None, + create_organization_enabled: Optional[Nullable[bool]] = None, + created_at: Optional[str] = None, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.User: + r"""Update a user + + Update a user's attributes. + + You can set the user's primary contact identifiers (email address and phone numbers) by updating the `primary_email_address_id` and `primary_phone_number_id` attributes respectively. + Both IDs should correspond to verified identifications that belong to the user. + + You can remove a user's username by setting the username attribute to null or the blank string \"\". + This is a destructive action; the identification will be deleted forever. + Usernames can be removed only if they are optional in your instance settings and there's at least one other identifier which can be used for authentication. + + This endpoint allows changing a user's password. When passing the `password` parameter directly you have two further options. + You can ignore the password policy checks for your instance by setting the `skip_password_checks` parameter to `true`. + You can also choose to sign the user out of all their active sessions on any device once the password is updated. Just set `sign_out_of_other_sessions` to `true`. + + :param user_id: The ID of the user to update + :param external_id: The ID of the user as used in your external systems or your previous authentication solution. Must be unique across your instance. + :param first_name: The first name to assign to the user + :param last_name: The last name to assign to the user + :param primary_email_address_id: The ID of the email address to set as primary. It must be verified, and present on the current user. + :param notify_primary_email_address_changed: If set to `true`, the user will be notified that their primary email address has changed. By default, no notification is sent. + :param primary_phone_number_id: The ID of the phone number to set as primary. It must be verified, and present on the current user. + :param primary_web3_wallet_id: The ID of the web3 wallets to set as primary. It must be verified, and present on the current user. + :param username: The username to give to the user. It must be unique across your instance. + :param profile_image_id: The ID of the image to set as the user's profile image + :param password: The plaintext password to give the user. Must be at least 8 characters long, and can not be in any list of hacked passwords. + :param password_digest: In case you already have the password digests and not the passwords, you can use them for the newly created user via this property. The digests should be generated with one of the supported algorithms. The hashing algorithm can be specified using the `password_hasher` property. + :param password_hasher: The hashing algorithm that was used to generate the password digest. The algorithms we support at the moment are [bcrypt](https://en.wikipedia.org/wiki/Bcrypt), [bcrypt_sha256_django](https://docs.djangoproject.com/en/4.0/topics/auth/passwords/), [md5](https://en.wikipedia.org/wiki/MD5), pbkdf2_sha256, pbkdf2_sha512, [pbkdf2_sha256_django](https://docs.djangoproject.com/en/4.0/topics/auth/passwords/), [phpass](https://www.openwall.com/phpass/), [scrypt_firebase](https://firebaseopensource.com/projects/firebase/scrypt/), [sha256](https://en.wikipedia.org/wiki/SHA-2), [scrypt_werkzeug](https://werkzeug.palletsprojects.com/en/3.0.x/utils/#werkzeug.security.generate_password_hash) and the [argon2](https://argon2.online/) variants argon2i and argon2id. If you need support for any particular hashing algorithm, [please let us know](https://clerk.com/support). Note: for password hashers considered insecure (at this moment MD5 and SHA256), the corresponding user password hashes will be transparently migrated to Bcrypt (a secure hasher) upon the user's first successful password sign in. Insecure schemes are marked with `(insecure)` in the list below. Each of the supported hashers expects the incoming digest to be in a particular format. Specifically: **bcrypt:** The digest should be of the following form: `$$$` **bcrypt_sha256_django:** This is the Django-specific variant of Bcrypt, using SHA256 hashing function. The format should be as follows (as exported from Django): `bcrypt_sha256$$$$` **md5** (insecure): The digest should follow the regular form e.g.: `5f4dcc3b5aa765d61d8327deb882cf99` **pbkdf2_sha256:** This is the PBKDF2 algorithm using the SHA256 hashing function. The format should be as follows: `pbkdf2_sha256$$$` Note: Both the salt and the hash are expected to be base64-encoded. **pbkdf2_sha512:** This is the PBKDF2 algorithm using the SHA512 hashing function. The format should be as follows: `pbkdf2_sha512$$$` _iterations:_ The number of iterations used. Must be an integer less than 420000. _salt:_ The salt used when generating the hash. Must be less than bytes. _hash:_ The hex-encoded hash. Must have been generated with a key length less than 1024 bytes. **pbkdf2_sha256_django:** This is the Django-specific variant of PBKDF2 and the digest should have the following format (as exported from Django): `pbkdf2_sha256$$$` Note: The salt is expected to be un-encoded, the hash is expected base64-encoded. **pbkdf2_sha1:** This is similar to pkbdf2_sha256_django, but with two differences: 1. uses sha1 instead of sha256 2. accepts the hash as a hex-encoded string The format is the following: `pbkdf2_sha1$$$` **phpass:** Portable public domain password hashing framework for use in PHP applications. Digests hashed with phpass have the following sections: The format is the following: `$P$` - $P$ is the prefix used to identify phpass hashes. - rounds is a single character encoding a 6-bit integer representing the number of rounds used. - salt is eight characters drawn from [./0-9A-Za-z], providing a 48-bit salt. - checksum is 22 characters drawn from the same set, encoding the 128-bit checksum with MD5. **scrypt_firebase:** The Firebase-specific variant of scrypt. The value is expected to have 6 segments separated by the $ character and include the following information: _hash:_ The actual Base64 hash. This can be retrieved when exporting the user from Firebase. _salt:_ The salt used to generate the above hash. Again, this is given when exporting the user. _signer key:_ The base64 encoded signer key. _salt separator:_ The base64 encoded salt separator. _rounds:_ The number of rounds the algorithm needs to run. _memory cost:_ The cost of the algorithm run The first 2 (hash and salt) are per user and can be retrieved when exporting the user from Firebase. The other 4 values (signer key, salt separator, rounds and memory cost) are project-wide settings and can be retrieved from the project's password hash parameters. Once you have all these, you can combine it in the following format and send this as the digest in order for Clerk to accept it: `$$$$$` **scrypt_werkzeug:** The Werkzeug-specific variant of scrypt. The value is expected to have 3 segments separated by the $ character and include the following information: _algorithm args:_ The algorithm used to generate the hash. _salt:_ The salt used to generate the above hash. _hash:_ The actual Base64 hash. The algorithm args are the parameters used to generate the hash and are included in the digest. **argon2i:** Algorithms in the argon2 family generate digests that encode the following information: _version (v):_ The argon version, version 19 is assumed _memory (m):_ The memory used by the algorithm (in kibibytes) _iterations (t):_ The number of iterations to perform _parallelism (p):_ The number of threads to use Parts are demarcated by the `$` character, with the first part identifying the algorithm variant. The middle part is a comma-separated list of the encoding options (memory, iterations, parallelism). The final part is the actual digest. `$argon2i$v=19$m=4096,t=3,p=1$4t6CL3P7YiHBtwESXawI8Hm20zJj4cs7/4/G3c187e0$m7RQFczcKr5bIR0IIxbpO2P0tyrLjf3eUW3M3QSwnLc` **argon2id:** See the previous algorithm for an explanation of the formatting. For the argon2id case, the value of the algorithm in the first part of the digest is `argon2id`: `$argon2id$v=19$m=64,t=4,p=8$Z2liZXJyaXNo$iGXEpMBTDYQ8G/71tF0qGjxRHEmR3gpGULcE93zUJVU` **sha256** (insecure): The digest should be a 64-length hex string, e.g.: `9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08` + :param skip_password_checks: Set it to `true` if you're updating the user's password and want to skip any password policy settings check. This parameter can only be used when providing a `password`. + :param sign_out_of_other_sessions: Set to `true` to sign out the user from all their active sessions once their password is updated. This parameter can only be used when providing a `password`. + :param totp_secret: In case TOTP is configured on the instance, you can provide the secret to enable it on the specific user without the need to reset it. Please note that currently the supported options are: * Period: 30 seconds * Code length: 6 digits * Algorithm: SHA1 + :param backup_codes: If Backup Codes are configured on the instance, you can provide them to enable it on the specific user without the need to reset them. You must provide the backup codes in plain format or the corresponding bcrypt digest. + :param public_metadata: Metadata saved on the user, that is visible to both your Frontend and Backend APIs + :param private_metadata: Metadata saved on the user, that is only visible to your Backend API + :param unsafe_metadata: Metadata saved on the user, that can be updated from both the Frontend and Backend APIs. Note: Since this data can be modified from the frontend, it is not guaranteed to be safe. + :param delete_self_enabled: If true, the user can delete themselves with the Frontend API. + :param create_organization_enabled: If true, the user can create organizations with the Frontend API. + :param created_at: A custom date/time denoting _when_ the user signed up to the application, specified in RFC3339 format (e.g. `2012-10-20T07:15:20.902Z`). + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.UpdateUserRequest( + user_id=user_id, + request_body=models.UpdateUserRequestBody( + external_id=external_id, + first_name=first_name, + last_name=last_name, + primary_email_address_id=primary_email_address_id, + notify_primary_email_address_changed=notify_primary_email_address_changed, + primary_phone_number_id=primary_phone_number_id, + primary_web3_wallet_id=primary_web3_wallet_id, + username=username, + profile_image_id=profile_image_id, + password=password, + password_digest=password_digest, + password_hasher=password_hasher, + skip_password_checks=skip_password_checks, + sign_out_of_other_sessions=sign_out_of_other_sessions, + totp_secret=totp_secret, + backup_codes=backup_codes, + public_metadata=utils.unmarshal(public_metadata, models.UpdateUserPublicMetadata) if not isinstance(public_metadata, BaseModel) and public_metadata is not None else public_metadata, + private_metadata=utils.unmarshal(private_metadata, models.UpdateUserPrivateMetadata) if not isinstance(private_metadata, BaseModel) and private_metadata is not None else private_metadata, + unsafe_metadata=utils.unmarshal(unsafe_metadata, models.UpdateUserUnsafeMetadata) if not isinstance(unsafe_metadata, BaseModel) and unsafe_metadata is not None else unsafe_metadata, + delete_self_enabled=delete_self_enabled, + create_organization_enabled=create_organization_enabled, + created_at=created_at, + ), + ) + + req = self.build_request( + method="PATCH", + path="/users/{user_id}", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=True, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + get_serialized_body=lambda: utils.serialize_request_body(request.request_body, False, False, "json", models.UpdateUserRequestBody), + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="UpdateUser", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","401","404","422","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.User]) + if utils.match_response(http_res, ["400","401","404","422"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + async def update_async( + self, *, + user_id: str, + external_id: Optional[Nullable[str]] = None, + first_name: Optional[Nullable[str]] = None, + last_name: Optional[Nullable[str]] = None, + primary_email_address_id: Optional[str] = None, + notify_primary_email_address_changed: Optional[bool] = None, + primary_phone_number_id: Optional[str] = None, + primary_web3_wallet_id: Optional[str] = None, + username: Optional[Nullable[str]] = None, + profile_image_id: Optional[Nullable[str]] = None, + password: Optional[Nullable[str]] = None, + password_digest: Optional[str] = None, + password_hasher: Optional[models.UpdateUserPasswordHasher] = None, + skip_password_checks: Optional[Nullable[bool]] = None, + sign_out_of_other_sessions: Optional[Nullable[bool]] = None, + totp_secret: Optional[str] = None, + backup_codes: Optional[List[str]] = None, + public_metadata: Optional[Union[models.UpdateUserPublicMetadata, models.UpdateUserPublicMetadataTypedDict]] = None, + private_metadata: Optional[Union[models.UpdateUserPrivateMetadata, models.UpdateUserPrivateMetadataTypedDict]] = None, + unsafe_metadata: Optional[Union[models.UpdateUserUnsafeMetadata, models.UpdateUserUnsafeMetadataTypedDict]] = None, + delete_self_enabled: Optional[Nullable[bool]] = None, + create_organization_enabled: Optional[Nullable[bool]] = None, + created_at: Optional[str] = None, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.User: + r"""Update a user + + Update a user's attributes. + + You can set the user's primary contact identifiers (email address and phone numbers) by updating the `primary_email_address_id` and `primary_phone_number_id` attributes respectively. + Both IDs should correspond to verified identifications that belong to the user. + + You can remove a user's username by setting the username attribute to null or the blank string \"\". + This is a destructive action; the identification will be deleted forever. + Usernames can be removed only if they are optional in your instance settings and there's at least one other identifier which can be used for authentication. + + This endpoint allows changing a user's password. When passing the `password` parameter directly you have two further options. + You can ignore the password policy checks for your instance by setting the `skip_password_checks` parameter to `true`. + You can also choose to sign the user out of all their active sessions on any device once the password is updated. Just set `sign_out_of_other_sessions` to `true`. + + :param user_id: The ID of the user to update + :param external_id: The ID of the user as used in your external systems or your previous authentication solution. Must be unique across your instance. + :param first_name: The first name to assign to the user + :param last_name: The last name to assign to the user + :param primary_email_address_id: The ID of the email address to set as primary. It must be verified, and present on the current user. + :param notify_primary_email_address_changed: If set to `true`, the user will be notified that their primary email address has changed. By default, no notification is sent. + :param primary_phone_number_id: The ID of the phone number to set as primary. It must be verified, and present on the current user. + :param primary_web3_wallet_id: The ID of the web3 wallets to set as primary. It must be verified, and present on the current user. + :param username: The username to give to the user. It must be unique across your instance. + :param profile_image_id: The ID of the image to set as the user's profile image + :param password: The plaintext password to give the user. Must be at least 8 characters long, and can not be in any list of hacked passwords. + :param password_digest: In case you already have the password digests and not the passwords, you can use them for the newly created user via this property. The digests should be generated with one of the supported algorithms. The hashing algorithm can be specified using the `password_hasher` property. + :param password_hasher: The hashing algorithm that was used to generate the password digest. The algorithms we support at the moment are [bcrypt](https://en.wikipedia.org/wiki/Bcrypt), [bcrypt_sha256_django](https://docs.djangoproject.com/en/4.0/topics/auth/passwords/), [md5](https://en.wikipedia.org/wiki/MD5), pbkdf2_sha256, pbkdf2_sha512, [pbkdf2_sha256_django](https://docs.djangoproject.com/en/4.0/topics/auth/passwords/), [phpass](https://www.openwall.com/phpass/), [scrypt_firebase](https://firebaseopensource.com/projects/firebase/scrypt/), [sha256](https://en.wikipedia.org/wiki/SHA-2), [scrypt_werkzeug](https://werkzeug.palletsprojects.com/en/3.0.x/utils/#werkzeug.security.generate_password_hash) and the [argon2](https://argon2.online/) variants argon2i and argon2id. If you need support for any particular hashing algorithm, [please let us know](https://clerk.com/support). Note: for password hashers considered insecure (at this moment MD5 and SHA256), the corresponding user password hashes will be transparently migrated to Bcrypt (a secure hasher) upon the user's first successful password sign in. Insecure schemes are marked with `(insecure)` in the list below. Each of the supported hashers expects the incoming digest to be in a particular format. Specifically: **bcrypt:** The digest should be of the following form: `$$$` **bcrypt_sha256_django:** This is the Django-specific variant of Bcrypt, using SHA256 hashing function. The format should be as follows (as exported from Django): `bcrypt_sha256$$$$` **md5** (insecure): The digest should follow the regular form e.g.: `5f4dcc3b5aa765d61d8327deb882cf99` **pbkdf2_sha256:** This is the PBKDF2 algorithm using the SHA256 hashing function. The format should be as follows: `pbkdf2_sha256$$$` Note: Both the salt and the hash are expected to be base64-encoded. **pbkdf2_sha512:** This is the PBKDF2 algorithm using the SHA512 hashing function. The format should be as follows: `pbkdf2_sha512$$$` _iterations:_ The number of iterations used. Must be an integer less than 420000. _salt:_ The salt used when generating the hash. Must be less than bytes. _hash:_ The hex-encoded hash. Must have been generated with a key length less than 1024 bytes. **pbkdf2_sha256_django:** This is the Django-specific variant of PBKDF2 and the digest should have the following format (as exported from Django): `pbkdf2_sha256$$$` Note: The salt is expected to be un-encoded, the hash is expected base64-encoded. **pbkdf2_sha1:** This is similar to pkbdf2_sha256_django, but with two differences: 1. uses sha1 instead of sha256 2. accepts the hash as a hex-encoded string The format is the following: `pbkdf2_sha1$$$` **phpass:** Portable public domain password hashing framework for use in PHP applications. Digests hashed with phpass have the following sections: The format is the following: `$P$` - $P$ is the prefix used to identify phpass hashes. - rounds is a single character encoding a 6-bit integer representing the number of rounds used. - salt is eight characters drawn from [./0-9A-Za-z], providing a 48-bit salt. - checksum is 22 characters drawn from the same set, encoding the 128-bit checksum with MD5. **scrypt_firebase:** The Firebase-specific variant of scrypt. The value is expected to have 6 segments separated by the $ character and include the following information: _hash:_ The actual Base64 hash. This can be retrieved when exporting the user from Firebase. _salt:_ The salt used to generate the above hash. Again, this is given when exporting the user. _signer key:_ The base64 encoded signer key. _salt separator:_ The base64 encoded salt separator. _rounds:_ The number of rounds the algorithm needs to run. _memory cost:_ The cost of the algorithm run The first 2 (hash and salt) are per user and can be retrieved when exporting the user from Firebase. The other 4 values (signer key, salt separator, rounds and memory cost) are project-wide settings and can be retrieved from the project's password hash parameters. Once you have all these, you can combine it in the following format and send this as the digest in order for Clerk to accept it: `$$$$$` **scrypt_werkzeug:** The Werkzeug-specific variant of scrypt. The value is expected to have 3 segments separated by the $ character and include the following information: _algorithm args:_ The algorithm used to generate the hash. _salt:_ The salt used to generate the above hash. _hash:_ The actual Base64 hash. The algorithm args are the parameters used to generate the hash and are included in the digest. **argon2i:** Algorithms in the argon2 family generate digests that encode the following information: _version (v):_ The argon version, version 19 is assumed _memory (m):_ The memory used by the algorithm (in kibibytes) _iterations (t):_ The number of iterations to perform _parallelism (p):_ The number of threads to use Parts are demarcated by the `$` character, with the first part identifying the algorithm variant. The middle part is a comma-separated list of the encoding options (memory, iterations, parallelism). The final part is the actual digest. `$argon2i$v=19$m=4096,t=3,p=1$4t6CL3P7YiHBtwESXawI8Hm20zJj4cs7/4/G3c187e0$m7RQFczcKr5bIR0IIxbpO2P0tyrLjf3eUW3M3QSwnLc` **argon2id:** See the previous algorithm for an explanation of the formatting. For the argon2id case, the value of the algorithm in the first part of the digest is `argon2id`: `$argon2id$v=19$m=64,t=4,p=8$Z2liZXJyaXNo$iGXEpMBTDYQ8G/71tF0qGjxRHEmR3gpGULcE93zUJVU` **sha256** (insecure): The digest should be a 64-length hex string, e.g.: `9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08` + :param skip_password_checks: Set it to `true` if you're updating the user's password and want to skip any password policy settings check. This parameter can only be used when providing a `password`. + :param sign_out_of_other_sessions: Set to `true` to sign out the user from all their active sessions once their password is updated. This parameter can only be used when providing a `password`. + :param totp_secret: In case TOTP is configured on the instance, you can provide the secret to enable it on the specific user without the need to reset it. Please note that currently the supported options are: * Period: 30 seconds * Code length: 6 digits * Algorithm: SHA1 + :param backup_codes: If Backup Codes are configured on the instance, you can provide them to enable it on the specific user without the need to reset them. You must provide the backup codes in plain format or the corresponding bcrypt digest. + :param public_metadata: Metadata saved on the user, that is visible to both your Frontend and Backend APIs + :param private_metadata: Metadata saved on the user, that is only visible to your Backend API + :param unsafe_metadata: Metadata saved on the user, that can be updated from both the Frontend and Backend APIs. Note: Since this data can be modified from the frontend, it is not guaranteed to be safe. + :param delete_self_enabled: If true, the user can delete themselves with the Frontend API. + :param create_organization_enabled: If true, the user can create organizations with the Frontend API. + :param created_at: A custom date/time denoting _when_ the user signed up to the application, specified in RFC3339 format (e.g. `2012-10-20T07:15:20.902Z`). + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.UpdateUserRequest( + user_id=user_id, + request_body=models.UpdateUserRequestBody( + external_id=external_id, + first_name=first_name, + last_name=last_name, + primary_email_address_id=primary_email_address_id, + notify_primary_email_address_changed=notify_primary_email_address_changed, + primary_phone_number_id=primary_phone_number_id, + primary_web3_wallet_id=primary_web3_wallet_id, + username=username, + profile_image_id=profile_image_id, + password=password, + password_digest=password_digest, + password_hasher=password_hasher, + skip_password_checks=skip_password_checks, + sign_out_of_other_sessions=sign_out_of_other_sessions, + totp_secret=totp_secret, + backup_codes=backup_codes, + public_metadata=utils.unmarshal(public_metadata, models.UpdateUserPublicMetadata) if not isinstance(public_metadata, BaseModel) and public_metadata is not None else public_metadata, + private_metadata=utils.unmarshal(private_metadata, models.UpdateUserPrivateMetadata) if not isinstance(private_metadata, BaseModel) and private_metadata is not None else private_metadata, + unsafe_metadata=utils.unmarshal(unsafe_metadata, models.UpdateUserUnsafeMetadata) if not isinstance(unsafe_metadata, BaseModel) and unsafe_metadata is not None else unsafe_metadata, + delete_self_enabled=delete_self_enabled, + create_organization_enabled=create_organization_enabled, + created_at=created_at, + ), + ) + + req = self.build_request( + method="PATCH", + path="/users/{user_id}", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=True, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + get_serialized_body=lambda: utils.serialize_request_body(request.request_body, False, False, "json", models.UpdateUserRequestBody), + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="UpdateUser", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","401","404","422","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.User]) + if utils.match_response(http_res, ["400","401","404","422"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + def delete( + self, *, + user_id: str, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.DeletedObject: + r"""Delete a user + + Delete the specified user + + :param user_id: The ID of the user to delete + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.DeleteUserRequest( + user_id=user_id, + ) + + req = self.build_request( + method="DELETE", + path="/users/{user_id}", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="DeleteUser", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","401","404","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.DeletedObject]) + if utils.match_response(http_res, ["400","401","404"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + async def delete_async( + self, *, + user_id: str, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.DeletedObject: + r"""Delete a user + + Delete the specified user + + :param user_id: The ID of the user to delete + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.DeleteUserRequest( + user_id=user_id, + ) + + req = self.build_request( + method="DELETE", + path="/users/{user_id}", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="DeleteUser", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","401","404","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.DeletedObject]) + if utils.match_response(http_res, ["400","401","404"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + def ban( + self, *, + user_id: str, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.User: + r"""Ban a user + + Marks the given user as banned, which means that all their sessions are revoked and they are not allowed to sign in again. + + :param user_id: The ID of the user to ban + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.BanUserRequest( + user_id=user_id, + ) + + req = self.build_request( + method="POST", + path="/users/{user_id}/ban", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="BanUser", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["402","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.User]) + if utils.match_response(http_res, "402", "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + async def ban_async( + self, *, + user_id: str, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.User: + r"""Ban a user + + Marks the given user as banned, which means that all their sessions are revoked and they are not allowed to sign in again. + + :param user_id: The ID of the user to ban + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.BanUserRequest( + user_id=user_id, + ) + + req = self.build_request( + method="POST", + path="/users/{user_id}/ban", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="BanUser", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["402","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.User]) + if utils.match_response(http_res, "402", "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + def unban( + self, *, + user_id: str, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.User: + r"""Unban a user + + Removes the ban mark from the given user. + + :param user_id: The ID of the user to unban + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.UnbanUserRequest( + user_id=user_id, + ) + + req = self.build_request( + method="POST", + path="/users/{user_id}/unban", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="UnbanUser", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["402","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.User]) + if utils.match_response(http_res, "402", "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + async def unban_async( + self, *, + user_id: str, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.User: + r"""Unban a user + + Removes the ban mark from the given user. + + :param user_id: The ID of the user to unban + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.UnbanUserRequest( + user_id=user_id, + ) + + req = self.build_request( + method="POST", + path="/users/{user_id}/unban", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="UnbanUser", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["402","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.User]) + if utils.match_response(http_res, "402", "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + def lock( + self, *, + user_id: str, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.User: + r"""Lock a user + + Marks the given user as locked, which means they are not allowed to sign in again until the lock expires. + Lock duration can be configured in the instance's restrictions settings. + + :param user_id: The ID of the user to lock + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.LockUserRequest( + user_id=user_id, + ) + + req = self.build_request( + method="POST", + path="/users/{user_id}/lock", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="LockUser", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["403","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.User]) + if utils.match_response(http_res, "403", "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + async def lock_async( + self, *, + user_id: str, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.User: + r"""Lock a user + + Marks the given user as locked, which means they are not allowed to sign in again until the lock expires. + Lock duration can be configured in the instance's restrictions settings. + + :param user_id: The ID of the user to lock + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.LockUserRequest( + user_id=user_id, + ) + + req = self.build_request( + method="POST", + path="/users/{user_id}/lock", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="LockUser", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["403","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.User]) + if utils.match_response(http_res, "403", "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + def unlock( + self, *, + user_id: str, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.User: + r"""Unlock a user + + Removes the lock from the given user. + + :param user_id: The ID of the user to unlock + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.UnlockUserRequest( + user_id=user_id, + ) + + req = self.build_request( + method="POST", + path="/users/{user_id}/unlock", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="UnlockUser", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["403","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.User]) + if utils.match_response(http_res, "403", "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + async def unlock_async( + self, *, + user_id: str, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.User: + r"""Unlock a user + + Removes the lock from the given user. + + :param user_id: The ID of the user to unlock + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.UnlockUserRequest( + user_id=user_id, + ) + + req = self.build_request( + method="POST", + path="/users/{user_id}/unlock", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="UnlockUser", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["403","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.User]) + if utils.match_response(http_res, "403", "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + def set_profile_image( + self, *, + user_id: str, + file: Optional[Union[models.File, models.FileTypedDict]] = None, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.User: + r"""Set user profile image + + Update a user's profile image + + :param user_id: The ID of the user to update the profile image for + :param file: + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.SetUserProfileImageRequest( + user_id=user_id, + request_body=models.SetUserProfileImageRequestBody( + file=utils.unmarshal(file, models.File) if not isinstance(file, BaseModel) and file is not None else file, + ), + ) + + req = self.build_request( + method="POST", + path="/users/{user_id}/profile_image", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=True, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + get_serialized_body=lambda: utils.serialize_request_body(request.request_body, False, False, "multipart", models.SetUserProfileImageRequestBody), + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="SetUserProfileImage", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","401","404","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.User]) + if utils.match_response(http_res, ["400","401","404"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + async def set_profile_image_async( + self, *, + user_id: str, + file: Optional[Union[models.File, models.FileTypedDict]] = None, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.User: + r"""Set user profile image + + Update a user's profile image + + :param user_id: The ID of the user to update the profile image for + :param file: + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.SetUserProfileImageRequest( + user_id=user_id, + request_body=models.SetUserProfileImageRequestBody( + file=utils.unmarshal(file, models.File) if not isinstance(file, BaseModel) and file is not None else file, + ), + ) + + req = self.build_request( + method="POST", + path="/users/{user_id}/profile_image", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=True, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + get_serialized_body=lambda: utils.serialize_request_body(request.request_body, False, False, "multipart", models.SetUserProfileImageRequestBody), + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="SetUserProfileImage", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","401","404","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.User]) + if utils.match_response(http_res, ["400","401","404"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + def delete_profile_image( + self, *, + user_id: str, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.User: + r"""Delete user profile image + + Delete a user's profile image + + :param user_id: The ID of the user to delete the profile image for + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.DeleteUserProfileImageRequest( + user_id=user_id, + ) + + req = self.build_request( + method="DELETE", + path="/users/{user_id}/profile_image", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="DeleteUserProfileImage", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["404","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.User]) + if utils.match_response(http_res, "404", "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + async def delete_profile_image_async( + self, *, + user_id: str, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.User: + r"""Delete user profile image + + Delete a user's profile image + + :param user_id: The ID of the user to delete the profile image for + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.DeleteUserProfileImageRequest( + user_id=user_id, + ) + + req = self.build_request( + method="DELETE", + path="/users/{user_id}/profile_image", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="DeleteUserProfileImage", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["404","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.User]) + if utils.match_response(http_res, "404", "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + def update_metadata( + self, *, + user_id: str, + public_metadata: Optional[Dict[str, Any]] = None, + private_metadata: Optional[Union[models.UpdateUserMetadataPrivateMetadata, models.UpdateUserMetadataPrivateMetadataTypedDict]] = None, + unsafe_metadata: Optional[Union[models.UpdateUserMetadataUnsafeMetadata, models.UpdateUserMetadataUnsafeMetadataTypedDict]] = None, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.User: + r"""Merge and update a user's metadata + + Update a user's metadata attributes by merging existing values with the provided parameters. + + This endpoint behaves differently than the *Update a user* endpoint. + Metadata values will not be replaced entirely. + Instead, a deep merge will be performed. + Deep means that any nested JSON objects will be merged as well. + + You can remove metadata keys at any level by setting their value to `null`. + + :param user_id: The ID of the user whose metadata will be updated and merged + :param public_metadata: Metadata saved on the user, that is visible to both your frontend and backend. The new object will be merged with the existing value. + :param private_metadata: Metadata saved on the user that is only visible to your backend. The new object will be merged with the existing value. + :param unsafe_metadata: Metadata saved on the user, that can be updated from both the Frontend and Backend APIs. The new object will be merged with the existing value. Note: Since this data can be modified from the frontend, it is not guaranteed to be safe. + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.UpdateUserMetadataRequest( + user_id=user_id, + request_body=models.UpdateUserMetadataRequestBody( + public_metadata=public_metadata, + private_metadata=utils.unmarshal(private_metadata, models.UpdateUserMetadataPrivateMetadata) if not isinstance(private_metadata, BaseModel) and private_metadata is not None else private_metadata, + unsafe_metadata=utils.unmarshal(unsafe_metadata, models.UpdateUserMetadataUnsafeMetadata) if not isinstance(unsafe_metadata, BaseModel) and unsafe_metadata is not None else unsafe_metadata, + ), + ) + + req = self.build_request( + method="PATCH", + path="/users/{user_id}/metadata", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + get_serialized_body=lambda: utils.serialize_request_body(request.request_body, False, True, "json", Optional[models.UpdateUserMetadataRequestBody]), + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="UpdateUserMetadata", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","401","404","422","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.User]) + if utils.match_response(http_res, ["400","401","404","422"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + async def update_metadata_async( + self, *, + user_id: str, + public_metadata: Optional[Dict[str, Any]] = None, + private_metadata: Optional[Union[models.UpdateUserMetadataPrivateMetadata, models.UpdateUserMetadataPrivateMetadataTypedDict]] = None, + unsafe_metadata: Optional[Union[models.UpdateUserMetadataUnsafeMetadata, models.UpdateUserMetadataUnsafeMetadataTypedDict]] = None, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.User: + r"""Merge and update a user's metadata + + Update a user's metadata attributes by merging existing values with the provided parameters. + + This endpoint behaves differently than the *Update a user* endpoint. + Metadata values will not be replaced entirely. + Instead, a deep merge will be performed. + Deep means that any nested JSON objects will be merged as well. + + You can remove metadata keys at any level by setting their value to `null`. + + :param user_id: The ID of the user whose metadata will be updated and merged + :param public_metadata: Metadata saved on the user, that is visible to both your frontend and backend. The new object will be merged with the existing value. + :param private_metadata: Metadata saved on the user that is only visible to your backend. The new object will be merged with the existing value. + :param unsafe_metadata: Metadata saved on the user, that can be updated from both the Frontend and Backend APIs. The new object will be merged with the existing value. Note: Since this data can be modified from the frontend, it is not guaranteed to be safe. + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.UpdateUserMetadataRequest( + user_id=user_id, + request_body=models.UpdateUserMetadataRequestBody( + public_metadata=public_metadata, + private_metadata=utils.unmarshal(private_metadata, models.UpdateUserMetadataPrivateMetadata) if not isinstance(private_metadata, BaseModel) and private_metadata is not None else private_metadata, + unsafe_metadata=utils.unmarshal(unsafe_metadata, models.UpdateUserMetadataUnsafeMetadata) if not isinstance(unsafe_metadata, BaseModel) and unsafe_metadata is not None else unsafe_metadata, + ), + ) + + req = self.build_request( + method="PATCH", + path="/users/{user_id}/metadata", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + get_serialized_body=lambda: utils.serialize_request_body(request.request_body, False, True, "json", Optional[models.UpdateUserMetadataRequestBody]), + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="UpdateUserMetadata", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","401","404","422","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.User]) + if utils.match_response(http_res, ["400","401","404","422"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + def get_o_auth_access_token( + self, *, + user_id: str, + provider: str, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> List[models.ResponseBody]: + r"""Retrieve the OAuth access token of a user + + Fetch the corresponding OAuth access token for a user that has previously authenticated with a particular OAuth provider. + For OAuth 2.0, if the access token has expired and we have a corresponding refresh token, the access token will be refreshed transparently the new one will be returned. + + :param user_id: The ID of the user for which to retrieve the OAuth access token + :param provider: The ID of the OAuth provider (e.g. `oauth_google`) + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.GetOAuthAccessTokenRequest( + user_id=user_id, + provider=provider, + ) + + req = self.build_request( + method="GET", + path="/users/{user_id}/oauth_access_tokens/{provider}", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="GetOAuthAccessToken", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["422","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[List[models.ResponseBody]]) + if utils.match_response(http_res, "422", "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + async def get_o_auth_access_token_async( + self, *, + user_id: str, + provider: str, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> List[models.ResponseBody]: + r"""Retrieve the OAuth access token of a user + + Fetch the corresponding OAuth access token for a user that has previously authenticated with a particular OAuth provider. + For OAuth 2.0, if the access token has expired and we have a corresponding refresh token, the access token will be refreshed transparently the new one will be returned. + + :param user_id: The ID of the user for which to retrieve the OAuth access token + :param provider: The ID of the OAuth provider (e.g. `oauth_google`) + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.GetOAuthAccessTokenRequest( + user_id=user_id, + provider=provider, + ) + + req = self.build_request( + method="GET", + path="/users/{user_id}/oauth_access_tokens/{provider}", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="GetOAuthAccessToken", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["422","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[List[models.ResponseBody]]) + if utils.match_response(http_res, "422", "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + def get_organization_memberships( + self, *, + user_id: str, + limit: Optional[float] = None, + offset: Optional[float] = None, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.UsersGetOrganizationMembershipsResponse: + r"""Retrieve all memberships for a user + + Retrieve a paginated list of the user's organization memberships + + :param user_id: The ID of the user whose organization memberships we want to retrieve + :param limit: Applies a limit to the number of results returned. Can be used for paginating the results together with `offset`. + :param offset: Skip the first `offset` results when paginating. Needs to be an integer greater or equal to zero. To be used in conjunction with `limit`. + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.UsersGetOrganizationMembershipsRequest( + user_id=user_id, + limit=limit, + offset=offset, + ) + + req = self.build_request( + method="GET", + path="/users/{user_id}/organization_memberships", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="UsersGetOrganizationMemberships", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["403","4XX","5XX"], + retry_config=retry_config + ) + + def next_func() -> Optional[models.UsersGetOrganizationMembershipsResponse]: + body = utils.unmarshal_json(http_res.text, Dict[Any, Any]) + offset = request.offset if not request.offset is None else 0 + + if not http_res.text: + return None + results = JSONPath("$").parse(body) + if len(results) == 0 or len(results[0]) == 0: + return None + limit = request.limit if not request.limit is None else 0 + if len(results[0]) < limit: + return None + next_offset = offset + len(results[0]) + + return self.get_organization_memberships( + user_id=user_id, + limit=limit, + offset=next_offset, + retries=retries, + ) + + res = models.UsersGetOrganizationMembershipsResponse(result=None, next=next_func) + + if utils.match_response(http_res, "200", "application/json"): + res.result = utils.unmarshal_json(http_res.text, Optional[models.OrganizationMemberships]) + elif utils.match_response(http_res, "403", "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + elif utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + else: + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + return res + + + async def get_organization_memberships_async( + self, *, + user_id: str, + limit: Optional[float] = None, + offset: Optional[float] = None, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.UsersGetOrganizationMembershipsResponse: + r"""Retrieve all memberships for a user + + Retrieve a paginated list of the user's organization memberships + + :param user_id: The ID of the user whose organization memberships we want to retrieve + :param limit: Applies a limit to the number of results returned. Can be used for paginating the results together with `offset`. + :param offset: Skip the first `offset` results when paginating. Needs to be an integer greater or equal to zero. To be used in conjunction with `limit`. + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.UsersGetOrganizationMembershipsRequest( + user_id=user_id, + limit=limit, + offset=offset, + ) + + req = self.build_request( + method="GET", + path="/users/{user_id}/organization_memberships", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="UsersGetOrganizationMemberships", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["403","4XX","5XX"], + retry_config=retry_config + ) + + def next_func() -> Optional[models.UsersGetOrganizationMembershipsResponse]: + body = utils.unmarshal_json(http_res.text, Dict[Any, Any]) + offset = request.offset if not request.offset is None else 0 + + if not http_res.text: + return None + results = JSONPath("$").parse(body) + if len(results) == 0 or len(results[0]) == 0: + return None + limit = request.limit if not request.limit is None else 0 + if len(results[0]) < limit: + return None + next_offset = offset + len(results[0]) + + return self.get_organization_memberships( + user_id=user_id, + limit=limit, + offset=next_offset, + retries=retries, + ) + + res = models.UsersGetOrganizationMembershipsResponse(result=None, next=next_func) + + if utils.match_response(http_res, "200", "application/json"): + res.result = utils.unmarshal_json(http_res.text, Optional[models.OrganizationMemberships]) + elif utils.match_response(http_res, "403", "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + elif utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + else: + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + return res + + + def verify_password( + self, *, + user_id: str, + password: str, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.VerifyPasswordResponseBody: + r"""Verify the password of a user + + Check that the user's password matches the supplied input. + Useful for custom auth flows and re-verification. + + :param user_id: The ID of the user for whom to verify the password + :param password: The user password to verify + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.VerifyPasswordRequest( + user_id=user_id, + request_body=models.VerifyPasswordRequestBody( + password=password, + ), + ) + + req = self.build_request( + method="POST", + path="/users/{user_id}/verify_password", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + get_serialized_body=lambda: utils.serialize_request_body(request.request_body, False, True, "json", Optional[models.VerifyPasswordRequestBody]), + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="VerifyPassword", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","404","422","4XX","500","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.VerifyPasswordResponseBody]) + if utils.match_response(http_res, ["400","404","422","4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + if utils.match_response(http_res, "500", "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + async def verify_password_async( + self, *, + user_id: str, + password: str, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.VerifyPasswordResponseBody: + r"""Verify the password of a user + + Check that the user's password matches the supplied input. + Useful for custom auth flows and re-verification. + + :param user_id: The ID of the user for whom to verify the password + :param password: The user password to verify + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.VerifyPasswordRequest( + user_id=user_id, + request_body=models.VerifyPasswordRequestBody( + password=password, + ), + ) + + req = self.build_request( + method="POST", + path="/users/{user_id}/verify_password", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + get_serialized_body=lambda: utils.serialize_request_body(request.request_body, False, True, "json", Optional[models.VerifyPasswordRequestBody]), + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="VerifyPassword", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","404","422","4XX","500","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.VerifyPasswordResponseBody]) + if utils.match_response(http_res, ["400","404","422","4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + if utils.match_response(http_res, "500", "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + def verify_totp( + self, *, + user_id: str, + code: str, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.VerifyTOTPResponseBody: + r"""Verify a TOTP or backup code for a user + + Verify that the provided TOTP or backup code is valid for the user. + Verifying a backup code will result it in being consumed (i.e. it will + become invalid). + Useful for custom auth flows and re-verification. + + :param user_id: The ID of the user for whom to verify the TOTP + :param code: The TOTP or backup code to verify + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.VerifyTOTPRequest( + user_id=user_id, + request_body=models.VerifyTOTPRequestBody( + code=code, + ), + ) + + req = self.build_request( + method="POST", + path="/users/{user_id}/verify_totp", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + get_serialized_body=lambda: utils.serialize_request_body(request.request_body, False, True, "json", Optional[models.VerifyTOTPRequestBody]), + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="VerifyTOTP", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","404","422","4XX","500","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.VerifyTOTPResponseBody]) + if utils.match_response(http_res, ["400","404","422","4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + if utils.match_response(http_res, "500", "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + async def verify_totp_async( + self, *, + user_id: str, + code: str, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.VerifyTOTPResponseBody: + r"""Verify a TOTP or backup code for a user + + Verify that the provided TOTP or backup code is valid for the user. + Verifying a backup code will result it in being consumed (i.e. it will + become invalid). + Useful for custom auth flows and re-verification. + + :param user_id: The ID of the user for whom to verify the TOTP + :param code: The TOTP or backup code to verify + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.VerifyTOTPRequest( + user_id=user_id, + request_body=models.VerifyTOTPRequestBody( + code=code, + ), + ) + + req = self.build_request( + method="POST", + path="/users/{user_id}/verify_totp", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + get_serialized_body=lambda: utils.serialize_request_body(request.request_body, False, True, "json", Optional[models.VerifyTOTPRequestBody]), + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="VerifyTOTP", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","404","422","4XX","500","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.VerifyTOTPResponseBody]) + if utils.match_response(http_res, ["400","404","422","4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + if utils.match_response(http_res, "500", "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + def disable_mfa( + self, *, + user_id: str, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.DisableMFAResponseBody: + r"""Disable a user's MFA methods + + Disable all of a user's MFA methods (e.g. OTP sent via SMS, TOTP on their authenticator app) at once. + + :param user_id: The ID of the user whose MFA methods are to be disabled + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.DisableMFARequest( + user_id=user_id, + ) + + req = self.build_request( + method="DELETE", + path="/users/{user_id}/mfa", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="DisableMFA", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["404","4XX","500","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.DisableMFAResponseBody]) + if utils.match_response(http_res, ["404","500"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + async def disable_mfa_async( + self, *, + user_id: str, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.DisableMFAResponseBody: + r"""Disable a user's MFA methods + + Disable all of a user's MFA methods (e.g. OTP sent via SMS, TOTP on their authenticator app) at once. + + :param user_id: The ID of the user whose MFA methods are to be disabled + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + + request = models.DisableMFARequest( + user_id=user_id, + ) + + req = self.build_request( + method="DELETE", + path="/users/{user_id}/mfa", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="DisableMFA", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["404","4XX","500","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.DisableMFAResponseBody]) + if utils.match_response(http_res, ["404","500"], "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + diff --git a/src/clerk/utils/__init__.py b/src/clerk/utils/__init__.py new file mode 100644 index 0000000..95cdf57 --- /dev/null +++ b/src/clerk/utils/__init__.py @@ -0,0 +1,74 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from .enums import OpenEnumMeta +from .headers import get_headers, get_response_headers +from .metadata import ( + FieldMetadata, + find_metadata, + FormMetadata, + HeaderMetadata, + MultipartFormMetadata, + PathParamMetadata, + QueryParamMetadata, + RequestMetadata, + SecurityMetadata, +) +from .queryparams import get_query_params +from .retries import BackoffStrategy, Retries, retry, retry_async, RetryConfig +from .requestbodies import serialize_request_body, SerializedRequestBody +from .security import get_security +from .serializers import ( + marshal_json, + unmarshal, + unmarshal_json, + serialize_decimal, + serialize_float, + serialize_int, + validate_decimal, + validate_float, + validate_int, + validate_open_enum, +) +from .url import generate_url, template_url, remove_suffix +from .values import get_global_from_env, match_content_type, match_status_codes, match_response + +__all__ = [ + "BackoffStrategy", + "FieldMetadata", + "find_metadata", + "FormMetadata", + "generate_url", + "get_global_from_env", + "get_headers", + "get_query_params", + "get_response_headers", + "get_security", + "HeaderMetadata", + "marshal_json", + "match_content_type", + "match_status_codes", + "match_response", + "MultipartFormMetadata", + "OpenEnumMeta", + "PathParamMetadata", + "QueryParamMetadata", + "remove_suffix", + "Retries", + "retry", + "retry_async", + "RetryConfig", + "RequestMetadata", + "SecurityMetadata", + "serialize_decimal", + "serialize_float", + "serialize_int", + "serialize_request_body", + "SerializedRequestBody", + "template_url", + "unmarshal", + "unmarshal_json", + "validate_decimal", + "validate_float", + "validate_int", + "validate_open_enum", +] diff --git a/src/clerk/utils/enums.py b/src/clerk/utils/enums.py new file mode 100644 index 0000000..2804f7d --- /dev/null +++ b/src/clerk/utils/enums.py @@ -0,0 +1,34 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +import enum + + +class OpenEnumMeta(enum.EnumMeta): + def __call__( + cls, value, names=None, *, module=None, qualname=None, type=None, start=1 + ): + # The `type` kwarg also happens to be a built-in that pylint flags as + # redeclared. Safe to ignore this lint rule with this scope. + # pylint: disable=redefined-builtin + + if names is not None: + return super().__call__( + value, + names=names, + module=module, + qualname=qualname, + type=type, + start=start, + ) + + try: + return super().__call__( + value, + names=names, # pyright: ignore[reportArgumentType] + module=module, + qualname=qualname, + type=type, + start=start, + ) + except ValueError: + return value diff --git a/src/clerk/utils/eventstreaming.py b/src/clerk/utils/eventstreaming.py new file mode 100644 index 0000000..c9ace01 --- /dev/null +++ b/src/clerk/utils/eventstreaming.py @@ -0,0 +1,156 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +import re +import json +from typing import Callable, TypeVar, Optional, Generator, AsyncGenerator +import httpx + +T = TypeVar("T") + + +class ServerEvent: + id: Optional[str] = None + event: Optional[str] = None + data: Optional[str] = None + retry: Optional[int] = None + + +MESSAGE_BOUNDARIES = [ + b"\r\n\r\n", + b"\n\n", + b"\r\r", +] + +async def stream_events_async( + response: httpx.Response, decoder: Callable[[str], T] +) -> AsyncGenerator[T, None]: + buffer = bytearray() + position = 0 + async for chunk in response.aiter_bytes(): + buffer += chunk + for i in range(position, len(buffer)): + char = buffer[i: i + 1] + seq: Optional[bytes] = None + if char in [b"\r", b"\n"]: + for boundary in MESSAGE_BOUNDARIES: + seq = _peek_sequence(i, buffer, boundary) + if seq is not None: + break + if seq is None: + continue + + block = buffer[position:i] + position = i + len(seq) + event = _parse_event(block, decoder) + if event is not None: + yield event + + if position > 0: + buffer = buffer[position:] + position = 0 + + event = _parse_event(buffer, decoder) + if event is not None: + yield event + + + +def stream_events( + response: httpx.Response, decoder: Callable[[str], T] +) -> Generator[T, None, None]: + buffer = bytearray() + position = 0 + for chunk in response.iter_bytes(): + buffer += chunk + for i in range(position, len(buffer)): + char = buffer[i : i + 1] + seq: Optional[bytes] = None + if char in [b"\r", b"\n"]: + for boundary in MESSAGE_BOUNDARIES: + seq = _peek_sequence(i, buffer, boundary) + if seq is not None: + break + if seq is None: + continue + + block = buffer[position:i] + position = i + len(seq) + event = _parse_event(block, decoder) + if event is not None: + yield event + + if position > 0: + buffer = buffer[position:] + position = 0 + + event = _parse_event(buffer, decoder) + if event is not None: + yield event + + +def _parse_event(raw: bytearray, decoder: Callable[[str], T]): + block = raw.decode() + lines = re.split(r"\r?\n|\r", block) + publish = False + event = ServerEvent() + data = "" + for line in lines: + if not line: + continue + + delim = line.find(":") + if delim <= 0: + continue + + field = line[0:delim] + value = line[delim + 1 :] if delim < len(line) - 1 else "" + if len(value) and value[0] == " ": + value = value[1:] + + if field == "event": + event.event = value + publish = True + elif field == "data": + data += value + "\n" + publish = True + elif field == "id": + event.id = value + publish = True + elif field == "retry": + event.retry = int(value) if value.isdigit() else None + publish = True + + if data: + data = data[:-1] + event.data = data + + if ( + data.isnumeric() + or data == "true" + or data == "false" + or data == "null" + or data.startswith("{") + or data.startswith("[") + or data.startswith('"') + ): + try: + event.data = json.loads(data) + except Exception: + pass + + out = None + if publish: + out = decoder(json.dumps(event.__dict__)) + + return out + + +def _peek_sequence(position: int, buffer: bytearray, sequence: bytes): + if len(sequence) > (len(buffer) - position): + return None + + for i, seq in enumerate(sequence): + if buffer[position + i] != seq: + return None + + return sequence diff --git a/src/clerk/utils/forms.py b/src/clerk/utils/forms.py new file mode 100644 index 0000000..4df2b8d --- /dev/null +++ b/src/clerk/utils/forms.py @@ -0,0 +1,207 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from typing import ( + Any, + Dict, + get_type_hints, + List, + Tuple, +) +from pydantic import BaseModel +from pydantic.fields import FieldInfo + +from .serializers import marshal_json + +from .metadata import ( + FormMetadata, + MultipartFormMetadata, + find_field_metadata, +) +from .values import _val_to_string + + +def _populate_form( + field_name: str, + explode: bool, + obj: Any, + delimiter: str, + form: Dict[str, List[str]], +): + if obj is None: + return form + + if isinstance(obj, BaseModel): + items = [] + + obj_fields: Dict[str, FieldInfo] = obj.__class__.model_fields + for name in obj_fields: + obj_field = obj_fields[name] + obj_field_name = obj_field.alias if obj_field.alias is not None else name + if obj_field_name == "": + continue + + val = getattr(obj, name) + if val is None: + continue + + if explode: + form[obj_field_name] = [_val_to_string(val)] + else: + items.append(f"{obj_field_name}{delimiter}{_val_to_string(val)}") + + if len(items) > 0: + form[field_name] = [delimiter.join(items)] + elif isinstance(obj, Dict): + items = [] + for key, value in obj.items(): + if value is None: + continue + + if explode: + form[key] = [_val_to_string(value)] + else: + items.append(f"{key}{delimiter}{_val_to_string(value)}") + + if len(items) > 0: + form[field_name] = [delimiter.join(items)] + elif isinstance(obj, List): + items = [] + + for value in obj: + if value is None: + continue + + if explode: + if not field_name in form: + form[field_name] = [] + form[field_name].append(_val_to_string(value)) + else: + items.append(_val_to_string(value)) + + if len(items) > 0: + form[field_name] = [delimiter.join([str(item) for item in items])] + else: + form[field_name] = [_val_to_string(obj)] + + return form + + +def serialize_multipart_form( + media_type: str, request: Any +) -> Tuple[str, Dict[str, Any], Dict[str, Any]]: + form: Dict[str, Any] = {} + files: Dict[str, Any] = {} + + if not isinstance(request, BaseModel): + raise TypeError("invalid request body type") + + request_fields: Dict[str, FieldInfo] = request.__class__.model_fields + request_field_types = get_type_hints(request.__class__) + + for name in request_fields: + field = request_fields[name] + + val = getattr(request, name) + if val is None: + continue + + field_metadata = find_field_metadata(field, MultipartFormMetadata) + if not field_metadata: + continue + + f_name = field.alias if field.alias is not None else name + + if field_metadata.file: + file_fields: Dict[str, FieldInfo] = val.__class__.model_fields + + file_name = "" + field_name = "" + content = None + content_type = None + + for file_field_name in file_fields: + file_field = file_fields[file_field_name] + + file_metadata = find_field_metadata(file_field, MultipartFormMetadata) + if file_metadata is None: + continue + + if file_metadata.content: + content = getattr(val, file_field_name, None) + elif file_field_name == "content_type": + content_type = getattr(val, file_field_name, None) + else: + field_name = ( + file_field.alias + if file_field.alias is not None + else file_field_name + ) + file_name = getattr(val, file_field_name) + + if field_name == "" or file_name == "" or content is None: + raise ValueError("invalid multipart/form-data file") + + if content_type is not None: + files[field_name] = (file_name, content, content_type) + else: + files[field_name] = (file_name, content) + elif field_metadata.json: + files[f_name] = ( + None, + marshal_json(val, request_field_types[name]), + "application/json", + ) + else: + if isinstance(val, List): + values = [] + + for value in val: + if value is None: + continue + values.append(_val_to_string(value)) + + form[f_name + "[]"] = values + else: + form[f_name] = _val_to_string(val) + return media_type, form, files + + +def serialize_form_data(data: Any) -> Dict[str, Any]: + form: Dict[str, List[str]] = {} + + if isinstance(data, BaseModel): + data_fields: Dict[str, FieldInfo] = data.__class__.model_fields + data_field_types = get_type_hints(data.__class__) + for name in data_fields: + field = data_fields[name] + + val = getattr(data, name) + if val is None: + continue + + metadata = find_field_metadata(field, FormMetadata) + if metadata is None: + continue + + f_name = field.alias if field.alias is not None else name + + if metadata.json: + form[f_name] = [marshal_json(val, data_field_types[name])] + else: + if metadata.style == "form": + _populate_form( + f_name, + metadata.explode, + val, + ",", + form, + ) + else: + raise ValueError(f"Invalid form style for field {name}") + elif isinstance(data, Dict): + for key, value in data.items(): + form[key] = [_val_to_string(value)] + else: + raise TypeError(f"Invalid request body type {type(data)} for form data") + + return form diff --git a/src/clerk/utils/headers.py b/src/clerk/utils/headers.py new file mode 100644 index 0000000..ad25879 --- /dev/null +++ b/src/clerk/utils/headers.py @@ -0,0 +1,136 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from typing import ( + Any, + Dict, + List, + Optional, +) +from httpx import Headers +from pydantic import BaseModel +from pydantic.fields import FieldInfo + +from .metadata import ( + HeaderMetadata, + find_field_metadata, +) + +from .values import _populate_from_globals, _val_to_string + + +def get_headers(headers_params: Any, gbls: Optional[Any] = None) -> Dict[str, str]: + headers: Dict[str, str] = {} + + globals_already_populated = [] + if headers_params is not None: + globals_already_populated = _populate_headers(headers_params, gbls, headers, []) + if gbls is not None: + _populate_headers(gbls, None, headers, globals_already_populated) + + return headers + + +def _populate_headers( + headers_params: Any, + gbls: Any, + header_values: Dict[str, str], + skip_fields: List[str], +) -> List[str]: + globals_already_populated: List[str] = [] + + if not isinstance(headers_params, BaseModel): + return globals_already_populated + + param_fields: Dict[str, FieldInfo] = headers_params.__class__.model_fields + for name in param_fields: + if name in skip_fields: + continue + + field = param_fields[name] + f_name = field.alias if field.alias is not None else name + + metadata = find_field_metadata(field, HeaderMetadata) + if metadata is None: + continue + + value, global_found = _populate_from_globals( + name, getattr(headers_params, name), HeaderMetadata, gbls + ) + if global_found: + globals_already_populated.append(name) + value = _serialize_header(metadata.explode, value) + + if value != "": + header_values[f_name] = value + + return globals_already_populated + + +def _serialize_header(explode: bool, obj: Any) -> str: + if obj is None: + return "" + + if isinstance(obj, BaseModel): + items = [] + obj_fields: Dict[str, FieldInfo] = obj.__class__.model_fields + for name in obj_fields: + obj_field = obj_fields[name] + obj_param_metadata = find_field_metadata(obj_field, HeaderMetadata) + + if not obj_param_metadata: + continue + + f_name = obj_field.alias if obj_field.alias is not None else name + + val = getattr(obj, name) + if val is None: + continue + + if explode: + items.append(f"{f_name}={_val_to_string(val)}") + else: + items.append(f_name) + items.append(_val_to_string(val)) + + if len(items) > 0: + return ",".join(items) + elif isinstance(obj, Dict): + items = [] + + for key, value in obj.items(): + if value is None: + continue + + if explode: + items.append(f"{key}={_val_to_string(value)}") + else: + items.append(key) + items.append(_val_to_string(value)) + + if len(items) > 0: + return ",".join([str(item) for item in items]) + elif isinstance(obj, List): + items = [] + + for value in obj: + if value is None: + continue + + items.append(_val_to_string(value)) + + if len(items) > 0: + return ",".join(items) + else: + return f"{_val_to_string(obj)}" + + return "" + + +def get_response_headers(headers: Headers) -> Dict[str, List[str]]: + res = {} + for k, v in headers.items(): + if not k in res: + res[k] = [] + + res[k].append(v) + return res diff --git a/src/clerk/utils/metadata.py b/src/clerk/utils/metadata.py new file mode 100644 index 0000000..b5693b3 --- /dev/null +++ b/src/clerk/utils/metadata.py @@ -0,0 +1,118 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from typing import Optional, Type, TypeVar, Union +from dataclasses import dataclass +from pydantic.fields import FieldInfo + + +T = TypeVar("T") + + +@dataclass +class SecurityMetadata: + option: bool = False + scheme: bool = False + scheme_type: Optional[str] = None + sub_type: Optional[str] = None + field_name: Optional[str] = None + + def get_field_name(self, default: str) -> str: + return self.field_name or default + + +@dataclass +class ParamMetadata: + serialization: Optional[str] = None + style: str = "simple" + explode: bool = False + + +@dataclass +class PathParamMetadata(ParamMetadata): + pass + + +@dataclass +class QueryParamMetadata(ParamMetadata): + style: str = "form" + explode: bool = True + + +@dataclass +class HeaderMetadata(ParamMetadata): + pass + + +@dataclass +class RequestMetadata: + media_type: str = "application/octet-stream" + + +@dataclass +class MultipartFormMetadata: + file: bool = False + content: bool = False + json: bool = False + + +@dataclass +class FormMetadata: + json: bool = False + style: str = "form" + explode: bool = True + + +class FieldMetadata: + security: Optional[SecurityMetadata] = None + path: Optional[PathParamMetadata] = None + query: Optional[QueryParamMetadata] = None + header: Optional[HeaderMetadata] = None + request: Optional[RequestMetadata] = None + form: Optional[FormMetadata] = None + multipart: Optional[MultipartFormMetadata] = None + + def __init__( + self, + security: Optional[SecurityMetadata] = None, + path: Optional[Union[PathParamMetadata, bool]] = None, + query: Optional[Union[QueryParamMetadata, bool]] = None, + header: Optional[Union[HeaderMetadata, bool]] = None, + request: Optional[Union[RequestMetadata, bool]] = None, + form: Optional[Union[FormMetadata, bool]] = None, + multipart: Optional[Union[MultipartFormMetadata, bool]] = None, + ): + self.security = security + self.path = PathParamMetadata() if isinstance(path, bool) else path + self.query = QueryParamMetadata() if isinstance(query, bool) else query + self.header = HeaderMetadata() if isinstance(header, bool) else header + self.request = RequestMetadata() if isinstance(request, bool) else request + self.form = FormMetadata() if isinstance(form, bool) else form + self.multipart = ( + MultipartFormMetadata() if isinstance(multipart, bool) else multipart + ) + + +def find_field_metadata(field_info: FieldInfo, metadata_type: Type[T]) -> Optional[T]: + metadata = find_metadata(field_info, FieldMetadata) + if not metadata: + return None + + fields = metadata.__dict__ + + for field in fields: + if isinstance(fields[field], metadata_type): + return fields[field] + + return None + + +def find_metadata(field_info: FieldInfo, metadata_type: Type[T]) -> Optional[T]: + metadata = field_info.metadata + if not metadata: + return None + + for md in metadata: + if isinstance(md, metadata_type): + return md + + return None diff --git a/src/clerk/utils/queryparams.py b/src/clerk/utils/queryparams.py new file mode 100644 index 0000000..5f5ca8d --- /dev/null +++ b/src/clerk/utils/queryparams.py @@ -0,0 +1,162 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from typing import ( + Any, + Dict, + get_type_hints, + List, + Optional, +) + +from pydantic import BaseModel +from pydantic.fields import FieldInfo + +from .metadata import ( + QueryParamMetadata, + find_field_metadata, +) +from .values import _get_serialized_params, _populate_from_globals, _val_to_string +from .forms import _populate_form + + +def get_query_params( + query_params: Any, + gbls: Optional[Any] = None, +) -> Dict[str, List[str]]: + params: Dict[str, List[str]] = {} + + globals_already_populated = _populate_query_params(query_params, gbls, params, []) + if gbls is not None: + _populate_query_params(gbls, None, params, globals_already_populated) + + return params + + +def _populate_query_params( + query_params: Any, + gbls: Any, + query_param_values: Dict[str, List[str]], + skip_fields: List[str], +) -> List[str]: + globals_already_populated: List[str] = [] + + if not isinstance(query_params, BaseModel): + return globals_already_populated + + param_fields: Dict[str, FieldInfo] = query_params.__class__.model_fields + param_field_types = get_type_hints(query_params.__class__) + for name in param_fields: + if name in skip_fields: + continue + + field = param_fields[name] + + metadata = find_field_metadata(field, QueryParamMetadata) + if not metadata: + continue + + value = getattr(query_params, name) if query_params is not None else None + + value, global_found = _populate_from_globals( + name, value, QueryParamMetadata, gbls + ) + if global_found: + globals_already_populated.append(name) + + f_name = field.alias if field.alias is not None else name + serialization = metadata.serialization + if serialization is not None: + serialized_parms = _get_serialized_params( + metadata, f_name, value, param_field_types[name] + ) + for key, value in serialized_parms.items(): + if key in query_param_values: + query_param_values[key].extend(value) + else: + query_param_values[key] = [value] + else: + style = metadata.style + if style == "deepObject": + _populate_deep_object_query_params(f_name, value, query_param_values) + elif style == "form": + _populate_delimited_query_params( + metadata, f_name, value, ",", query_param_values + ) + elif style == "pipeDelimited": + _populate_delimited_query_params( + metadata, f_name, value, "|", query_param_values + ) + else: + raise NotImplementedError( + f"query param style {style} not yet supported" + ) + + return globals_already_populated + + +def _populate_deep_object_query_params( + field_name: str, + obj: Any, + params: Dict[str, List[str]], +): + if obj is None: + return + + if isinstance(obj, BaseModel): + obj_fields: Dict[str, FieldInfo] = obj.__class__.model_fields + for name in obj_fields: + obj_field = obj_fields[name] + + f_name = obj_field.alias if obj_field.alias is not None else name + + obj_param_metadata = find_field_metadata(obj_field, QueryParamMetadata) + if obj_param_metadata is None: + continue + + obj_val = getattr(obj, name) + if obj_val is None: + continue + + if isinstance(obj_val, List): + for val in obj_val: + if val is None: + continue + + if params.get(f"{field_name}[{f_name}]") is None: + params[f"{field_name}[{f_name}]"] = [] + + params[f"{field_name}[{f_name}]"].append(_val_to_string(val)) + else: + params[f"{field_name}[{f_name}]"] = [_val_to_string(obj_val)] + elif isinstance(obj, Dict): + for key, value in obj.items(): + if value is None: + continue + + if isinstance(value, List): + for val in value: + if val is None: + continue + + if params.get(f"{field_name}[{key}]") is None: + params[f"{field_name}[{key}]"] = [] + + params[f"{field_name}[{key}]"].append(_val_to_string(val)) + else: + params[f"{field_name}[{key}]"] = [_val_to_string(value)] + + +def _populate_delimited_query_params( + metadata: QueryParamMetadata, + field_name: str, + obj: Any, + delimiter: str, + query_param_values: Dict[str, List[str]], +): + _populate_form( + field_name, + metadata.explode, + obj, + delimiter, + query_param_values, + ) diff --git a/src/clerk/utils/requestbodies.py b/src/clerk/utils/requestbodies.py new file mode 100644 index 0000000..c01e275 --- /dev/null +++ b/src/clerk/utils/requestbodies.py @@ -0,0 +1,66 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +import io +from dataclasses import dataclass +import re +from typing import ( + Any, + Optional, +) + +from .forms import serialize_form_data, serialize_multipart_form + +from .serializers import marshal_json + +SERIALIZATION_METHOD_TO_CONTENT_TYPE = { + "json": "application/json", + "form": "application/x-www-form-urlencoded", + "multipart": "multipart/form-data", + "raw": "application/octet-stream", + "string": "text/plain", +} + + +@dataclass +class SerializedRequestBody: + media_type: str + content: Optional[Any] = None + data: Optional[Any] = None + files: Optional[Any] = None + + +def serialize_request_body( + request_body: Any, + nullable: bool, + optional: bool, + serialization_method: str, + request_body_type, +) -> Optional[SerializedRequestBody]: + if request_body is None: + if not nullable and optional: + return None + + media_type = SERIALIZATION_METHOD_TO_CONTENT_TYPE[serialization_method] + + serialized_request_body = SerializedRequestBody(media_type) + + if re.match(r"(application|text)\/.*?\+*json.*", media_type) is not None: + serialized_request_body.content = marshal_json(request_body, request_body_type) + elif re.match(r"multipart\/.*", media_type) is not None: + ( + serialized_request_body.media_type, + serialized_request_body.data, + serialized_request_body.files, + ) = serialize_multipart_form(media_type, request_body) + elif re.match(r"application\/x-www-form-urlencoded.*", media_type) is not None: + serialized_request_body.data = serialize_form_data(request_body) + elif isinstance(request_body, (bytes, bytearray, io.BytesIO, io.BufferedReader)): + serialized_request_body.content = request_body + elif isinstance(request_body, str): + serialized_request_body.content = request_body + else: + raise TypeError( + f"invalid request body type {type(request_body)} for mediaType {media_type}" + ) + + return serialized_request_body diff --git a/src/clerk/utils/retries.py b/src/clerk/utils/retries.py new file mode 100644 index 0000000..2540494 --- /dev/null +++ b/src/clerk/utils/retries.py @@ -0,0 +1,216 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +import random +import time +from typing import List + +import httpx + + +class BackoffStrategy: + initial_interval: int + max_interval: int + exponent: float + max_elapsed_time: int + + def __init__( + self, + initial_interval: int, + max_interval: int, + exponent: float, + max_elapsed_time: int, + ): + self.initial_interval = initial_interval + self.max_interval = max_interval + self.exponent = exponent + self.max_elapsed_time = max_elapsed_time + + +class RetryConfig: + strategy: str + backoff: BackoffStrategy + retry_connection_errors: bool + + def __init__( + self, strategy: str, backoff: BackoffStrategy, retry_connection_errors: bool + ): + self.strategy = strategy + self.backoff = backoff + self.retry_connection_errors = retry_connection_errors + + +class Retries: + config: RetryConfig + status_codes: List[str] + + def __init__(self, config: RetryConfig, status_codes: List[str]): + self.config = config + self.status_codes = status_codes + + +class TemporaryError(Exception): + response: httpx.Response + + def __init__(self, response: httpx.Response): + self.response = response + + +class PermanentError(Exception): + inner: Exception + + def __init__(self, inner: Exception): + self.inner = inner + + +def retry(func, retries: Retries): + if retries.config.strategy == "backoff": + + def do_request(): + res: httpx.Response + try: + res = func() + + for code in retries.status_codes: + if "X" in code.upper(): + code_range = int(code[0]) + + status_major = res.status_code / 100 + + if status_major >= code_range and status_major < code_range + 1: + raise TemporaryError(res) + else: + parsed_code = int(code) + + if res.status_code == parsed_code: + raise TemporaryError(res) + except httpx.ConnectError as exception: + if retries.config.retry_connection_errors: + raise + + raise PermanentError(exception) from exception + except httpx.TimeoutException as exception: + if retries.config.retry_connection_errors: + raise + + raise PermanentError(exception) from exception + except TemporaryError: + raise + except Exception as exception: + raise PermanentError(exception) from exception + + return res + + return retry_with_backoff( + do_request, + retries.config.backoff.initial_interval, + retries.config.backoff.max_interval, + retries.config.backoff.exponent, + retries.config.backoff.max_elapsed_time, + ) + + return func() + + +async def retry_async(func, retries: Retries): + if retries.config.strategy == "backoff": + + async def do_request(): + res: httpx.Response + try: + res = await func() + + for code in retries.status_codes: + if "X" in code.upper(): + code_range = int(code[0]) + + status_major = res.status_code / 100 + + if status_major >= code_range and status_major < code_range + 1: + raise TemporaryError(res) + else: + parsed_code = int(code) + + if res.status_code == parsed_code: + raise TemporaryError(res) + except httpx.ConnectError as exception: + if retries.config.retry_connection_errors: + raise + + raise PermanentError(exception) from exception + except httpx.TimeoutException as exception: + if retries.config.retry_connection_errors: + raise + + raise PermanentError(exception) from exception + except TemporaryError: + raise + except Exception as exception: + raise PermanentError(exception) from exception + + return res + + return await retry_with_backoff_async( + do_request, + retries.config.backoff.initial_interval, + retries.config.backoff.max_interval, + retries.config.backoff.exponent, + retries.config.backoff.max_elapsed_time, + ) + + return await func() + + +def retry_with_backoff( + func, + initial_interval=500, + max_interval=60000, + exponent=1.5, + max_elapsed_time=3600000, +): + start = round(time.time() * 1000) + retries = 0 + + while True: + try: + return func() + except PermanentError as exception: + raise exception.inner + except Exception as exception: # pylint: disable=broad-exception-caught + now = round(time.time() * 1000) + if now - start > max_elapsed_time: + if isinstance(exception, TemporaryError): + return exception.response + + raise + sleep = (initial_interval / 1000) * exponent**retries + random.uniform(0, 1) + sleep = min(sleep, max_interval / 1000) + time.sleep(sleep) + retries += 1 + + +async def retry_with_backoff_async( + func, + initial_interval=500, + max_interval=60000, + exponent=1.5, + max_elapsed_time=3600000, +): + start = round(time.time() * 1000) + retries = 0 + + while True: + try: + return await func() + except PermanentError as exception: + raise exception.inner + except Exception as exception: # pylint: disable=broad-exception-caught + now = round(time.time() * 1000) + if now - start > max_elapsed_time: + if isinstance(exception, TemporaryError): + return exception.response + + raise + sleep = (initial_interval / 1000) * exponent**retries + random.uniform(0, 1) + sleep = min(sleep, max_interval / 1000) + time.sleep(sleep) + retries += 1 diff --git a/src/clerk/utils/security.py b/src/clerk/utils/security.py new file mode 100644 index 0000000..d25d654 --- /dev/null +++ b/src/clerk/utils/security.py @@ -0,0 +1,166 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +import base64 +from typing import ( + Any, + Dict, + Tuple, +) +from pydantic import BaseModel +from pydantic.fields import FieldInfo + +from .metadata import ( + SecurityMetadata, + find_field_metadata, +) + + +def get_security(security: Any) -> Tuple[Dict[str, str], Dict[str, str]]: + headers: Dict[str, str] = {} + query_params: Dict[str, str] = {} + + if security is None: + return headers, query_params + + if not isinstance(security, BaseModel): + raise TypeError("security must be a pydantic model") + + sec_fields: Dict[str, FieldInfo] = security.__class__.model_fields + for name in sec_fields: + sec_field = sec_fields[name] + + value = getattr(security, name) + if value is None: + continue + + metadata = find_field_metadata(sec_field, SecurityMetadata) + if metadata is None: + continue + if metadata.option: + _parse_security_option(headers, query_params, value) + return headers, query_params + if metadata.scheme: + # Special case for basic auth which could be a flattened model + if metadata.sub_type == "basic" and not isinstance(value, BaseModel): + _parse_security_scheme(headers, query_params, metadata, name, security) + else: + _parse_security_scheme(headers, query_params, metadata, name, value) + + return headers, query_params + + +def _parse_security_option( + headers: Dict[str, str], query_params: Dict[str, str], option: Any +): + if not isinstance(option, BaseModel): + raise TypeError("security option must be a pydantic model") + + opt_fields: Dict[str, FieldInfo] = option.__class__.model_fields + for name in opt_fields: + opt_field = opt_fields[name] + + metadata = find_field_metadata(opt_field, SecurityMetadata) + if metadata is None or not metadata.scheme: + continue + _parse_security_scheme( + headers, query_params, metadata, name, getattr(option, name) + ) + + +def _parse_security_scheme( + headers: Dict[str, str], + query_params: Dict[str, str], + scheme_metadata: SecurityMetadata, + field_name: str, + scheme: Any, +): + scheme_type = scheme_metadata.scheme_type + sub_type = scheme_metadata.sub_type + + if isinstance(scheme, BaseModel): + if scheme_type == "http" and sub_type == "basic": + _parse_basic_auth_scheme(headers, scheme) + return + + scheme_fields: Dict[str, FieldInfo] = scheme.__class__.model_fields + for name in scheme_fields: + scheme_field = scheme_fields[name] + + metadata = find_field_metadata(scheme_field, SecurityMetadata) + if metadata is None or metadata.field_name is None: + continue + + value = getattr(scheme, name) + + _parse_security_scheme_value( + headers, query_params, scheme_metadata, metadata, name, value + ) + else: + _parse_security_scheme_value( + headers, query_params, scheme_metadata, scheme_metadata, field_name, scheme + ) + + +def _parse_security_scheme_value( + headers: Dict[str, str], + query_params: Dict[str, str], + scheme_metadata: SecurityMetadata, + security_metadata: SecurityMetadata, + field_name: str, + value: Any, +): + scheme_type = scheme_metadata.scheme_type + sub_type = scheme_metadata.sub_type + + header_name = security_metadata.get_field_name(field_name) + + if scheme_type == "apiKey": + if sub_type == "header": + headers[header_name] = value + elif sub_type == "query": + query_params[header_name] = value + else: + raise ValueError("sub type {sub_type} not supported") + elif scheme_type == "openIdConnect": + headers[header_name] = _apply_bearer(value) + elif scheme_type == "oauth2": + if sub_type != "client_credentials": + headers[header_name] = _apply_bearer(value) + elif scheme_type == "http": + if sub_type == "bearer": + headers[header_name] = _apply_bearer(value) + else: + raise ValueError("sub type {sub_type} not supported") + else: + raise ValueError("scheme type {scheme_type} not supported") + + +def _apply_bearer(token: str) -> str: + return token.lower().startswith("bearer ") and token or f"Bearer {token}" + + +def _parse_basic_auth_scheme(headers: Dict[str, str], scheme: Any): + username = "" + password = "" + + if not isinstance(scheme, BaseModel): + raise TypeError("basic auth scheme must be a pydantic model") + + scheme_fields: Dict[str, FieldInfo] = scheme.__class__.model_fields + for name in scheme_fields: + scheme_field = scheme_fields[name] + + metadata = find_field_metadata(scheme_field, SecurityMetadata) + if metadata is None or metadata.field_name is None: + continue + + field_name = metadata.field_name + value = getattr(scheme, name) + + if field_name == "username": + username = value + if field_name == "password": + password = value + + data = f"{username}:{password}".encode() + headers["Authorization"] = f"Basic {base64.b64encode(data).decode()}" diff --git a/src/clerk/utils/serializers.py b/src/clerk/utils/serializers.py new file mode 100644 index 0000000..15cca42 --- /dev/null +++ b/src/clerk/utils/serializers.py @@ -0,0 +1,159 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from decimal import Decimal +import json +from typing import Type, TypeVar, Union, get_args +from typing_extensions import get_origin +from pydantic import ConfigDict, create_model +from pydantic_core import from_json +from typing_inspect import is_optional_type + +from ..types.basemodel import Nullable + + +def serialize_decimal(as_str: bool): + def serialize(d): + if is_optional_type(type(d)) and d is None: + return None + + if not isinstance(d, Decimal): + raise ValueError("Expected Decimal object") + + return str(d) if as_str else float(d) + + return serialize + + +def validate_decimal(d): + if d is None: + return None + + if isinstance(d, Decimal): + return d + + if not isinstance(d, (str, int, float)): + raise ValueError("Expected string, int or float") + + return Decimal(str(d)) + + +def serialize_float(as_str: bool): + def serialize(f): + if is_optional_type(type(f)) and f is None: + return None + + if not isinstance(f, float): + raise ValueError("Expected float") + + return str(f) if as_str else f + + return serialize + + +def validate_float(f): + if f is None: + return None + + if isinstance(f, float): + return f + + if not isinstance(f, str): + raise ValueError("Expected string") + + return float(f) + + +def serialize_int(as_str: bool): + def serialize(b): + if is_optional_type(type(b)) and b is None: + return None + + if not isinstance(b, int): + raise ValueError("Expected int") + + return str(b) if as_str else b + + return serialize + + +def validate_int(b): + if b is None: + return None + + if isinstance(b, int): + return b + + if not isinstance(b, str): + raise ValueError("Expected string") + + return int(b) + + +def validate_open_enum(is_int: bool): + def validate(e): + if e is None: + return None + + if is_int: + if not isinstance(e, int): + raise ValueError("Expected int") + else: + if not isinstance(e, str): + raise ValueError("Expected string") + + return e + + return validate + + +T = TypeVar("T") + + +def unmarshal_json(raw, typ: Type[T]) -> T: + return unmarshal(from_json(raw), typ) + + +def unmarshal(val, typ: Type[T]) -> T: + unmarshaller = create_model( + "Unmarshaller", + body=(typ, ...), + __config__=ConfigDict(populate_by_name=True, arbitrary_types_allowed=True), + ) + + m = unmarshaller(body=val) + + return m.body # pyright: ignore[reportAttributeAccessIssue] + + +def marshal_json(val, typ): + if is_nullable(typ) and val is None: + return "null" + + marshaller = create_model( + "Marshaller", + body=(typ, ...), + __config__=ConfigDict(populate_by_name=True, arbitrary_types_allowed=True), + ) + + m = marshaller(body=val) + + d = m.model_dump(by_alias=True, mode="json", exclude_none=True) + + if len(d) == 0: + return "" + + return json.dumps(d[next(iter(d))], separators=(",", ":"), sort_keys=True) + + +def is_nullable(field): + if get_origin(field) is Nullable: + return True + + if not get_origin(field) is Union or type(None) not in get_args(field): + return False + + for arg in get_args(field): + if get_origin(arg) is Nullable: + return True + + return False diff --git a/src/clerk/utils/url.py b/src/clerk/utils/url.py new file mode 100644 index 0000000..481ae77 --- /dev/null +++ b/src/clerk/utils/url.py @@ -0,0 +1,152 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from decimal import Decimal +from typing import ( + Any, + Dict, + get_type_hints, + List, + Optional, + Union, + get_args, + get_origin, +) +from pydantic import BaseModel +from pydantic.fields import FieldInfo + +from .metadata import ( + PathParamMetadata, + find_field_metadata, +) +from .values import _get_serialized_params, _populate_from_globals, _val_to_string + + +def generate_url( + server_url: str, + path: str, + path_params: Any, + gbls: Optional[Any] = None, +) -> str: + path_param_values: Dict[str, str] = {} + + globals_already_populated = _populate_path_params( + path_params, gbls, path_param_values, [] + ) + if gbls is not None: + _populate_path_params(gbls, None, path_param_values, globals_already_populated) + + for key, value in path_param_values.items(): + path = path.replace("{" + key + "}", value, 1) + + return remove_suffix(server_url, "/") + path + + +def _populate_path_params( + path_params: Any, + gbls: Any, + path_param_values: Dict[str, str], + skip_fields: List[str], +) -> List[str]: + globals_already_populated: List[str] = [] + + if not isinstance(path_params, BaseModel): + return globals_already_populated + + path_param_fields: Dict[str, FieldInfo] = path_params.__class__.model_fields + path_param_field_types = get_type_hints(path_params.__class__) + for name in path_param_fields: + if name in skip_fields: + continue + + field = path_param_fields[name] + + param_metadata = find_field_metadata(field, PathParamMetadata) + if param_metadata is None: + continue + + param = getattr(path_params, name) if path_params is not None else None + param, global_found = _populate_from_globals( + name, param, PathParamMetadata, gbls + ) + if global_found: + globals_already_populated.append(name) + + if param is None: + continue + + f_name = field.alias if field.alias is not None else name + serialization = param_metadata.serialization + if serialization is not None: + serialized_params = _get_serialized_params( + param_metadata, f_name, param, path_param_field_types[name] + ) + for key, value in serialized_params.items(): + path_param_values[key] = value + else: + if param_metadata.style == "simple": + if isinstance(param, List): + pp_vals: List[str] = [] + for pp_val in param: + if pp_val is None: + continue + pp_vals.append(_val_to_string(pp_val)) + path_param_values[f_name] = ",".join(pp_vals) + elif isinstance(param, Dict): + pp_vals: List[str] = [] + for pp_key in param: + if param[pp_key] is None: + continue + if param_metadata.explode: + pp_vals.append(f"{pp_key}={_val_to_string(param[pp_key])}") + else: + pp_vals.append(f"{pp_key},{_val_to_string(param[pp_key])}") + path_param_values[f_name] = ",".join(pp_vals) + elif not isinstance(param, (str, int, float, complex, bool, Decimal)): + pp_vals: List[str] = [] + param_fields: Dict[str, FieldInfo] = param.__class__.model_fields + for name in param_fields: + param_field = param_fields[name] + + param_value_metadata = find_field_metadata( + param_field, PathParamMetadata + ) + if param_value_metadata is None: + continue + + param_name = ( + param_field.alias if param_field.alias is not None else name + ) + + param_field_val = getattr(param, name) + if param_field_val is None: + continue + if param_metadata.explode: + pp_vals.append( + f"{param_name}={_val_to_string(param_field_val)}" + ) + else: + pp_vals.append( + f"{param_name},{_val_to_string(param_field_val)}" + ) + path_param_values[f_name] = ",".join(pp_vals) + else: + path_param_values[f_name] = _val_to_string(param) + + return globals_already_populated + + +def is_optional(field): + return get_origin(field) is Union and type(None) in get_args(field) + + +def template_url(url_with_params: str, params: Dict[str, str]) -> str: + for key, value in params.items(): + url_with_params = url_with_params.replace("{" + key + "}", value) + + return url_with_params + + +def remove_suffix(input_string, suffix): + if suffix and input_string.endswith(suffix): + return input_string[: -len(suffix)] + return input_string diff --git a/src/clerk/utils/values.py b/src/clerk/utils/values.py new file mode 100644 index 0000000..e0be587 --- /dev/null +++ b/src/clerk/utils/values.py @@ -0,0 +1,128 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from datetime import datetime +from enum import Enum +from email.message import Message +import os +from typing import Any, Callable, Dict, List, Optional, Tuple, TypeVar, Union + +from httpx import Response +from pydantic import BaseModel +from pydantic.fields import FieldInfo + +from .serializers import marshal_json + +from .metadata import ParamMetadata, find_field_metadata + + +def match_content_type(content_type: str, pattern: str) -> bool: + if pattern in (content_type, "*", "*/*"): + return True + + msg = Message() + msg["content-type"] = content_type + media_type = msg.get_content_type() + + if media_type == pattern: + return True + + parts = media_type.split("/") + if len(parts) == 2: + if pattern in (f"{parts[0]}/*", f"*/{parts[1]}"): + return True + + return False + + +def match_status_codes(status_codes: List[str], status_code: int) -> bool: + if "default" in status_codes: + return True + + for code in status_codes: + if code == str(status_code): + return True + + if code.endswith("XX") and code.startswith(str(status_code)[:1]): + return True + return False + +T = TypeVar("T") + +def get_global_from_env( + value: Optional[T], + env_key: str, + type_cast: Callable[[str], T] = str +) -> Optional[T]: + if value is not None: + return value + env_value = os.getenv(env_key) + if env_value is not None: + try: + return type_cast(env_value) + except ValueError: + pass + return None + + +def match_response( + response: Response, code: Union[str, List[str]], content_type: str +) -> bool: + codes = code if isinstance(code, list) else [code] + return match_status_codes(codes, response.status_code) and match_content_type( + response.headers.get("content-type", "application/octet-stream"), content_type + ) + + +def _populate_from_globals( + param_name: str, value: Any, param_metadata_type: type, gbls: Any +) -> Tuple[Any, bool]: + if gbls is None: + return value, False + + if not isinstance(gbls, BaseModel): + raise TypeError("globals must be a pydantic model") + + global_fields: Dict[str, FieldInfo] = gbls.__class__.model_fields + found = False + for name in global_fields: + field = global_fields[name] + if name is not param_name: + continue + + found = True + + if value is not None: + return value, True + + global_value = getattr(gbls, name) + + param_metadata = find_field_metadata(field, param_metadata_type) + if param_metadata is None: + return value, True + + return global_value, True + + return value, found + + +def _val_to_string(val) -> str: + if isinstance(val, bool): + return str(val).lower() + if isinstance(val, datetime): + return str(val.isoformat().replace("+00:00", "Z")) + if isinstance(val, Enum): + return str(val.value) + + return str(val) + + +def _get_serialized_params( + metadata: ParamMetadata, field_name: str, obj: Any, typ: type +) -> Dict[str, str]: + params: Dict[str, str] = {} + + serialization = metadata.serialization + if serialization == "json": + params[field_name] = marshal_json(obj, typ) + + return params diff --git a/src/clerk/webhooks.py b/src/clerk/webhooks.py new file mode 100644 index 0000000..77f9eba --- /dev/null +++ b/src/clerk/webhooks.py @@ -0,0 +1,431 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from .basesdk import BaseSDK +from clerk import models +from clerk._hooks import HookContext +from clerk.types import Nullable, UNSET +import clerk.utils as utils +from typing import Optional + +class Webhooks(BaseSDK): + + + def create_svix_app( + self, *, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.SvixURL: + r"""Create a Svix app + + Create a Svix app and associate it with the current instance + + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + req = self.build_request( + method="POST", + path="/webhooks/svix", + base_url=base_url, + url_variables=url_variables, + request=None, + request_body_required=False, + request_has_path_params=False, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="CreateSvixApp", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.SvixURL]) + if utils.match_response(http_res, "400", "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + async def create_svix_app_async( + self, *, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.SvixURL: + r"""Create a Svix app + + Create a Svix app and associate it with the current instance + + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + req = self.build_request( + method="POST", + path="/webhooks/svix", + base_url=base_url, + url_variables=url_variables, + request=None, + request_body_required=False, + request_has_path_params=False, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="CreateSvixApp", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.SvixURL]) + if utils.match_response(http_res, "400", "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + def delete_svix_app( + self, *, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ): + r"""Delete a Svix app + + Delete a Svix app and disassociate it from the current instance + + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + req = self.build_request( + method="DELETE", + path="/webhooks/svix", + base_url=base_url, + url_variables=url_variables, + request=None, + request_body_required=False, + request_has_path_params=False, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="DeleteSvixApp", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "204", "*"): + return + if utils.match_response(http_res, "400", "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + async def delete_svix_app_async( + self, *, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ): + r"""Delete a Svix app + + Delete a Svix app and disassociate it from the current instance + + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + req = self.build_request( + method="DELETE", + path="/webhooks/svix", + base_url=base_url, + url_variables=url_variables, + request=None, + request_body_required=False, + request_has_path_params=False, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="DeleteSvixApp", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "204", "*"): + return + if utils.match_response(http_res, "400", "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + def generate_svix_auth_url( + self, *, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.SvixURL: + r"""Create a Svix Dashboard URL + + Generate a new url for accessing the Svix's management dashboard for that particular instance + + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + req = self.build_request( + method="POST", + path="/webhooks/svix_url", + base_url=base_url, + url_variables=url_variables, + request=None, + request_body_required=False, + request_has_path_params=False, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = self.do_request( + hook_ctx=HookContext(operation_id="GenerateSvixAuthURL", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.SvixURL]) + if utils.match_response(http_res, "400", "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) + + + async def generate_svix_auth_url_async( + self, *, + retries: Optional[Nullable[utils.RetryConfig]] = UNSET, + server_url: Optional[str] = None, + timeout_config: Optional[int] = None, + ) -> models.SvixURL: + r"""Create a Svix Dashboard URL + + Generate a new url for accessing the Svix's management dashboard for that particular instance + + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_config: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_config is None: + timeout_config = self.sdk_configuration.timeout_config + + if server_url is not None: + base_url = server_url + req = self.build_request( + method="POST", + path="/webhooks/svix_url", + base_url=base_url, + url_variables=url_variables, + request=None, + request_body_required=False, + request_has_path_params=False, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_config=timeout_config, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, [ + "429", + "500", + "502", + "503", + "504" + ]) + + http_res = await self.do_request_async( + hook_ctx=HookContext(operation_id="GenerateSvixAuthURL", oauth2_scopes=[], security_source=self.sdk_configuration.security), + request=req, + error_status_codes=["400","4XX","5XX"], + retry_config=retry_config + ) + + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.SvixURL]) + if utils.match_response(http_res, "400", "application/json"): + data = utils.unmarshal_json(http_res.text, models.ClerkErrorsData) + raise models.ClerkErrors(data=data) + if utils.match_response(http_res, ["4XX","5XX"], "*"): + raise models.SDKError("API error occurred", http_res.status_code, http_res.text, http_res) + + content_type = http_res.headers.get("Content-Type") + raise models.SDKError(f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", http_res.status_code, http_res.text, http_res) +