From 981340c8309e1afdbe123194e881840fba10d412 Mon Sep 17 00:00:00 2001 From: speakeasybot Date: Thu, 11 Jul 2024 21:13:52 +0000 Subject: [PATCH] ci: regenerated with OpenAPI Doc , Speakeasy CLI 1.331.2 --- .speakeasy/gen.lock | 400 +- .speakeasy/gen.yaml | 2 +- .speakeasy/workflow.lock | 8 +- README.md | 30 +- RELEASES.md | 12 +- USAGE.md | 4 +- docs/sdks/actortokens/README.md | 4 +- docs/sdks/allowlistidentifiers/README.md | 6 +- docs/sdks/betafeatures/README.md | 6 +- docs/sdks/blocklistidentifierssdk/README.md | 6 +- docs/sdks/clients/README.md | 6 +- docs/sdks/domainssdk/README.md | 8 +- docs/sdks/emailaddresses/README.md | 8 +- docs/sdks/instancesettingssdk/README.md | 6 +- docs/sdks/invitations/README.md | 10 +- docs/sdks/jwks/README.md | 2 +- docs/sdks/jwttemplates/README.md | 10 +- docs/sdks/misc/README.md | 2 +- docs/sdks/oauthapplicationssdk/README.md | 12 +- .../sdks/organizationinvitationssdk/README.md | 16 +- .../sdks/organizationmembershipssdk/README.md | 10 +- docs/sdks/organizationssdk/README.md | 16 +- docs/sdks/phonenumbers/README.md | 8 +- docs/sdks/proxychecks/README.md | 2 +- docs/sdks/redirecturls/README.md | 8 +- docs/sdks/samlconnectionssdk/README.md | 14 +- docs/sdks/sessions/README.md | 14 +- docs/sdks/signintokens/README.md | 4 +- docs/sdks/signups/README.md | 2 +- docs/sdks/templates/README.md | 32 +- docs/sdks/testingtokens/README.md | 2 +- docs/sdks/users/README.md | 44 +- docs/sdks/webhooks/README.md | 6 +- pyproject.toml | 6 +- src/clerk_backend_api/__init__.py | 5 + src/clerk_backend_api/_hooks/__init__.py | 5 + src/clerk_backend_api/_hooks/registration.py | 13 + src/clerk_backend_api/_hooks/sdkhooks.py | 57 + src/clerk_backend_api/_hooks/types.py | 76 + src/clerk_backend_api/actortokens.py | 341 ++ src/clerk_backend_api/allowlistidentifiers.py | 467 +++ src/clerk_backend_api/basesdk.py | 213 ++ src/clerk_backend_api/betafeatures.py | 528 +++ .../blocklistidentifiers_sdk.py | 461 +++ src/clerk_backend_api/clients.py | 535 +++ src/clerk_backend_api/domains_sdk.py | 665 ++++ src/clerk_backend_api/emailaddresses.py | 665 ++++ src/clerk_backend_api/httpclient.py | 78 + src/clerk_backend_api/instancesettings_sdk.py | 587 +++ src/clerk_backend_api/invitations.py | 564 +++ src/clerk_backend_api/jwks.py | 145 + src/clerk_backend_api/jwttemplates.py | 839 +++++ src/clerk_backend_api/misc.py | 165 + src/clerk_backend_api/models/__init__.py | 151 + src/clerk_backend_api/models/actortoken.py | 88 + src/clerk_backend_api/models/adddomainop.py | 25 + .../models/allowlistidentifier.py | 67 + src/clerk_backend_api/models/banuserop.py | 18 + .../models/blocklistidentifier.py | 65 + .../models/blocklistidentifiers.py | 23 + .../changeproductioninstancedomainop.py | 17 + src/clerk_backend_api/models/clerkerror.py | 31 + src/clerk_backend_api/models/clerkerrors.py | 32 + src/clerk_backend_api/models/client.py | 95 + src/clerk_backend_api/models/cnametarget.py | 24 + .../models/createactortokenop.py | 41 + .../models/createallowlistidentifierop.py | 29 + .../models/createblocklistidentifierop.py | 20 + .../models/createemailaddressop.py | 59 + .../models/createinvitationop.py | 93 + .../models/createjwttemplateop.py | 77 + .../models/createoauthapplicationop.py | 35 + .../createorganizationinvitationbulkop.py | 74 + .../models/createorganizationinvitationop.py | 74 + .../models/createorganizationmembershipop.py | 34 + .../models/createorganizationop.py | 63 + .../models/createphonenumberop.py | 69 + .../models/createredirecturlop.py | 17 + .../models/createsamlconnectionop.py | 102 + .../createsessiontokenfromtemplateop.py | 41 + .../models/createsignintokenop.py | 25 + src/clerk_backend_api/models/createuserop.py | 599 +++ .../models/deleteallowlistidentifierop.py | 18 + .../models/deleteblocklistidentifierop.py | 18 + src/clerk_backend_api/models/deletedobject.py | 21 + .../models/deletedomainop.py | 18 + .../models/deleteemailaddressop.py | 18 + .../models/deletejwttemplateop.py | 18 + .../models/deleteoauthapplicationop.py | 18 + .../models/deleteorganizationlogoop.py | 18 + .../models/deleteorganizationmembershipop.py | 22 + .../models/deleteorganizationop.py | 18 + .../models/deletephonenumberop.py | 18 + .../models/deleteredirecturlop.py | 18 + .../models/deletesamlconnectionop.py | 18 + src/clerk_backend_api/models/deleteuserop.py | 18 + .../models/deleteuserprofileimageop.py | 18 + src/clerk_backend_api/models/disablemfaop.py | 30 + src/clerk_backend_api/models/domain.py | 69 + src/clerk_backend_api/models/domains.py | 23 + src/clerk_backend_api/models/emailaddress.py | 277 ++ .../models/getclientlistop.py | 43 + src/clerk_backend_api/models/getclientop.py | 18 + .../models/getemailaddressop.py | 18 + .../models/getjwttemplateop.py | 18 + .../models/getoauthaccesstokenop.py | 96 + .../models/getoauthapplicationop.py | 18 + .../models/getorganizationinvitationop.py | 22 + .../models/getorganizationop.py | 18 + .../models/getphonenumberop.py | 18 + .../models/getpublicinterstitialop.py | 23 + .../models/getredirecturlop.py | 18 + .../models/getsamlconnectionop.py | 18 + .../models/getsessionlistop.py | 56 + src/clerk_backend_api/models/getsessionop.py | 18 + .../models/gettemplatelistop.py | 25 + src/clerk_backend_api/models/gettemplateop.py | 29 + src/clerk_backend_api/models/getuserlistop.py | 162 + src/clerk_backend_api/models/getuserop.py | 18 + .../models/getuserscountop.py | 84 + .../models/identificationlink.py | 24 + .../models/instancerestrictions.py | 31 + .../models/instancesettings.py | 33 + src/clerk_backend_api/models/invitation.py | 88 + .../models/invitation_revoked.py | 86 + src/clerk_backend_api/models/jwttemplate.py | 58 + .../models/listinvitationsop.py | 55 + .../models/listoauthapplicationsop.py | 43 + .../models/listorganizationinvitationsop.py | 59 + .../models/listorganizationmembershipsop.py | 57 + .../models/listorganizationsop.py | 60 + .../listpendingorganizationinvitationsop.py | 47 + .../models/listsamlconnectionsop.py | 43 + src/clerk_backend_api/models/lockuserop.py | 18 + .../models/mergeorganizationmetadataop.py | 70 + .../models/oauthapplication.py | 55 + .../models/oauthapplications.py | 23 + .../models/oauthapplicationwithsecret.py | 64 + src/clerk_backend_api/models/organization.py | 96 + .../models/organizationinvitation.py | 71 + .../models/organizationinvitations.py | 23 + .../models/organizationmembership.py | 213 ++ .../models/organizationmemberships.py | 23 + src/clerk_backend_api/models/organizations.py | 23 + .../models/organizationsettings.py | 53 + .../models/organizationwithlogo.py | 103 + src/clerk_backend_api/models/phonenumber.py | 195 + .../models/previewtemplateop.py | 104 + src/clerk_backend_api/models/proxycheck.py | 33 + src/clerk_backend_api/models/redirecturl.py | 39 + .../models/reverttemplateop.py | 29 + .../models/revokeactortokenop.py | 18 + .../models/revokeinvitationop.py | 18 + .../models/revokeorganizationinvitationop.py | 38 + .../models/revokesessionop.py | 18 + .../models/revokesignintokenop.py | 18 + .../models/rotateoauthapplicationsecretop.py | 18 + src/clerk_backend_api/models/samlaccount.py | 221 ++ .../models/samlconnection.py | 112 + .../models/samlconnections.py | 23 + .../models/schemas_passkey.py | 128 + src/clerk_backend_api/models/sdkerror.py | 22 + src/clerk_backend_api/models/security.py | 16 + src/clerk_backend_api/models/session.py | 107 + .../models/setuserprofileimageop.py | 42 + src/clerk_backend_api/models/signintoken.py | 78 + src/clerk_backend_api/models/signup.py | 128 + src/clerk_backend_api/models/svixurl.py | 14 + src/clerk_backend_api/models/template.py | 135 + src/clerk_backend_api/models/testingtoken.py | 35 + .../models/toggletemplatedeliveryop.py | 67 + src/clerk_backend_api/models/totalcount.py | 30 + src/clerk_backend_api/models/unbanuserop.py | 18 + src/clerk_backend_api/models/unlockuserop.py | 18 + .../models/updatedomainop.py | 70 + .../models/updateemailaddressop.py | 60 + .../models/updateinstanceauthconfigop.py | 77 + .../models/updateinstanceop.py | 86 + .../updateinstanceorganizationsettingsop.py | 63 + .../models/updateinstancerestrictionsop.py | 49 + .../models/updatejwttemplateop.py | 90 + .../models/updateoauthapplicationop.py | 38 + .../updateorganizationmembershipmetadataop.py | 74 + .../models/updateorganizationmembershipop.py | 34 + .../models/updateorganizationop.py | 96 + .../models/updatephonenumberop.py | 70 + .../updateproductioninstancedomainop.py | 17 + .../models/updatesamlconnectionop.py | 118 + .../models/updatesignupop.py | 70 + .../models/updateusermetadataop.py | 86 + src/clerk_backend_api/models/updateuserop.py | 586 +++ .../models/uploadorganizationlogoop.py | 46 + .../models/upserttemplateop.py | 107 + src/clerk_backend_api/models/user.py | 237 ++ .../usersgetorganizationmembershipsop.py | 47 + .../models/verifyclientop.py | 21 + .../models/verifydomainproxyop.py | 21 + .../models/verifypasswordop.py | 42 + .../models/verifysessionop.py | 40 + src/clerk_backend_api/models/verifytotpop.py | 50 + src/clerk_backend_api/models/web3wallet.py | 184 + .../oauthapplications_sdk.py | 1046 ++++++ .../organizationinvitations_sdk.py | 1223 ++++++ .../organizationmemberships_sdk.py | 920 +++++ src/clerk_backend_api/organizations_sdk.py | 1411 +++++++ src/clerk_backend_api/phonenumbers.py | 677 ++++ src/clerk_backend_api/proxychecks.py | 187 + src/clerk_backend_api/redirecturls.py | 609 +++ src/clerk_backend_api/samlconnections_sdk.py | 966 +++++ src/clerk_backend_api/sdk.py | 179 + src/clerk_backend_api/sdkconfiguration.py | 46 + src/clerk_backend_api/sessions.py | 840 +++++ src/clerk_backend_api/signintokens.py | 331 ++ src/clerk_backend_api/signups.py | 183 + src/clerk_backend_api/templates.py | 1061 ++++++ src/clerk_backend_api/testingtokens.py | 145 + src/clerk_backend_api/types/__init__.py | 9 + src/clerk_backend_api/types/basemodel.py | 18 + src/clerk_backend_api/users.py | 3316 +++++++++++++++++ src/clerk_backend_api/utils/__init__.py | 74 + src/clerk_backend_api/utils/enums.py | 34 + src/clerk_backend_api/utils/eventstreaming.py | 156 + src/clerk_backend_api/utils/forms.py | 207 + src/clerk_backend_api/utils/headers.py | 136 + src/clerk_backend_api/utils/metadata.py | 118 + src/clerk_backend_api/utils/queryparams.py | 162 + src/clerk_backend_api/utils/requestbodies.py | 66 + src/clerk_backend_api/utils/retries.py | 216 ++ src/clerk_backend_api/utils/security.py | 166 + src/clerk_backend_api/utils/serializers.py | 159 + src/clerk_backend_api/utils/url.py | 152 + src/clerk_backend_api/utils/values.py | 128 + src/clerk_backend_api/webhooks.py | 431 +++ 233 files changed, 31353 insertions(+), 358 deletions(-) create mode 100644 src/clerk_backend_api/__init__.py create mode 100644 src/clerk_backend_api/_hooks/__init__.py create mode 100644 src/clerk_backend_api/_hooks/registration.py create mode 100644 src/clerk_backend_api/_hooks/sdkhooks.py create mode 100644 src/clerk_backend_api/_hooks/types.py create mode 100644 src/clerk_backend_api/actortokens.py create mode 100644 src/clerk_backend_api/allowlistidentifiers.py create mode 100644 src/clerk_backend_api/basesdk.py create mode 100644 src/clerk_backend_api/betafeatures.py create mode 100644 src/clerk_backend_api/blocklistidentifiers_sdk.py create mode 100644 src/clerk_backend_api/clients.py create mode 100644 src/clerk_backend_api/domains_sdk.py create mode 100644 src/clerk_backend_api/emailaddresses.py create mode 100644 src/clerk_backend_api/httpclient.py create mode 100644 src/clerk_backend_api/instancesettings_sdk.py create mode 100644 src/clerk_backend_api/invitations.py create mode 100644 src/clerk_backend_api/jwks.py create mode 100644 src/clerk_backend_api/jwttemplates.py create mode 100644 src/clerk_backend_api/misc.py create mode 100644 src/clerk_backend_api/models/__init__.py create mode 100644 src/clerk_backend_api/models/actortoken.py create mode 100644 src/clerk_backend_api/models/adddomainop.py create mode 100644 src/clerk_backend_api/models/allowlistidentifier.py create mode 100644 src/clerk_backend_api/models/banuserop.py create mode 100644 src/clerk_backend_api/models/blocklistidentifier.py create mode 100644 src/clerk_backend_api/models/blocklistidentifiers.py create mode 100644 src/clerk_backend_api/models/changeproductioninstancedomainop.py create mode 100644 src/clerk_backend_api/models/clerkerror.py create mode 100644 src/clerk_backend_api/models/clerkerrors.py create mode 100644 src/clerk_backend_api/models/client.py create mode 100644 src/clerk_backend_api/models/cnametarget.py create mode 100644 src/clerk_backend_api/models/createactortokenop.py create mode 100644 src/clerk_backend_api/models/createallowlistidentifierop.py create mode 100644 src/clerk_backend_api/models/createblocklistidentifierop.py create mode 100644 src/clerk_backend_api/models/createemailaddressop.py create mode 100644 src/clerk_backend_api/models/createinvitationop.py create mode 100644 src/clerk_backend_api/models/createjwttemplateop.py create mode 100644 src/clerk_backend_api/models/createoauthapplicationop.py create mode 100644 src/clerk_backend_api/models/createorganizationinvitationbulkop.py create mode 100644 src/clerk_backend_api/models/createorganizationinvitationop.py create mode 100644 src/clerk_backend_api/models/createorganizationmembershipop.py create mode 100644 src/clerk_backend_api/models/createorganizationop.py create mode 100644 src/clerk_backend_api/models/createphonenumberop.py create mode 100644 src/clerk_backend_api/models/createredirecturlop.py create mode 100644 src/clerk_backend_api/models/createsamlconnectionop.py create mode 100644 src/clerk_backend_api/models/createsessiontokenfromtemplateop.py create mode 100644 src/clerk_backend_api/models/createsignintokenop.py create mode 100644 src/clerk_backend_api/models/createuserop.py create mode 100644 src/clerk_backend_api/models/deleteallowlistidentifierop.py create mode 100644 src/clerk_backend_api/models/deleteblocklistidentifierop.py create mode 100644 src/clerk_backend_api/models/deletedobject.py create mode 100644 src/clerk_backend_api/models/deletedomainop.py create mode 100644 src/clerk_backend_api/models/deleteemailaddressop.py create mode 100644 src/clerk_backend_api/models/deletejwttemplateop.py create mode 100644 src/clerk_backend_api/models/deleteoauthapplicationop.py create mode 100644 src/clerk_backend_api/models/deleteorganizationlogoop.py create mode 100644 src/clerk_backend_api/models/deleteorganizationmembershipop.py create mode 100644 src/clerk_backend_api/models/deleteorganizationop.py create mode 100644 src/clerk_backend_api/models/deletephonenumberop.py create mode 100644 src/clerk_backend_api/models/deleteredirecturlop.py create mode 100644 src/clerk_backend_api/models/deletesamlconnectionop.py create mode 100644 src/clerk_backend_api/models/deleteuserop.py create mode 100644 src/clerk_backend_api/models/deleteuserprofileimageop.py create mode 100644 src/clerk_backend_api/models/disablemfaop.py create mode 100644 src/clerk_backend_api/models/domain.py create mode 100644 src/clerk_backend_api/models/domains.py create mode 100644 src/clerk_backend_api/models/emailaddress.py create mode 100644 src/clerk_backend_api/models/getclientlistop.py create mode 100644 src/clerk_backend_api/models/getclientop.py create mode 100644 src/clerk_backend_api/models/getemailaddressop.py create mode 100644 src/clerk_backend_api/models/getjwttemplateop.py create mode 100644 src/clerk_backend_api/models/getoauthaccesstokenop.py create mode 100644 src/clerk_backend_api/models/getoauthapplicationop.py create mode 100644 src/clerk_backend_api/models/getorganizationinvitationop.py create mode 100644 src/clerk_backend_api/models/getorganizationop.py create mode 100644 src/clerk_backend_api/models/getphonenumberop.py create mode 100644 src/clerk_backend_api/models/getpublicinterstitialop.py create mode 100644 src/clerk_backend_api/models/getredirecturlop.py create mode 100644 src/clerk_backend_api/models/getsamlconnectionop.py create mode 100644 src/clerk_backend_api/models/getsessionlistop.py create mode 100644 src/clerk_backend_api/models/getsessionop.py create mode 100644 src/clerk_backend_api/models/gettemplatelistop.py create mode 100644 src/clerk_backend_api/models/gettemplateop.py create mode 100644 src/clerk_backend_api/models/getuserlistop.py create mode 100644 src/clerk_backend_api/models/getuserop.py create mode 100644 src/clerk_backend_api/models/getuserscountop.py create mode 100644 src/clerk_backend_api/models/identificationlink.py create mode 100644 src/clerk_backend_api/models/instancerestrictions.py create mode 100644 src/clerk_backend_api/models/instancesettings.py create mode 100644 src/clerk_backend_api/models/invitation.py create mode 100644 src/clerk_backend_api/models/invitation_revoked.py create mode 100644 src/clerk_backend_api/models/jwttemplate.py create mode 100644 src/clerk_backend_api/models/listinvitationsop.py create mode 100644 src/clerk_backend_api/models/listoauthapplicationsop.py create mode 100644 src/clerk_backend_api/models/listorganizationinvitationsop.py create mode 100644 src/clerk_backend_api/models/listorganizationmembershipsop.py create mode 100644 src/clerk_backend_api/models/listorganizationsop.py create mode 100644 src/clerk_backend_api/models/listpendingorganizationinvitationsop.py create mode 100644 src/clerk_backend_api/models/listsamlconnectionsop.py create mode 100644 src/clerk_backend_api/models/lockuserop.py create mode 100644 src/clerk_backend_api/models/mergeorganizationmetadataop.py create mode 100644 src/clerk_backend_api/models/oauthapplication.py create mode 100644 src/clerk_backend_api/models/oauthapplications.py create mode 100644 src/clerk_backend_api/models/oauthapplicationwithsecret.py create mode 100644 src/clerk_backend_api/models/organization.py create mode 100644 src/clerk_backend_api/models/organizationinvitation.py create mode 100644 src/clerk_backend_api/models/organizationinvitations.py create mode 100644 src/clerk_backend_api/models/organizationmembership.py create mode 100644 src/clerk_backend_api/models/organizationmemberships.py create mode 100644 src/clerk_backend_api/models/organizations.py create mode 100644 src/clerk_backend_api/models/organizationsettings.py create mode 100644 src/clerk_backend_api/models/organizationwithlogo.py create mode 100644 src/clerk_backend_api/models/phonenumber.py create mode 100644 src/clerk_backend_api/models/previewtemplateop.py create mode 100644 src/clerk_backend_api/models/proxycheck.py create mode 100644 src/clerk_backend_api/models/redirecturl.py create mode 100644 src/clerk_backend_api/models/reverttemplateop.py create mode 100644 src/clerk_backend_api/models/revokeactortokenop.py create mode 100644 src/clerk_backend_api/models/revokeinvitationop.py create mode 100644 src/clerk_backend_api/models/revokeorganizationinvitationop.py create mode 100644 src/clerk_backend_api/models/revokesessionop.py create mode 100644 src/clerk_backend_api/models/revokesignintokenop.py create mode 100644 src/clerk_backend_api/models/rotateoauthapplicationsecretop.py create mode 100644 src/clerk_backend_api/models/samlaccount.py create mode 100644 src/clerk_backend_api/models/samlconnection.py create mode 100644 src/clerk_backend_api/models/samlconnections.py create mode 100644 src/clerk_backend_api/models/schemas_passkey.py create mode 100644 src/clerk_backend_api/models/sdkerror.py create mode 100644 src/clerk_backend_api/models/security.py create mode 100644 src/clerk_backend_api/models/session.py create mode 100644 src/clerk_backend_api/models/setuserprofileimageop.py create mode 100644 src/clerk_backend_api/models/signintoken.py create mode 100644 src/clerk_backend_api/models/signup.py create mode 100644 src/clerk_backend_api/models/svixurl.py create mode 100644 src/clerk_backend_api/models/template.py create mode 100644 src/clerk_backend_api/models/testingtoken.py create mode 100644 src/clerk_backend_api/models/toggletemplatedeliveryop.py create mode 100644 src/clerk_backend_api/models/totalcount.py create mode 100644 src/clerk_backend_api/models/unbanuserop.py create mode 100644 src/clerk_backend_api/models/unlockuserop.py create mode 100644 src/clerk_backend_api/models/updatedomainop.py create mode 100644 src/clerk_backend_api/models/updateemailaddressop.py create mode 100644 src/clerk_backend_api/models/updateinstanceauthconfigop.py create mode 100644 src/clerk_backend_api/models/updateinstanceop.py create mode 100644 src/clerk_backend_api/models/updateinstanceorganizationsettingsop.py create mode 100644 src/clerk_backend_api/models/updateinstancerestrictionsop.py create mode 100644 src/clerk_backend_api/models/updatejwttemplateop.py create mode 100644 src/clerk_backend_api/models/updateoauthapplicationop.py create mode 100644 src/clerk_backend_api/models/updateorganizationmembershipmetadataop.py create mode 100644 src/clerk_backend_api/models/updateorganizationmembershipop.py create mode 100644 src/clerk_backend_api/models/updateorganizationop.py create mode 100644 src/clerk_backend_api/models/updatephonenumberop.py create mode 100644 src/clerk_backend_api/models/updateproductioninstancedomainop.py create mode 100644 src/clerk_backend_api/models/updatesamlconnectionop.py create mode 100644 src/clerk_backend_api/models/updatesignupop.py create mode 100644 src/clerk_backend_api/models/updateusermetadataop.py create mode 100644 src/clerk_backend_api/models/updateuserop.py create mode 100644 src/clerk_backend_api/models/uploadorganizationlogoop.py create mode 100644 src/clerk_backend_api/models/upserttemplateop.py create mode 100644 src/clerk_backend_api/models/user.py create mode 100644 src/clerk_backend_api/models/usersgetorganizationmembershipsop.py create mode 100644 src/clerk_backend_api/models/verifyclientop.py create mode 100644 src/clerk_backend_api/models/verifydomainproxyop.py create mode 100644 src/clerk_backend_api/models/verifypasswordop.py create mode 100644 src/clerk_backend_api/models/verifysessionop.py create mode 100644 src/clerk_backend_api/models/verifytotpop.py create mode 100644 src/clerk_backend_api/models/web3wallet.py create mode 100644 src/clerk_backend_api/oauthapplications_sdk.py create mode 100644 src/clerk_backend_api/organizationinvitations_sdk.py create mode 100644 src/clerk_backend_api/organizationmemberships_sdk.py create mode 100644 src/clerk_backend_api/organizations_sdk.py create mode 100644 src/clerk_backend_api/phonenumbers.py create mode 100644 src/clerk_backend_api/proxychecks.py create mode 100644 src/clerk_backend_api/redirecturls.py create mode 100644 src/clerk_backend_api/samlconnections_sdk.py create mode 100644 src/clerk_backend_api/sdk.py create mode 100644 src/clerk_backend_api/sdkconfiguration.py create mode 100644 src/clerk_backend_api/sessions.py create mode 100644 src/clerk_backend_api/signintokens.py create mode 100644 src/clerk_backend_api/signups.py create mode 100644 src/clerk_backend_api/templates.py create mode 100644 src/clerk_backend_api/testingtokens.py create mode 100644 src/clerk_backend_api/types/__init__.py create mode 100644 src/clerk_backend_api/types/basemodel.py create mode 100644 src/clerk_backend_api/users.py create mode 100644 src/clerk_backend_api/utils/__init__.py create mode 100644 src/clerk_backend_api/utils/enums.py create mode 100644 src/clerk_backend_api/utils/eventstreaming.py create mode 100644 src/clerk_backend_api/utils/forms.py create mode 100644 src/clerk_backend_api/utils/headers.py create mode 100644 src/clerk_backend_api/utils/metadata.py create mode 100644 src/clerk_backend_api/utils/queryparams.py create mode 100644 src/clerk_backend_api/utils/requestbodies.py create mode 100644 src/clerk_backend_api/utils/retries.py create mode 100644 src/clerk_backend_api/utils/security.py create mode 100644 src/clerk_backend_api/utils/serializers.py create mode 100644 src/clerk_backend_api/utils/url.py create mode 100644 src/clerk_backend_api/utils/values.py create mode 100644 src/clerk_backend_api/webhooks.py diff --git a/.speakeasy/gen.lock b/.speakeasy/gen.lock index b31f98cc..7ce740e9 100644 --- a/.speakeasy/gen.lock +++ b/.speakeasy/gen.lock @@ -5,8 +5,8 @@ management: docVersion: v1 speakeasyVersion: 1.331.2 generationVersion: 2.366.1 - releaseVersion: 0.5.0-alpha.6 - configChecksum: b234669f372cf694e810c4b3cf07d654 + releaseVersion: 0.5.0-alpha.7 + configChecksum: 2d94b80871c84384d32f0c2f89c26d3f repoURL: https://github.com/clerk/clerk-sdk-python.git installationURL: https://github.com/clerk/clerk-sdk-python.git published: true @@ -35,205 +35,205 @@ features: 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 + - src/clerk_backend_api/sdkconfiguration.py + - src/clerk_backend_api/misc.py + - src/clerk_backend_api/jwks.py + - src/clerk_backend_api/clients.py + - src/clerk_backend_api/emailaddresses.py + - src/clerk_backend_api/phonenumbers.py + - src/clerk_backend_api/sessions.py + - src/clerk_backend_api/templates.py + - src/clerk_backend_api/users.py + - src/clerk_backend_api/invitations.py + - src/clerk_backend_api/allowlistidentifiers.py + - src/clerk_backend_api/blocklistidentifiers_sdk.py + - src/clerk_backend_api/betafeatures.py + - src/clerk_backend_api/actortokens.py + - src/clerk_backend_api/domains_sdk.py + - src/clerk_backend_api/instancesettings_sdk.py + - src/clerk_backend_api/webhooks.py + - src/clerk_backend_api/jwttemplates.py + - src/clerk_backend_api/organizations_sdk.py + - src/clerk_backend_api/organizationinvitations_sdk.py + - src/clerk_backend_api/organizationmemberships_sdk.py + - src/clerk_backend_api/proxychecks.py + - src/clerk_backend_api/redirecturls.py + - src/clerk_backend_api/signintokens.py + - src/clerk_backend_api/signups.py + - src/clerk_backend_api/oauthapplications_sdk.py + - src/clerk_backend_api/samlconnections_sdk.py + - src/clerk_backend_api/testingtokens.py + - src/clerk_backend_api/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 + - src/clerk_backend_api/__init__.py + - src/clerk_backend_api/basesdk.py + - src/clerk_backend_api/httpclient.py + - src/clerk_backend_api/types/__init__.py + - src/clerk_backend_api/types/basemodel.py + - src/clerk_backend_api/utils/__init__.py + - src/clerk_backend_api/utils/enums.py + - src/clerk_backend_api/utils/eventstreaming.py + - src/clerk_backend_api/utils/forms.py + - src/clerk_backend_api/utils/headers.py + - src/clerk_backend_api/utils/metadata.py + - src/clerk_backend_api/utils/queryparams.py + - src/clerk_backend_api/utils/requestbodies.py + - src/clerk_backend_api/utils/retries.py + - src/clerk_backend_api/utils/security.py + - src/clerk_backend_api/utils/serializers.py + - src/clerk_backend_api/utils/url.py + - src/clerk_backend_api/utils/values.py + - src/clerk_backend_api/models/sdkerror.py + - src/clerk_backend_api/models/getpublicinterstitialop.py + - src/clerk_backend_api/models/getclientlistop.py + - src/clerk_backend_api/models/client.py + - src/clerk_backend_api/models/session.py + - src/clerk_backend_api/models/clerkerrors.py + - src/clerk_backend_api/models/clerkerror.py + - src/clerk_backend_api/models/verifyclientop.py + - src/clerk_backend_api/models/getclientop.py + - src/clerk_backend_api/models/emailaddress.py + - src/clerk_backend_api/models/identificationlink.py + - src/clerk_backend_api/models/createemailaddressop.py + - src/clerk_backend_api/models/getemailaddressop.py + - src/clerk_backend_api/models/deletedobject.py + - src/clerk_backend_api/models/deleteemailaddressop.py + - src/clerk_backend_api/models/updateemailaddressop.py + - src/clerk_backend_api/models/phonenumber.py + - src/clerk_backend_api/models/createphonenumberop.py + - src/clerk_backend_api/models/getphonenumberop.py + - src/clerk_backend_api/models/deletephonenumberop.py + - src/clerk_backend_api/models/updatephonenumberop.py + - src/clerk_backend_api/models/getsessionlistop.py + - src/clerk_backend_api/models/getsessionop.py + - src/clerk_backend_api/models/revokesessionop.py + - src/clerk_backend_api/models/verifysessionop.py + - src/clerk_backend_api/models/createsessiontokenfromtemplateop.py + - src/clerk_backend_api/models/template.py + - src/clerk_backend_api/models/gettemplatelistop.py + - src/clerk_backend_api/models/gettemplateop.py + - src/clerk_backend_api/models/upserttemplateop.py + - src/clerk_backend_api/models/reverttemplateop.py + - src/clerk_backend_api/models/previewtemplateop.py + - src/clerk_backend_api/models/toggletemplatedeliveryop.py + - src/clerk_backend_api/models/user.py + - src/clerk_backend_api/models/samlaccount.py + - src/clerk_backend_api/models/schemas_passkey.py + - src/clerk_backend_api/models/web3wallet.py + - src/clerk_backend_api/models/getuserlistop.py + - src/clerk_backend_api/models/createuserop.py + - src/clerk_backend_api/models/totalcount.py + - src/clerk_backend_api/models/getuserscountop.py + - src/clerk_backend_api/models/getuserop.py + - src/clerk_backend_api/models/updateuserop.py + - src/clerk_backend_api/models/deleteuserop.py + - src/clerk_backend_api/models/banuserop.py + - src/clerk_backend_api/models/unbanuserop.py + - src/clerk_backend_api/models/lockuserop.py + - src/clerk_backend_api/models/unlockuserop.py + - src/clerk_backend_api/models/setuserprofileimageop.py + - src/clerk_backend_api/models/deleteuserprofileimageop.py + - src/clerk_backend_api/models/updateusermetadataop.py + - src/clerk_backend_api/models/getoauthaccesstokenop.py + - src/clerk_backend_api/models/usersgetorganizationmembershipsop.py + - src/clerk_backend_api/models/organizationmemberships.py + - src/clerk_backend_api/models/organizationmembership.py + - src/clerk_backend_api/models/verifypasswordop.py + - src/clerk_backend_api/models/verifytotpop.py + - src/clerk_backend_api/models/disablemfaop.py + - src/clerk_backend_api/models/invitation.py + - src/clerk_backend_api/models/createinvitationop.py + - src/clerk_backend_api/models/listinvitationsop.py + - src/clerk_backend_api/models/invitation_revoked.py + - src/clerk_backend_api/models/revokeinvitationop.py + - src/clerk_backend_api/models/allowlistidentifier.py + - src/clerk_backend_api/models/createallowlistidentifierop.py + - src/clerk_backend_api/models/deleteallowlistidentifierop.py + - src/clerk_backend_api/models/blocklistidentifiers.py + - src/clerk_backend_api/models/blocklistidentifier.py + - src/clerk_backend_api/models/createblocklistidentifierop.py + - src/clerk_backend_api/models/deleteblocklistidentifierop.py + - src/clerk_backend_api/models/instancesettings.py + - src/clerk_backend_api/models/updateinstanceauthconfigop.py + - src/clerk_backend_api/models/updateproductioninstancedomainop.py + - src/clerk_backend_api/models/changeproductioninstancedomainop.py + - src/clerk_backend_api/models/actortoken.py + - src/clerk_backend_api/models/createactortokenop.py + - src/clerk_backend_api/models/revokeactortokenop.py + - src/clerk_backend_api/models/domains.py + - src/clerk_backend_api/models/domain.py + - src/clerk_backend_api/models/cnametarget.py + - src/clerk_backend_api/models/adddomainop.py + - src/clerk_backend_api/models/deletedomainop.py + - src/clerk_backend_api/models/updatedomainop.py + - src/clerk_backend_api/models/updateinstanceop.py + - src/clerk_backend_api/models/instancerestrictions.py + - src/clerk_backend_api/models/updateinstancerestrictionsop.py + - src/clerk_backend_api/models/organizationsettings.py + - src/clerk_backend_api/models/updateinstanceorganizationsettingsop.py + - src/clerk_backend_api/models/svixurl.py + - src/clerk_backend_api/models/jwttemplate.py + - src/clerk_backend_api/models/createjwttemplateop.py + - src/clerk_backend_api/models/getjwttemplateop.py + - src/clerk_backend_api/models/updatejwttemplateop.py + - src/clerk_backend_api/models/deletejwttemplateop.py + - src/clerk_backend_api/models/organizations.py + - src/clerk_backend_api/models/organization.py + - src/clerk_backend_api/models/listorganizationsop.py + - src/clerk_backend_api/models/createorganizationop.py + - src/clerk_backend_api/models/getorganizationop.py + - src/clerk_backend_api/models/updateorganizationop.py + - src/clerk_backend_api/models/deleteorganizationop.py + - src/clerk_backend_api/models/mergeorganizationmetadataop.py + - src/clerk_backend_api/models/organizationwithlogo.py + - src/clerk_backend_api/models/uploadorganizationlogoop.py + - src/clerk_backend_api/models/deleteorganizationlogoop.py + - src/clerk_backend_api/models/organizationinvitation.py + - src/clerk_backend_api/models/createorganizationinvitationop.py + - src/clerk_backend_api/models/listorganizationinvitationsop.py + - src/clerk_backend_api/models/organizationinvitations.py + - src/clerk_backend_api/models/createorganizationinvitationbulkop.py + - src/clerk_backend_api/models/listpendingorganizationinvitationsop.py + - src/clerk_backend_api/models/getorganizationinvitationop.py + - src/clerk_backend_api/models/revokeorganizationinvitationop.py + - src/clerk_backend_api/models/createorganizationmembershipop.py + - src/clerk_backend_api/models/listorganizationmembershipsop.py + - src/clerk_backend_api/models/updateorganizationmembershipop.py + - src/clerk_backend_api/models/deleteorganizationmembershipop.py + - src/clerk_backend_api/models/updateorganizationmembershipmetadataop.py + - src/clerk_backend_api/models/proxycheck.py + - src/clerk_backend_api/models/verifydomainproxyop.py + - src/clerk_backend_api/models/redirecturl.py + - src/clerk_backend_api/models/createredirecturlop.py + - src/clerk_backend_api/models/getredirecturlop.py + - src/clerk_backend_api/models/deleteredirecturlop.py + - src/clerk_backend_api/models/signintoken.py + - src/clerk_backend_api/models/createsignintokenop.py + - src/clerk_backend_api/models/revokesignintokenop.py + - src/clerk_backend_api/models/signup.py + - src/clerk_backend_api/models/updatesignupop.py + - src/clerk_backend_api/models/listoauthapplicationsop.py + - src/clerk_backend_api/models/oauthapplications.py + - src/clerk_backend_api/models/oauthapplication.py + - src/clerk_backend_api/models/oauthapplicationwithsecret.py + - src/clerk_backend_api/models/createoauthapplicationop.py + - src/clerk_backend_api/models/getoauthapplicationop.py + - src/clerk_backend_api/models/updateoauthapplicationop.py + - src/clerk_backend_api/models/deleteoauthapplicationop.py + - src/clerk_backend_api/models/rotateoauthapplicationsecretop.py + - src/clerk_backend_api/models/listsamlconnectionsop.py + - src/clerk_backend_api/models/samlconnections.py + - src/clerk_backend_api/models/samlconnection.py + - src/clerk_backend_api/models/createsamlconnectionop.py + - src/clerk_backend_api/models/getsamlconnectionop.py + - src/clerk_backend_api/models/updatesamlconnectionop.py + - src/clerk_backend_api/models/deletesamlconnectionop.py + - src/clerk_backend_api/models/testingtoken.py + - src/clerk_backend_api/models/security.py + - src/clerk_backend_api/models/__init__.py - docs/models/getpublicinterstitialrequest.md - docs/models/getclientlistrequest.md - docs/models/getclientlistresponse.md @@ -606,6 +606,6 @@ generatedFiles: - docs/sdks/testingtokens/README.md - USAGE.md - .gitattributes - - src/clerk/_hooks/sdkhooks.py - - src/clerk/_hooks/types.py - - src/clerk/_hooks/__init__.py + - src/clerk_backend_api/_hooks/sdkhooks.py + - src/clerk_backend_api/_hooks/types.py + - src/clerk_backend_api/_hooks/__init__.py diff --git a/.speakeasy/gen.yaml b/.speakeasy/gen.yaml index c898e630..920bf485 100644 --- a/.speakeasy/gen.yaml +++ b/.speakeasy/gen.yaml @@ -12,7 +12,7 @@ generation: auth: oAuth2ClientCredentialsEnabled: true python: - version: 0.5.0-alpha.6 + version: 0.5.0-alpha.7 additionalDependencies: dev: {} main: {} diff --git a/.speakeasy/workflow.lock b/.speakeasy/workflow.lock index 7ef0be25..531f639a 100644 --- a/.speakeasy/workflow.lock +++ b/.speakeasy/workflow.lock @@ -2,8 +2,8 @@ speakeasyVersion: 1.331.2 sources: clerk-openapi: sourceNamespace: clerk-openapi - sourceRevisionDigest: sha256:4ce22a0cdb7433f376f0842a2dda1143fc61c2da241b5903d6239a44fc978fec - sourceBlobDigest: sha256:c715e59591e54f9e2beca3ed567d1a12edc3f20580cac065511ce19c4423e3aa + sourceRevisionDigest: sha256:83887503bf502c2b1e816b079beba5218998adb827d73f2ac6de809e14f4389b + sourceBlobDigest: sha256:0181726a4ca9a31eae12e6bdd2d42c0aeca0e25a76d8e9c82b57a829b69dff68 tags: - latest - main @@ -11,8 +11,8 @@ targets: clerk-sdk-python: source: clerk-openapi sourceNamespace: clerk-openapi - sourceRevisionDigest: sha256:4ce22a0cdb7433f376f0842a2dda1143fc61c2da241b5903d6239a44fc978fec - sourceBlobDigest: sha256:c715e59591e54f9e2beca3ed567d1a12edc3f20580cac065511ce19c4423e3aa + sourceRevisionDigest: sha256:83887503bf502c2b1e816b079beba5218998adb827d73f2ac6de809e14f4389b + sourceBlobDigest: sha256:0181726a4ca9a31eae12e6bdd2d42c0aeca0e25a76d8e9c82b57a829b69dff68 outLocation: . workflow: workflowVersion: 1.0.0 diff --git a/README.md b/README.md index 4a297bb1..495a2284 100644 --- a/README.md +++ b/README.md @@ -13,12 +13,12 @@ The Clerk Python library provides convenient access to the Clerk REST API from a PIP ```bash -pip install clerk +pip install clerk-backend-api ``` Poetry ```bash -poetry add clerk +poetry add clerk-backend-api ``` @@ -29,7 +29,7 @@ poetry add clerk ```python # Synchronous Example -from clerk import Clerk +from clerk_backend_api import Clerk import os s = Clerk( @@ -50,7 +50,7 @@ The same SDK client can also be used to make asychronous requests by importing a ```python # Asynchronous Example import asyncio -from clerk import Clerk +from clerk_backend_api import Clerk import os async def main(): @@ -270,7 +270,7 @@ 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 +from clerk_backend_api import Clerk import os s = Clerk( @@ -303,7 +303,7 @@ Certain SDK methods accept file objects as part of a request body or multi-part > ```python -from clerk import Clerk +from clerk_backend_api import Clerk import os s = Clerk( @@ -331,8 +331,8 @@ Some of the endpoints in this SDK support retries. If you use the SDK without an 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 +from clerk_backend_api import Clerk s = Clerk() @@ -346,8 +346,8 @@ s.misc.get_public_interstitial(frontend_api="frontend-api_1a2b3c4d", publishable 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 +from clerk_backend_api import Clerk s = Clerk( retry_config=RetryConfig("backoff", BackoffStrategy(1, 50, 1.1, 100), False), @@ -374,7 +374,7 @@ Handling errors in this SDK should largely match your expectations. All operati ### Example ```python -from clerk import Clerk, models +from clerk_backend_api import Clerk, models import os s = Clerk( @@ -418,7 +418,7 @@ You can override the default server globally by passing a server index to the `s #### Example ```python -from clerk import Clerk +from clerk_backend_api import Clerk s = Clerk( server_idx=0, @@ -436,7 +436,7 @@ s.misc.get_public_interstitial(frontend_api="frontend-api_1a2b3c4d", publishable 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 +from clerk_backend_api import Clerk s = Clerk( server_url="https://api.clerk.com/v1", @@ -459,7 +459,7 @@ This allows you to wrap the client with your own custom logic, such as adding cu For example, you could specify a header for every request that this sdk makes as follows: ```python -from clerk import Clerk +from clerk_backend_api import Clerk import httpx http_client = httpx.Client(headers={"x-custom-header": "someValue"}) @@ -468,8 +468,8 @@ 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 +from clerk_backend_api import Clerk +from clerk_backend_api.httpclient import AsyncHttpClient import httpx class CustomClient(AsyncHttpClient): @@ -544,7 +544,7 @@ This SDK supports the following security scheme globally: 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 +from clerk_backend_api import Clerk import os s = Clerk( diff --git a/RELEASES.md b/RELEASES.md index 48f7a743..e2919c42 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -8,4 +8,14 @@ Based on: ### Generated - [python v0.5.0-alpha.6] . ### Releases -- [PyPI v0.5.0-alpha.6] https://pypi.org/project/clerk/0.5.0-alpha.6 - . \ No newline at end of file +- [PyPI v0.5.0-alpha.6] https://pypi.org/project/clerk/0.5.0-alpha.6 - . + +## 2024-07-11 21:13:04 +### Changes +Based on: +- OpenAPI Doc +- Speakeasy CLI 1.331.2 (2.366.1) https://github.com/speakeasy-api/speakeasy +### Generated +- [python v0.5.0-alpha.7] . +### Releases +- [PyPI v0.5.0-alpha.7] https://pypi.org/project/clerk-backend-api/0.5.0-alpha.7 - . \ No newline at end of file diff --git a/USAGE.md b/USAGE.md index 3becc193..f29ae7be 100644 --- a/USAGE.md +++ b/USAGE.md @@ -1,7 +1,7 @@ ```python # Synchronous Example -from clerk import Clerk +from clerk_backend_api import Clerk import os s = Clerk( @@ -22,7 +22,7 @@ The same SDK client can also be used to make asychronous requests by importing a ```python # Asynchronous Example import asyncio -from clerk import Clerk +from clerk_backend_api import Clerk import os async def main(): diff --git a/docs/sdks/actortokens/README.md b/docs/sdks/actortokens/README.md index a8b31502..549d9c9c 100644 --- a/docs/sdks/actortokens/README.md +++ b/docs/sdks/actortokens/README.md @@ -14,7 +14,7 @@ The `actor` parameter needs to include at least a "sub" key whose value is the I ### Example Usage ```python -from clerk import Clerk +from clerk_backend_api import Clerk import os s = Clerk( @@ -60,7 +60,7 @@ Revokes a pending actor token. ### Example Usage ```python -from clerk import Clerk +from clerk_backend_api import Clerk import os s = Clerk( diff --git a/docs/sdks/allowlistidentifiers/README.md b/docs/sdks/allowlistidentifiers/README.md index 7cdb914b..c86019d9 100644 --- a/docs/sdks/allowlistidentifiers/README.md +++ b/docs/sdks/allowlistidentifiers/README.md @@ -14,7 +14,7 @@ Get a list of all identifiers allowed to sign up to an instance ### Example Usage ```python -from clerk import Clerk +from clerk_backend_api import Clerk import os s = Clerk( @@ -54,7 +54,7 @@ Create an identifier allowed to sign up to an instance ### Example Usage ```python -from clerk import Clerk +from clerk_backend_api import Clerk import os s = Clerk( @@ -96,7 +96,7 @@ Delete an identifier from the instance allow-list ### Example Usage ```python -from clerk import Clerk +from clerk_backend_api import Clerk import os s = Clerk( diff --git a/docs/sdks/betafeatures/README.md b/docs/sdks/betafeatures/README.md index a7b5ba58..5988cfaf 100644 --- a/docs/sdks/betafeatures/README.md +++ b/docs/sdks/betafeatures/README.md @@ -14,7 +14,7 @@ Updates the settings of an instance ### Example Usage ```python -from clerk import Clerk +from clerk_backend_api import Clerk import os s = Clerk( @@ -66,7 +66,7 @@ WARNING: Changing your domain will invalidate all current user sessions (i.e. us ### Example Usage ```python -from clerk import Clerk +from clerk_backend_api import Clerk import os s = Clerk( @@ -105,7 +105,7 @@ WARNING: Changing your domain will invalidate all current user sessions (i.e. us ### Example Usage ```python -from clerk import Clerk +from clerk_backend_api import Clerk import os s = Clerk( diff --git a/docs/sdks/blocklistidentifierssdk/README.md b/docs/sdks/blocklistidentifierssdk/README.md index 71ab7386..96667fa7 100644 --- a/docs/sdks/blocklistidentifierssdk/README.md +++ b/docs/sdks/blocklistidentifierssdk/README.md @@ -14,7 +14,7 @@ Get a list of all identifiers which are not allowed to access an instance ### Example Usage ```python -from clerk import Clerk +from clerk_backend_api import Clerk import os s = Clerk( @@ -54,7 +54,7 @@ Create an identifier that is blocked from accessing an instance ### Example Usage ```python -from clerk import Clerk +from clerk_backend_api import Clerk import os s = Clerk( @@ -95,7 +95,7 @@ Delete an identifier from the instance block-list ### Example Usage ```python -from clerk import Clerk +from clerk_backend_api import Clerk import os s = Clerk( diff --git a/docs/sdks/clients/README.md b/docs/sdks/clients/README.md index 7082ec4f..3f6fa578 100644 --- a/docs/sdks/clients/README.md +++ b/docs/sdks/clients/README.md @@ -18,7 +18,7 @@ Warning: the endpoint is being deprecated and will be removed in future versions ### Example Usage ```python -from clerk import Clerk +from clerk_backend_api import Clerk import os s = Clerk( @@ -65,7 +65,7 @@ Verifies the client in the provided token ### Example Usage ```python -from clerk import Clerk +from clerk_backend_api import Clerk import os s = Clerk( @@ -106,7 +106,7 @@ Returns the details of a client. ### Example Usage ```python -from clerk import Clerk +from clerk_backend_api import Clerk import os s = Clerk( diff --git a/docs/sdks/domainssdk/README.md b/docs/sdks/domainssdk/README.md index 052dd2d4..bd734720 100644 --- a/docs/sdks/domainssdk/README.md +++ b/docs/sdks/domainssdk/README.md @@ -16,7 +16,7 @@ The response will contain the primary domain for the instance and any satellite ### Example Usage ```python -from clerk import Clerk +from clerk_backend_api import Clerk import os s = Clerk( @@ -59,7 +59,7 @@ If you're planning to configure the new satellite domain to run behind a proxy, ### Example Usage ```python -from clerk import Clerk +from clerk_backend_api import Clerk import os s = Clerk( @@ -103,7 +103,7 @@ It is currently not possible to delete the instance's primary domain. ### Example Usage ```python -from clerk import Clerk +from clerk_backend_api import Clerk import os s = Clerk( @@ -151,7 +151,7 @@ update the instance's home origin, affecting the default application paths. ### Example Usage ```python -from clerk import Clerk +from clerk_backend_api import Clerk import os s = Clerk( diff --git a/docs/sdks/emailaddresses/README.md b/docs/sdks/emailaddresses/README.md index 41e9e525..2d5bfaae 100644 --- a/docs/sdks/emailaddresses/README.md +++ b/docs/sdks/emailaddresses/README.md @@ -15,7 +15,7 @@ Create a new email address ### Example Usage ```python -from clerk import Clerk +from clerk_backend_api import Clerk import os s = Clerk( @@ -59,7 +59,7 @@ Returns the details of an email address. ### Example Usage ```python -from clerk import Clerk +from clerk_backend_api import Clerk import os s = Clerk( @@ -100,7 +100,7 @@ Delete the email address with the given ID ### Example Usage ```python -from clerk import Clerk +from clerk_backend_api import Clerk import os s = Clerk( @@ -141,7 +141,7 @@ Updates an email address. ### Example Usage ```python -from clerk import Clerk +from clerk_backend_api import Clerk import os s = Clerk( diff --git a/docs/sdks/instancesettingssdk/README.md b/docs/sdks/instancesettingssdk/README.md index 8f5debfb..b114c373 100644 --- a/docs/sdks/instancesettingssdk/README.md +++ b/docs/sdks/instancesettingssdk/README.md @@ -14,7 +14,7 @@ Updates the settings of an instance ### Example Usage ```python -from clerk import Clerk +from clerk_backend_api import Clerk import os s = Clerk( @@ -61,7 +61,7 @@ Updates the restriction settings of an instance ### Example Usage ```python -from clerk import Clerk +from clerk_backend_api import Clerk import os s = Clerk( @@ -106,7 +106,7 @@ Updates the organization settings of the instance ### Example Usage ```python -from clerk import Clerk +from clerk_backend_api import Clerk import os s = Clerk( diff --git a/docs/sdks/invitations/README.md b/docs/sdks/invitations/README.md index a796b6fe..8fb2e64e 100644 --- a/docs/sdks/invitations/README.md +++ b/docs/sdks/invitations/README.md @@ -16,7 +16,7 @@ Also, trying to create an invitation for an email address that already exists in ### Example Usage ```python -from clerk import Clerk +from clerk_backend_api import Clerk import os s = Clerk( @@ -61,8 +61,8 @@ Returns all non-revoked invitations for your application, sorted by creation dat ### Example Usage ```python -import clerk -from clerk import Clerk +import clerk_backend_api +from clerk_backend_api import Clerk import os s = Clerk( @@ -70,7 +70,7 @@ s = Clerk( ) -res = s.invitations.list(limit=20, offset=10, status=clerk.ListInvitationsQueryParamStatus.PENDING) +res = s.invitations.list(limit=20, offset=10, status=clerk_backend_api.ListInvitationsQueryParamStatus.PENDING) if res is not None: while True: @@ -112,7 +112,7 @@ Only active (i.e. non-revoked) invitations can be revoked. ### Example Usage ```python -from clerk import Clerk +from clerk_backend_api import Clerk import os s = Clerk( diff --git a/docs/sdks/jwks/README.md b/docs/sdks/jwks/README.md index 9dd18d69..66603d3c 100644 --- a/docs/sdks/jwks/README.md +++ b/docs/sdks/jwks/README.md @@ -12,7 +12,7 @@ Retrieve the JSON Web Key Set of the instance ### Example Usage ```python -from clerk import Clerk +from clerk_backend_api import Clerk import os s = Clerk( diff --git a/docs/sdks/jwttemplates/README.md b/docs/sdks/jwttemplates/README.md index 0cf45c7b..7572cac5 100644 --- a/docs/sdks/jwttemplates/README.md +++ b/docs/sdks/jwttemplates/README.md @@ -16,7 +16,7 @@ List all templates ### Example Usage ```python -from clerk import Clerk +from clerk_backend_api import Clerk import os s = Clerk( @@ -55,7 +55,7 @@ Create a new JWT template ### Example Usage ```python -from clerk import Clerk +from clerk_backend_api import Clerk import os s = Clerk( @@ -102,7 +102,7 @@ Retrieve the details of a given JWT template ### Example Usage ```python -from clerk import Clerk +from clerk_backend_api import Clerk import os s = Clerk( @@ -143,7 +143,7 @@ Updates an existing JWT template ### Example Usage ```python -from clerk import Clerk +from clerk_backend_api import Clerk import os s = Clerk( @@ -191,7 +191,7 @@ Delete a Template ### Example Usage ```python -from clerk import Clerk +from clerk_backend_api import Clerk import os s = Clerk( diff --git a/docs/sdks/misc/README.md b/docs/sdks/misc/README.md index 5e3e972a..ba72cd5f 100644 --- a/docs/sdks/misc/README.md +++ b/docs/sdks/misc/README.md @@ -13,7 +13,7 @@ It is used by Clerk SDKs when the user's authentication state cannot be immediat ### Example Usage ```python -from clerk import Clerk +from clerk_backend_api import Clerk s = Clerk() diff --git a/docs/sdks/oauthapplicationssdk/README.md b/docs/sdks/oauthapplicationssdk/README.md index b47a67bf..398f5def 100644 --- a/docs/sdks/oauthapplicationssdk/README.md +++ b/docs/sdks/oauthapplicationssdk/README.md @@ -20,7 +20,7 @@ Most recent OAuth applications will be returned first. ### Example Usage ```python -from clerk import Clerk +from clerk_backend_api import Clerk import os s = Clerk( @@ -69,7 +69,7 @@ All URL schemes are allowed such as `http://`, `https://`, `myapp://`, etc... ### Example Usage ```python -from clerk import Clerk +from clerk_backend_api import Clerk import os s = Clerk( @@ -113,7 +113,7 @@ Fetches the OAuth application whose ID matches the provided `id` in the path. ### Example Usage ```python -from clerk import Clerk +from clerk_backend_api import Clerk import os s = Clerk( @@ -154,7 +154,7 @@ Updates an existing OAuth application ### Example Usage ```python -from clerk import Clerk +from clerk_backend_api import Clerk import os s = Clerk( @@ -199,7 +199,7 @@ This is not reversible. ### Example Usage ```python -from clerk import Clerk +from clerk_backend_api import Clerk import os s = Clerk( @@ -241,7 +241,7 @@ When the client secret is rotated, make sure to update it in authorized OAuth cl ### Example Usage ```python -from clerk import Clerk +from clerk_backend_api import Clerk import os s = Clerk( diff --git a/docs/sdks/organizationinvitationssdk/README.md b/docs/sdks/organizationinvitationssdk/README.md index 965a6ee3..6af12338 100644 --- a/docs/sdks/organizationinvitationssdk/README.md +++ b/docs/sdks/organizationinvitationssdk/README.md @@ -32,7 +32,7 @@ When the organization invitation is accepted, the metadata will be transferred t ### Example Usage ```python -from clerk import Clerk +from clerk_backend_api import Clerk import os s = Clerk( @@ -84,8 +84,8 @@ Any invitations created as a result of an Organization Domain are not included i ### Example Usage ```python -import clerk -from clerk import Clerk +import clerk_backend_api +from clerk_backend_api import Clerk import os s = Clerk( @@ -93,7 +93,7 @@ s = Clerk( ) -res = s.organization_invitations.list(organization_id="org_12345", limit=20, offset=10, status=clerk.ListOrganizationInvitationsQueryParamStatus.PENDING) +res = s.organization_invitations.list(organization_id="org_12345", limit=20, offset=10, status=clerk_backend_api.ListOrganizationInvitationsQueryParamStatus.PENDING) if res is not None: while True: @@ -146,7 +146,7 @@ When the organization invitation is accepted, the metadata will be transferred t ### Example Usage ```python -from clerk import Clerk +from clerk_backend_api import Clerk import os s = Clerk( @@ -204,7 +204,7 @@ Any invitations created as a result of an Organization Domain are not included i ### Example Usage ```python -from clerk import Clerk +from clerk_backend_api import Clerk import os s = Clerk( @@ -252,7 +252,7 @@ Use this request to get an existing organization invitation by ID. ### Example Usage ```python -from clerk import Clerk +from clerk_backend_api import Clerk import os s = Clerk( @@ -298,7 +298,7 @@ Only users with "admin" role can revoke invitations. ### Example Usage ```python -from clerk import Clerk +from clerk_backend_api import Clerk import os s = Clerk( diff --git a/docs/sdks/organizationmembershipssdk/README.md b/docs/sdks/organizationmembershipssdk/README.md index c6e78771..a2789799 100644 --- a/docs/sdks/organizationmembershipssdk/README.md +++ b/docs/sdks/organizationmembershipssdk/README.md @@ -16,7 +16,7 @@ Adds a user as a member to the given organization. ### Example Usage ```python -from clerk import Clerk +from clerk_backend_api import Clerk import os s = Clerk( @@ -59,7 +59,7 @@ Retrieves all user memberships for the given organization ### Example Usage ```python -from clerk import Clerk +from clerk_backend_api import Clerk import os s = Clerk( @@ -108,7 +108,7 @@ Updates the properties of an existing organization membership ### Example Usage ```python -from clerk import Clerk +from clerk_backend_api import Clerk import os s = Clerk( @@ -151,7 +151,7 @@ Removes the given membership from the organization ### Example Usage ```python -from clerk import Clerk +from clerk_backend_api import Clerk import os s = Clerk( @@ -195,7 +195,7 @@ You can remove metadata keys at any level by setting their value to `null`. ### Example Usage ```python -from clerk import Clerk +from clerk_backend_api import Clerk import os s = Clerk( diff --git a/docs/sdks/organizationssdk/README.md b/docs/sdks/organizationssdk/README.md index 5ab8a245..8a4a3425 100644 --- a/docs/sdks/organizationssdk/README.md +++ b/docs/sdks/organizationssdk/README.md @@ -22,7 +22,7 @@ Most recent organizations will be returned first. ### Example Usage ```python -from clerk import Clerk +from clerk_backend_api import Clerk import os s = Clerk( @@ -75,7 +75,7 @@ Public metadata can be accessed from the Backend API, and are read-only from the ### Example Usage ```python -from clerk import Clerk +from clerk_backend_api import Clerk import os s = Clerk( @@ -121,7 +121,7 @@ Fetches the organization whose ID or slug matches the provided `id_or_slug` URL ### Example Usage ```python -from clerk import Clerk +from clerk_backend_api import Clerk import os s = Clerk( @@ -162,7 +162,7 @@ Updates an existing organization ### Example Usage ```python -from clerk import Clerk +from clerk_backend_api import Clerk import os s = Clerk( @@ -211,7 +211,7 @@ This is not reversible. ### Example Usage ```python -from clerk import Clerk +from clerk_backend_api import Clerk import os s = Clerk( @@ -255,7 +255,7 @@ You can remove metadata keys at any level by setting their value to `null`. ### Example Usage ```python -from clerk import Clerk +from clerk_backend_api import Clerk import os s = Clerk( @@ -301,7 +301,7 @@ Only the following file content types are supported: `image/jpeg`, `image/png`, ### Example Usage ```python -from clerk import Clerk +from clerk_backend_api import Clerk import os s = Clerk( @@ -348,7 +348,7 @@ Delete the organization's logo. ### Example Usage ```python -from clerk import Clerk +from clerk_backend_api import Clerk import os s = Clerk( diff --git a/docs/sdks/phonenumbers/README.md b/docs/sdks/phonenumbers/README.md index a0cc7a17..c50c1228 100644 --- a/docs/sdks/phonenumbers/README.md +++ b/docs/sdks/phonenumbers/README.md @@ -15,7 +15,7 @@ Create a new phone number ### Example Usage ```python -from clerk import Clerk +from clerk_backend_api import Clerk import os s = Clerk( @@ -60,7 +60,7 @@ Returns the details of a phone number ### Example Usage ```python -from clerk import Clerk +from clerk_backend_api import Clerk import os s = Clerk( @@ -101,7 +101,7 @@ Delete the phone number with the given ID ### Example Usage ```python -from clerk import Clerk +from clerk_backend_api import Clerk import os s = Clerk( @@ -142,7 +142,7 @@ Updates a phone number ### Example Usage ```python -from clerk import Clerk +from clerk_backend_api import Clerk import os s = Clerk( diff --git a/docs/sdks/proxychecks/README.md b/docs/sdks/proxychecks/README.md index 64841146..ac1ebc0b 100644 --- a/docs/sdks/proxychecks/README.md +++ b/docs/sdks/proxychecks/README.md @@ -19,7 +19,7 @@ a different proxy URL than the one provided. It can also be used to re-validate ### Example Usage ```python -from clerk import Clerk +from clerk_backend_api import Clerk import os s = Clerk( diff --git a/docs/sdks/redirecturls/README.md b/docs/sdks/redirecturls/README.md index bae9ee00..c4f80166 100644 --- a/docs/sdks/redirecturls/README.md +++ b/docs/sdks/redirecturls/README.md @@ -15,7 +15,7 @@ Lists all whitelisted redirect_urls for the instance ### Example Usage ```python -from clerk import Clerk +from clerk_backend_api import Clerk import os s = Clerk( @@ -54,7 +54,7 @@ Create a redirect URL ### Example Usage ```python -from clerk import Clerk +from clerk_backend_api import Clerk import os s = Clerk( @@ -95,7 +95,7 @@ Retrieve the details of the redirect URL with the given ID ### Example Usage ```python -from clerk import Clerk +from clerk_backend_api import Clerk import os s = Clerk( @@ -136,7 +136,7 @@ Remove the selected redirect URL from the whitelist of the instance ### Example Usage ```python -from clerk import Clerk +from clerk_backend_api import Clerk import os s = Clerk( diff --git a/docs/sdks/samlconnectionssdk/README.md b/docs/sdks/samlconnectionssdk/README.md index a00646c6..b0e0470c 100644 --- a/docs/sdks/samlconnectionssdk/README.md +++ b/docs/sdks/samlconnectionssdk/README.md @@ -18,7 +18,7 @@ The SAML Connections are ordered by descending creation date and the most recent ### Example Usage ```python -from clerk import Clerk +from clerk_backend_api import Clerk import os s = Clerk( @@ -65,8 +65,8 @@ Create a new SAML Connection. ### Example Usage ```python -import clerk -from clerk import Clerk +import clerk_backend_api +from clerk_backend_api import Clerk import os s = Clerk( @@ -74,7 +74,7 @@ s = Clerk( ) -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=" 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_backend_api/_hooks/types.py b/src/clerk_backend_api/_hooks/types.py new file mode 100644 index 00000000..4da654fd --- /dev/null +++ b/src/clerk_backend_api/_hooks/types.py @@ -0,0 +1,76 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + + +from abc import ABC, abstractmethod +from clerk_backend_api.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_backend_api/actortokens.py b/src/clerk_backend_api/actortokens.py new file mode 100644 index 00000000..5f2c19ee --- /dev/null +++ b/src/clerk_backend_api/actortokens.py @@ -0,0 +1,341 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from .basesdk import BaseSDK +from clerk_backend_api import models +from clerk_backend_api._hooks import HookContext +from clerk_backend_api.types import Nullable, UNSET +import clerk_backend_api.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_backend_api/allowlistidentifiers.py b/src/clerk_backend_api/allowlistidentifiers.py new file mode 100644 index 00000000..144b4a6b --- /dev/null +++ b/src/clerk_backend_api/allowlistidentifiers.py @@ -0,0 +1,467 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from .basesdk import BaseSDK +from clerk_backend_api import models +from clerk_backend_api._hooks import HookContext +from clerk_backend_api.types import Nullable, UNSET +import clerk_backend_api.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_backend_api/basesdk.py b/src/clerk_backend_api/basesdk.py new file mode 100644 index 00000000..765288ec --- /dev/null +++ b/src/clerk_backend_api/basesdk.py @@ -0,0 +1,213 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from .sdkconfiguration import SDKConfiguration +from clerk_backend_api import models +from clerk_backend_api._hooks import AfterErrorContext, AfterSuccessContext, BeforeRequestContext +import clerk_backend_api.utils as utils +from clerk_backend_api.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_backend_api/betafeatures.py b/src/clerk_backend_api/betafeatures.py new file mode 100644 index 00000000..74d69411 --- /dev/null +++ b/src/clerk_backend_api/betafeatures.py @@ -0,0 +1,528 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from .basesdk import BaseSDK +from clerk_backend_api import models +from clerk_backend_api._hooks import HookContext +from clerk_backend_api.types import Nullable, UNSET +import clerk_backend_api.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_backend_api/blocklistidentifiers_sdk.py b/src/clerk_backend_api/blocklistidentifiers_sdk.py new file mode 100644 index 00000000..fe0e9cc3 --- /dev/null +++ b/src/clerk_backend_api/blocklistidentifiers_sdk.py @@ -0,0 +1,461 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from .basesdk import BaseSDK +from clerk_backend_api import models +from clerk_backend_api._hooks import HookContext +from clerk_backend_api.types import Nullable, UNSET +import clerk_backend_api.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_backend_api/clients.py b/src/clerk_backend_api/clients.py new file mode 100644 index 00000000..4509d4c1 --- /dev/null +++ b/src/clerk_backend_api/clients.py @@ -0,0 +1,535 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from .basesdk import BaseSDK +from clerk_backend_api import models +from clerk_backend_api._hooks import HookContext +from clerk_backend_api.types import Nullable, UNSET +import clerk_backend_api.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_backend_api/domains_sdk.py b/src/clerk_backend_api/domains_sdk.py new file mode 100644 index 00000000..b254a395 --- /dev/null +++ b/src/clerk_backend_api/domains_sdk.py @@ -0,0 +1,665 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from .basesdk import BaseSDK +from clerk_backend_api import models +from clerk_backend_api._hooks import HookContext +from clerk_backend_api.types import Nullable, UNSET +import clerk_backend_api.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_backend_api/emailaddresses.py b/src/clerk_backend_api/emailaddresses.py new file mode 100644 index 00000000..b4d8b3b6 --- /dev/null +++ b/src/clerk_backend_api/emailaddresses.py @@ -0,0 +1,665 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from .basesdk import BaseSDK +from clerk_backend_api import models +from clerk_backend_api._hooks import HookContext +from clerk_backend_api.types import Nullable, UNSET +import clerk_backend_api.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_backend_api/httpclient.py b/src/clerk_backend_api/httpclient.py new file mode 100644 index 00000000..985e31cd --- /dev/null +++ b/src/clerk_backend_api/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_backend_api/instancesettings_sdk.py b/src/clerk_backend_api/instancesettings_sdk.py new file mode 100644 index 00000000..8d49aeff --- /dev/null +++ b/src/clerk_backend_api/instancesettings_sdk.py @@ -0,0 +1,587 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from .basesdk import BaseSDK +from clerk_backend_api import models +from clerk_backend_api._hooks import HookContext +from clerk_backend_api.types import Nullable, UNSET +import clerk_backend_api.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_backend_api/invitations.py b/src/clerk_backend_api/invitations.py new file mode 100644 index 00000000..225a4eb7 --- /dev/null +++ b/src/clerk_backend_api/invitations.py @@ -0,0 +1,564 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from .basesdk import BaseSDK +from clerk_backend_api import models +from clerk_backend_api._hooks import HookContext +from clerk_backend_api.types import BaseModel, Nullable, UNSET +import clerk_backend_api.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_backend_api/jwks.py b/src/clerk_backend_api/jwks.py new file mode 100644 index 00000000..959e4de6 --- /dev/null +++ b/src/clerk_backend_api/jwks.py @@ -0,0 +1,145 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from .basesdk import BaseSDK +from clerk_backend_api import models +from clerk_backend_api._hooks import HookContext +from clerk_backend_api.types import Nullable, UNSET +import clerk_backend_api.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_backend_api/jwttemplates.py b/src/clerk_backend_api/jwttemplates.py new file mode 100644 index 00000000..e8c087a4 --- /dev/null +++ b/src/clerk_backend_api/jwttemplates.py @@ -0,0 +1,839 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from .basesdk import BaseSDK +from clerk_backend_api import models +from clerk_backend_api._hooks import HookContext +from clerk_backend_api.types import BaseModel, Nullable, UNSET +import clerk_backend_api.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_backend_api/misc.py b/src/clerk_backend_api/misc.py new file mode 100644 index 00000000..aec0e1bd --- /dev/null +++ b/src/clerk_backend_api/misc.py @@ -0,0 +1,165 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from .basesdk import BaseSDK +from clerk_backend_api import models +from clerk_backend_api._hooks import HookContext +from clerk_backend_api.types import Nullable, UNSET +import clerk_backend_api.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_backend_api/models/__init__.py b/src/clerk_backend_api/models/__init__.py new file mode 100644 index 00000000..55dfc046 --- /dev/null +++ b/src/clerk_backend_api/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_backend_api/models/actortoken.py b/src/clerk_backend_api/models/actortoken.py new file mode 100644 index 00000000..10b9dc8c --- /dev/null +++ b/src/clerk_backend_api/models/actortoken.py @@ -0,0 +1,88 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.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_backend_api/models/adddomainop.py b/src/clerk_backend_api/models/adddomainop.py new file mode 100644 index 00000000..d4a1fe84 --- /dev/null +++ b/src/clerk_backend_api/models/adddomainop.py @@ -0,0 +1,25 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.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_backend_api/models/allowlistidentifier.py b/src/clerk_backend_api/models/allowlistidentifier.py new file mode 100644 index 00000000..573037a0 --- /dev/null +++ b/src/clerk_backend_api/models/allowlistidentifier.py @@ -0,0 +1,67 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.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_backend_api/models/banuserop.py b/src/clerk_backend_api/models/banuserop.py new file mode 100644 index 00000000..e94ac589 --- /dev/null +++ b/src/clerk_backend_api/models/banuserop.py @@ -0,0 +1,18 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.types import BaseModel +from clerk_backend_api.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_backend_api/models/blocklistidentifier.py b/src/clerk_backend_api/models/blocklistidentifier.py new file mode 100644 index 00000000..f5a618c8 --- /dev/null +++ b/src/clerk_backend_api/models/blocklistidentifier.py @@ -0,0 +1,65 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.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_backend_api/models/blocklistidentifiers.py b/src/clerk_backend_api/models/blocklistidentifiers.py new file mode 100644 index 00000000..04f5eb63 --- /dev/null +++ b/src/clerk_backend_api/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_backend_api.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_backend_api/models/changeproductioninstancedomainop.py b/src/clerk_backend_api/models/changeproductioninstancedomainop.py new file mode 100644 index 00000000..c9f63145 --- /dev/null +++ b/src/clerk_backend_api/models/changeproductioninstancedomainop.py @@ -0,0 +1,17 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.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_backend_api/models/clerkerror.py b/src/clerk_backend_api/models/clerkerror.py new file mode 100644 index 00000000..63c9ae74 --- /dev/null +++ b/src/clerk_backend_api/models/clerkerror.py @@ -0,0 +1,31 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.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_backend_api/models/clerkerrors.py b/src/clerk_backend_api/models/clerkerrors.py new file mode 100644 index 00000000..0edd970b --- /dev/null +++ b/src/clerk_backend_api/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_backend_api.types import BaseModel +import clerk_backend_api.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_backend_api/models/client.py b/src/clerk_backend_api/models/client.py new file mode 100644 index 00000000..0da1cb2e --- /dev/null +++ b/src/clerk_backend_api/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_backend_api.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_backend_api/models/cnametarget.py b/src/clerk_backend_api/models/cnametarget.py new file mode 100644 index 00000000..73df77a5 --- /dev/null +++ b/src/clerk_backend_api/models/cnametarget.py @@ -0,0 +1,24 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.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_backend_api/models/createactortokenop.py b/src/clerk_backend_api/models/createactortokenop.py new file mode 100644 index 00000000..df139a8c --- /dev/null +++ b/src/clerk_backend_api/models/createactortokenop.py @@ -0,0 +1,41 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.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_backend_api/models/createallowlistidentifierop.py b/src/clerk_backend_api/models/createallowlistidentifierop.py new file mode 100644 index 00000000..505d11a7 --- /dev/null +++ b/src/clerk_backend_api/models/createallowlistidentifierop.py @@ -0,0 +1,29 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.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_backend_api/models/createblocklistidentifierop.py b/src/clerk_backend_api/models/createblocklistidentifierop.py new file mode 100644 index 00000000..19faac56 --- /dev/null +++ b/src/clerk_backend_api/models/createblocklistidentifierop.py @@ -0,0 +1,20 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.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_backend_api/models/createemailaddressop.py b/src/clerk_backend_api/models/createemailaddressop.py new file mode 100644 index 00000000..ac233d2c --- /dev/null +++ b/src/clerk_backend_api/models/createemailaddressop.py @@ -0,0 +1,59 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.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_backend_api/models/createinvitationop.py b/src/clerk_backend_api/models/createinvitationop.py new file mode 100644 index 00000000..07ad4e79 --- /dev/null +++ b/src/clerk_backend_api/models/createinvitationop.py @@ -0,0 +1,93 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.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_backend_api/models/createjwttemplateop.py b/src/clerk_backend_api/models/createjwttemplateop.py new file mode 100644 index 00000000..60e4348e --- /dev/null +++ b/src/clerk_backend_api/models/createjwttemplateop.py @@ -0,0 +1,77 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.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_backend_api/models/createoauthapplicationop.py b/src/clerk_backend_api/models/createoauthapplicationop.py new file mode 100644 index 00000000..e8703fb1 --- /dev/null +++ b/src/clerk_backend_api/models/createoauthapplicationop.py @@ -0,0 +1,35 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.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_backend_api/models/createorganizationinvitationbulkop.py b/src/clerk_backend_api/models/createorganizationinvitationbulkop.py new file mode 100644 index 00000000..99f19d97 --- /dev/null +++ b/src/clerk_backend_api/models/createorganizationinvitationbulkop.py @@ -0,0 +1,74 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.types import BaseModel +from clerk_backend_api.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_backend_api/models/createorganizationinvitationop.py b/src/clerk_backend_api/models/createorganizationinvitationop.py new file mode 100644 index 00000000..24ea74ac --- /dev/null +++ b/src/clerk_backend_api/models/createorganizationinvitationop.py @@ -0,0 +1,74 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.types import BaseModel +from clerk_backend_api.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_backend_api/models/createorganizationmembershipop.py b/src/clerk_backend_api/models/createorganizationmembershipop.py new file mode 100644 index 00000000..f54e8b91 --- /dev/null +++ b/src/clerk_backend_api/models/createorganizationmembershipop.py @@ -0,0 +1,34 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.types import BaseModel +from clerk_backend_api.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_backend_api/models/createorganizationop.py b/src/clerk_backend_api/models/createorganizationop.py new file mode 100644 index 00000000..5ca5be5c --- /dev/null +++ b/src/clerk_backend_api/models/createorganizationop.py @@ -0,0 +1,63 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.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_backend_api/models/createphonenumberop.py b/src/clerk_backend_api/models/createphonenumberop.py new file mode 100644 index 00000000..41da5e98 --- /dev/null +++ b/src/clerk_backend_api/models/createphonenumberop.py @@ -0,0 +1,69 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.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_backend_api/models/createredirecturlop.py b/src/clerk_backend_api/models/createredirecturlop.py new file mode 100644 index 00000000..409910d0 --- /dev/null +++ b/src/clerk_backend_api/models/createredirecturlop.py @@ -0,0 +1,17 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.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_backend_api/models/createsamlconnectionop.py b/src/clerk_backend_api/models/createsamlconnectionop.py new file mode 100644 index 00000000..0bbb7325 --- /dev/null +++ b/src/clerk_backend_api/models/createsamlconnectionop.py @@ -0,0 +1,102 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.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_backend_api/models/createsessiontokenfromtemplateop.py b/src/clerk_backend_api/models/createsessiontokenfromtemplateop.py new file mode 100644 index 00000000..b35cf7bd --- /dev/null +++ b/src/clerk_backend_api/models/createsessiontokenfromtemplateop.py @@ -0,0 +1,41 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.types import BaseModel +from clerk_backend_api.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_backend_api/models/createsignintokenop.py b/src/clerk_backend_api/models/createsignintokenop.py new file mode 100644 index 00000000..e143d9c9 --- /dev/null +++ b/src/clerk_backend_api/models/createsignintokenop.py @@ -0,0 +1,25 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.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_backend_api/models/createuserop.py b/src/clerk_backend_api/models/createuserop.py new file mode 100644 index 00000000..5eee8577 --- /dev/null +++ b/src/clerk_backend_api/models/createuserop.py @@ -0,0 +1,599 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.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_backend_api/models/deleteallowlistidentifierop.py b/src/clerk_backend_api/models/deleteallowlistidentifierop.py new file mode 100644 index 00000000..3f2ea487 --- /dev/null +++ b/src/clerk_backend_api/models/deleteallowlistidentifierop.py @@ -0,0 +1,18 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.types import BaseModel +from clerk_backend_api.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_backend_api/models/deleteblocklistidentifierop.py b/src/clerk_backend_api/models/deleteblocklistidentifierop.py new file mode 100644 index 00000000..005b0f0b --- /dev/null +++ b/src/clerk_backend_api/models/deleteblocklistidentifierop.py @@ -0,0 +1,18 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.types import BaseModel +from clerk_backend_api.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_backend_api/models/deletedobject.py b/src/clerk_backend_api/models/deletedobject.py new file mode 100644 index 00000000..0270eb2e --- /dev/null +++ b/src/clerk_backend_api/models/deletedobject.py @@ -0,0 +1,21 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.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_backend_api/models/deletedomainop.py b/src/clerk_backend_api/models/deletedomainop.py new file mode 100644 index 00000000..21792ab0 --- /dev/null +++ b/src/clerk_backend_api/models/deletedomainop.py @@ -0,0 +1,18 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.types import BaseModel +from clerk_backend_api.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_backend_api/models/deleteemailaddressop.py b/src/clerk_backend_api/models/deleteemailaddressop.py new file mode 100644 index 00000000..2763cf65 --- /dev/null +++ b/src/clerk_backend_api/models/deleteemailaddressop.py @@ -0,0 +1,18 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.types import BaseModel +from clerk_backend_api.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_backend_api/models/deletejwttemplateop.py b/src/clerk_backend_api/models/deletejwttemplateop.py new file mode 100644 index 00000000..568e5230 --- /dev/null +++ b/src/clerk_backend_api/models/deletejwttemplateop.py @@ -0,0 +1,18 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.types import BaseModel +from clerk_backend_api.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_backend_api/models/deleteoauthapplicationop.py b/src/clerk_backend_api/models/deleteoauthapplicationop.py new file mode 100644 index 00000000..711b4ca0 --- /dev/null +++ b/src/clerk_backend_api/models/deleteoauthapplicationop.py @@ -0,0 +1,18 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.types import BaseModel +from clerk_backend_api.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_backend_api/models/deleteorganizationlogoop.py b/src/clerk_backend_api/models/deleteorganizationlogoop.py new file mode 100644 index 00000000..62919c6a --- /dev/null +++ b/src/clerk_backend_api/models/deleteorganizationlogoop.py @@ -0,0 +1,18 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.types import BaseModel +from clerk_backend_api.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_backend_api/models/deleteorganizationmembershipop.py b/src/clerk_backend_api/models/deleteorganizationmembershipop.py new file mode 100644 index 00000000..855ec84a --- /dev/null +++ b/src/clerk_backend_api/models/deleteorganizationmembershipop.py @@ -0,0 +1,22 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.types import BaseModel +from clerk_backend_api.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_backend_api/models/deleteorganizationop.py b/src/clerk_backend_api/models/deleteorganizationop.py new file mode 100644 index 00000000..2fd59ff2 --- /dev/null +++ b/src/clerk_backend_api/models/deleteorganizationop.py @@ -0,0 +1,18 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.types import BaseModel +from clerk_backend_api.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_backend_api/models/deletephonenumberop.py b/src/clerk_backend_api/models/deletephonenumberop.py new file mode 100644 index 00000000..bb26133f --- /dev/null +++ b/src/clerk_backend_api/models/deletephonenumberop.py @@ -0,0 +1,18 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.types import BaseModel +from clerk_backend_api.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_backend_api/models/deleteredirecturlop.py b/src/clerk_backend_api/models/deleteredirecturlop.py new file mode 100644 index 00000000..98afb131 --- /dev/null +++ b/src/clerk_backend_api/models/deleteredirecturlop.py @@ -0,0 +1,18 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.types import BaseModel +from clerk_backend_api.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_backend_api/models/deletesamlconnectionop.py b/src/clerk_backend_api/models/deletesamlconnectionop.py new file mode 100644 index 00000000..516eeccc --- /dev/null +++ b/src/clerk_backend_api/models/deletesamlconnectionop.py @@ -0,0 +1,18 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.types import BaseModel +from clerk_backend_api.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_backend_api/models/deleteuserop.py b/src/clerk_backend_api/models/deleteuserop.py new file mode 100644 index 00000000..a1a19bb7 --- /dev/null +++ b/src/clerk_backend_api/models/deleteuserop.py @@ -0,0 +1,18 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.types import BaseModel +from clerk_backend_api.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_backend_api/models/deleteuserprofileimageop.py b/src/clerk_backend_api/models/deleteuserprofileimageop.py new file mode 100644 index 00000000..055ac7ee --- /dev/null +++ b/src/clerk_backend_api/models/deleteuserprofileimageop.py @@ -0,0 +1,18 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.types import BaseModel +from clerk_backend_api.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_backend_api/models/disablemfaop.py b/src/clerk_backend_api/models/disablemfaop.py new file mode 100644 index 00000000..4ff1f824 --- /dev/null +++ b/src/clerk_backend_api/models/disablemfaop.py @@ -0,0 +1,30 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.types import BaseModel +from clerk_backend_api.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_backend_api/models/domain.py b/src/clerk_backend_api/models/domain.py new file mode 100644 index 00000000..9f9a36c5 --- /dev/null +++ b/src/clerk_backend_api/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_backend_api.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_backend_api/models/domains.py b/src/clerk_backend_api/models/domains.py new file mode 100644 index 00000000..cda995f6 --- /dev/null +++ b/src/clerk_backend_api/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_backend_api.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_backend_api/models/emailaddress.py b/src/clerk_backend_api/models/emailaddress.py new file mode 100644 index 00000000..bac4ae99 --- /dev/null +++ b/src/clerk_backend_api/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_backend_api.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_backend_api/models/getclientlistop.py b/src/clerk_backend_api/models/getclientlistop.py new file mode 100644 index 00000000..7be68451 --- /dev/null +++ b/src/clerk_backend_api/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_backend_api.types import BaseModel +from clerk_backend_api.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_backend_api/models/getclientop.py b/src/clerk_backend_api/models/getclientop.py new file mode 100644 index 00000000..fb4e2249 --- /dev/null +++ b/src/clerk_backend_api/models/getclientop.py @@ -0,0 +1,18 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.types import BaseModel +from clerk_backend_api.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_backend_api/models/getemailaddressop.py b/src/clerk_backend_api/models/getemailaddressop.py new file mode 100644 index 00000000..fb34ce46 --- /dev/null +++ b/src/clerk_backend_api/models/getemailaddressop.py @@ -0,0 +1,18 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.types import BaseModel +from clerk_backend_api.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_backend_api/models/getjwttemplateop.py b/src/clerk_backend_api/models/getjwttemplateop.py new file mode 100644 index 00000000..8b4692e9 --- /dev/null +++ b/src/clerk_backend_api/models/getjwttemplateop.py @@ -0,0 +1,18 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.types import BaseModel +from clerk_backend_api.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_backend_api/models/getoauthaccesstokenop.py b/src/clerk_backend_api/models/getoauthaccesstokenop.py new file mode 100644 index 00000000..0b1f4ae1 --- /dev/null +++ b/src/clerk_backend_api/models/getoauthaccesstokenop.py @@ -0,0 +1,96 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.types import BaseModel, Nullable +from clerk_backend_api.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_backend_api/models/getoauthapplicationop.py b/src/clerk_backend_api/models/getoauthapplicationop.py new file mode 100644 index 00000000..238d0723 --- /dev/null +++ b/src/clerk_backend_api/models/getoauthapplicationop.py @@ -0,0 +1,18 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.types import BaseModel +from clerk_backend_api.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_backend_api/models/getorganizationinvitationop.py b/src/clerk_backend_api/models/getorganizationinvitationop.py new file mode 100644 index 00000000..cf7d9dad --- /dev/null +++ b/src/clerk_backend_api/models/getorganizationinvitationop.py @@ -0,0 +1,22 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.types import BaseModel +from clerk_backend_api.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_backend_api/models/getorganizationop.py b/src/clerk_backend_api/models/getorganizationop.py new file mode 100644 index 00000000..ff04c067 --- /dev/null +++ b/src/clerk_backend_api/models/getorganizationop.py @@ -0,0 +1,18 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.types import BaseModel +from clerk_backend_api.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_backend_api/models/getphonenumberop.py b/src/clerk_backend_api/models/getphonenumberop.py new file mode 100644 index 00000000..3f213ed5 --- /dev/null +++ b/src/clerk_backend_api/models/getphonenumberop.py @@ -0,0 +1,18 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.types import BaseModel +from clerk_backend_api.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_backend_api/models/getpublicinterstitialop.py b/src/clerk_backend_api/models/getpublicinterstitialop.py new file mode 100644 index 00000000..9e02b305 --- /dev/null +++ b/src/clerk_backend_api/models/getpublicinterstitialop.py @@ -0,0 +1,23 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.types import BaseModel +from clerk_backend_api.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_backend_api/models/getredirecturlop.py b/src/clerk_backend_api/models/getredirecturlop.py new file mode 100644 index 00000000..e6773b02 --- /dev/null +++ b/src/clerk_backend_api/models/getredirecturlop.py @@ -0,0 +1,18 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.types import BaseModel +from clerk_backend_api.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_backend_api/models/getsamlconnectionop.py b/src/clerk_backend_api/models/getsamlconnectionop.py new file mode 100644 index 00000000..015f75c1 --- /dev/null +++ b/src/clerk_backend_api/models/getsamlconnectionop.py @@ -0,0 +1,18 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.types import BaseModel +from clerk_backend_api.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_backend_api/models/getsessionlistop.py b/src/clerk_backend_api/models/getsessionlistop.py new file mode 100644 index 00000000..4067e9df --- /dev/null +++ b/src/clerk_backend_api/models/getsessionlistop.py @@ -0,0 +1,56 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.types import BaseModel +from clerk_backend_api.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_backend_api/models/getsessionop.py b/src/clerk_backend_api/models/getsessionop.py new file mode 100644 index 00000000..53f0fd2a --- /dev/null +++ b/src/clerk_backend_api/models/getsessionop.py @@ -0,0 +1,18 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.types import BaseModel +from clerk_backend_api.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_backend_api/models/gettemplatelistop.py b/src/clerk_backend_api/models/gettemplatelistop.py new file mode 100644 index 00000000..2542dae2 --- /dev/null +++ b/src/clerk_backend_api/models/gettemplatelistop.py @@ -0,0 +1,25 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.types import BaseModel +from clerk_backend_api.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_backend_api/models/gettemplateop.py b/src/clerk_backend_api/models/gettemplateop.py new file mode 100644 index 00000000..880e6c9b --- /dev/null +++ b/src/clerk_backend_api/models/gettemplateop.py @@ -0,0 +1,29 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.types import BaseModel +from clerk_backend_api.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_backend_api/models/getuserlistop.py b/src/clerk_backend_api/models/getuserlistop.py new file mode 100644 index 00000000..f40520e0 --- /dev/null +++ b/src/clerk_backend_api/models/getuserlistop.py @@ -0,0 +1,162 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.types import BaseModel +from clerk_backend_api.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_backend_api/models/getuserop.py b/src/clerk_backend_api/models/getuserop.py new file mode 100644 index 00000000..43451a50 --- /dev/null +++ b/src/clerk_backend_api/models/getuserop.py @@ -0,0 +1,18 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.types import BaseModel +from clerk_backend_api.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_backend_api/models/getuserscountop.py b/src/clerk_backend_api/models/getuserscountop.py new file mode 100644 index 00000000..1f5e881c --- /dev/null +++ b/src/clerk_backend_api/models/getuserscountop.py @@ -0,0 +1,84 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.types import BaseModel +from clerk_backend_api.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_backend_api/models/identificationlink.py b/src/clerk_backend_api/models/identificationlink.py new file mode 100644 index 00000000..138c252d --- /dev/null +++ b/src/clerk_backend_api/models/identificationlink.py @@ -0,0 +1,24 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.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_backend_api/models/instancerestrictions.py b/src/clerk_backend_api/models/instancerestrictions.py new file mode 100644 index 00000000..d0396771 --- /dev/null +++ b/src/clerk_backend_api/models/instancerestrictions.py @@ -0,0 +1,31 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.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_backend_api/models/instancesettings.py b/src/clerk_backend_api/models/instancesettings.py new file mode 100644 index 00000000..0df4fb2d --- /dev/null +++ b/src/clerk_backend_api/models/instancesettings.py @@ -0,0 +1,33 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.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_backend_api/models/invitation.py b/src/clerk_backend_api/models/invitation.py new file mode 100644 index 00000000..7056be19 --- /dev/null +++ b/src/clerk_backend_api/models/invitation.py @@ -0,0 +1,88 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.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_backend_api/models/invitation_revoked.py b/src/clerk_backend_api/models/invitation_revoked.py new file mode 100644 index 00000000..e3506ab9 --- /dev/null +++ b/src/clerk_backend_api/models/invitation_revoked.py @@ -0,0 +1,86 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.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_backend_api/models/jwttemplate.py b/src/clerk_backend_api/models/jwttemplate.py new file mode 100644 index 00000000..fbd53163 --- /dev/null +++ b/src/clerk_backend_api/models/jwttemplate.py @@ -0,0 +1,58 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.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_backend_api/models/listinvitationsop.py b/src/clerk_backend_api/models/listinvitationsop.py new file mode 100644 index 00000000..6903aa0f --- /dev/null +++ b/src/clerk_backend_api/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_backend_api.types import BaseModel +from clerk_backend_api.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_backend_api/models/listoauthapplicationsop.py b/src/clerk_backend_api/models/listoauthapplicationsop.py new file mode 100644 index 00000000..af8812ad --- /dev/null +++ b/src/clerk_backend_api/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_backend_api.types import BaseModel +from clerk_backend_api.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_backend_api/models/listorganizationinvitationsop.py b/src/clerk_backend_api/models/listorganizationinvitationsop.py new file mode 100644 index 00000000..22355e49 --- /dev/null +++ b/src/clerk_backend_api/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_backend_api.types import BaseModel +from clerk_backend_api.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_backend_api/models/listorganizationmembershipsop.py b/src/clerk_backend_api/models/listorganizationmembershipsop.py new file mode 100644 index 00000000..2e761c41 --- /dev/null +++ b/src/clerk_backend_api/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_backend_api.types import BaseModel +from clerk_backend_api.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_backend_api/models/listorganizationsop.py b/src/clerk_backend_api/models/listorganizationsop.py new file mode 100644 index 00000000..f87b81ec --- /dev/null +++ b/src/clerk_backend_api/models/listorganizationsop.py @@ -0,0 +1,60 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.types import BaseModel +from clerk_backend_api.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_backend_api/models/listpendingorganizationinvitationsop.py b/src/clerk_backend_api/models/listpendingorganizationinvitationsop.py new file mode 100644 index 00000000..3835fd8a --- /dev/null +++ b/src/clerk_backend_api/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_backend_api.types import BaseModel +from clerk_backend_api.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_backend_api/models/listsamlconnectionsop.py b/src/clerk_backend_api/models/listsamlconnectionsop.py new file mode 100644 index 00000000..aaf2ae5b --- /dev/null +++ b/src/clerk_backend_api/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_backend_api.types import BaseModel +from clerk_backend_api.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_backend_api/models/lockuserop.py b/src/clerk_backend_api/models/lockuserop.py new file mode 100644 index 00000000..c613e075 --- /dev/null +++ b/src/clerk_backend_api/models/lockuserop.py @@ -0,0 +1,18 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.types import BaseModel +from clerk_backend_api.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_backend_api/models/mergeorganizationmetadataop.py b/src/clerk_backend_api/models/mergeorganizationmetadataop.py new file mode 100644 index 00000000..b706fd92 --- /dev/null +++ b/src/clerk_backend_api/models/mergeorganizationmetadataop.py @@ -0,0 +1,70 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.types import BaseModel +from clerk_backend_api.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_backend_api/models/oauthapplication.py b/src/clerk_backend_api/models/oauthapplication.py new file mode 100644 index 00000000..6a807553 --- /dev/null +++ b/src/clerk_backend_api/models/oauthapplication.py @@ -0,0 +1,55 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.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_backend_api/models/oauthapplications.py b/src/clerk_backend_api/models/oauthapplications.py new file mode 100644 index 00000000..e22f5187 --- /dev/null +++ b/src/clerk_backend_api/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_backend_api.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_backend_api/models/oauthapplicationwithsecret.py b/src/clerk_backend_api/models/oauthapplicationwithsecret.py new file mode 100644 index 00000000..4a8f3d91 --- /dev/null +++ b/src/clerk_backend_api/models/oauthapplicationwithsecret.py @@ -0,0 +1,64 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.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_backend_api/models/organization.py b/src/clerk_backend_api/models/organization.py new file mode 100644 index 00000000..12c83742 --- /dev/null +++ b/src/clerk_backend_api/models/organization.py @@ -0,0 +1,96 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.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_backend_api/models/organizationinvitation.py b/src/clerk_backend_api/models/organizationinvitation.py new file mode 100644 index 00000000..73597039 --- /dev/null +++ b/src/clerk_backend_api/models/organizationinvitation.py @@ -0,0 +1,71 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.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_backend_api/models/organizationinvitations.py b/src/clerk_backend_api/models/organizationinvitations.py new file mode 100644 index 00000000..29e02eae --- /dev/null +++ b/src/clerk_backend_api/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_backend_api.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_backend_api/models/organizationmembership.py b/src/clerk_backend_api/models/organizationmembership.py new file mode 100644 index 00000000..3289d1c2 --- /dev/null +++ b/src/clerk_backend_api/models/organizationmembership.py @@ -0,0 +1,213 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.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_backend_api/models/organizationmemberships.py b/src/clerk_backend_api/models/organizationmemberships.py new file mode 100644 index 00000000..50051a6a --- /dev/null +++ b/src/clerk_backend_api/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_backend_api.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_backend_api/models/organizations.py b/src/clerk_backend_api/models/organizations.py new file mode 100644 index 00000000..95ab8a44 --- /dev/null +++ b/src/clerk_backend_api/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_backend_api.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_backend_api/models/organizationsettings.py b/src/clerk_backend_api/models/organizationsettings.py new file mode 100644 index 00000000..98dd9d62 --- /dev/null +++ b/src/clerk_backend_api/models/organizationsettings.py @@ -0,0 +1,53 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.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_backend_api/models/organizationwithlogo.py b/src/clerk_backend_api/models/organizationwithlogo.py new file mode 100644 index 00000000..cb836b1d --- /dev/null +++ b/src/clerk_backend_api/models/organizationwithlogo.py @@ -0,0 +1,103 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.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_backend_api/models/phonenumber.py b/src/clerk_backend_api/models/phonenumber.py new file mode 100644 index 00000000..16a484f8 --- /dev/null +++ b/src/clerk_backend_api/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_backend_api.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_backend_api/models/previewtemplateop.py b/src/clerk_backend_api/models/previewtemplateop.py new file mode 100644 index 00000000..6c0a2deb --- /dev/null +++ b/src/clerk_backend_api/models/previewtemplateop.py @@ -0,0 +1,104 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.types import BaseModel, Nullable +from clerk_backend_api.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_backend_api/models/proxycheck.py b/src/clerk_backend_api/models/proxycheck.py new file mode 100644 index 00000000..9de9dc1c --- /dev/null +++ b/src/clerk_backend_api/models/proxycheck.py @@ -0,0 +1,33 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.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_backend_api/models/redirecturl.py b/src/clerk_backend_api/models/redirecturl.py new file mode 100644 index 00000000..d50d76ef --- /dev/null +++ b/src/clerk_backend_api/models/redirecturl.py @@ -0,0 +1,39 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.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_backend_api/models/reverttemplateop.py b/src/clerk_backend_api/models/reverttemplateop.py new file mode 100644 index 00000000..65facee2 --- /dev/null +++ b/src/clerk_backend_api/models/reverttemplateop.py @@ -0,0 +1,29 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.types import BaseModel +from clerk_backend_api.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_backend_api/models/revokeactortokenop.py b/src/clerk_backend_api/models/revokeactortokenop.py new file mode 100644 index 00000000..bf442046 --- /dev/null +++ b/src/clerk_backend_api/models/revokeactortokenop.py @@ -0,0 +1,18 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.types import BaseModel +from clerk_backend_api.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_backend_api/models/revokeinvitationop.py b/src/clerk_backend_api/models/revokeinvitationop.py new file mode 100644 index 00000000..57d5d3ab --- /dev/null +++ b/src/clerk_backend_api/models/revokeinvitationop.py @@ -0,0 +1,18 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.types import BaseModel +from clerk_backend_api.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_backend_api/models/revokeorganizationinvitationop.py b/src/clerk_backend_api/models/revokeorganizationinvitationop.py new file mode 100644 index 00000000..37d17483 --- /dev/null +++ b/src/clerk_backend_api/models/revokeorganizationinvitationop.py @@ -0,0 +1,38 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.types import BaseModel +from clerk_backend_api.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_backend_api/models/revokesessionop.py b/src/clerk_backend_api/models/revokesessionop.py new file mode 100644 index 00000000..0b2011d7 --- /dev/null +++ b/src/clerk_backend_api/models/revokesessionop.py @@ -0,0 +1,18 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.types import BaseModel +from clerk_backend_api.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_backend_api/models/revokesignintokenop.py b/src/clerk_backend_api/models/revokesignintokenop.py new file mode 100644 index 00000000..04b4cf34 --- /dev/null +++ b/src/clerk_backend_api/models/revokesignintokenop.py @@ -0,0 +1,18 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.types import BaseModel +from clerk_backend_api.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_backend_api/models/rotateoauthapplicationsecretop.py b/src/clerk_backend_api/models/rotateoauthapplicationsecretop.py new file mode 100644 index 00000000..375695aa --- /dev/null +++ b/src/clerk_backend_api/models/rotateoauthapplicationsecretop.py @@ -0,0 +1,18 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.types import BaseModel +from clerk_backend_api.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_backend_api/models/samlaccount.py b/src/clerk_backend_api/models/samlaccount.py new file mode 100644 index 00000000..aacd8ae5 --- /dev/null +++ b/src/clerk_backend_api/models/samlaccount.py @@ -0,0 +1,221 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.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_backend_api/models/samlconnection.py b/src/clerk_backend_api/models/samlconnection.py new file mode 100644 index 00000000..b8ca49c2 --- /dev/null +++ b/src/clerk_backend_api/models/samlconnection.py @@ -0,0 +1,112 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.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_backend_api/models/samlconnections.py b/src/clerk_backend_api/models/samlconnections.py new file mode 100644 index 00000000..371f9a1d --- /dev/null +++ b/src/clerk_backend_api/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_backend_api.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_backend_api/models/schemas_passkey.py b/src/clerk_backend_api/models/schemas_passkey.py new file mode 100644 index 00000000..43252810 --- /dev/null +++ b/src/clerk_backend_api/models/schemas_passkey.py @@ -0,0 +1,128 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.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_backend_api/models/sdkerror.py b/src/clerk_backend_api/models/sdkerror.py new file mode 100644 index 00000000..cc9bf0f5 --- /dev/null +++ b/src/clerk_backend_api/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_backend_api/models/security.py b/src/clerk_backend_api/models/security.py new file mode 100644 index 00000000..046dcf71 --- /dev/null +++ b/src/clerk_backend_api/models/security.py @@ -0,0 +1,16 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.types import BaseModel +from clerk_backend_api.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_backend_api/models/session.py b/src/clerk_backend_api/models/session.py new file mode 100644 index 00000000..b140d677 --- /dev/null +++ b/src/clerk_backend_api/models/session.py @@ -0,0 +1,107 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.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_backend_api/models/setuserprofileimageop.py b/src/clerk_backend_api/models/setuserprofileimageop.py new file mode 100644 index 00000000..e9be7bbf --- /dev/null +++ b/src/clerk_backend_api/models/setuserprofileimageop.py @@ -0,0 +1,42 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.types import BaseModel +from clerk_backend_api.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_backend_api/models/signintoken.py b/src/clerk_backend_api/models/signintoken.py new file mode 100644 index 00000000..eb5987ed --- /dev/null +++ b/src/clerk_backend_api/models/signintoken.py @@ -0,0 +1,78 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.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_backend_api/models/signup.py b/src/clerk_backend_api/models/signup.py new file mode 100644 index 00000000..08c69736 --- /dev/null +++ b/src/clerk_backend_api/models/signup.py @@ -0,0 +1,128 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.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_backend_api/models/svixurl.py b/src/clerk_backend_api/models/svixurl.py new file mode 100644 index 00000000..19815941 --- /dev/null +++ b/src/clerk_backend_api/models/svixurl.py @@ -0,0 +1,14 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.types import BaseModel +from typing import TypedDict + + +class SvixURLTypedDict(TypedDict): + svix_url: str + + +class SvixURL(BaseModel): + svix_url: str + diff --git a/src/clerk_backend_api/models/template.py b/src/clerk_backend_api/models/template.py new file mode 100644 index 00000000..65960926 --- /dev/null +++ b/src/clerk_backend_api/models/template.py @@ -0,0 +1,135 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.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_backend_api/models/testingtoken.py b/src/clerk_backend_api/models/testingtoken.py new file mode 100644 index 00000000..245f5af3 --- /dev/null +++ b/src/clerk_backend_api/models/testingtoken.py @@ -0,0 +1,35 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.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_backend_api/models/toggletemplatedeliveryop.py b/src/clerk_backend_api/models/toggletemplatedeliveryop.py new file mode 100644 index 00000000..d839bf03 --- /dev/null +++ b/src/clerk_backend_api/models/toggletemplatedeliveryop.py @@ -0,0 +1,67 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.types import BaseModel, Nullable +from clerk_backend_api.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_backend_api/models/totalcount.py b/src/clerk_backend_api/models/totalcount.py new file mode 100644 index 00000000..589e51bc --- /dev/null +++ b/src/clerk_backend_api/models/totalcount.py @@ -0,0 +1,30 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.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_backend_api/models/unbanuserop.py b/src/clerk_backend_api/models/unbanuserop.py new file mode 100644 index 00000000..b1fdcb93 --- /dev/null +++ b/src/clerk_backend_api/models/unbanuserop.py @@ -0,0 +1,18 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.types import BaseModel +from clerk_backend_api.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_backend_api/models/unlockuserop.py b/src/clerk_backend_api/models/unlockuserop.py new file mode 100644 index 00000000..40a64025 --- /dev/null +++ b/src/clerk_backend_api/models/unlockuserop.py @@ -0,0 +1,18 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.types import BaseModel +from clerk_backend_api.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_backend_api/models/updatedomainop.py b/src/clerk_backend_api/models/updatedomainop.py new file mode 100644 index 00000000..3335a3c8 --- /dev/null +++ b/src/clerk_backend_api/models/updatedomainop.py @@ -0,0 +1,70 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.types import BaseModel, Nullable +from clerk_backend_api.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_backend_api/models/updateemailaddressop.py b/src/clerk_backend_api/models/updateemailaddressop.py new file mode 100644 index 00000000..1770dc60 --- /dev/null +++ b/src/clerk_backend_api/models/updateemailaddressop.py @@ -0,0 +1,60 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.types import BaseModel, Nullable +from clerk_backend_api.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_backend_api/models/updateinstanceauthconfigop.py b/src/clerk_backend_api/models/updateinstanceauthconfigop.py new file mode 100644 index 00000000..c793f11b --- /dev/null +++ b/src/clerk_backend_api/models/updateinstanceauthconfigop.py @@ -0,0 +1,77 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.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_backend_api/models/updateinstanceop.py b/src/clerk_backend_api/models/updateinstanceop.py new file mode 100644 index 00000000..be4f2670 --- /dev/null +++ b/src/clerk_backend_api/models/updateinstanceop.py @@ -0,0 +1,86 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.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_backend_api/models/updateinstanceorganizationsettingsop.py b/src/clerk_backend_api/models/updateinstanceorganizationsettingsop.py new file mode 100644 index 00000000..927cb492 --- /dev/null +++ b/src/clerk_backend_api/models/updateinstanceorganizationsettingsop.py @@ -0,0 +1,63 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.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_backend_api/models/updateinstancerestrictionsop.py b/src/clerk_backend_api/models/updateinstancerestrictionsop.py new file mode 100644 index 00000000..09494ba4 --- /dev/null +++ b/src/clerk_backend_api/models/updateinstancerestrictionsop.py @@ -0,0 +1,49 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.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_backend_api/models/updatejwttemplateop.py b/src/clerk_backend_api/models/updatejwttemplateop.py new file mode 100644 index 00000000..a430e44e --- /dev/null +++ b/src/clerk_backend_api/models/updatejwttemplateop.py @@ -0,0 +1,90 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.types import BaseModel, Nullable +from clerk_backend_api.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_backend_api/models/updateoauthapplicationop.py b/src/clerk_backend_api/models/updateoauthapplicationop.py new file mode 100644 index 00000000..a964e9ce --- /dev/null +++ b/src/clerk_backend_api/models/updateoauthapplicationop.py @@ -0,0 +1,38 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.types import BaseModel +from clerk_backend_api.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_backend_api/models/updateorganizationmembershipmetadataop.py b/src/clerk_backend_api/models/updateorganizationmembershipmetadataop.py new file mode 100644 index 00000000..a7eed6aa --- /dev/null +++ b/src/clerk_backend_api/models/updateorganizationmembershipmetadataop.py @@ -0,0 +1,74 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.types import BaseModel +from clerk_backend_api.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_backend_api/models/updateorganizationmembershipop.py b/src/clerk_backend_api/models/updateorganizationmembershipop.py new file mode 100644 index 00000000..49d47067 --- /dev/null +++ b/src/clerk_backend_api/models/updateorganizationmembershipop.py @@ -0,0 +1,34 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.types import BaseModel +from clerk_backend_api.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_backend_api/models/updateorganizationop.py b/src/clerk_backend_api/models/updateorganizationop.py new file mode 100644 index 00000000..5c3e075f --- /dev/null +++ b/src/clerk_backend_api/models/updateorganizationop.py @@ -0,0 +1,96 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.types import BaseModel, Nullable +from clerk_backend_api.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_backend_api/models/updatephonenumberop.py b/src/clerk_backend_api/models/updatephonenumberop.py new file mode 100644 index 00000000..09d74f86 --- /dev/null +++ b/src/clerk_backend_api/models/updatephonenumberop.py @@ -0,0 +1,70 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.types import BaseModel, Nullable +from clerk_backend_api.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_backend_api/models/updateproductioninstancedomainop.py b/src/clerk_backend_api/models/updateproductioninstancedomainop.py new file mode 100644 index 00000000..f2b712c0 --- /dev/null +++ b/src/clerk_backend_api/models/updateproductioninstancedomainop.py @@ -0,0 +1,17 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.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_backend_api/models/updatesamlconnectionop.py b/src/clerk_backend_api/models/updatesamlconnectionop.py new file mode 100644 index 00000000..75d515a3 --- /dev/null +++ b/src/clerk_backend_api/models/updatesamlconnectionop.py @@ -0,0 +1,118 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.types import BaseModel, Nullable +from clerk_backend_api.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_backend_api/models/updatesignupop.py b/src/clerk_backend_api/models/updatesignupop.py new file mode 100644 index 00000000..d790e99c --- /dev/null +++ b/src/clerk_backend_api/models/updatesignupop.py @@ -0,0 +1,70 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.types import BaseModel, Nullable +from clerk_backend_api.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_backend_api/models/updateusermetadataop.py b/src/clerk_backend_api/models/updateusermetadataop.py new file mode 100644 index 00000000..bea7d378 --- /dev/null +++ b/src/clerk_backend_api/models/updateusermetadataop.py @@ -0,0 +1,86 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.types import BaseModel +from clerk_backend_api.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_backend_api/models/updateuserop.py b/src/clerk_backend_api/models/updateuserop.py new file mode 100644 index 00000000..918e4569 --- /dev/null +++ b/src/clerk_backend_api/models/updateuserop.py @@ -0,0 +1,586 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.types import BaseModel, Nullable +from clerk_backend_api.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_backend_api/models/uploadorganizationlogoop.py b/src/clerk_backend_api/models/uploadorganizationlogoop.py new file mode 100644 index 00000000..6d25f2ff --- /dev/null +++ b/src/clerk_backend_api/models/uploadorganizationlogoop.py @@ -0,0 +1,46 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.types import BaseModel +from clerk_backend_api.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_backend_api/models/upserttemplateop.py b/src/clerk_backend_api/models/upserttemplateop.py new file mode 100644 index 00000000..c36df92d --- /dev/null +++ b/src/clerk_backend_api/models/upserttemplateop.py @@ -0,0 +1,107 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.types import BaseModel, Nullable +from clerk_backend_api.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_backend_api/models/user.py b/src/clerk_backend_api/models/user.py new file mode 100644 index 00000000..80b7b6ee --- /dev/null +++ b/src/clerk_backend_api/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_backend_api.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_backend_api/models/usersgetorganizationmembershipsop.py b/src/clerk_backend_api/models/usersgetorganizationmembershipsop.py new file mode 100644 index 00000000..aa34b348 --- /dev/null +++ b/src/clerk_backend_api/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_backend_api.types import BaseModel +from clerk_backend_api.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_backend_api/models/verifyclientop.py b/src/clerk_backend_api/models/verifyclientop.py new file mode 100644 index 00000000..f44328f0 --- /dev/null +++ b/src/clerk_backend_api/models/verifyclientop.py @@ -0,0 +1,21 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.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_backend_api/models/verifydomainproxyop.py b/src/clerk_backend_api/models/verifydomainproxyop.py new file mode 100644 index 00000000..41453825 --- /dev/null +++ b/src/clerk_backend_api/models/verifydomainproxyop.py @@ -0,0 +1,21 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.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_backend_api/models/verifypasswordop.py b/src/clerk_backend_api/models/verifypasswordop.py new file mode 100644 index 00000000..230a171e --- /dev/null +++ b/src/clerk_backend_api/models/verifypasswordop.py @@ -0,0 +1,42 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.types import BaseModel +from clerk_backend_api.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_backend_api/models/verifysessionop.py b/src/clerk_backend_api/models/verifysessionop.py new file mode 100644 index 00000000..8d84e0ba --- /dev/null +++ b/src/clerk_backend_api/models/verifysessionop.py @@ -0,0 +1,40 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.types import BaseModel +from clerk_backend_api.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_backend_api/models/verifytotpop.py b/src/clerk_backend_api/models/verifytotpop.py new file mode 100644 index 00000000..735ba14a --- /dev/null +++ b/src/clerk_backend_api/models/verifytotpop.py @@ -0,0 +1,50 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.types import BaseModel +from clerk_backend_api.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_backend_api/models/web3wallet.py b/src/clerk_backend_api/models/web3wallet.py new file mode 100644 index 00000000..801351dd --- /dev/null +++ b/src/clerk_backend_api/models/web3wallet.py @@ -0,0 +1,184 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +from clerk_backend_api.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_backend_api/oauthapplications_sdk.py b/src/clerk_backend_api/oauthapplications_sdk.py new file mode 100644 index 00000000..533b4c24 --- /dev/null +++ b/src/clerk_backend_api/oauthapplications_sdk.py @@ -0,0 +1,1046 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from .basesdk import BaseSDK +from clerk_backend_api import models +from clerk_backend_api._hooks import HookContext +from clerk_backend_api.types import Nullable, UNSET +import clerk_backend_api.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_backend_api/organizationinvitations_sdk.py b/src/clerk_backend_api/organizationinvitations_sdk.py new file mode 100644 index 00000000..e698012b --- /dev/null +++ b/src/clerk_backend_api/organizationinvitations_sdk.py @@ -0,0 +1,1223 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from .basesdk import BaseSDK +from clerk_backend_api import models +from clerk_backend_api._hooks import HookContext +from clerk_backend_api.types import BaseModel, Nullable, UNSET +import clerk_backend_api.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_backend_api/organizationmemberships_sdk.py b/src/clerk_backend_api/organizationmemberships_sdk.py new file mode 100644 index 00000000..be6b0911 --- /dev/null +++ b/src/clerk_backend_api/organizationmemberships_sdk.py @@ -0,0 +1,920 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from .basesdk import BaseSDK +from clerk_backend_api import models +from clerk_backend_api._hooks import HookContext +from clerk_backend_api.types import BaseModel, Nullable, UNSET +import clerk_backend_api.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_backend_api/organizations_sdk.py b/src/clerk_backend_api/organizations_sdk.py new file mode 100644 index 00000000..5cccec82 --- /dev/null +++ b/src/clerk_backend_api/organizations_sdk.py @@ -0,0 +1,1411 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from .basesdk import BaseSDK +from clerk_backend_api import models +from clerk_backend_api._hooks import HookContext +from clerk_backend_api.types import BaseModel, Nullable, UNSET +import clerk_backend_api.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_backend_api/phonenumbers.py b/src/clerk_backend_api/phonenumbers.py new file mode 100644 index 00000000..751ee7a0 --- /dev/null +++ b/src/clerk_backend_api/phonenumbers.py @@ -0,0 +1,677 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from .basesdk import BaseSDK +from clerk_backend_api import models +from clerk_backend_api._hooks import HookContext +from clerk_backend_api.types import Nullable, UNSET +import clerk_backend_api.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_backend_api/proxychecks.py b/src/clerk_backend_api/proxychecks.py new file mode 100644 index 00000000..753383f4 --- /dev/null +++ b/src/clerk_backend_api/proxychecks.py @@ -0,0 +1,187 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from .basesdk import BaseSDK +from clerk_backend_api import models +from clerk_backend_api._hooks import HookContext +from clerk_backend_api.types import Nullable, UNSET +import clerk_backend_api.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_backend_api/redirecturls.py b/src/clerk_backend_api/redirecturls.py new file mode 100644 index 00000000..3edb3fae --- /dev/null +++ b/src/clerk_backend_api/redirecturls.py @@ -0,0 +1,609 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from .basesdk import BaseSDK +from clerk_backend_api import models +from clerk_backend_api._hooks import HookContext +from clerk_backend_api.types import Nullable, UNSET +import clerk_backend_api.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_backend_api/samlconnections_sdk.py b/src/clerk_backend_api/samlconnections_sdk.py new file mode 100644 index 00000000..8dd54aa0 --- /dev/null +++ b/src/clerk_backend_api/samlconnections_sdk.py @@ -0,0 +1,966 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from .basesdk import BaseSDK +from clerk_backend_api import models +from clerk_backend_api._hooks import HookContext +from clerk_backend_api.types import BaseModel, Nullable, UNSET +import clerk_backend_api.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_backend_api/sdk.py b/src/clerk_backend_api/sdk.py new file mode 100644 index 00000000..d7c66b93 --- /dev/null +++ b/src/clerk_backend_api/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_backend_api import models +from clerk_backend_api._hooks import SDKHooks +from clerk_backend_api.actortokens import ActorTokens +from clerk_backend_api.allowlistidentifiers import AllowlistIdentifiers +from clerk_backend_api.betafeatures import BetaFeatures +from clerk_backend_api.blocklistidentifiers_sdk import BlocklistIdentifiersSDK +from clerk_backend_api.clients import Clients +from clerk_backend_api.domains_sdk import DomainsSDK +from clerk_backend_api.emailaddresses import EmailAddresses +from clerk_backend_api.instancesettings_sdk import InstanceSettingsSDK +from clerk_backend_api.invitations import Invitations +from clerk_backend_api.jwks import Jwks +from clerk_backend_api.jwttemplates import JwtTemplates +from clerk_backend_api.misc import Misc +from clerk_backend_api.oauthapplications_sdk import OAuthApplicationsSDK +from clerk_backend_api.organizationinvitations_sdk import OrganizationInvitationsSDK +from clerk_backend_api.organizationmemberships_sdk import OrganizationMembershipsSDK +from clerk_backend_api.organizations_sdk import OrganizationsSDK +from clerk_backend_api.phonenumbers import PhoneNumbers +from clerk_backend_api.proxychecks import ProxyChecks +from clerk_backend_api.redirecturls import RedirectUrls +from clerk_backend_api.samlconnections_sdk import SamlConnectionsSDK +from clerk_backend_api.sessions import Sessions +from clerk_backend_api.signintokens import SignInTokens +from clerk_backend_api.signups import SignUps +from clerk_backend_api.templates import Templates +from clerk_backend_api.testingtokens import TestingTokens +from clerk_backend_api.types import Nullable, UNSET +from clerk_backend_api.users import Users +import clerk_backend_api.utils as utils +from clerk_backend_api.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_backend_api/sdkconfiguration.py b/src/clerk_backend_api/sdkconfiguration.py new file mode 100644 index 00000000..af39fe83 --- /dev/null +++ b/src/clerk_backend_api/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_backend_api import models +from clerk_backend_api.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.7" + gen_version: str = "2.366.1" + user_agent: str = "speakeasy-sdk/python 0.5.0-alpha.7 2.366.1 v1 clerk-backend-api" + 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_backend_api/sessions.py b/src/clerk_backend_api/sessions.py new file mode 100644 index 00000000..48f2bf82 --- /dev/null +++ b/src/clerk_backend_api/sessions.py @@ -0,0 +1,840 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from .basesdk import BaseSDK +from clerk_backend_api import models +from clerk_backend_api._hooks import HookContext +from clerk_backend_api.types import Nullable, UNSET +import clerk_backend_api.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_backend_api/signintokens.py b/src/clerk_backend_api/signintokens.py new file mode 100644 index 00000000..a0779004 --- /dev/null +++ b/src/clerk_backend_api/signintokens.py @@ -0,0 +1,331 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from .basesdk import BaseSDK +from clerk_backend_api import models +from clerk_backend_api._hooks import HookContext +from clerk_backend_api.types import Nullable, UNSET +import clerk_backend_api.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_backend_api/signups.py b/src/clerk_backend_api/signups.py new file mode 100644 index 00000000..0684df97 --- /dev/null +++ b/src/clerk_backend_api/signups.py @@ -0,0 +1,183 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from .basesdk import BaseSDK +from clerk_backend_api import models +from clerk_backend_api._hooks import HookContext +from clerk_backend_api.types import Nullable, UNSET +import clerk_backend_api.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_backend_api/templates.py b/src/clerk_backend_api/templates.py new file mode 100644 index 00000000..93f68f37 --- /dev/null +++ b/src/clerk_backend_api/templates.py @@ -0,0 +1,1061 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from .basesdk import BaseSDK +from clerk_backend_api import models +from clerk_backend_api._hooks import HookContext +from clerk_backend_api.types import Nullable, UNSET +import clerk_backend_api.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_backend_api/testingtokens.py b/src/clerk_backend_api/testingtokens.py new file mode 100644 index 00000000..27996ac1 --- /dev/null +++ b/src/clerk_backend_api/testingtokens.py @@ -0,0 +1,145 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from .basesdk import BaseSDK +from clerk_backend_api import models +from clerk_backend_api._hooks import HookContext +from clerk_backend_api.types import Nullable, UNSET +import clerk_backend_api.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_backend_api/types/__init__.py b/src/clerk_backend_api/types/__init__.py new file mode 100644 index 00000000..f2314e91 --- /dev/null +++ b/src/clerk_backend_api/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_backend_api/types/basemodel.py b/src/clerk_backend_api/types/basemodel.py new file mode 100644 index 00000000..969e85a1 --- /dev/null +++ b/src/clerk_backend_api/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_backend_api/users.py b/src/clerk_backend_api/users.py new file mode 100644 index 00000000..c53b31b3 --- /dev/null +++ b/src/clerk_backend_api/users.py @@ -0,0 +1,3316 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from .basesdk import BaseSDK +from clerk_backend_api import models +from clerk_backend_api._hooks import HookContext +from clerk_backend_api.types import BaseModel, Nullable, UNSET +import clerk_backend_api.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_backend_api/utils/__init__.py b/src/clerk_backend_api/utils/__init__.py new file mode 100644 index 00000000..95cdf570 --- /dev/null +++ b/src/clerk_backend_api/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_backend_api/utils/enums.py b/src/clerk_backend_api/utils/enums.py new file mode 100644 index 00000000..2804f7d6 --- /dev/null +++ b/src/clerk_backend_api/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_backend_api/utils/eventstreaming.py b/src/clerk_backend_api/utils/eventstreaming.py new file mode 100644 index 00000000..c9ace010 --- /dev/null +++ b/src/clerk_backend_api/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_backend_api/utils/forms.py b/src/clerk_backend_api/utils/forms.py new file mode 100644 index 00000000..4df2b8df --- /dev/null +++ b/src/clerk_backend_api/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_backend_api/utils/headers.py b/src/clerk_backend_api/utils/headers.py new file mode 100644 index 00000000..ad258798 --- /dev/null +++ b/src/clerk_backend_api/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_backend_api/utils/metadata.py b/src/clerk_backend_api/utils/metadata.py new file mode 100644 index 00000000..b5693b37 --- /dev/null +++ b/src/clerk_backend_api/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_backend_api/utils/queryparams.py b/src/clerk_backend_api/utils/queryparams.py new file mode 100644 index 00000000..5f5ca8d3 --- /dev/null +++ b/src/clerk_backend_api/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_backend_api/utils/requestbodies.py b/src/clerk_backend_api/utils/requestbodies.py new file mode 100644 index 00000000..c01e2750 --- /dev/null +++ b/src/clerk_backend_api/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_backend_api/utils/retries.py b/src/clerk_backend_api/utils/retries.py new file mode 100644 index 00000000..25404948 --- /dev/null +++ b/src/clerk_backend_api/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_backend_api/utils/security.py b/src/clerk_backend_api/utils/security.py new file mode 100644 index 00000000..d25d6544 --- /dev/null +++ b/src/clerk_backend_api/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_backend_api/utils/serializers.py b/src/clerk_backend_api/utils/serializers.py new file mode 100644 index 00000000..15cca42c --- /dev/null +++ b/src/clerk_backend_api/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_backend_api/utils/url.py b/src/clerk_backend_api/utils/url.py new file mode 100644 index 00000000..481ae779 --- /dev/null +++ b/src/clerk_backend_api/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_backend_api/utils/values.py b/src/clerk_backend_api/utils/values.py new file mode 100644 index 00000000..e0be5876 --- /dev/null +++ b/src/clerk_backend_api/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_backend_api/webhooks.py b/src/clerk_backend_api/webhooks.py new file mode 100644 index 00000000..22a9ea5a --- /dev/null +++ b/src/clerk_backend_api/webhooks.py @@ -0,0 +1,431 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from .basesdk import BaseSDK +from clerk_backend_api import models +from clerk_backend_api._hooks import HookContext +from clerk_backend_api.types import Nullable, UNSET +import clerk_backend_api.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) +