From 5d39039e7e470f8a983c8fc019fda8d8ca13f4a7 Mon Sep 17 00:00:00 2001
From: fern-api <115122769+fern-api[bot]@users.noreply.github.com>
Date: Mon, 15 Jun 2026 09:36:03 +0000
Subject: [PATCH 1/7] SDK regeneration
---
reference.md | 1011 +++++++++++++++++
src/auth0/myorganization/client.py | 4 +-
src/auth0/myorganization/environment.py | 2 +-
.../myorganization/organization/__init__.py | 8 +-
.../myorganization/organization/client.py | 76 ++
.../provisioning/raw_client.py | 6 -
.../identity_providers/raw_client.py | 18 -
.../organization/invitations/__init__.py | 4 +
.../organization/invitations/client.py | 507 +++++++++
.../organization/invitations/raw_client.py | 974 ++++++++++++++++
.../organization/members/__init__.py | 34 +
.../organization/members/client.py | 294 +++++
.../organization/members/raw_client.py | 519 +++++++++
.../organization/members/roles/__init__.py | 4 +
.../organization/members/roles/client.py | 322 ++++++
.../organization/members/roles/raw_client.py | 678 +++++++++++
.../organization/memberships/__init__.py | 4 +
.../organization/memberships/client.py | 113 ++
.../organization/memberships/raw_client.py | 224 ++++
.../organization/roles/__init__.py | 4 +
.../organization/roles/client.py | 151 +++
.../organization/roles/raw_client.py | 256 +++++
.../organization_details/raw_client.py | 6 -
src/auth0/myorganization/types/__init__.py | 36 +-
.../types/create_member_invitation_invitee.py | 28 +
...eate_member_invitation_response_content.py | 7 +
...anization_member_roles_response_content.py | 25 +
...st_members_invitations_response_content.py | 25 +
...t_organization_members_response_content.py | 25 +
.../types/list_roles_response_content.py | 24 +
.../myorganization/types/member_invitation.py | 4 +-
src/auth0/myorganization/types/oauth_scope.py | 2 -
src/auth0/myorganization/types/org_member.py | 9 +-
.../myorganization/types/org_member_id.py | 6 +
...ion_member_roles_change_request_content.py | 20 +
.../types/{org_member_role.py => role.py} | 6 +-
.../{org_member_role_id.py => role_id.py} | 2 +-
tests/wire/test_organization_invitations.py | 67 ++
tests/wire/test_organization_members.py | 28 +
tests/wire/test_organization_members_roles.py | 35 +
tests/wire/test_organization_memberships.py | 11 +
tests/wire/test_organization_roles.py | 13 +
wiremock/wiremock-mappings.json | 442 ++++++-
43 files changed, 5982 insertions(+), 52 deletions(-)
create mode 100644 src/auth0/myorganization/organization/invitations/__init__.py
create mode 100644 src/auth0/myorganization/organization/invitations/client.py
create mode 100644 src/auth0/myorganization/organization/invitations/raw_client.py
create mode 100644 src/auth0/myorganization/organization/members/__init__.py
create mode 100644 src/auth0/myorganization/organization/members/client.py
create mode 100644 src/auth0/myorganization/organization/members/raw_client.py
create mode 100644 src/auth0/myorganization/organization/members/roles/__init__.py
create mode 100644 src/auth0/myorganization/organization/members/roles/client.py
create mode 100644 src/auth0/myorganization/organization/members/roles/raw_client.py
create mode 100644 src/auth0/myorganization/organization/memberships/__init__.py
create mode 100644 src/auth0/myorganization/organization/memberships/client.py
create mode 100644 src/auth0/myorganization/organization/memberships/raw_client.py
create mode 100644 src/auth0/myorganization/organization/roles/__init__.py
create mode 100644 src/auth0/myorganization/organization/roles/client.py
create mode 100644 src/auth0/myorganization/organization/roles/raw_client.py
create mode 100644 src/auth0/myorganization/types/create_member_invitation_invitee.py
create mode 100644 src/auth0/myorganization/types/create_member_invitation_response_content.py
create mode 100644 src/auth0/myorganization/types/get_organization_member_roles_response_content.py
create mode 100644 src/auth0/myorganization/types/list_members_invitations_response_content.py
create mode 100644 src/auth0/myorganization/types/list_organization_members_response_content.py
create mode 100644 src/auth0/myorganization/types/list_roles_response_content.py
create mode 100644 src/auth0/myorganization/types/org_member_id.py
create mode 100644 src/auth0/myorganization/types/organization_member_roles_change_request_content.py
rename src/auth0/myorganization/types/{org_member_role.py => role.py} (82%)
rename src/auth0/myorganization/types/{org_member_role_id.py => role_id.py} (86%)
create mode 100644 tests/wire/test_organization_invitations.py
create mode 100644 tests/wire/test_organization_members.py
create mode 100644 tests/wire/test_organization_members_roles.py
create mode 100644 tests/wire/test_organization_memberships.py
create mode 100644 tests/wire/test_organization_roles.py
diff --git a/reference.md b/reference.md
index 2f84ce8..906dad5 100644
--- a/reference.md
+++ b/reference.md
@@ -1055,6 +1055,757 @@ client.organization.identity_providers.detach(
+
+
+
+
+## Organization Members
+client.organization.members.list(...) -> ListOrganizationMembersResponseContent
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Retrieve a list of all members for this Organization. The `roles` field is only included for each member when the token also carries the `read:my_org:member_roles` scope; without that scope the `roles` field is omitted from the response.
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from auth0.myorganization import Auth0
+from auth0.myorganization.environment import Auth0Environment
+
+client = Auth0(
+ token="",
+ environment=Auth0Environment.DEFAULT,
+)
+
+client.organization.members.list(
+ fields="fields",
+ include_fields=True,
+ from_="from",
+ take=1,
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**fields:** `typing.Optional[str]` — Comma-separated list of fields to include or exclude (based on value provided for include_fields) in the result. Leave empty to retrieve all fields.
+
+
+
+
+
+-
+
+**include_fields:** `typing.Optional[bool]` — Whether specified fields are to be included (true) or excluded (false). Defaults to true
+
+
+
+
+
+-
+
+**from:** `typing.Optional[str]` — An optional cursor from which to start the selection (exclusive).
+
+
+
+
+
+-
+
+**take:** `typing.Optional[int]` — Number of results per page. Defaults to 50.
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.organization.members.get(...) -> GetOrganizationMemberResponseContent
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Retrieve details of a member specified by user ID for this Organization.
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from auth0.myorganization import Auth0
+from auth0.myorganization.environment import Auth0Environment
+
+client = Auth0(
+ token="",
+ environment=Auth0Environment.DEFAULT,
+)
+
+client.organization.members.get(
+ user_id="user_id",
+ fields="fields",
+ include_fields=True,
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**user_id:** `OrgMemberId`
+
+
+
+
+
+-
+
+**fields:** `typing.Optional[str]` — Comma-separated list of fields to include or exclude (based on value provided for include_fields) in the result. Leave empty to retrieve all fields.
+
+
+
+
+
+-
+
+**include_fields:** `typing.Optional[bool]` — Whether specified fields are to be included (true) or excluded (false). Defaults to true
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+## Organization Memberships
+client.organization.memberships.delete_memberships(...)
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Remove one member from this Organization. The underlying user account is not deleted.
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from auth0.myorganization import Auth0
+from auth0.myorganization.environment import Auth0Environment
+
+client = Auth0(
+ token="",
+ environment=Auth0Environment.DEFAULT,
+)
+
+client.organization.memberships.delete_memberships(
+ members=[
+ "auth0|1234567890"
+ ],
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**members:** `typing.List[OrgMemberId]`
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+## Organization Invitations
+client.organization.invitations.list(...) -> ListMembersInvitationsResponseContent
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Retrieve a list of all member invitations for this Organization.
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from auth0.myorganization import Auth0
+from auth0.myorganization.environment import Auth0Environment
+
+client = Auth0(
+ token="",
+ environment=Auth0Environment.DEFAULT,
+)
+
+client.organization.invitations.list(
+ fields="fields",
+ include_fields=True,
+ from_="from",
+ take=1,
+ sort="sort",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**fields:** `typing.Optional[str]` — Comma-separated list of fields to include or exclude (based on value provided for include_fields) in the result. Leave empty to retrieve all fields. Note: you cannot filter on ticket_id and this value will only be returned when fields are not filtered.
+
+
+
+
+
+-
+
+**include_fields:** `typing.Optional[bool]` — Whether specified fields are to be included (true) or excluded (false). Defaults to true
+
+
+
+
+
+-
+
+**from:** `typing.Optional[str]` — An optional cursor from which to start the selection (exclusive).
+
+
+
+
+
+-
+
+**take:** `typing.Optional[int]` — Number of results per page. Defaults to 50.
+
+
+
+
+
+-
+
+**sort:** `typing.Optional[str]` — Field to sort by. Use field:order where order is 1 for ascending and -1 for descending. Defaults to created_at:-1
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.organization.invitations.create(...) -> CreateMemberInvitationResponseContent
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Create one or more member invitations for this Organization. If an active invitation already exists for a user, generating a new invitation will automatically revoke any outstanding invitations for that user. Roles specified in the payload will be granted to the user upon acceptance of the invitation.
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from auth0.myorganization import Auth0, CreateMemberInvitationInvitee, MemberInvitationInviter
+from auth0.myorganization.environment import Auth0Environment
+
+client = Auth0(
+ token="",
+ environment=Auth0Environment.DEFAULT,
+)
+
+client.organization.invitations.create(
+ invitees=[
+ CreateMemberInvitationInvitee(
+ email="user@example.com",
+ roles=[
+ "rol_0000000000000001"
+ ],
+ )
+ ],
+ inviter=MemberInvitationInviter(
+ name="Allison the Admin",
+ ),
+ identity_provider_id="con_2CZPv6IY0gWzDaQJ",
+ ttl_sec=3600,
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**invitees:** `typing.List[CreateMemberInvitationInvitee]`
+
+
+
+
+
+-
+
+**auth_0_custom_domain:** `typing.Optional[str]`
+
+
+
+
+
+-
+
+**inviter:** `typing.Optional[MemberInvitationInviter]`
+
+
+
+
+
+-
+
+**identity_provider_id:** `typing.Optional[str]` — Identity provider identifier.
+
+
+
+
+
+-
+
+**ttl_sec:** `typing.Optional[int]` — Number of seconds for which the invitation is valid before expiration. If unspecified or set to 0, this value defaults to 604800 seconds (7 days). Max value: 2592000 seconds (30 days).
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.organization.invitations.get(...) -> GetMemberInvitationResponseContent
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Retrieve details of a member invitation specified by ID for this Organization.
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from auth0.myorganization import Auth0
+from auth0.myorganization.environment import Auth0Environment
+
+client = Auth0(
+ token="",
+ environment=Auth0Environment.DEFAULT,
+)
+
+client.organization.invitations.get(
+ invitation_id="invitation_id",
+ fields="fields",
+ include_fields=True,
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**invitation_id:** `InvitationId`
+
+
+
+
+
+-
+
+**fields:** `typing.Optional[str]` — Comma-separated list of fields to include or exclude (based on value provided for include_fields) in the result. Leave empty to retrieve all fields. Note: you cannot filter on ticket_id and this value will only be returned when fields are not filtered.
+
+
+
+
+
+-
+
+**include_fields:** `typing.Optional[bool]` — Whether specified fields are to be included (true) or excluded (false). Defaults to true
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.organization.invitations.delete(...)
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Revoke a member invitation specified by ID for this Organization.
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from auth0.myorganization import Auth0
+from auth0.myorganization.environment import Auth0Environment
+
+client = Auth0(
+ token="",
+ environment=Auth0Environment.DEFAULT,
+)
+
+client.organization.invitations.delete(
+ invitation_id="invitation_id",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**invitation_id:** `InvitationId`
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+## Organization Roles
+client.organization.roles.list(...) -> ListRolesResponseContent
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Retrieve the list of roles available for binding to members and invitations for this Organization. Only roles made visible to this Organization by the Tenant Admin are returned.
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from auth0.myorganization import Auth0
+from auth0.myorganization.environment import Auth0Environment
+
+client = Auth0(
+ token="",
+ environment=Auth0Environment.DEFAULT,
+)
+
+client.organization.roles.list(
+ from_="from",
+ take=1,
+ name="name",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**from:** `typing.Optional[str]` — An optional cursor from which to start the selection (exclusive).
+
+
+
+
+
+-
+
+**take:** `typing.Optional[int]` — Number of results per page. Defaults to 50.
+
+
+
+
+
+-
+
+**name:** `typing.Optional[str]` — An optional filter on the name (case-insensitive).
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
@@ -1978,3 +2729,263 @@ client.organization.identity_providers.provisioning.scim_tokens.delete(
+## Organization Members Roles
+client.organization.members.roles.list(...) -> GetOrganizationMemberRolesResponseContent
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Retrieve a list of roles assigned to a member specified by ID for this Organization.
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from auth0.myorganization import Auth0
+from auth0.myorganization.environment import Auth0Environment
+
+client = Auth0(
+ token="",
+ environment=Auth0Environment.DEFAULT,
+)
+
+client.organization.members.roles.list(
+ user_id="user_id",
+ from_="from",
+ take=1,
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**user_id:** `OrgMemberId`
+
+
+
+
+
+-
+
+**from:** `typing.Optional[str]` — An optional cursor from which to start the selection (exclusive).
+
+
+
+
+
+-
+
+**take:** `typing.Optional[int]` — Number of results per page. Defaults to 50.
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.organization.members.roles.assign(...)
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Assign roles to a member specified by ID for this Organization.
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from auth0.myorganization import Auth0
+from auth0.myorganization.environment import Auth0Environment
+
+client = Auth0(
+ token="",
+ environment=Auth0Environment.DEFAULT,
+)
+
+client.organization.members.roles.assign(
+ user_id="user_id",
+ role_ids=[
+ "rol_SO2j0sFo9NFa3F9w"
+ ],
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**user_id:** `OrgMemberId`
+
+
+
+
+
+-
+
+**request:** `OrganizationMemberRolesChangeRequestContent`
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.organization.members.roles.unassign(...)
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Remove roles from a member specified by ID for this Organization.
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from auth0.myorganization import Auth0
+from auth0.myorganization.environment import Auth0Environment
+
+client = Auth0(
+ token="",
+ environment=Auth0Environment.DEFAULT,
+)
+
+client.organization.members.roles.unassign(
+ user_id="user_id",
+ role_ids=[
+ "rol_SO2j0sFo9NFa3F9w"
+ ],
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**user_id:** `OrgMemberId`
+
+
+
+
+
+-
+
+**request:** `OrganizationMemberRolesChangeRequestContent`
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/auth0/myorganization/client.py b/src/auth0/myorganization/client.py
index 2d48176..815f543 100644
--- a/src/auth0/myorganization/client.py
+++ b/src/auth0/myorganization/client.py
@@ -78,7 +78,7 @@ def __init__(
)
if tenant_domain is not None:
_tenant_domain = tenant_domain if tenant_domain is not None else "{TENANT}.auth0.com"
- base_url = "https://{tenantDomain}/my-org".format(tenantDomain=_tenant_domain)
+ base_url = "https://{tenantDomain}/my-org/v1".format(tenantDomain=_tenant_domain)
self._client_wrapper = SyncClientWrapper(
base_url=_get_base_url(base_url=base_url, environment=environment),
token=token,
@@ -197,7 +197,7 @@ def __init__(
)
if tenant_domain is not None:
_tenant_domain = tenant_domain if tenant_domain is not None else "{TENANT}.auth0.com"
- base_url = "https://{tenantDomain}/my-org".format(tenantDomain=_tenant_domain)
+ base_url = "https://{tenantDomain}/my-org/v1".format(tenantDomain=_tenant_domain)
self._client_wrapper = AsyncClientWrapper(
base_url=_get_base_url(base_url=base_url, environment=environment),
token=token,
diff --git a/src/auth0/myorganization/environment.py b/src/auth0/myorganization/environment.py
index e7c6f18..f249107 100644
--- a/src/auth0/myorganization/environment.py
+++ b/src/auth0/myorganization/environment.py
@@ -4,4 +4,4 @@
class Auth0Environment(enum.Enum):
- DEFAULT = "https://%7BTENANT%7D.auth0.com/my-org"
+ DEFAULT = "https://%7BTENANT%7D.auth0.com/my-org/v1"
diff --git a/src/auth0/myorganization/organization/__init__.py b/src/auth0/myorganization/organization/__init__.py
index b543c1d..acd9d53 100644
--- a/src/auth0/myorganization/organization/__init__.py
+++ b/src/auth0/myorganization/organization/__init__.py
@@ -6,11 +6,15 @@
from importlib import import_module
if typing.TYPE_CHECKING:
- from . import configuration, domains, identity_providers
+ from . import configuration, domains, identity_providers, invitations, members, memberships, roles
_dynamic_imports: typing.Dict[str, str] = {
"configuration": ".configuration",
"domains": ".domains",
"identity_providers": ".identity_providers",
+ "invitations": ".invitations",
+ "members": ".members",
+ "memberships": ".memberships",
+ "roles": ".roles",
}
@@ -35,4 +39,4 @@ def __dir__():
return sorted(lazy_attrs)
-__all__ = ["configuration", "domains", "identity_providers"]
+__all__ = ["configuration", "domains", "identity_providers", "invitations", "members", "memberships", "roles"]
diff --git a/src/auth0/myorganization/organization/client.py b/src/auth0/myorganization/organization/client.py
index 679155a..7711a7b 100644
--- a/src/auth0/myorganization/organization/client.py
+++ b/src/auth0/myorganization/organization/client.py
@@ -11,6 +11,10 @@
from .configuration.client import AsyncConfigurationClient, ConfigurationClient
from .domains.client import AsyncDomainsClient, DomainsClient
from .identity_providers.client import AsyncIdentityProvidersClient, IdentityProvidersClient
+ from .invitations.client import AsyncInvitationsClient, InvitationsClient
+ from .members.client import AsyncMembersClient, MembersClient
+ from .memberships.client import AsyncMembershipsClient, MembershipsClient
+ from .roles.client import AsyncRolesClient, RolesClient
class OrganizationClient:
@@ -20,6 +24,10 @@ def __init__(self, *, client_wrapper: SyncClientWrapper):
self._configuration: typing.Optional[ConfigurationClient] = None
self._domains: typing.Optional[DomainsClient] = None
self._identity_providers: typing.Optional[IdentityProvidersClient] = None
+ self._members: typing.Optional[MembersClient] = None
+ self._memberships: typing.Optional[MembershipsClient] = None
+ self._invitations: typing.Optional[InvitationsClient] = None
+ self._roles: typing.Optional[RolesClient] = None
@property
def with_raw_response(self) -> RawOrganizationClient:
@@ -56,6 +64,38 @@ def identity_providers(self):
self._identity_providers = IdentityProvidersClient(client_wrapper=self._client_wrapper)
return self._identity_providers
+ @property
+ def members(self):
+ if self._members is None:
+ from .members.client import MembersClient # noqa: E402
+
+ self._members = MembersClient(client_wrapper=self._client_wrapper)
+ return self._members
+
+ @property
+ def memberships(self):
+ if self._memberships is None:
+ from .memberships.client import MembershipsClient # noqa: E402
+
+ self._memberships = MembershipsClient(client_wrapper=self._client_wrapper)
+ return self._memberships
+
+ @property
+ def invitations(self):
+ if self._invitations is None:
+ from .invitations.client import InvitationsClient # noqa: E402
+
+ self._invitations = InvitationsClient(client_wrapper=self._client_wrapper)
+ return self._invitations
+
+ @property
+ def roles(self):
+ if self._roles is None:
+ from .roles.client import RolesClient # noqa: E402
+
+ self._roles = RolesClient(client_wrapper=self._client_wrapper)
+ return self._roles
+
class AsyncOrganizationClient:
def __init__(self, *, client_wrapper: AsyncClientWrapper):
@@ -64,6 +104,10 @@ def __init__(self, *, client_wrapper: AsyncClientWrapper):
self._configuration: typing.Optional[AsyncConfigurationClient] = None
self._domains: typing.Optional[AsyncDomainsClient] = None
self._identity_providers: typing.Optional[AsyncIdentityProvidersClient] = None
+ self._members: typing.Optional[AsyncMembersClient] = None
+ self._memberships: typing.Optional[AsyncMembershipsClient] = None
+ self._invitations: typing.Optional[AsyncInvitationsClient] = None
+ self._roles: typing.Optional[AsyncRolesClient] = None
@property
def with_raw_response(self) -> AsyncRawOrganizationClient:
@@ -99,3 +143,35 @@ def identity_providers(self):
self._identity_providers = AsyncIdentityProvidersClient(client_wrapper=self._client_wrapper)
return self._identity_providers
+
+ @property
+ def members(self):
+ if self._members is None:
+ from .members.client import AsyncMembersClient # noqa: E402
+
+ self._members = AsyncMembersClient(client_wrapper=self._client_wrapper)
+ return self._members
+
+ @property
+ def memberships(self):
+ if self._memberships is None:
+ from .memberships.client import AsyncMembershipsClient # noqa: E402
+
+ self._memberships = AsyncMembershipsClient(client_wrapper=self._client_wrapper)
+ return self._memberships
+
+ @property
+ def invitations(self):
+ if self._invitations is None:
+ from .invitations.client import AsyncInvitationsClient # noqa: E402
+
+ self._invitations = AsyncInvitationsClient(client_wrapper=self._client_wrapper)
+ return self._invitations
+
+ @property
+ def roles(self):
+ if self._roles is None:
+ from .roles.client import AsyncRolesClient # noqa: E402
+
+ self._roles = AsyncRolesClient(client_wrapper=self._client_wrapper)
+ return self._roles
diff --git a/src/auth0/myorganization/organization/identity_providers/provisioning/raw_client.py b/src/auth0/myorganization/organization/identity_providers/provisioning/raw_client.py
index 1c183e1..3a2c500 100644
--- a/src/auth0/myorganization/organization/identity_providers/provisioning/raw_client.py
+++ b/src/auth0/myorganization/organization/identity_providers/provisioning/raw_client.py
@@ -338,9 +338,6 @@ def update_attributes(
f"identity-providers/{encode_path_param(idp_id)}/provisioning/update-attributes",
method="PUT",
json=request,
- headers={
- "content-type": "application/json",
- },
request_options=request_options,
omit=OMIT,
)
@@ -734,9 +731,6 @@ async def update_attributes(
f"identity-providers/{encode_path_param(idp_id)}/provisioning/update-attributes",
method="PUT",
json=request,
- headers={
- "content-type": "application/json",
- },
request_options=request_options,
omit=OMIT,
)
diff --git a/src/auth0/myorganization/organization/identity_providers/raw_client.py b/src/auth0/myorganization/organization/identity_providers/raw_client.py
index f442220..e80a140 100644
--- a/src/auth0/myorganization/organization/identity_providers/raw_client.py
+++ b/src/auth0/myorganization/organization/identity_providers/raw_client.py
@@ -143,9 +143,6 @@ def create(
json=convert_and_respect_annotation_metadata(
object_=request, annotation=CreateIdentityProviderRequestContent, direction="write"
),
- headers={
- "content-type": "application/json",
- },
request_options=request_options,
omit=OMIT,
)
@@ -448,9 +445,6 @@ def update(
json=convert_and_respect_annotation_metadata(
object_=request, annotation=UpdateIdentityProviderRequestContent, direction="write"
),
- headers={
- "content-type": "application/json",
- },
request_options=request_options,
omit=OMIT,
)
@@ -556,9 +550,6 @@ def update_attributes(
f"identity-providers/{encode_path_param(idp_id)}/update-attributes",
method="PUT",
json=request,
- headers={
- "content-type": "application/json",
- },
request_options=request_options,
omit=OMIT,
)
@@ -836,9 +827,6 @@ async def create(
json=convert_and_respect_annotation_metadata(
object_=request, annotation=CreateIdentityProviderRequestContent, direction="write"
),
- headers={
- "content-type": "application/json",
- },
request_options=request_options,
omit=OMIT,
)
@@ -1143,9 +1131,6 @@ async def update(
json=convert_and_respect_annotation_metadata(
object_=request, annotation=UpdateIdentityProviderRequestContent, direction="write"
),
- headers={
- "content-type": "application/json",
- },
request_options=request_options,
omit=OMIT,
)
@@ -1251,9 +1236,6 @@ async def update_attributes(
f"identity-providers/{encode_path_param(idp_id)}/update-attributes",
method="PUT",
json=request,
- headers={
- "content-type": "application/json",
- },
request_options=request_options,
omit=OMIT,
)
diff --git a/src/auth0/myorganization/organization/invitations/__init__.py b/src/auth0/myorganization/organization/invitations/__init__.py
new file mode 100644
index 0000000..5cde020
--- /dev/null
+++ b/src/auth0/myorganization/organization/invitations/__init__.py
@@ -0,0 +1,4 @@
+# This file was auto-generated by Fern from our API Definition.
+
+# isort: skip_file
+
diff --git a/src/auth0/myorganization/organization/invitations/client.py b/src/auth0/myorganization/organization/invitations/client.py
new file mode 100644
index 0000000..5580e0e
--- /dev/null
+++ b/src/auth0/myorganization/organization/invitations/client.py
@@ -0,0 +1,507 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+from ...core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
+from ...core.pagination import AsyncPager, SyncPager
+from ...core.request_options import RequestOptions
+from ...types.create_member_invitation_invitee import CreateMemberInvitationInvitee
+from ...types.create_member_invitation_response_content import CreateMemberInvitationResponseContent
+from ...types.get_member_invitation_response_content import GetMemberInvitationResponseContent
+from ...types.invitation_id import InvitationId
+from ...types.list_members_invitations_response_content import ListMembersInvitationsResponseContent
+from ...types.member_invitation import MemberInvitation
+from ...types.member_invitation_inviter import MemberInvitationInviter
+from .raw_client import AsyncRawInvitationsClient, RawInvitationsClient
+
+# this is used as the default value for optional parameters
+OMIT = typing.cast(typing.Any, ...)
+
+
+class InvitationsClient:
+ def __init__(self, *, client_wrapper: SyncClientWrapper):
+ self._raw_client = RawInvitationsClient(client_wrapper=client_wrapper)
+
+ @property
+ def with_raw_response(self) -> RawInvitationsClient:
+ """
+ Retrieves a raw implementation of this client that returns raw responses.
+
+ Returns
+ -------
+ RawInvitationsClient
+ """
+ return self._raw_client
+
+ def list(
+ self,
+ *,
+ fields: typing.Optional[str] = None,
+ include_fields: typing.Optional[bool] = True,
+ from_: typing.Optional[str] = None,
+ take: typing.Optional[int] = 50,
+ sort: typing.Optional[str] = "created_at:-1",
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> SyncPager[MemberInvitation, ListMembersInvitationsResponseContent]:
+ """
+ Retrieve a list of all member invitations for this Organization.
+
+ Parameters
+ ----------
+ fields : typing.Optional[str]
+ Comma-separated list of fields to include or exclude (based on value provided for include_fields) in the result. Leave empty to retrieve all fields. Note: you cannot filter on ticket_id and this value will only be returned when fields are not filtered.
+
+ include_fields : typing.Optional[bool]
+ Whether specified fields are to be included (true) or excluded (false). Defaults to true
+
+ from_ : typing.Optional[str]
+ An optional cursor from which to start the selection (exclusive).
+
+ take : typing.Optional[int]
+ Number of results per page. Defaults to 50.
+
+ sort : typing.Optional[str]
+ Field to sort by. Use field:order where order is 1 for ascending and -1 for descending. Defaults to created_at:-1
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ SyncPager[MemberInvitation, ListMembersInvitationsResponseContent]
+ List Members Invitations for an Organization.
+
+ Examples
+ --------
+ from auth0 import Auth0
+
+ client = Auth0(
+ token="YOUR_TOKEN",
+ )
+ response = client.organization.invitations.list(
+ fields="fields",
+ include_fields=True,
+ from_="from",
+ take=1,
+ sort="sort",
+ )
+ for item in response:
+ yield item
+ # alternatively, you can paginate page-by-page
+ for page in response.iter_pages():
+ yield page
+ """
+ return self._raw_client.list(
+ fields=fields,
+ include_fields=include_fields,
+ from_=from_,
+ take=take,
+ sort=sort,
+ request_options=request_options,
+ )
+
+ def create(
+ self,
+ *,
+ invitees: typing.Sequence[CreateMemberInvitationInvitee],
+ auth_0_custom_domain: typing.Optional[str] = None,
+ inviter: typing.Optional[MemberInvitationInviter] = OMIT,
+ identity_provider_id: typing.Optional[str] = OMIT,
+ ttl_sec: typing.Optional[int] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> CreateMemberInvitationResponseContent:
+ """
+ Create one or more member invitations for this Organization. If an active invitation already exists for a user, generating a new invitation will automatically revoke any outstanding invitations for that user. Roles specified in the payload will be granted to the user upon acceptance of the invitation.
+
+ Parameters
+ ----------
+ invitees : typing.Sequence[CreateMemberInvitationInvitee]
+
+ auth_0_custom_domain : typing.Optional[str]
+
+ inviter : typing.Optional[MemberInvitationInviter]
+
+ identity_provider_id : typing.Optional[str]
+ Identity provider identifier.
+
+ ttl_sec : typing.Optional[int]
+ Number of seconds for which the invitation is valid before expiration. If unspecified or set to 0, this value defaults to 604800 seconds (7 days). Max value: 2592000 seconds (30 days).
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ CreateMemberInvitationResponseContent
+ Create Member Invitations for an Organization.
+
+ Examples
+ --------
+ from auth0 import Auth0, CreateMemberInvitationInvitee, MemberInvitationInviter
+
+ client = Auth0(
+ token="YOUR_TOKEN",
+ )
+ client.organization.invitations.create(
+ invitees=[
+ CreateMemberInvitationInvitee(
+ email="user@example.com",
+ roles=["rol_0000000000000001"],
+ )
+ ],
+ inviter=MemberInvitationInviter(
+ name="Allison the Admin",
+ ),
+ identity_provider_id="con_2CZPv6IY0gWzDaQJ",
+ ttl_sec=3600,
+ )
+ """
+ _response = self._raw_client.create(
+ invitees=invitees,
+ auth_0_custom_domain=auth_0_custom_domain,
+ inviter=inviter,
+ identity_provider_id=identity_provider_id,
+ ttl_sec=ttl_sec,
+ request_options=request_options,
+ )
+ return _response.data
+
+ def get(
+ self,
+ invitation_id: InvitationId,
+ *,
+ fields: typing.Optional[str] = None,
+ include_fields: typing.Optional[bool] = True,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> GetMemberInvitationResponseContent:
+ """
+ Retrieve details of a member invitation specified by ID for this Organization.
+
+ Parameters
+ ----------
+ invitation_id : InvitationId
+
+ fields : typing.Optional[str]
+ Comma-separated list of fields to include or exclude (based on value provided for include_fields) in the result. Leave empty to retrieve all fields. Note: you cannot filter on ticket_id and this value will only be returned when fields are not filtered.
+
+ include_fields : typing.Optional[bool]
+ Whether specified fields are to be included (true) or excluded (false). Defaults to true
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ GetMemberInvitationResponseContent
+ Get Member Invitation for an Organization by Id.
+
+ Examples
+ --------
+ from auth0 import Auth0
+
+ client = Auth0(
+ token="YOUR_TOKEN",
+ )
+ client.organization.invitations.get(
+ invitation_id="invitation_id",
+ fields="fields",
+ include_fields=True,
+ )
+ """
+ _response = self._raw_client.get(
+ invitation_id, fields=fields, include_fields=include_fields, request_options=request_options
+ )
+ return _response.data
+
+ def delete(self, invitation_id: InvitationId, *, request_options: typing.Optional[RequestOptions] = None) -> None:
+ """
+ Revoke a member invitation specified by ID for this Organization.
+
+ Parameters
+ ----------
+ invitation_id : InvitationId
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ None
+
+ Examples
+ --------
+ from auth0 import Auth0
+
+ client = Auth0(
+ token="YOUR_TOKEN",
+ )
+ client.organization.invitations.delete(
+ invitation_id="invitation_id",
+ )
+ """
+ _response = self._raw_client.delete(invitation_id, request_options=request_options)
+ return _response.data
+
+
+class AsyncInvitationsClient:
+ def __init__(self, *, client_wrapper: AsyncClientWrapper):
+ self._raw_client = AsyncRawInvitationsClient(client_wrapper=client_wrapper)
+
+ @property
+ def with_raw_response(self) -> AsyncRawInvitationsClient:
+ """
+ Retrieves a raw implementation of this client that returns raw responses.
+
+ Returns
+ -------
+ AsyncRawInvitationsClient
+ """
+ return self._raw_client
+
+ async def list(
+ self,
+ *,
+ fields: typing.Optional[str] = None,
+ include_fields: typing.Optional[bool] = True,
+ from_: typing.Optional[str] = None,
+ take: typing.Optional[int] = 50,
+ sort: typing.Optional[str] = "created_at:-1",
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> AsyncPager[MemberInvitation, ListMembersInvitationsResponseContent]:
+ """
+ Retrieve a list of all member invitations for this Organization.
+
+ Parameters
+ ----------
+ fields : typing.Optional[str]
+ Comma-separated list of fields to include or exclude (based on value provided for include_fields) in the result. Leave empty to retrieve all fields. Note: you cannot filter on ticket_id and this value will only be returned when fields are not filtered.
+
+ include_fields : typing.Optional[bool]
+ Whether specified fields are to be included (true) or excluded (false). Defaults to true
+
+ from_ : typing.Optional[str]
+ An optional cursor from which to start the selection (exclusive).
+
+ take : typing.Optional[int]
+ Number of results per page. Defaults to 50.
+
+ sort : typing.Optional[str]
+ Field to sort by. Use field:order where order is 1 for ascending and -1 for descending. Defaults to created_at:-1
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncPager[MemberInvitation, ListMembersInvitationsResponseContent]
+ List Members Invitations for an Organization.
+
+ Examples
+ --------
+ import asyncio
+
+ from auth0 import AsyncAuth0
+
+ client = AsyncAuth0(
+ token="YOUR_TOKEN",
+ )
+
+
+ async def main() -> None:
+ response = await client.organization.invitations.list(
+ fields="fields",
+ include_fields=True,
+ from_="from",
+ take=1,
+ sort="sort",
+ )
+ async for item in response:
+ yield item
+
+ # alternatively, you can paginate page-by-page
+ async for page in response.iter_pages():
+ yield page
+
+
+ asyncio.run(main())
+ """
+ return await self._raw_client.list(
+ fields=fields,
+ include_fields=include_fields,
+ from_=from_,
+ take=take,
+ sort=sort,
+ request_options=request_options,
+ )
+
+ async def create(
+ self,
+ *,
+ invitees: typing.Sequence[CreateMemberInvitationInvitee],
+ auth_0_custom_domain: typing.Optional[str] = None,
+ inviter: typing.Optional[MemberInvitationInviter] = OMIT,
+ identity_provider_id: typing.Optional[str] = OMIT,
+ ttl_sec: typing.Optional[int] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> CreateMemberInvitationResponseContent:
+ """
+ Create one or more member invitations for this Organization. If an active invitation already exists for a user, generating a new invitation will automatically revoke any outstanding invitations for that user. Roles specified in the payload will be granted to the user upon acceptance of the invitation.
+
+ Parameters
+ ----------
+ invitees : typing.Sequence[CreateMemberInvitationInvitee]
+
+ auth_0_custom_domain : typing.Optional[str]
+
+ inviter : typing.Optional[MemberInvitationInviter]
+
+ identity_provider_id : typing.Optional[str]
+ Identity provider identifier.
+
+ ttl_sec : typing.Optional[int]
+ Number of seconds for which the invitation is valid before expiration. If unspecified or set to 0, this value defaults to 604800 seconds (7 days). Max value: 2592000 seconds (30 days).
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ CreateMemberInvitationResponseContent
+ Create Member Invitations for an Organization.
+
+ Examples
+ --------
+ import asyncio
+
+ from auth0 import (
+ AsyncAuth0,
+ CreateMemberInvitationInvitee,
+ MemberInvitationInviter,
+ )
+
+ client = AsyncAuth0(
+ token="YOUR_TOKEN",
+ )
+
+
+ async def main() -> None:
+ await client.organization.invitations.create(
+ invitees=[
+ CreateMemberInvitationInvitee(
+ email="user@example.com",
+ roles=["rol_0000000000000001"],
+ )
+ ],
+ inviter=MemberInvitationInviter(
+ name="Allison the Admin",
+ ),
+ identity_provider_id="con_2CZPv6IY0gWzDaQJ",
+ ttl_sec=3600,
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.create(
+ invitees=invitees,
+ auth_0_custom_domain=auth_0_custom_domain,
+ inviter=inviter,
+ identity_provider_id=identity_provider_id,
+ ttl_sec=ttl_sec,
+ request_options=request_options,
+ )
+ return _response.data
+
+ async def get(
+ self,
+ invitation_id: InvitationId,
+ *,
+ fields: typing.Optional[str] = None,
+ include_fields: typing.Optional[bool] = True,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> GetMemberInvitationResponseContent:
+ """
+ Retrieve details of a member invitation specified by ID for this Organization.
+
+ Parameters
+ ----------
+ invitation_id : InvitationId
+
+ fields : typing.Optional[str]
+ Comma-separated list of fields to include or exclude (based on value provided for include_fields) in the result. Leave empty to retrieve all fields. Note: you cannot filter on ticket_id and this value will only be returned when fields are not filtered.
+
+ include_fields : typing.Optional[bool]
+ Whether specified fields are to be included (true) or excluded (false). Defaults to true
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ GetMemberInvitationResponseContent
+ Get Member Invitation for an Organization by Id.
+
+ Examples
+ --------
+ import asyncio
+
+ from auth0 import AsyncAuth0
+
+ client = AsyncAuth0(
+ token="YOUR_TOKEN",
+ )
+
+
+ async def main() -> None:
+ await client.organization.invitations.get(
+ invitation_id="invitation_id",
+ fields="fields",
+ include_fields=True,
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.get(
+ invitation_id, fields=fields, include_fields=include_fields, request_options=request_options
+ )
+ return _response.data
+
+ async def delete(
+ self, invitation_id: InvitationId, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> None:
+ """
+ Revoke a member invitation specified by ID for this Organization.
+
+ Parameters
+ ----------
+ invitation_id : InvitationId
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ None
+
+ Examples
+ --------
+ import asyncio
+
+ from auth0 import AsyncAuth0
+
+ client = AsyncAuth0(
+ token="YOUR_TOKEN",
+ )
+
+
+ async def main() -> None:
+ await client.organization.invitations.delete(
+ invitation_id="invitation_id",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.delete(invitation_id, request_options=request_options)
+ return _response.data
diff --git a/src/auth0/myorganization/organization/invitations/raw_client.py b/src/auth0/myorganization/organization/invitations/raw_client.py
new file mode 100644
index 0000000..e8ec9d7
--- /dev/null
+++ b/src/auth0/myorganization/organization/invitations/raw_client.py
@@ -0,0 +1,974 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+from json.decoder import JSONDecodeError
+
+from ...core.api_error import ApiError
+from ...core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
+from ...core.http_response import AsyncHttpResponse, HttpResponse
+from ...core.jsonable_encoder import encode_path_param
+from ...core.pagination import AsyncPager, SyncPager
+from ...core.parse_error import ParsingError
+from ...core.pydantic_utilities import parse_obj_as
+from ...core.request_options import RequestOptions
+from ...core.serialization import convert_and_respect_annotation_metadata
+from ...errors.bad_request_error import BadRequestError
+from ...errors.forbidden_error import ForbiddenError
+from ...errors.not_found_error import NotFoundError
+from ...errors.too_many_requests_error import TooManyRequestsError
+from ...errors.unauthorized_error import UnauthorizedError
+from ...types.create_member_invitation_invitee import CreateMemberInvitationInvitee
+from ...types.create_member_invitation_response_content import CreateMemberInvitationResponseContent
+from ...types.error_response_content import ErrorResponseContent
+from ...types.get_member_invitation_response_content import GetMemberInvitationResponseContent
+from ...types.invitation_id import InvitationId
+from ...types.list_members_invitations_response_content import ListMembersInvitationsResponseContent
+from ...types.member_invitation import MemberInvitation
+from ...types.member_invitation_inviter import MemberInvitationInviter
+from pydantic import ValidationError
+
+# this is used as the default value for optional parameters
+OMIT = typing.cast(typing.Any, ...)
+
+
+class RawInvitationsClient:
+ def __init__(self, *, client_wrapper: SyncClientWrapper):
+ self._client_wrapper = client_wrapper
+
+ def list(
+ self,
+ *,
+ fields: typing.Optional[str] = None,
+ include_fields: typing.Optional[bool] = True,
+ from_: typing.Optional[str] = None,
+ take: typing.Optional[int] = 50,
+ sort: typing.Optional[str] = "created_at:-1",
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> SyncPager[MemberInvitation, ListMembersInvitationsResponseContent]:
+ """
+ Retrieve a list of all member invitations for this Organization.
+
+ Parameters
+ ----------
+ fields : typing.Optional[str]
+ Comma-separated list of fields to include or exclude (based on value provided for include_fields) in the result. Leave empty to retrieve all fields. Note: you cannot filter on ticket_id and this value will only be returned when fields are not filtered.
+
+ include_fields : typing.Optional[bool]
+ Whether specified fields are to be included (true) or excluded (false). Defaults to true
+
+ from_ : typing.Optional[str]
+ An optional cursor from which to start the selection (exclusive).
+
+ take : typing.Optional[int]
+ Number of results per page. Defaults to 50.
+
+ sort : typing.Optional[str]
+ Field to sort by. Use field:order where order is 1 for ascending and -1 for descending. Defaults to created_at:-1
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ SyncPager[MemberInvitation, ListMembersInvitationsResponseContent]
+ List Members Invitations for an Organization.
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ "member-invitations",
+ method="GET",
+ params={
+ "fields": fields,
+ "include_fields": include_fields,
+ "from": from_,
+ "take": take,
+ "sort": sort,
+ },
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _parsed_response = typing.cast(
+ ListMembersInvitationsResponseContent,
+ parse_obj_as(
+ type_=ListMembersInvitationsResponseContent, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ _items = _parsed_response.invitations
+ _parsed_next = _parsed_response.next
+ _has_next = _parsed_next is not None and _parsed_next != ""
+ _get_next = lambda: self.list(
+ fields=fields,
+ include_fields=include_fields,
+ from_=_parsed_next,
+ take=take,
+ sort=sort,
+ request_options=request_options,
+ )
+ return SyncPager(has_next=_has_next, items=_items, get_next=_get_next, response=_parsed_response)
+ if _response.status_code == 400:
+ raise BadRequestError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 401:
+ raise UnauthorizedError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ ErrorResponseContent,
+ parse_obj_as(
+ type_=ErrorResponseContent, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 403:
+ raise ForbiddenError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ ErrorResponseContent,
+ parse_obj_as(
+ type_=ErrorResponseContent, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 404:
+ raise NotFoundError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ ErrorResponseContent,
+ parse_obj_as(
+ type_=ErrorResponseContent, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 429:
+ raise TooManyRequestsError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ ErrorResponseContent,
+ parse_obj_as(
+ type_=ErrorResponseContent, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def create(
+ self,
+ *,
+ invitees: typing.Sequence[CreateMemberInvitationInvitee],
+ auth_0_custom_domain: typing.Optional[str] = None,
+ inviter: typing.Optional[MemberInvitationInviter] = OMIT,
+ identity_provider_id: typing.Optional[str] = OMIT,
+ ttl_sec: typing.Optional[int] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> HttpResponse[CreateMemberInvitationResponseContent]:
+ """
+ Create one or more member invitations for this Organization. If an active invitation already exists for a user, generating a new invitation will automatically revoke any outstanding invitations for that user. Roles specified in the payload will be granted to the user upon acceptance of the invitation.
+
+ Parameters
+ ----------
+ invitees : typing.Sequence[CreateMemberInvitationInvitee]
+
+ auth_0_custom_domain : typing.Optional[str]
+
+ inviter : typing.Optional[MemberInvitationInviter]
+
+ identity_provider_id : typing.Optional[str]
+ Identity provider identifier.
+
+ ttl_sec : typing.Optional[int]
+ Number of seconds for which the invitation is valid before expiration. If unspecified or set to 0, this value defaults to 604800 seconds (7 days). Max value: 2592000 seconds (30 days).
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[CreateMemberInvitationResponseContent]
+ Create Member Invitations for an Organization.
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ "member-invitations",
+ method="POST",
+ json={
+ "invitees": convert_and_respect_annotation_metadata(
+ object_=invitees, annotation=typing.Sequence[CreateMemberInvitationInvitee], direction="write"
+ ),
+ "inviter": convert_and_respect_annotation_metadata(
+ object_=inviter, annotation=MemberInvitationInviter, direction="write"
+ ),
+ "identity_provider_id": identity_provider_id,
+ "ttl_sec": ttl_sec,
+ },
+ headers={
+ "content-type": "application/json",
+ "auth0-custom-domain": str(auth_0_custom_domain) if auth_0_custom_domain is not None else None,
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ CreateMemberInvitationResponseContent,
+ parse_obj_as(
+ type_=CreateMemberInvitationResponseContent, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 400:
+ raise BadRequestError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 401:
+ raise UnauthorizedError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ ErrorResponseContent,
+ parse_obj_as(
+ type_=ErrorResponseContent, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 403:
+ raise ForbiddenError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ ErrorResponseContent,
+ parse_obj_as(
+ type_=ErrorResponseContent, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 404:
+ raise NotFoundError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ ErrorResponseContent,
+ parse_obj_as(
+ type_=ErrorResponseContent, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 429:
+ raise TooManyRequestsError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ ErrorResponseContent,
+ parse_obj_as(
+ type_=ErrorResponseContent, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def get(
+ self,
+ invitation_id: InvitationId,
+ *,
+ fields: typing.Optional[str] = None,
+ include_fields: typing.Optional[bool] = True,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> HttpResponse[GetMemberInvitationResponseContent]:
+ """
+ Retrieve details of a member invitation specified by ID for this Organization.
+
+ Parameters
+ ----------
+ invitation_id : InvitationId
+
+ fields : typing.Optional[str]
+ Comma-separated list of fields to include or exclude (based on value provided for include_fields) in the result. Leave empty to retrieve all fields. Note: you cannot filter on ticket_id and this value will only be returned when fields are not filtered.
+
+ include_fields : typing.Optional[bool]
+ Whether specified fields are to be included (true) or excluded (false). Defaults to true
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[GetMemberInvitationResponseContent]
+ Get Member Invitation for an Organization by Id.
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"member-invitations/{encode_path_param(invitation_id)}",
+ method="GET",
+ params={
+ "fields": fields,
+ "include_fields": include_fields,
+ },
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ GetMemberInvitationResponseContent,
+ parse_obj_as(
+ type_=GetMemberInvitationResponseContent, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 400:
+ raise BadRequestError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 401:
+ raise UnauthorizedError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ ErrorResponseContent,
+ parse_obj_as(
+ type_=ErrorResponseContent, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 403:
+ raise ForbiddenError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ ErrorResponseContent,
+ parse_obj_as(
+ type_=ErrorResponseContent, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 404:
+ raise NotFoundError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ ErrorResponseContent,
+ parse_obj_as(
+ type_=ErrorResponseContent, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 429:
+ raise TooManyRequestsError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ ErrorResponseContent,
+ parse_obj_as(
+ type_=ErrorResponseContent, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def delete(
+ self, invitation_id: InvitationId, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> HttpResponse[None]:
+ """
+ Revoke a member invitation specified by ID for this Organization.
+
+ Parameters
+ ----------
+ invitation_id : InvitationId
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[None]
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"member-invitations/{encode_path_param(invitation_id)}",
+ method="DELETE",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ return HttpResponse(response=_response, data=None)
+ if _response.status_code == 400:
+ raise BadRequestError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 401:
+ raise UnauthorizedError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ ErrorResponseContent,
+ parse_obj_as(
+ type_=ErrorResponseContent, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 403:
+ raise ForbiddenError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ ErrorResponseContent,
+ parse_obj_as(
+ type_=ErrorResponseContent, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 404:
+ raise NotFoundError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ ErrorResponseContent,
+ parse_obj_as(
+ type_=ErrorResponseContent, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 429:
+ raise TooManyRequestsError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ ErrorResponseContent,
+ parse_obj_as(
+ type_=ErrorResponseContent, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+
+class AsyncRawInvitationsClient:
+ def __init__(self, *, client_wrapper: AsyncClientWrapper):
+ self._client_wrapper = client_wrapper
+
+ async def list(
+ self,
+ *,
+ fields: typing.Optional[str] = None,
+ include_fields: typing.Optional[bool] = True,
+ from_: typing.Optional[str] = None,
+ take: typing.Optional[int] = 50,
+ sort: typing.Optional[str] = "created_at:-1",
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> AsyncPager[MemberInvitation, ListMembersInvitationsResponseContent]:
+ """
+ Retrieve a list of all member invitations for this Organization.
+
+ Parameters
+ ----------
+ fields : typing.Optional[str]
+ Comma-separated list of fields to include or exclude (based on value provided for include_fields) in the result. Leave empty to retrieve all fields. Note: you cannot filter on ticket_id and this value will only be returned when fields are not filtered.
+
+ include_fields : typing.Optional[bool]
+ Whether specified fields are to be included (true) or excluded (false). Defaults to true
+
+ from_ : typing.Optional[str]
+ An optional cursor from which to start the selection (exclusive).
+
+ take : typing.Optional[int]
+ Number of results per page. Defaults to 50.
+
+ sort : typing.Optional[str]
+ Field to sort by. Use field:order where order is 1 for ascending and -1 for descending. Defaults to created_at:-1
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncPager[MemberInvitation, ListMembersInvitationsResponseContent]
+ List Members Invitations for an Organization.
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ "member-invitations",
+ method="GET",
+ params={
+ "fields": fields,
+ "include_fields": include_fields,
+ "from": from_,
+ "take": take,
+ "sort": sort,
+ },
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _parsed_response = typing.cast(
+ ListMembersInvitationsResponseContent,
+ parse_obj_as(
+ type_=ListMembersInvitationsResponseContent, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ _items = _parsed_response.invitations
+ _parsed_next = _parsed_response.next
+ _has_next = _parsed_next is not None and _parsed_next != ""
+
+ async def _get_next():
+ return await self.list(
+ fields=fields,
+ include_fields=include_fields,
+ from_=_parsed_next,
+ take=take,
+ sort=sort,
+ request_options=request_options,
+ )
+
+ return AsyncPager(has_next=_has_next, items=_items, get_next=_get_next, response=_parsed_response)
+ if _response.status_code == 400:
+ raise BadRequestError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 401:
+ raise UnauthorizedError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ ErrorResponseContent,
+ parse_obj_as(
+ type_=ErrorResponseContent, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 403:
+ raise ForbiddenError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ ErrorResponseContent,
+ parse_obj_as(
+ type_=ErrorResponseContent, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 404:
+ raise NotFoundError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ ErrorResponseContent,
+ parse_obj_as(
+ type_=ErrorResponseContent, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 429:
+ raise TooManyRequestsError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ ErrorResponseContent,
+ parse_obj_as(
+ type_=ErrorResponseContent, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def create(
+ self,
+ *,
+ invitees: typing.Sequence[CreateMemberInvitationInvitee],
+ auth_0_custom_domain: typing.Optional[str] = None,
+ inviter: typing.Optional[MemberInvitationInviter] = OMIT,
+ identity_provider_id: typing.Optional[str] = OMIT,
+ ttl_sec: typing.Optional[int] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> AsyncHttpResponse[CreateMemberInvitationResponseContent]:
+ """
+ Create one or more member invitations for this Organization. If an active invitation already exists for a user, generating a new invitation will automatically revoke any outstanding invitations for that user. Roles specified in the payload will be granted to the user upon acceptance of the invitation.
+
+ Parameters
+ ----------
+ invitees : typing.Sequence[CreateMemberInvitationInvitee]
+
+ auth_0_custom_domain : typing.Optional[str]
+
+ inviter : typing.Optional[MemberInvitationInviter]
+
+ identity_provider_id : typing.Optional[str]
+ Identity provider identifier.
+
+ ttl_sec : typing.Optional[int]
+ Number of seconds for which the invitation is valid before expiration. If unspecified or set to 0, this value defaults to 604800 seconds (7 days). Max value: 2592000 seconds (30 days).
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[CreateMemberInvitationResponseContent]
+ Create Member Invitations for an Organization.
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ "member-invitations",
+ method="POST",
+ json={
+ "invitees": convert_and_respect_annotation_metadata(
+ object_=invitees, annotation=typing.Sequence[CreateMemberInvitationInvitee], direction="write"
+ ),
+ "inviter": convert_and_respect_annotation_metadata(
+ object_=inviter, annotation=MemberInvitationInviter, direction="write"
+ ),
+ "identity_provider_id": identity_provider_id,
+ "ttl_sec": ttl_sec,
+ },
+ headers={
+ "content-type": "application/json",
+ "auth0-custom-domain": str(auth_0_custom_domain) if auth_0_custom_domain is not None else None,
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ CreateMemberInvitationResponseContent,
+ parse_obj_as(
+ type_=CreateMemberInvitationResponseContent, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 400:
+ raise BadRequestError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 401:
+ raise UnauthorizedError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ ErrorResponseContent,
+ parse_obj_as(
+ type_=ErrorResponseContent, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 403:
+ raise ForbiddenError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ ErrorResponseContent,
+ parse_obj_as(
+ type_=ErrorResponseContent, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 404:
+ raise NotFoundError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ ErrorResponseContent,
+ parse_obj_as(
+ type_=ErrorResponseContent, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 429:
+ raise TooManyRequestsError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ ErrorResponseContent,
+ parse_obj_as(
+ type_=ErrorResponseContent, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def get(
+ self,
+ invitation_id: InvitationId,
+ *,
+ fields: typing.Optional[str] = None,
+ include_fields: typing.Optional[bool] = True,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> AsyncHttpResponse[GetMemberInvitationResponseContent]:
+ """
+ Retrieve details of a member invitation specified by ID for this Organization.
+
+ Parameters
+ ----------
+ invitation_id : InvitationId
+
+ fields : typing.Optional[str]
+ Comma-separated list of fields to include or exclude (based on value provided for include_fields) in the result. Leave empty to retrieve all fields. Note: you cannot filter on ticket_id and this value will only be returned when fields are not filtered.
+
+ include_fields : typing.Optional[bool]
+ Whether specified fields are to be included (true) or excluded (false). Defaults to true
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[GetMemberInvitationResponseContent]
+ Get Member Invitation for an Organization by Id.
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"member-invitations/{encode_path_param(invitation_id)}",
+ method="GET",
+ params={
+ "fields": fields,
+ "include_fields": include_fields,
+ },
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ GetMemberInvitationResponseContent,
+ parse_obj_as(
+ type_=GetMemberInvitationResponseContent, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 400:
+ raise BadRequestError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 401:
+ raise UnauthorizedError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ ErrorResponseContent,
+ parse_obj_as(
+ type_=ErrorResponseContent, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 403:
+ raise ForbiddenError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ ErrorResponseContent,
+ parse_obj_as(
+ type_=ErrorResponseContent, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 404:
+ raise NotFoundError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ ErrorResponseContent,
+ parse_obj_as(
+ type_=ErrorResponseContent, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 429:
+ raise TooManyRequestsError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ ErrorResponseContent,
+ parse_obj_as(
+ type_=ErrorResponseContent, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def delete(
+ self, invitation_id: InvitationId, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> AsyncHttpResponse[None]:
+ """
+ Revoke a member invitation specified by ID for this Organization.
+
+ Parameters
+ ----------
+ invitation_id : InvitationId
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[None]
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"member-invitations/{encode_path_param(invitation_id)}",
+ method="DELETE",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ return AsyncHttpResponse(response=_response, data=None)
+ if _response.status_code == 400:
+ raise BadRequestError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 401:
+ raise UnauthorizedError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ ErrorResponseContent,
+ parse_obj_as(
+ type_=ErrorResponseContent, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 403:
+ raise ForbiddenError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ ErrorResponseContent,
+ parse_obj_as(
+ type_=ErrorResponseContent, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 404:
+ raise NotFoundError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ ErrorResponseContent,
+ parse_obj_as(
+ type_=ErrorResponseContent, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 429:
+ raise TooManyRequestsError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ ErrorResponseContent,
+ parse_obj_as(
+ type_=ErrorResponseContent, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
diff --git a/src/auth0/myorganization/organization/members/__init__.py b/src/auth0/myorganization/organization/members/__init__.py
new file mode 100644
index 0000000..686aa75
--- /dev/null
+++ b/src/auth0/myorganization/organization/members/__init__.py
@@ -0,0 +1,34 @@
+# This file was auto-generated by Fern from our API Definition.
+
+# isort: skip_file
+
+import typing
+from importlib import import_module
+
+if typing.TYPE_CHECKING:
+ from . import roles
+_dynamic_imports: typing.Dict[str, str] = {"roles": ".roles"}
+
+
+def __getattr__(attr_name: str) -> typing.Any:
+ module_name = _dynamic_imports.get(attr_name)
+ if module_name is None:
+ raise AttributeError(f"No {attr_name} found in _dynamic_imports for module name -> {__name__}")
+ try:
+ module = import_module(module_name, __package__)
+ if module_name == f".{attr_name}":
+ return module
+ else:
+ return getattr(module, attr_name)
+ except ImportError as e:
+ raise ImportError(f"Failed to import {attr_name} from {module_name}: {e}") from e
+ except AttributeError as e:
+ raise AttributeError(f"Failed to get {attr_name} from {module_name}: {e}") from e
+
+
+def __dir__():
+ lazy_attrs = list(_dynamic_imports.keys())
+ return sorted(lazy_attrs)
+
+
+__all__ = ["roles"]
diff --git a/src/auth0/myorganization/organization/members/client.py b/src/auth0/myorganization/organization/members/client.py
new file mode 100644
index 0000000..99a588b
--- /dev/null
+++ b/src/auth0/myorganization/organization/members/client.py
@@ -0,0 +1,294 @@
+# This file was auto-generated by Fern from our API Definition.
+
+from __future__ import annotations
+
+import typing
+
+from ...core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
+from ...core.pagination import AsyncPager, SyncPager
+from ...core.request_options import RequestOptions
+from ...types.get_organization_member_response_content import GetOrganizationMemberResponseContent
+from ...types.list_organization_members_response_content import ListOrganizationMembersResponseContent
+from ...types.org_member import OrgMember
+from ...types.org_member_id import OrgMemberId
+from .raw_client import AsyncRawMembersClient, RawMembersClient
+
+if typing.TYPE_CHECKING:
+ from .roles.client import AsyncRolesClient, RolesClient
+
+
+class MembersClient:
+ def __init__(self, *, client_wrapper: SyncClientWrapper):
+ self._raw_client = RawMembersClient(client_wrapper=client_wrapper)
+ self._client_wrapper = client_wrapper
+ self._roles: typing.Optional[RolesClient] = None
+
+ @property
+ def with_raw_response(self) -> RawMembersClient:
+ """
+ Retrieves a raw implementation of this client that returns raw responses.
+
+ Returns
+ -------
+ RawMembersClient
+ """
+ return self._raw_client
+
+ def list(
+ self,
+ *,
+ fields: typing.Optional[str] = None,
+ include_fields: typing.Optional[bool] = True,
+ from_: typing.Optional[str] = None,
+ take: typing.Optional[int] = 50,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> SyncPager[OrgMember, ListOrganizationMembersResponseContent]:
+ """
+ Retrieve a list of all members for this Organization. The `roles` field is only included for each member when the token also carries the `read:my_org:member_roles` scope; without that scope the `roles` field is omitted from the response.
+
+ Parameters
+ ----------
+ fields : typing.Optional[str]
+ Comma-separated list of fields to include or exclude (based on value provided for include_fields) in the result. Leave empty to retrieve all fields.
+
+ include_fields : typing.Optional[bool]
+ Whether specified fields are to be included (true) or excluded (false). Defaults to true
+
+ from_ : typing.Optional[str]
+ An optional cursor from which to start the selection (exclusive).
+
+ take : typing.Optional[int]
+ Number of results per page. Defaults to 50.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ SyncPager[OrgMember, ListOrganizationMembersResponseContent]
+ List members for an organization.
+
+ Examples
+ --------
+ from auth0 import Auth0
+
+ client = Auth0(
+ token="YOUR_TOKEN",
+ )
+ response = client.organization.members.list(
+ fields="fields",
+ include_fields=True,
+ from_="from",
+ take=1,
+ )
+ for item in response:
+ yield item
+ # alternatively, you can paginate page-by-page
+ for page in response.iter_pages():
+ yield page
+ """
+ return self._raw_client.list(
+ fields=fields, include_fields=include_fields, from_=from_, take=take, request_options=request_options
+ )
+
+ def get(
+ self,
+ user_id: OrgMemberId,
+ *,
+ fields: typing.Optional[str] = None,
+ include_fields: typing.Optional[bool] = True,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> GetOrganizationMemberResponseContent:
+ """
+ Retrieve details of a member specified by user ID for this Organization.
+
+ Parameters
+ ----------
+ user_id : OrgMemberId
+
+ fields : typing.Optional[str]
+ Comma-separated list of fields to include or exclude (based on value provided for include_fields) in the result. Leave empty to retrieve all fields.
+
+ include_fields : typing.Optional[bool]
+ Whether specified fields are to be included (true) or excluded (false). Defaults to true
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ GetOrganizationMemberResponseContent
+ Retrieve a member of the organization.
+
+ Examples
+ --------
+ from auth0 import Auth0
+
+ client = Auth0(
+ token="YOUR_TOKEN",
+ )
+ client.organization.members.get(
+ user_id="user_id",
+ fields="fields",
+ include_fields=True,
+ )
+ """
+ _response = self._raw_client.get(
+ user_id, fields=fields, include_fields=include_fields, request_options=request_options
+ )
+ return _response.data
+
+ @property
+ def roles(self):
+ if self._roles is None:
+ from .roles.client import RolesClient # noqa: E402
+
+ self._roles = RolesClient(client_wrapper=self._client_wrapper)
+ return self._roles
+
+
+class AsyncMembersClient:
+ def __init__(self, *, client_wrapper: AsyncClientWrapper):
+ self._raw_client = AsyncRawMembersClient(client_wrapper=client_wrapper)
+ self._client_wrapper = client_wrapper
+ self._roles: typing.Optional[AsyncRolesClient] = None
+
+ @property
+ def with_raw_response(self) -> AsyncRawMembersClient:
+ """
+ Retrieves a raw implementation of this client that returns raw responses.
+
+ Returns
+ -------
+ AsyncRawMembersClient
+ """
+ return self._raw_client
+
+ async def list(
+ self,
+ *,
+ fields: typing.Optional[str] = None,
+ include_fields: typing.Optional[bool] = True,
+ from_: typing.Optional[str] = None,
+ take: typing.Optional[int] = 50,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> AsyncPager[OrgMember, ListOrganizationMembersResponseContent]:
+ """
+ Retrieve a list of all members for this Organization. The `roles` field is only included for each member when the token also carries the `read:my_org:member_roles` scope; without that scope the `roles` field is omitted from the response.
+
+ Parameters
+ ----------
+ fields : typing.Optional[str]
+ Comma-separated list of fields to include or exclude (based on value provided for include_fields) in the result. Leave empty to retrieve all fields.
+
+ include_fields : typing.Optional[bool]
+ Whether specified fields are to be included (true) or excluded (false). Defaults to true
+
+ from_ : typing.Optional[str]
+ An optional cursor from which to start the selection (exclusive).
+
+ take : typing.Optional[int]
+ Number of results per page. Defaults to 50.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncPager[OrgMember, ListOrganizationMembersResponseContent]
+ List members for an organization.
+
+ Examples
+ --------
+ import asyncio
+
+ from auth0 import AsyncAuth0
+
+ client = AsyncAuth0(
+ token="YOUR_TOKEN",
+ )
+
+
+ async def main() -> None:
+ response = await client.organization.members.list(
+ fields="fields",
+ include_fields=True,
+ from_="from",
+ take=1,
+ )
+ async for item in response:
+ yield item
+
+ # alternatively, you can paginate page-by-page
+ async for page in response.iter_pages():
+ yield page
+
+
+ asyncio.run(main())
+ """
+ return await self._raw_client.list(
+ fields=fields, include_fields=include_fields, from_=from_, take=take, request_options=request_options
+ )
+
+ async def get(
+ self,
+ user_id: OrgMemberId,
+ *,
+ fields: typing.Optional[str] = None,
+ include_fields: typing.Optional[bool] = True,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> GetOrganizationMemberResponseContent:
+ """
+ Retrieve details of a member specified by user ID for this Organization.
+
+ Parameters
+ ----------
+ user_id : OrgMemberId
+
+ fields : typing.Optional[str]
+ Comma-separated list of fields to include or exclude (based on value provided for include_fields) in the result. Leave empty to retrieve all fields.
+
+ include_fields : typing.Optional[bool]
+ Whether specified fields are to be included (true) or excluded (false). Defaults to true
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ GetOrganizationMemberResponseContent
+ Retrieve a member of the organization.
+
+ Examples
+ --------
+ import asyncio
+
+ from auth0 import AsyncAuth0
+
+ client = AsyncAuth0(
+ token="YOUR_TOKEN",
+ )
+
+
+ async def main() -> None:
+ await client.organization.members.get(
+ user_id="user_id",
+ fields="fields",
+ include_fields=True,
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.get(
+ user_id, fields=fields, include_fields=include_fields, request_options=request_options
+ )
+ return _response.data
+
+ @property
+ def roles(self):
+ if self._roles is None:
+ from .roles.client import AsyncRolesClient # noqa: E402
+
+ self._roles = AsyncRolesClient(client_wrapper=self._client_wrapper)
+ return self._roles
diff --git a/src/auth0/myorganization/organization/members/raw_client.py b/src/auth0/myorganization/organization/members/raw_client.py
new file mode 100644
index 0000000..98b1e4d
--- /dev/null
+++ b/src/auth0/myorganization/organization/members/raw_client.py
@@ -0,0 +1,519 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+from json.decoder import JSONDecodeError
+
+from ...core.api_error import ApiError
+from ...core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
+from ...core.http_response import AsyncHttpResponse, HttpResponse
+from ...core.jsonable_encoder import encode_path_param
+from ...core.pagination import AsyncPager, SyncPager
+from ...core.parse_error import ParsingError
+from ...core.pydantic_utilities import parse_obj_as
+from ...core.request_options import RequestOptions
+from ...errors.bad_request_error import BadRequestError
+from ...errors.forbidden_error import ForbiddenError
+from ...errors.not_found_error import NotFoundError
+from ...errors.too_many_requests_error import TooManyRequestsError
+from ...errors.unauthorized_error import UnauthorizedError
+from ...types.error_response_content import ErrorResponseContent
+from ...types.get_organization_member_response_content import GetOrganizationMemberResponseContent
+from ...types.list_organization_members_response_content import ListOrganizationMembersResponseContent
+from ...types.org_member import OrgMember
+from ...types.org_member_id import OrgMemberId
+from pydantic import ValidationError
+
+
+class RawMembersClient:
+ def __init__(self, *, client_wrapper: SyncClientWrapper):
+ self._client_wrapper = client_wrapper
+
+ def list(
+ self,
+ *,
+ fields: typing.Optional[str] = None,
+ include_fields: typing.Optional[bool] = True,
+ from_: typing.Optional[str] = None,
+ take: typing.Optional[int] = 50,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> SyncPager[OrgMember, ListOrganizationMembersResponseContent]:
+ """
+ Retrieve a list of all members for this Organization. The `roles` field is only included for each member when the token also carries the `read:my_org:member_roles` scope; without that scope the `roles` field is omitted from the response.
+
+ Parameters
+ ----------
+ fields : typing.Optional[str]
+ Comma-separated list of fields to include or exclude (based on value provided for include_fields) in the result. Leave empty to retrieve all fields.
+
+ include_fields : typing.Optional[bool]
+ Whether specified fields are to be included (true) or excluded (false). Defaults to true
+
+ from_ : typing.Optional[str]
+ An optional cursor from which to start the selection (exclusive).
+
+ take : typing.Optional[int]
+ Number of results per page. Defaults to 50.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ SyncPager[OrgMember, ListOrganizationMembersResponseContent]
+ List members for an organization.
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ "members",
+ method="GET",
+ params={
+ "fields": fields,
+ "include_fields": include_fields,
+ "from": from_,
+ "take": take,
+ },
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _parsed_response = typing.cast(
+ ListOrganizationMembersResponseContent,
+ parse_obj_as(
+ type_=ListOrganizationMembersResponseContent, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ _items = _parsed_response.members
+ _parsed_next = _parsed_response.next
+ _has_next = _parsed_next is not None and _parsed_next != ""
+ _get_next = lambda: self.list(
+ fields=fields,
+ include_fields=include_fields,
+ from_=_parsed_next,
+ take=take,
+ request_options=request_options,
+ )
+ return SyncPager(has_next=_has_next, items=_items, get_next=_get_next, response=_parsed_response)
+ if _response.status_code == 400:
+ raise BadRequestError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 401:
+ raise UnauthorizedError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ ErrorResponseContent,
+ parse_obj_as(
+ type_=ErrorResponseContent, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 403:
+ raise ForbiddenError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ ErrorResponseContent,
+ parse_obj_as(
+ type_=ErrorResponseContent, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 404:
+ raise NotFoundError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ ErrorResponseContent,
+ parse_obj_as(
+ type_=ErrorResponseContent, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 429:
+ raise TooManyRequestsError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ ErrorResponseContent,
+ parse_obj_as(
+ type_=ErrorResponseContent, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def get(
+ self,
+ user_id: OrgMemberId,
+ *,
+ fields: typing.Optional[str] = None,
+ include_fields: typing.Optional[bool] = True,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> HttpResponse[GetOrganizationMemberResponseContent]:
+ """
+ Retrieve details of a member specified by user ID for this Organization.
+
+ Parameters
+ ----------
+ user_id : OrgMemberId
+
+ fields : typing.Optional[str]
+ Comma-separated list of fields to include or exclude (based on value provided for include_fields) in the result. Leave empty to retrieve all fields.
+
+ include_fields : typing.Optional[bool]
+ Whether specified fields are to be included (true) or excluded (false). Defaults to true
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[GetOrganizationMemberResponseContent]
+ Retrieve a member of the organization.
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"members/{encode_path_param(user_id)}",
+ method="GET",
+ params={
+ "fields": fields,
+ "include_fields": include_fields,
+ },
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ GetOrganizationMemberResponseContent,
+ parse_obj_as(
+ type_=GetOrganizationMemberResponseContent, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 400:
+ raise BadRequestError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 401:
+ raise UnauthorizedError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ ErrorResponseContent,
+ parse_obj_as(
+ type_=ErrorResponseContent, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 403:
+ raise ForbiddenError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ ErrorResponseContent,
+ parse_obj_as(
+ type_=ErrorResponseContent, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 404:
+ raise NotFoundError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ ErrorResponseContent,
+ parse_obj_as(
+ type_=ErrorResponseContent, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 429:
+ raise TooManyRequestsError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ ErrorResponseContent,
+ parse_obj_as(
+ type_=ErrorResponseContent, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+
+class AsyncRawMembersClient:
+ def __init__(self, *, client_wrapper: AsyncClientWrapper):
+ self._client_wrapper = client_wrapper
+
+ async def list(
+ self,
+ *,
+ fields: typing.Optional[str] = None,
+ include_fields: typing.Optional[bool] = True,
+ from_: typing.Optional[str] = None,
+ take: typing.Optional[int] = 50,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> AsyncPager[OrgMember, ListOrganizationMembersResponseContent]:
+ """
+ Retrieve a list of all members for this Organization. The `roles` field is only included for each member when the token also carries the `read:my_org:member_roles` scope; without that scope the `roles` field is omitted from the response.
+
+ Parameters
+ ----------
+ fields : typing.Optional[str]
+ Comma-separated list of fields to include or exclude (based on value provided for include_fields) in the result. Leave empty to retrieve all fields.
+
+ include_fields : typing.Optional[bool]
+ Whether specified fields are to be included (true) or excluded (false). Defaults to true
+
+ from_ : typing.Optional[str]
+ An optional cursor from which to start the selection (exclusive).
+
+ take : typing.Optional[int]
+ Number of results per page. Defaults to 50.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncPager[OrgMember, ListOrganizationMembersResponseContent]
+ List members for an organization.
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ "members",
+ method="GET",
+ params={
+ "fields": fields,
+ "include_fields": include_fields,
+ "from": from_,
+ "take": take,
+ },
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _parsed_response = typing.cast(
+ ListOrganizationMembersResponseContent,
+ parse_obj_as(
+ type_=ListOrganizationMembersResponseContent, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ _items = _parsed_response.members
+ _parsed_next = _parsed_response.next
+ _has_next = _parsed_next is not None and _parsed_next != ""
+
+ async def _get_next():
+ return await self.list(
+ fields=fields,
+ include_fields=include_fields,
+ from_=_parsed_next,
+ take=take,
+ request_options=request_options,
+ )
+
+ return AsyncPager(has_next=_has_next, items=_items, get_next=_get_next, response=_parsed_response)
+ if _response.status_code == 400:
+ raise BadRequestError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 401:
+ raise UnauthorizedError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ ErrorResponseContent,
+ parse_obj_as(
+ type_=ErrorResponseContent, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 403:
+ raise ForbiddenError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ ErrorResponseContent,
+ parse_obj_as(
+ type_=ErrorResponseContent, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 404:
+ raise NotFoundError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ ErrorResponseContent,
+ parse_obj_as(
+ type_=ErrorResponseContent, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 429:
+ raise TooManyRequestsError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ ErrorResponseContent,
+ parse_obj_as(
+ type_=ErrorResponseContent, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def get(
+ self,
+ user_id: OrgMemberId,
+ *,
+ fields: typing.Optional[str] = None,
+ include_fields: typing.Optional[bool] = True,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> AsyncHttpResponse[GetOrganizationMemberResponseContent]:
+ """
+ Retrieve details of a member specified by user ID for this Organization.
+
+ Parameters
+ ----------
+ user_id : OrgMemberId
+
+ fields : typing.Optional[str]
+ Comma-separated list of fields to include or exclude (based on value provided for include_fields) in the result. Leave empty to retrieve all fields.
+
+ include_fields : typing.Optional[bool]
+ Whether specified fields are to be included (true) or excluded (false). Defaults to true
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[GetOrganizationMemberResponseContent]
+ Retrieve a member of the organization.
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"members/{encode_path_param(user_id)}",
+ method="GET",
+ params={
+ "fields": fields,
+ "include_fields": include_fields,
+ },
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ GetOrganizationMemberResponseContent,
+ parse_obj_as(
+ type_=GetOrganizationMemberResponseContent, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 400:
+ raise BadRequestError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 401:
+ raise UnauthorizedError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ ErrorResponseContent,
+ parse_obj_as(
+ type_=ErrorResponseContent, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 403:
+ raise ForbiddenError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ ErrorResponseContent,
+ parse_obj_as(
+ type_=ErrorResponseContent, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 404:
+ raise NotFoundError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ ErrorResponseContent,
+ parse_obj_as(
+ type_=ErrorResponseContent, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 429:
+ raise TooManyRequestsError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ ErrorResponseContent,
+ parse_obj_as(
+ type_=ErrorResponseContent, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
diff --git a/src/auth0/myorganization/organization/members/roles/__init__.py b/src/auth0/myorganization/organization/members/roles/__init__.py
new file mode 100644
index 0000000..5cde020
--- /dev/null
+++ b/src/auth0/myorganization/organization/members/roles/__init__.py
@@ -0,0 +1,4 @@
+# This file was auto-generated by Fern from our API Definition.
+
+# isort: skip_file
+
diff --git a/src/auth0/myorganization/organization/members/roles/client.py b/src/auth0/myorganization/organization/members/roles/client.py
new file mode 100644
index 0000000..7915477
--- /dev/null
+++ b/src/auth0/myorganization/organization/members/roles/client.py
@@ -0,0 +1,322 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+from ....core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
+from ....core.pagination import AsyncPager, SyncPager
+from ....core.request_options import RequestOptions
+from ....types.get_organization_member_roles_response_content import GetOrganizationMemberRolesResponseContent
+from ....types.org_member_id import OrgMemberId
+from ....types.role import Role
+from ....types.role_id import RoleId
+from .raw_client import AsyncRawRolesClient, RawRolesClient
+
+# this is used as the default value for optional parameters
+OMIT = typing.cast(typing.Any, ...)
+
+
+class RolesClient:
+ def __init__(self, *, client_wrapper: SyncClientWrapper):
+ self._raw_client = RawRolesClient(client_wrapper=client_wrapper)
+
+ @property
+ def with_raw_response(self) -> RawRolesClient:
+ """
+ Retrieves a raw implementation of this client that returns raw responses.
+
+ Returns
+ -------
+ RawRolesClient
+ """
+ return self._raw_client
+
+ def list(
+ self,
+ user_id: OrgMemberId,
+ *,
+ from_: typing.Optional[str] = None,
+ take: typing.Optional[int] = 50,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> SyncPager[Role, GetOrganizationMemberRolesResponseContent]:
+ """
+ Retrieve a list of roles assigned to a member specified by ID for this Organization.
+
+ Parameters
+ ----------
+ user_id : OrgMemberId
+
+ from_ : typing.Optional[str]
+ An optional cursor from which to start the selection (exclusive).
+
+ take : typing.Optional[int]
+ Number of results per page. Defaults to 50.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ SyncPager[Role, GetOrganizationMemberRolesResponseContent]
+ Retrieved memeber roles successfully.
+
+ Examples
+ --------
+ from auth0 import Auth0
+
+ client = Auth0(
+ token="YOUR_TOKEN",
+ )
+ response = client.organization.members.roles.list(
+ user_id="user_id",
+ from_="from",
+ take=1,
+ )
+ for item in response:
+ yield item
+ # alternatively, you can paginate page-by-page
+ for page in response.iter_pages():
+ yield page
+ """
+ return self._raw_client.list(user_id, from_=from_, take=take, request_options=request_options)
+
+ def assign(
+ self,
+ user_id: OrgMemberId,
+ *,
+ role_ids: typing.Sequence[RoleId],
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> None:
+ """
+ Assign roles to a member specified by ID for this Organization.
+
+ Parameters
+ ----------
+ user_id : OrgMemberId
+
+ role_ids : typing.Sequence[RoleId]
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ None
+
+ Examples
+ --------
+ from auth0 import Auth0
+
+ client = Auth0(
+ token="YOUR_TOKEN",
+ )
+ client.organization.members.roles.assign(
+ user_id="user_id",
+ role_ids=["rol_SO2j0sFo9NFa3F9w"],
+ )
+ """
+ _response = self._raw_client.assign(user_id, role_ids=role_ids, request_options=request_options)
+ return _response.data
+
+ def unassign(
+ self,
+ user_id: OrgMemberId,
+ *,
+ role_ids: typing.Sequence[RoleId],
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> None:
+ """
+ Remove roles from a member specified by ID for this Organization.
+
+ Parameters
+ ----------
+ user_id : OrgMemberId
+
+ role_ids : typing.Sequence[RoleId]
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ None
+
+ Examples
+ --------
+ from auth0 import Auth0
+
+ client = Auth0(
+ token="YOUR_TOKEN",
+ )
+ client.organization.members.roles.unassign(
+ user_id="user_id",
+ role_ids=["rol_SO2j0sFo9NFa3F9w"],
+ )
+ """
+ _response = self._raw_client.unassign(user_id, role_ids=role_ids, request_options=request_options)
+ return _response.data
+
+
+class AsyncRolesClient:
+ def __init__(self, *, client_wrapper: AsyncClientWrapper):
+ self._raw_client = AsyncRawRolesClient(client_wrapper=client_wrapper)
+
+ @property
+ def with_raw_response(self) -> AsyncRawRolesClient:
+ """
+ Retrieves a raw implementation of this client that returns raw responses.
+
+ Returns
+ -------
+ AsyncRawRolesClient
+ """
+ return self._raw_client
+
+ async def list(
+ self,
+ user_id: OrgMemberId,
+ *,
+ from_: typing.Optional[str] = None,
+ take: typing.Optional[int] = 50,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> AsyncPager[Role, GetOrganizationMemberRolesResponseContent]:
+ """
+ Retrieve a list of roles assigned to a member specified by ID for this Organization.
+
+ Parameters
+ ----------
+ user_id : OrgMemberId
+
+ from_ : typing.Optional[str]
+ An optional cursor from which to start the selection (exclusive).
+
+ take : typing.Optional[int]
+ Number of results per page. Defaults to 50.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncPager[Role, GetOrganizationMemberRolesResponseContent]
+ Retrieved memeber roles successfully.
+
+ Examples
+ --------
+ import asyncio
+
+ from auth0 import AsyncAuth0
+
+ client = AsyncAuth0(
+ token="YOUR_TOKEN",
+ )
+
+
+ async def main() -> None:
+ response = await client.organization.members.roles.list(
+ user_id="user_id",
+ from_="from",
+ take=1,
+ )
+ async for item in response:
+ yield item
+
+ # alternatively, you can paginate page-by-page
+ async for page in response.iter_pages():
+ yield page
+
+
+ asyncio.run(main())
+ """
+ return await self._raw_client.list(user_id, from_=from_, take=take, request_options=request_options)
+
+ async def assign(
+ self,
+ user_id: OrgMemberId,
+ *,
+ role_ids: typing.Sequence[RoleId],
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> None:
+ """
+ Assign roles to a member specified by ID for this Organization.
+
+ Parameters
+ ----------
+ user_id : OrgMemberId
+
+ role_ids : typing.Sequence[RoleId]
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ None
+
+ Examples
+ --------
+ import asyncio
+
+ from auth0 import AsyncAuth0
+
+ client = AsyncAuth0(
+ token="YOUR_TOKEN",
+ )
+
+
+ async def main() -> None:
+ await client.organization.members.roles.assign(
+ user_id="user_id",
+ role_ids=["rol_SO2j0sFo9NFa3F9w"],
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.assign(user_id, role_ids=role_ids, request_options=request_options)
+ return _response.data
+
+ async def unassign(
+ self,
+ user_id: OrgMemberId,
+ *,
+ role_ids: typing.Sequence[RoleId],
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> None:
+ """
+ Remove roles from a member specified by ID for this Organization.
+
+ Parameters
+ ----------
+ user_id : OrgMemberId
+
+ role_ids : typing.Sequence[RoleId]
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ None
+
+ Examples
+ --------
+ import asyncio
+
+ from auth0 import AsyncAuth0
+
+ client = AsyncAuth0(
+ token="YOUR_TOKEN",
+ )
+
+
+ async def main() -> None:
+ await client.organization.members.roles.unassign(
+ user_id="user_id",
+ role_ids=["rol_SO2j0sFo9NFa3F9w"],
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.unassign(user_id, role_ids=role_ids, request_options=request_options)
+ return _response.data
diff --git a/src/auth0/myorganization/organization/members/roles/raw_client.py b/src/auth0/myorganization/organization/members/roles/raw_client.py
new file mode 100644
index 0000000..638af88
--- /dev/null
+++ b/src/auth0/myorganization/organization/members/roles/raw_client.py
@@ -0,0 +1,678 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+from json.decoder import JSONDecodeError
+
+from ....core.api_error import ApiError
+from ....core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
+from ....core.http_response import AsyncHttpResponse, HttpResponse
+from ....core.jsonable_encoder import encode_path_param
+from ....core.pagination import AsyncPager, SyncPager
+from ....core.parse_error import ParsingError
+from ....core.pydantic_utilities import parse_obj_as
+from ....core.request_options import RequestOptions
+from ....errors.bad_request_error import BadRequestError
+from ....errors.forbidden_error import ForbiddenError
+from ....errors.not_found_error import NotFoundError
+from ....errors.too_many_requests_error import TooManyRequestsError
+from ....errors.unauthorized_error import UnauthorizedError
+from ....types.error_response_content import ErrorResponseContent
+from ....types.get_organization_member_roles_response_content import GetOrganizationMemberRolesResponseContent
+from ....types.org_member_id import OrgMemberId
+from ....types.role import Role
+from ....types.role_id import RoleId
+from pydantic import ValidationError
+
+# this is used as the default value for optional parameters
+OMIT = typing.cast(typing.Any, ...)
+
+
+class RawRolesClient:
+ def __init__(self, *, client_wrapper: SyncClientWrapper):
+ self._client_wrapper = client_wrapper
+
+ def list(
+ self,
+ user_id: OrgMemberId,
+ *,
+ from_: typing.Optional[str] = None,
+ take: typing.Optional[int] = 50,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> SyncPager[Role, GetOrganizationMemberRolesResponseContent]:
+ """
+ Retrieve a list of roles assigned to a member specified by ID for this Organization.
+
+ Parameters
+ ----------
+ user_id : OrgMemberId
+
+ from_ : typing.Optional[str]
+ An optional cursor from which to start the selection (exclusive).
+
+ take : typing.Optional[int]
+ Number of results per page. Defaults to 50.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ SyncPager[Role, GetOrganizationMemberRolesResponseContent]
+ Retrieved memeber roles successfully.
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"members/{encode_path_param(user_id)}/roles",
+ method="GET",
+ params={
+ "from": from_,
+ "take": take,
+ },
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _parsed_response = typing.cast(
+ GetOrganizationMemberRolesResponseContent,
+ parse_obj_as(
+ type_=GetOrganizationMemberRolesResponseContent, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ _items = _parsed_response.roles
+ _parsed_next = _parsed_response.next
+ _has_next = _parsed_next is not None and _parsed_next != ""
+ _get_next = lambda: self.list(
+ user_id,
+ from_=_parsed_next,
+ take=take,
+ request_options=request_options,
+ )
+ return SyncPager(has_next=_has_next, items=_items, get_next=_get_next, response=_parsed_response)
+ if _response.status_code == 400:
+ raise BadRequestError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 401:
+ raise UnauthorizedError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ ErrorResponseContent,
+ parse_obj_as(
+ type_=ErrorResponseContent, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 403:
+ raise ForbiddenError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ ErrorResponseContent,
+ parse_obj_as(
+ type_=ErrorResponseContent, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 404:
+ raise NotFoundError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ ErrorResponseContent,
+ parse_obj_as(
+ type_=ErrorResponseContent, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 429:
+ raise TooManyRequestsError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ ErrorResponseContent,
+ parse_obj_as(
+ type_=ErrorResponseContent, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def assign(
+ self,
+ user_id: OrgMemberId,
+ *,
+ role_ids: typing.Sequence[RoleId],
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> HttpResponse[None]:
+ """
+ Assign roles to a member specified by ID for this Organization.
+
+ Parameters
+ ----------
+ user_id : OrgMemberId
+
+ role_ids : typing.Sequence[RoleId]
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[None]
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"members/{encode_path_param(user_id)}/roles",
+ method="POST",
+ json={
+ "role_ids": role_ids,
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ return HttpResponse(response=_response, data=None)
+ if _response.status_code == 400:
+ raise BadRequestError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 401:
+ raise UnauthorizedError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ ErrorResponseContent,
+ parse_obj_as(
+ type_=ErrorResponseContent, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 403:
+ raise ForbiddenError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ ErrorResponseContent,
+ parse_obj_as(
+ type_=ErrorResponseContent, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 404:
+ raise NotFoundError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ ErrorResponseContent,
+ parse_obj_as(
+ type_=ErrorResponseContent, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 429:
+ raise TooManyRequestsError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ ErrorResponseContent,
+ parse_obj_as(
+ type_=ErrorResponseContent, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def unassign(
+ self,
+ user_id: OrgMemberId,
+ *,
+ role_ids: typing.Sequence[RoleId],
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> HttpResponse[None]:
+ """
+ Remove roles from a member specified by ID for this Organization.
+
+ Parameters
+ ----------
+ user_id : OrgMemberId
+
+ role_ids : typing.Sequence[RoleId]
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[None]
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"members/{encode_path_param(user_id)}/roles",
+ method="DELETE",
+ json={
+ "role_ids": role_ids,
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ return HttpResponse(response=_response, data=None)
+ if _response.status_code == 400:
+ raise BadRequestError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 401:
+ raise UnauthorizedError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ ErrorResponseContent,
+ parse_obj_as(
+ type_=ErrorResponseContent, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 403:
+ raise ForbiddenError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ ErrorResponseContent,
+ parse_obj_as(
+ type_=ErrorResponseContent, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 404:
+ raise NotFoundError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ ErrorResponseContent,
+ parse_obj_as(
+ type_=ErrorResponseContent, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 429:
+ raise TooManyRequestsError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ ErrorResponseContent,
+ parse_obj_as(
+ type_=ErrorResponseContent, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+
+class AsyncRawRolesClient:
+ def __init__(self, *, client_wrapper: AsyncClientWrapper):
+ self._client_wrapper = client_wrapper
+
+ async def list(
+ self,
+ user_id: OrgMemberId,
+ *,
+ from_: typing.Optional[str] = None,
+ take: typing.Optional[int] = 50,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> AsyncPager[Role, GetOrganizationMemberRolesResponseContent]:
+ """
+ Retrieve a list of roles assigned to a member specified by ID for this Organization.
+
+ Parameters
+ ----------
+ user_id : OrgMemberId
+
+ from_ : typing.Optional[str]
+ An optional cursor from which to start the selection (exclusive).
+
+ take : typing.Optional[int]
+ Number of results per page. Defaults to 50.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncPager[Role, GetOrganizationMemberRolesResponseContent]
+ Retrieved memeber roles successfully.
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"members/{encode_path_param(user_id)}/roles",
+ method="GET",
+ params={
+ "from": from_,
+ "take": take,
+ },
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _parsed_response = typing.cast(
+ GetOrganizationMemberRolesResponseContent,
+ parse_obj_as(
+ type_=GetOrganizationMemberRolesResponseContent, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ _items = _parsed_response.roles
+ _parsed_next = _parsed_response.next
+ _has_next = _parsed_next is not None and _parsed_next != ""
+
+ async def _get_next():
+ return await self.list(
+ user_id,
+ from_=_parsed_next,
+ take=take,
+ request_options=request_options,
+ )
+
+ return AsyncPager(has_next=_has_next, items=_items, get_next=_get_next, response=_parsed_response)
+ if _response.status_code == 400:
+ raise BadRequestError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 401:
+ raise UnauthorizedError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ ErrorResponseContent,
+ parse_obj_as(
+ type_=ErrorResponseContent, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 403:
+ raise ForbiddenError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ ErrorResponseContent,
+ parse_obj_as(
+ type_=ErrorResponseContent, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 404:
+ raise NotFoundError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ ErrorResponseContent,
+ parse_obj_as(
+ type_=ErrorResponseContent, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 429:
+ raise TooManyRequestsError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ ErrorResponseContent,
+ parse_obj_as(
+ type_=ErrorResponseContent, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def assign(
+ self,
+ user_id: OrgMemberId,
+ *,
+ role_ids: typing.Sequence[RoleId],
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> AsyncHttpResponse[None]:
+ """
+ Assign roles to a member specified by ID for this Organization.
+
+ Parameters
+ ----------
+ user_id : OrgMemberId
+
+ role_ids : typing.Sequence[RoleId]
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[None]
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"members/{encode_path_param(user_id)}/roles",
+ method="POST",
+ json={
+ "role_ids": role_ids,
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ return AsyncHttpResponse(response=_response, data=None)
+ if _response.status_code == 400:
+ raise BadRequestError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 401:
+ raise UnauthorizedError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ ErrorResponseContent,
+ parse_obj_as(
+ type_=ErrorResponseContent, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 403:
+ raise ForbiddenError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ ErrorResponseContent,
+ parse_obj_as(
+ type_=ErrorResponseContent, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 404:
+ raise NotFoundError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ ErrorResponseContent,
+ parse_obj_as(
+ type_=ErrorResponseContent, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 429:
+ raise TooManyRequestsError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ ErrorResponseContent,
+ parse_obj_as(
+ type_=ErrorResponseContent, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def unassign(
+ self,
+ user_id: OrgMemberId,
+ *,
+ role_ids: typing.Sequence[RoleId],
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> AsyncHttpResponse[None]:
+ """
+ Remove roles from a member specified by ID for this Organization.
+
+ Parameters
+ ----------
+ user_id : OrgMemberId
+
+ role_ids : typing.Sequence[RoleId]
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[None]
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"members/{encode_path_param(user_id)}/roles",
+ method="DELETE",
+ json={
+ "role_ids": role_ids,
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ return AsyncHttpResponse(response=_response, data=None)
+ if _response.status_code == 400:
+ raise BadRequestError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 401:
+ raise UnauthorizedError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ ErrorResponseContent,
+ parse_obj_as(
+ type_=ErrorResponseContent, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 403:
+ raise ForbiddenError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ ErrorResponseContent,
+ parse_obj_as(
+ type_=ErrorResponseContent, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 404:
+ raise NotFoundError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ ErrorResponseContent,
+ parse_obj_as(
+ type_=ErrorResponseContent, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 429:
+ raise TooManyRequestsError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ ErrorResponseContent,
+ parse_obj_as(
+ type_=ErrorResponseContent, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
diff --git a/src/auth0/myorganization/organization/memberships/__init__.py b/src/auth0/myorganization/organization/memberships/__init__.py
new file mode 100644
index 0000000..5cde020
--- /dev/null
+++ b/src/auth0/myorganization/organization/memberships/__init__.py
@@ -0,0 +1,4 @@
+# This file was auto-generated by Fern from our API Definition.
+
+# isort: skip_file
+
diff --git a/src/auth0/myorganization/organization/memberships/client.py b/src/auth0/myorganization/organization/memberships/client.py
new file mode 100644
index 0000000..0cfed6e
--- /dev/null
+++ b/src/auth0/myorganization/organization/memberships/client.py
@@ -0,0 +1,113 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+from ...core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
+from ...core.request_options import RequestOptions
+from ...types.org_member_id import OrgMemberId
+from .raw_client import AsyncRawMembershipsClient, RawMembershipsClient
+
+# this is used as the default value for optional parameters
+OMIT = typing.cast(typing.Any, ...)
+
+
+class MembershipsClient:
+ def __init__(self, *, client_wrapper: SyncClientWrapper):
+ self._raw_client = RawMembershipsClient(client_wrapper=client_wrapper)
+
+ @property
+ def with_raw_response(self) -> RawMembershipsClient:
+ """
+ Retrieves a raw implementation of this client that returns raw responses.
+
+ Returns
+ -------
+ RawMembershipsClient
+ """
+ return self._raw_client
+
+ def delete_memberships(
+ self, *, members: typing.Sequence[OrgMemberId], request_options: typing.Optional[RequestOptions] = None
+ ) -> None:
+ """
+ Remove one member from this Organization. The underlying user account is not deleted.
+
+ Parameters
+ ----------
+ members : typing.Sequence[OrgMemberId]
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ None
+
+ Examples
+ --------
+ from auth0 import Auth0
+
+ client = Auth0(
+ token="YOUR_TOKEN",
+ )
+ client.organization.memberships.delete_memberships(
+ members=["auth0|1234567890"],
+ )
+ """
+ _response = self._raw_client.delete_memberships(members=members, request_options=request_options)
+ return _response.data
+
+
+class AsyncMembershipsClient:
+ def __init__(self, *, client_wrapper: AsyncClientWrapper):
+ self._raw_client = AsyncRawMembershipsClient(client_wrapper=client_wrapper)
+
+ @property
+ def with_raw_response(self) -> AsyncRawMembershipsClient:
+ """
+ Retrieves a raw implementation of this client that returns raw responses.
+
+ Returns
+ -------
+ AsyncRawMembershipsClient
+ """
+ return self._raw_client
+
+ async def delete_memberships(
+ self, *, members: typing.Sequence[OrgMemberId], request_options: typing.Optional[RequestOptions] = None
+ ) -> None:
+ """
+ Remove one member from this Organization. The underlying user account is not deleted.
+
+ Parameters
+ ----------
+ members : typing.Sequence[OrgMemberId]
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ None
+
+ Examples
+ --------
+ import asyncio
+
+ from auth0 import AsyncAuth0
+
+ client = AsyncAuth0(
+ token="YOUR_TOKEN",
+ )
+
+
+ async def main() -> None:
+ await client.organization.memberships.delete_memberships(
+ members=["auth0|1234567890"],
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.delete_memberships(members=members, request_options=request_options)
+ return _response.data
diff --git a/src/auth0/myorganization/organization/memberships/raw_client.py b/src/auth0/myorganization/organization/memberships/raw_client.py
new file mode 100644
index 0000000..098fe8a
--- /dev/null
+++ b/src/auth0/myorganization/organization/memberships/raw_client.py
@@ -0,0 +1,224 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+from json.decoder import JSONDecodeError
+
+from ...core.api_error import ApiError
+from ...core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
+from ...core.http_response import AsyncHttpResponse, HttpResponse
+from ...core.parse_error import ParsingError
+from ...core.pydantic_utilities import parse_obj_as
+from ...core.request_options import RequestOptions
+from ...errors.bad_request_error import BadRequestError
+from ...errors.forbidden_error import ForbiddenError
+from ...errors.not_found_error import NotFoundError
+from ...errors.too_many_requests_error import TooManyRequestsError
+from ...errors.unauthorized_error import UnauthorizedError
+from ...types.error_response_content import ErrorResponseContent
+from ...types.org_member_id import OrgMemberId
+from pydantic import ValidationError
+
+# this is used as the default value for optional parameters
+OMIT = typing.cast(typing.Any, ...)
+
+
+class RawMembershipsClient:
+ def __init__(self, *, client_wrapper: SyncClientWrapper):
+ self._client_wrapper = client_wrapper
+
+ def delete_memberships(
+ self, *, members: typing.Sequence[OrgMemberId], request_options: typing.Optional[RequestOptions] = None
+ ) -> HttpResponse[None]:
+ """
+ Remove one member from this Organization. The underlying user account is not deleted.
+
+ Parameters
+ ----------
+ members : typing.Sequence[OrgMemberId]
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[None]
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ "delete-memberships",
+ method="POST",
+ json={
+ "members": members,
+ },
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ return HttpResponse(response=_response, data=None)
+ if _response.status_code == 400:
+ raise BadRequestError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 401:
+ raise UnauthorizedError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ ErrorResponseContent,
+ parse_obj_as(
+ type_=ErrorResponseContent, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 403:
+ raise ForbiddenError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ ErrorResponseContent,
+ parse_obj_as(
+ type_=ErrorResponseContent, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 404:
+ raise NotFoundError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ ErrorResponseContent,
+ parse_obj_as(
+ type_=ErrorResponseContent, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 429:
+ raise TooManyRequestsError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ ErrorResponseContent,
+ parse_obj_as(
+ type_=ErrorResponseContent, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+
+class AsyncRawMembershipsClient:
+ def __init__(self, *, client_wrapper: AsyncClientWrapper):
+ self._client_wrapper = client_wrapper
+
+ async def delete_memberships(
+ self, *, members: typing.Sequence[OrgMemberId], request_options: typing.Optional[RequestOptions] = None
+ ) -> AsyncHttpResponse[None]:
+ """
+ Remove one member from this Organization. The underlying user account is not deleted.
+
+ Parameters
+ ----------
+ members : typing.Sequence[OrgMemberId]
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[None]
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ "delete-memberships",
+ method="POST",
+ json={
+ "members": members,
+ },
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ return AsyncHttpResponse(response=_response, data=None)
+ if _response.status_code == 400:
+ raise BadRequestError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 401:
+ raise UnauthorizedError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ ErrorResponseContent,
+ parse_obj_as(
+ type_=ErrorResponseContent, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 403:
+ raise ForbiddenError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ ErrorResponseContent,
+ parse_obj_as(
+ type_=ErrorResponseContent, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 404:
+ raise NotFoundError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ ErrorResponseContent,
+ parse_obj_as(
+ type_=ErrorResponseContent, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 429:
+ raise TooManyRequestsError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ ErrorResponseContent,
+ parse_obj_as(
+ type_=ErrorResponseContent, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
diff --git a/src/auth0/myorganization/organization/roles/__init__.py b/src/auth0/myorganization/organization/roles/__init__.py
new file mode 100644
index 0000000..5cde020
--- /dev/null
+++ b/src/auth0/myorganization/organization/roles/__init__.py
@@ -0,0 +1,4 @@
+# This file was auto-generated by Fern from our API Definition.
+
+# isort: skip_file
+
diff --git a/src/auth0/myorganization/organization/roles/client.py b/src/auth0/myorganization/organization/roles/client.py
new file mode 100644
index 0000000..5c058ec
--- /dev/null
+++ b/src/auth0/myorganization/organization/roles/client.py
@@ -0,0 +1,151 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+from ...core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
+from ...core.pagination import AsyncPager, SyncPager
+from ...core.request_options import RequestOptions
+from ...types.list_roles_response_content import ListRolesResponseContent
+from ...types.role import Role
+from .raw_client import AsyncRawRolesClient, RawRolesClient
+
+
+class RolesClient:
+ def __init__(self, *, client_wrapper: SyncClientWrapper):
+ self._raw_client = RawRolesClient(client_wrapper=client_wrapper)
+
+ @property
+ def with_raw_response(self) -> RawRolesClient:
+ """
+ Retrieves a raw implementation of this client that returns raw responses.
+
+ Returns
+ -------
+ RawRolesClient
+ """
+ return self._raw_client
+
+ def list(
+ self,
+ *,
+ from_: typing.Optional[str] = None,
+ take: typing.Optional[int] = 50,
+ name: typing.Optional[str] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> SyncPager[Role, ListRolesResponseContent]:
+ """
+ Retrieve the list of roles available for binding to members and invitations for this Organization. Only roles made visible to this Organization by the Tenant Admin are returned.
+
+ Parameters
+ ----------
+ from_ : typing.Optional[str]
+ An optional cursor from which to start the selection (exclusive).
+
+ take : typing.Optional[int]
+ Number of results per page. Defaults to 50.
+
+ name : typing.Optional[str]
+ An optional filter on the name (case-insensitive).
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ SyncPager[Role, ListRolesResponseContent]
+ Retrieve roles for the organization.
+
+ Examples
+ --------
+ from auth0 import Auth0
+
+ client = Auth0(
+ token="YOUR_TOKEN",
+ )
+ response = client.organization.roles.list(
+ from_="from",
+ take=1,
+ name="name",
+ )
+ for item in response:
+ yield item
+ # alternatively, you can paginate page-by-page
+ for page in response.iter_pages():
+ yield page
+ """
+ return self._raw_client.list(from_=from_, take=take, name=name, request_options=request_options)
+
+
+class AsyncRolesClient:
+ def __init__(self, *, client_wrapper: AsyncClientWrapper):
+ self._raw_client = AsyncRawRolesClient(client_wrapper=client_wrapper)
+
+ @property
+ def with_raw_response(self) -> AsyncRawRolesClient:
+ """
+ Retrieves a raw implementation of this client that returns raw responses.
+
+ Returns
+ -------
+ AsyncRawRolesClient
+ """
+ return self._raw_client
+
+ async def list(
+ self,
+ *,
+ from_: typing.Optional[str] = None,
+ take: typing.Optional[int] = 50,
+ name: typing.Optional[str] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> AsyncPager[Role, ListRolesResponseContent]:
+ """
+ Retrieve the list of roles available for binding to members and invitations for this Organization. Only roles made visible to this Organization by the Tenant Admin are returned.
+
+ Parameters
+ ----------
+ from_ : typing.Optional[str]
+ An optional cursor from which to start the selection (exclusive).
+
+ take : typing.Optional[int]
+ Number of results per page. Defaults to 50.
+
+ name : typing.Optional[str]
+ An optional filter on the name (case-insensitive).
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncPager[Role, ListRolesResponseContent]
+ Retrieve roles for the organization.
+
+ Examples
+ --------
+ import asyncio
+
+ from auth0 import AsyncAuth0
+
+ client = AsyncAuth0(
+ token="YOUR_TOKEN",
+ )
+
+
+ async def main() -> None:
+ response = await client.organization.roles.list(
+ from_="from",
+ take=1,
+ name="name",
+ )
+ async for item in response:
+ yield item
+
+ # alternatively, you can paginate page-by-page
+ async for page in response.iter_pages():
+ yield page
+
+
+ asyncio.run(main())
+ """
+ return await self._raw_client.list(from_=from_, take=take, name=name, request_options=request_options)
diff --git a/src/auth0/myorganization/organization/roles/raw_client.py b/src/auth0/myorganization/organization/roles/raw_client.py
new file mode 100644
index 0000000..30595cf
--- /dev/null
+++ b/src/auth0/myorganization/organization/roles/raw_client.py
@@ -0,0 +1,256 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+from json.decoder import JSONDecodeError
+
+from ...core.api_error import ApiError
+from ...core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
+from ...core.pagination import AsyncPager, SyncPager
+from ...core.parse_error import ParsingError
+from ...core.pydantic_utilities import parse_obj_as
+from ...core.request_options import RequestOptions
+from ...errors.bad_request_error import BadRequestError
+from ...errors.forbidden_error import ForbiddenError
+from ...errors.too_many_requests_error import TooManyRequestsError
+from ...errors.unauthorized_error import UnauthorizedError
+from ...types.error_response_content import ErrorResponseContent
+from ...types.list_roles_response_content import ListRolesResponseContent
+from ...types.role import Role
+from pydantic import ValidationError
+
+
+class RawRolesClient:
+ def __init__(self, *, client_wrapper: SyncClientWrapper):
+ self._client_wrapper = client_wrapper
+
+ def list(
+ self,
+ *,
+ from_: typing.Optional[str] = None,
+ take: typing.Optional[int] = 50,
+ name: typing.Optional[str] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> SyncPager[Role, ListRolesResponseContent]:
+ """
+ Retrieve the list of roles available for binding to members and invitations for this Organization. Only roles made visible to this Organization by the Tenant Admin are returned.
+
+ Parameters
+ ----------
+ from_ : typing.Optional[str]
+ An optional cursor from which to start the selection (exclusive).
+
+ take : typing.Optional[int]
+ Number of results per page. Defaults to 50.
+
+ name : typing.Optional[str]
+ An optional filter on the name (case-insensitive).
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ SyncPager[Role, ListRolesResponseContent]
+ Retrieve roles for the organization.
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ "roles",
+ method="GET",
+ params={
+ "from": from_,
+ "take": take,
+ "name": name,
+ },
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _parsed_response = typing.cast(
+ ListRolesResponseContent,
+ parse_obj_as(
+ type_=ListRolesResponseContent, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ _items = _parsed_response.roles
+ _parsed_next = _parsed_response.next
+ _has_next = _parsed_next is not None and _parsed_next != ""
+ _get_next = lambda: self.list(
+ from_=_parsed_next,
+ take=take,
+ name=name,
+ request_options=request_options,
+ )
+ return SyncPager(has_next=_has_next, items=_items, get_next=_get_next, response=_parsed_response)
+ if _response.status_code == 400:
+ raise BadRequestError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 401:
+ raise UnauthorizedError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ ErrorResponseContent,
+ parse_obj_as(
+ type_=ErrorResponseContent, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 403:
+ raise ForbiddenError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ ErrorResponseContent,
+ parse_obj_as(
+ type_=ErrorResponseContent, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 429:
+ raise TooManyRequestsError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ ErrorResponseContent,
+ parse_obj_as(
+ type_=ErrorResponseContent, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+
+class AsyncRawRolesClient:
+ def __init__(self, *, client_wrapper: AsyncClientWrapper):
+ self._client_wrapper = client_wrapper
+
+ async def list(
+ self,
+ *,
+ from_: typing.Optional[str] = None,
+ take: typing.Optional[int] = 50,
+ name: typing.Optional[str] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> AsyncPager[Role, ListRolesResponseContent]:
+ """
+ Retrieve the list of roles available for binding to members and invitations for this Organization. Only roles made visible to this Organization by the Tenant Admin are returned.
+
+ Parameters
+ ----------
+ from_ : typing.Optional[str]
+ An optional cursor from which to start the selection (exclusive).
+
+ take : typing.Optional[int]
+ Number of results per page. Defaults to 50.
+
+ name : typing.Optional[str]
+ An optional filter on the name (case-insensitive).
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncPager[Role, ListRolesResponseContent]
+ Retrieve roles for the organization.
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ "roles",
+ method="GET",
+ params={
+ "from": from_,
+ "take": take,
+ "name": name,
+ },
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _parsed_response = typing.cast(
+ ListRolesResponseContent,
+ parse_obj_as(
+ type_=ListRolesResponseContent, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ _items = _parsed_response.roles
+ _parsed_next = _parsed_response.next
+ _has_next = _parsed_next is not None and _parsed_next != ""
+
+ async def _get_next():
+ return await self.list(
+ from_=_parsed_next,
+ take=take,
+ name=name,
+ request_options=request_options,
+ )
+
+ return AsyncPager(has_next=_has_next, items=_items, get_next=_get_next, response=_parsed_response)
+ if _response.status_code == 400:
+ raise BadRequestError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 401:
+ raise UnauthorizedError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ ErrorResponseContent,
+ parse_obj_as(
+ type_=ErrorResponseContent, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 403:
+ raise ForbiddenError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ ErrorResponseContent,
+ parse_obj_as(
+ type_=ErrorResponseContent, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 429:
+ raise TooManyRequestsError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ ErrorResponseContent,
+ parse_obj_as(
+ type_=ErrorResponseContent, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
diff --git a/src/auth0/myorganization/organization_details/raw_client.py b/src/auth0/myorganization/organization_details/raw_client.py
index bd709b4..b44e4a8 100644
--- a/src/auth0/myorganization/organization_details/raw_client.py
+++ b/src/auth0/myorganization/organization_details/raw_client.py
@@ -152,9 +152,6 @@ def update(
object_=branding, annotation=OrgBranding, direction="write"
),
},
- headers={
- "content-type": "application/json",
- },
request_options=request_options,
omit=OMIT,
)
@@ -360,9 +357,6 @@ async def update(
object_=branding, annotation=OrgBranding, direction="write"
),
},
- headers={
- "content-type": "application/json",
- },
request_options=request_options,
omit=OMIT,
)
diff --git a/src/auth0/myorganization/types/__init__.py b/src/auth0/myorganization/types/__init__.py
index d134221..a194782 100644
--- a/src/auth0/myorganization/types/__init__.py
+++ b/src/auth0/myorganization/types/__init__.py
@@ -14,6 +14,8 @@
from .create_identity_provider_response_content import CreateIdentityProviderResponseContent
from .create_idp_domain_response_content import CreateIdpDomainResponseContent
from .create_idp_provisioning_scim_token_response_content import CreateIdpProvisioningScimTokenResponseContent
+ from .create_member_invitation_invitee import CreateMemberInvitationInvitee
+ from .create_member_invitation_response_content import CreateMemberInvitationResponseContent
from .create_organization_domain_response_content import CreateOrganizationDomainResponseContent
from .domain_idp import DomainIdp
from .error_response_content import ErrorResponseContent
@@ -26,6 +28,7 @@
from .get_organization_details_response_content import GetOrganizationDetailsResponseContent
from .get_organization_domain_response_content import GetOrganizationDomainResponseContent
from .get_organization_member_response_content import GetOrganizationMemberResponseContent
+ from .get_organization_member_roles_response_content import GetOrganizationMemberRolesResponseContent
from .identity_provider_config_adfs import IdentityProviderConfigAdfs
from .identity_provider_config_google_apps import IdentityProviderConfigGoogleApps
from .identity_provider_config_oidc import IdentityProviderConfigOidc
@@ -117,7 +120,10 @@
from .list_domain_identity_providers_response_content import ListDomainIdentityProvidersResponseContent
from .list_identity_providers_response_content import ListIdentityProvidersResponseContent
from .list_idp_provisioning_scim_tokens_response_content import ListIdpProvisioningScimTokensResponseContent
+ from .list_members_invitations_response_content import ListMembersInvitationsResponseContent
from .list_organization_domains_response_content import ListOrganizationDomainsResponseContent
+ from .list_organization_members_response_content import ListOrganizationMembersResponseContent
+ from .list_roles_response_content import ListRolesResponseContent
from .manual import Manual
from .member_invitation import MemberInvitation
from .member_invitation_invitee import MemberInvitationInvitee
@@ -133,10 +139,12 @@
from .org_domain_status_enum import OrgDomainStatusEnum
from .org_id import OrgId
from .org_member import OrgMember
+ from .org_member_id import OrgMemberId
from .org_member_id_read_only import OrgMemberIdReadOnly
- from .org_member_role import OrgMemberRole
- from .org_member_role_id import OrgMemberRoleId
from .organization_access_level_enum import OrganizationAccessLevelEnum
+ from .organization_member_roles_change_request_content import OrganizationMemberRolesChangeRequestContent
+ from .role import Role
+ from .role_id import RoleId
from .start_organization_domain_verification_response_content import (
StartOrganizationDomainVerificationResponseContent,
)
@@ -156,6 +164,8 @@
"CreateIdentityProviderResponseContent": ".create_identity_provider_response_content",
"CreateIdpDomainResponseContent": ".create_idp_domain_response_content",
"CreateIdpProvisioningScimTokenResponseContent": ".create_idp_provisioning_scim_token_response_content",
+ "CreateMemberInvitationInvitee": ".create_member_invitation_invitee",
+ "CreateMemberInvitationResponseContent": ".create_member_invitation_response_content",
"CreateOrganizationDomainResponseContent": ".create_organization_domain_response_content",
"DomainIdp": ".domain_idp",
"ErrorResponseContent": ".error_response_content",
@@ -168,6 +178,7 @@
"GetOrganizationDetailsResponseContent": ".get_organization_details_response_content",
"GetOrganizationDomainResponseContent": ".get_organization_domain_response_content",
"GetOrganizationMemberResponseContent": ".get_organization_member_response_content",
+ "GetOrganizationMemberRolesResponseContent": ".get_organization_member_roles_response_content",
"IdentityProviderConfigAdfs": ".identity_provider_config_adfs",
"IdentityProviderConfigGoogleApps": ".identity_provider_config_google_apps",
"IdentityProviderConfigOidc": ".identity_provider_config_oidc",
@@ -259,7 +270,10 @@
"ListDomainIdentityProvidersResponseContent": ".list_domain_identity_providers_response_content",
"ListIdentityProvidersResponseContent": ".list_identity_providers_response_content",
"ListIdpProvisioningScimTokensResponseContent": ".list_idp_provisioning_scim_tokens_response_content",
+ "ListMembersInvitationsResponseContent": ".list_members_invitations_response_content",
"ListOrganizationDomainsResponseContent": ".list_organization_domains_response_content",
+ "ListOrganizationMembersResponseContent": ".list_organization_members_response_content",
+ "ListRolesResponseContent": ".list_roles_response_content",
"Manual": ".manual",
"MemberInvitation": ".member_invitation",
"MemberInvitationInvitee": ".member_invitation_invitee",
@@ -275,10 +289,12 @@
"OrgDomainStatusEnum": ".org_domain_status_enum",
"OrgId": ".org_id",
"OrgMember": ".org_member",
+ "OrgMemberId": ".org_member_id",
"OrgMemberIdReadOnly": ".org_member_id_read_only",
- "OrgMemberRole": ".org_member_role",
- "OrgMemberRoleId": ".org_member_role_id",
"OrganizationAccessLevelEnum": ".organization_access_level_enum",
+ "OrganizationMemberRolesChangeRequestContent": ".organization_member_roles_change_request_content",
+ "Role": ".role",
+ "RoleId": ".role_id",
"StartOrganizationDomainVerificationResponseContent": ".start_organization_domain_verification_response_content",
"UpdateIdentityProviderRequestContent": ".update_identity_provider_request_content",
"UpdateIdentityProviderResponseContent": ".update_identity_provider_response_content",
@@ -320,6 +336,8 @@ def __dir__():
"CreateIdentityProviderResponseContent",
"CreateIdpDomainResponseContent",
"CreateIdpProvisioningScimTokenResponseContent",
+ "CreateMemberInvitationInvitee",
+ "CreateMemberInvitationResponseContent",
"CreateOrganizationDomainResponseContent",
"DomainIdp",
"ErrorResponseContent",
@@ -332,6 +350,7 @@ def __dir__():
"GetOrganizationDetailsResponseContent",
"GetOrganizationDomainResponseContent",
"GetOrganizationMemberResponseContent",
+ "GetOrganizationMemberRolesResponseContent",
"IdentityProviderConfigAdfs",
"IdentityProviderConfigGoogleApps",
"IdentityProviderConfigOidc",
@@ -423,7 +442,10 @@ def __dir__():
"ListDomainIdentityProvidersResponseContent",
"ListIdentityProvidersResponseContent",
"ListIdpProvisioningScimTokensResponseContent",
+ "ListMembersInvitationsResponseContent",
"ListOrganizationDomainsResponseContent",
+ "ListOrganizationMembersResponseContent",
+ "ListRolesResponseContent",
"Manual",
"MemberInvitation",
"MemberInvitationInvitee",
@@ -439,10 +461,12 @@ def __dir__():
"OrgDomainStatusEnum",
"OrgId",
"OrgMember",
+ "OrgMemberId",
"OrgMemberIdReadOnly",
- "OrgMemberRole",
- "OrgMemberRoleId",
"OrganizationAccessLevelEnum",
+ "OrganizationMemberRolesChangeRequestContent",
+ "Role",
+ "RoleId",
"StartOrganizationDomainVerificationResponseContent",
"UpdateIdentityProviderRequestContent",
"UpdateIdentityProviderResponseContent",
diff --git a/src/auth0/myorganization/types/create_member_invitation_invitee.py b/src/auth0/myorganization/types/create_member_invitation_invitee.py
new file mode 100644
index 0000000..de64fce
--- /dev/null
+++ b/src/auth0/myorganization/types/create_member_invitation_invitee.py
@@ -0,0 +1,28 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .role_id import RoleId
+
+
+class CreateMemberInvitationInvitee(UniversalBaseModel):
+ email: str = pydantic.Field()
+ """
+ The invitee's email.
+ """
+
+ roles: typing.Optional[typing.List[RoleId]] = pydantic.Field(default=None)
+ """
+ List of role IDs to associate with the user.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/src/auth0/myorganization/types/create_member_invitation_response_content.py b/src/auth0/myorganization/types/create_member_invitation_response_content.py
new file mode 100644
index 0000000..36e05a9
--- /dev/null
+++ b/src/auth0/myorganization/types/create_member_invitation_response_content.py
@@ -0,0 +1,7 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+from .member_invitation import MemberInvitation
+
+CreateMemberInvitationResponseContent = typing.List[MemberInvitation]
diff --git a/src/auth0/myorganization/types/get_organization_member_roles_response_content.py b/src/auth0/myorganization/types/get_organization_member_roles_response_content.py
new file mode 100644
index 0000000..bd412d6
--- /dev/null
+++ b/src/auth0/myorganization/types/get_organization_member_roles_response_content.py
@@ -0,0 +1,25 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .role import Role
+
+
+class GetOrganizationMemberRolesResponseContent(UniversalBaseModel):
+ next: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Pagination cursor for the next page of results
+ """
+
+ roles: typing.List[Role]
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/src/auth0/myorganization/types/list_members_invitations_response_content.py b/src/auth0/myorganization/types/list_members_invitations_response_content.py
new file mode 100644
index 0000000..33243b6
--- /dev/null
+++ b/src/auth0/myorganization/types/list_members_invitations_response_content.py
@@ -0,0 +1,25 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .member_invitation import MemberInvitation
+
+
+class ListMembersInvitationsResponseContent(UniversalBaseModel):
+ next: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Pagination cursor for the next page of results.
+ """
+
+ invitations: typing.Optional[typing.List[MemberInvitation]] = None
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/src/auth0/myorganization/types/list_organization_members_response_content.py b/src/auth0/myorganization/types/list_organization_members_response_content.py
new file mode 100644
index 0000000..923e9aa
--- /dev/null
+++ b/src/auth0/myorganization/types/list_organization_members_response_content.py
@@ -0,0 +1,25 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .org_member import OrgMember
+
+
+class ListOrganizationMembersResponseContent(UniversalBaseModel):
+ next: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Pagination cursor for the next page of results.
+ """
+
+ members: typing.Optional[typing.List[OrgMember]] = None
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/src/auth0/myorganization/types/list_roles_response_content.py b/src/auth0/myorganization/types/list_roles_response_content.py
new file mode 100644
index 0000000..bff0af2
--- /dev/null
+++ b/src/auth0/myorganization/types/list_roles_response_content.py
@@ -0,0 +1,24 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .role import Role
+
+
+class ListRolesResponseContent(UniversalBaseModel):
+ roles: typing.List[Role]
+ next: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Pagination cursor for the next page of results
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/src/auth0/myorganization/types/member_invitation.py b/src/auth0/myorganization/types/member_invitation.py
index ab3a13b..88058ae 100644
--- a/src/auth0/myorganization/types/member_invitation.py
+++ b/src/auth0/myorganization/types/member_invitation.py
@@ -10,7 +10,7 @@
from .member_invitation_invitee import MemberInvitationInvitee
from .member_invitation_inviter import MemberInvitationInviter
from .org_id import OrgId
-from .org_member_role_id import OrgMemberRoleId
+from .role_id import RoleId
class MemberInvitation(UniversalBaseModel):
@@ -29,7 +29,7 @@ class MemberInvitation(UniversalBaseModel):
The ISO 8601 formatted timestamp representing the expiration time of the invitation.
"""
- roles: typing.Optional[typing.List[OrgMemberRoleId]] = None
+ roles: typing.Optional[typing.List[RoleId]] = None
invitation_url: typing.Optional[str] = pydantic.Field(default=None)
"""
The invitation url to be sent to the invitee.
diff --git a/src/auth0/myorganization/types/oauth_scope.py b/src/auth0/myorganization/types/oauth_scope.py
index 36b523e..cf5f330 100644
--- a/src/auth0/myorganization/types/oauth_scope.py
+++ b/src/auth0/myorganization/types/oauth_scope.py
@@ -29,11 +29,9 @@
"create:my_org:member_invitations",
"delete:my_org:member_invitations",
"read:my_org:members",
- "delete:my_org:members",
"delete:my_org:memberships",
"read:my_org:member_roles",
"create:my_org:member_roles",
- "update:my_org:member_roles",
"delete:my_org:member_roles",
"create:my_org:client_grants",
"create:my_org:clients",
diff --git a/src/auth0/myorganization/types/org_member.py b/src/auth0/myorganization/types/org_member.py
index a36f2a7..77a4766 100644
--- a/src/auth0/myorganization/types/org_member.py
+++ b/src/auth0/myorganization/types/org_member.py
@@ -6,13 +6,13 @@
import pydantic
from ..core.pydantic_utilities import IS_PYDANTIC_V2
from .org_member_id_read_only import OrgMemberIdReadOnly
-from .org_member_role import OrgMemberRole
+from .role import Role
from .user_attributes import UserAttributes
class OrgMember(UserAttributes):
user_id: typing.Optional[OrgMemberIdReadOnly] = None
- roles: typing.Optional[typing.List[OrgMemberRole]] = None
+ roles: typing.Optional[typing.List[Role]] = None
created_at: typing.Optional[dt.datetime] = pydantic.Field(default=None)
"""
Date and time when this user was created (ISO_8601 format).
@@ -28,6 +28,11 @@ class OrgMember(UserAttributes):
Last date and time this user logged in (ISO_8601 format).
"""
+ phone_number: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Phone number associated with the user.
+ """
+
if IS_PYDANTIC_V2:
model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
else:
diff --git a/src/auth0/myorganization/types/org_member_id.py b/src/auth0/myorganization/types/org_member_id.py
new file mode 100644
index 0000000..0b56064
--- /dev/null
+++ b/src/auth0/myorganization/types/org_member_id.py
@@ -0,0 +1,6 @@
+# This file was auto-generated by Fern from our API Definition.
+
+OrgMemberId = str
+"""
+The user ID.
+"""
diff --git a/src/auth0/myorganization/types/organization_member_roles_change_request_content.py b/src/auth0/myorganization/types/organization_member_roles_change_request_content.py
new file mode 100644
index 0000000..1c60589
--- /dev/null
+++ b/src/auth0/myorganization/types/organization_member_roles_change_request_content.py
@@ -0,0 +1,20 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .role_id import RoleId
+
+
+class OrganizationMemberRolesChangeRequestContent(UniversalBaseModel):
+ role_ids: typing.List[RoleId]
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/src/auth0/myorganization/types/org_member_role.py b/src/auth0/myorganization/types/role.py
similarity index 82%
rename from src/auth0/myorganization/types/org_member_role.py
rename to src/auth0/myorganization/types/role.py
index 3b462c0..2860305 100644
--- a/src/auth0/myorganization/types/org_member_role.py
+++ b/src/auth0/myorganization/types/role.py
@@ -4,11 +4,11 @@
import pydantic
from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
-from .org_member_role_id import OrgMemberRoleId
+from .role_id import RoleId
-class OrgMemberRole(UniversalBaseModel):
- id: OrgMemberRoleId
+class Role(UniversalBaseModel):
+ id: RoleId
name: str
description: typing.Optional[str] = None
diff --git a/src/auth0/myorganization/types/org_member_role_id.py b/src/auth0/myorganization/types/role_id.py
similarity index 86%
rename from src/auth0/myorganization/types/org_member_role_id.py
rename to src/auth0/myorganization/types/role_id.py
index d3e804d..1c4f987 100644
--- a/src/auth0/myorganization/types/org_member_role_id.py
+++ b/src/auth0/myorganization/types/role_id.py
@@ -1,6 +1,6 @@
# This file was auto-generated by Fern from our API Definition.
-OrgMemberRoleId = str
+RoleId = str
"""
The ID of a role that can be assigned to a member of an organization.
"""
diff --git a/tests/wire/test_organization_invitations.py b/tests/wire/test_organization_invitations.py
new file mode 100644
index 0000000..f4be29d
--- /dev/null
+++ b/tests/wire/test_organization_invitations.py
@@ -0,0 +1,67 @@
+from .conftest import get_client, verify_request_count
+
+from auth0.myorganization import CreateMemberInvitationInvitee, MemberInvitationInviter
+
+
+def test_organization_invitations_list_() -> None:
+ """Test list endpoint with WireMock"""
+ test_id = "organization.invitations.list_.0"
+ client = get_client(test_id)
+ client.organization.invitations.list(
+ fields="fields",
+ include_fields=True,
+ from_="from",
+ take=1,
+ sort="sort",
+ )
+ verify_request_count(
+ test_id,
+ "GET",
+ "/member-invitations",
+ {"fields": "fields", "include_fields": "true", "from": "from", "take": "1", "sort": "sort"},
+ 1,
+ )
+
+
+def test_organization_invitations_create() -> None:
+ """Test create endpoint with WireMock"""
+ test_id = "organization.invitations.create.0"
+ client = get_client(test_id)
+ client.organization.invitations.create(
+ invitees=[
+ CreateMemberInvitationInvitee(
+ email="user@example.com",
+ roles=["rol_0000000000000001"],
+ )
+ ],
+ inviter=MemberInvitationInviter(
+ name="Allison the Admin",
+ ),
+ identity_provider_id="con_2CZPv6IY0gWzDaQJ",
+ ttl_sec=3600,
+ )
+ verify_request_count(test_id, "POST", "/member-invitations", None, 1)
+
+
+def test_organization_invitations_get() -> None:
+ """Test get endpoint with WireMock"""
+ test_id = "organization.invitations.get.0"
+ client = get_client(test_id)
+ client.organization.invitations.get(
+ invitation_id="invitation_id",
+ fields="fields",
+ include_fields=True,
+ )
+ verify_request_count(
+ test_id, "GET", "/member-invitations/invitation_id", {"fields": "fields", "include_fields": "true"}, 1
+ )
+
+
+def test_organization_invitations_delete() -> None:
+ """Test delete endpoint with WireMock"""
+ test_id = "organization.invitations.delete.0"
+ client = get_client(test_id)
+ client.organization.invitations.delete(
+ invitation_id="invitation_id",
+ )
+ verify_request_count(test_id, "DELETE", "/member-invitations/invitation_id", None, 1)
diff --git a/tests/wire/test_organization_members.py b/tests/wire/test_organization_members.py
new file mode 100644
index 0000000..7ed97dc
--- /dev/null
+++ b/tests/wire/test_organization_members.py
@@ -0,0 +1,28 @@
+from .conftest import get_client, verify_request_count
+
+
+def test_organization_members_list_() -> None:
+ """Test list endpoint with WireMock"""
+ test_id = "organization.members.list_.0"
+ client = get_client(test_id)
+ client.organization.members.list(
+ fields="fields",
+ include_fields=True,
+ from_="from",
+ take=1,
+ )
+ verify_request_count(
+ test_id, "GET", "/members", {"fields": "fields", "include_fields": "true", "from": "from", "take": "1"}, 1
+ )
+
+
+def test_organization_members_get() -> None:
+ """Test get endpoint with WireMock"""
+ test_id = "organization.members.get.0"
+ client = get_client(test_id)
+ client.organization.members.get(
+ user_id="user_id",
+ fields="fields",
+ include_fields=True,
+ )
+ verify_request_count(test_id, "GET", "/members/user_id", {"fields": "fields", "include_fields": "true"}, 1)
diff --git a/tests/wire/test_organization_members_roles.py b/tests/wire/test_organization_members_roles.py
new file mode 100644
index 0000000..fe58e88
--- /dev/null
+++ b/tests/wire/test_organization_members_roles.py
@@ -0,0 +1,35 @@
+from .conftest import get_client, verify_request_count
+
+
+def test_organization_members_roles_list_() -> None:
+ """Test list endpoint with WireMock"""
+ test_id = "organization.members.roles.list_.0"
+ client = get_client(test_id)
+ client.organization.members.roles.list(
+ user_id="user_id",
+ from_="from",
+ take=1,
+ )
+ verify_request_count(test_id, "GET", "/members/user_id/roles", {"from": "from", "take": "1"}, 1)
+
+
+def test_organization_members_roles_assign() -> None:
+ """Test assign endpoint with WireMock"""
+ test_id = "organization.members.roles.assign.0"
+ client = get_client(test_id)
+ client.organization.members.roles.assign(
+ user_id="user_id",
+ role_ids=["rol_SO2j0sFo9NFa3F9w"],
+ )
+ verify_request_count(test_id, "POST", "/members/user_id/roles", None, 1)
+
+
+def test_organization_members_roles_unassign() -> None:
+ """Test unassign endpoint with WireMock"""
+ test_id = "organization.members.roles.unassign.0"
+ client = get_client(test_id)
+ client.organization.members.roles.unassign(
+ user_id="user_id",
+ role_ids=["rol_SO2j0sFo9NFa3F9w"],
+ )
+ verify_request_count(test_id, "DELETE", "/members/user_id/roles", None, 1)
diff --git a/tests/wire/test_organization_memberships.py b/tests/wire/test_organization_memberships.py
new file mode 100644
index 0000000..e070c76
--- /dev/null
+++ b/tests/wire/test_organization_memberships.py
@@ -0,0 +1,11 @@
+from .conftest import get_client, verify_request_count
+
+
+def test_organization_memberships_delete_memberships() -> None:
+ """Test deleteMemberships endpoint with WireMock"""
+ test_id = "organization.memberships.delete_memberships.0"
+ client = get_client(test_id)
+ client.organization.memberships.delete_memberships(
+ members=["auth0|1234567890"],
+ )
+ verify_request_count(test_id, "POST", "/delete-memberships", None, 1)
diff --git a/tests/wire/test_organization_roles.py b/tests/wire/test_organization_roles.py
new file mode 100644
index 0000000..555526b
--- /dev/null
+++ b/tests/wire/test_organization_roles.py
@@ -0,0 +1,13 @@
+from .conftest import get_client, verify_request_count
+
+
+def test_organization_roles_list_() -> None:
+ """Test list endpoint with WireMock"""
+ test_id = "organization.roles.list_.0"
+ client = get_client(test_id)
+ client.organization.roles.list(
+ from_="from",
+ take=1,
+ name="name",
+ )
+ verify_request_count(test_id, "GET", "/roles", {"from": "from", "take": "1", "name": "name"}, 1)
diff --git a/wiremock/wiremock-mappings.json b/wiremock/wiremock-mappings.json
index 3ecaf66..13ed5f0 100644
--- a/wiremock/wiremock-mappings.json
+++ b/wiremock/wiremock-mappings.json
@@ -481,6 +481,330 @@
}
}
},
+ {
+ "id": "8a221b24-aed6-4bfe-bfdb-c4329d8e2181",
+ "name": "List members - default",
+ "request": {
+ "urlPathTemplate": "/members",
+ "method": "GET",
+ "headers": {
+ "Authorization": {
+ "matches": "Bearer .+"
+ }
+ },
+ "queryParameters": {
+ "fields": {
+ "equalTo": "fields"
+ },
+ "include_fields": {
+ "equalTo": "true"
+ },
+ "from": {
+ "equalTo": "from"
+ },
+ "take": {
+ "equalTo": "1"
+ }
+ }
+ },
+ "response": {
+ "status": 200,
+ "body": "{\n \"next\": \"next\",\n \"members\": [\n {\n \"email\": \"roadrunner@acme.com\",\n \"name\": \"name\",\n \"nickname\": \"nickname\",\n \"given_name\": \"given_name\",\n \"family_name\": \"family_name\",\n \"user_id\": \"auth0|123234235\",\n \"roles\": [\n {\n \"id\": \"rol_BKI0BKI0BKI0BKI0\",\n \"name\": \"role1\"\n },\n {\n \"id\": \"rol_BKW1BKIfBKd0BaI0\",\n \"name\": \"role2\"\n }\n ],\n \"created_at\": \"2024-01-15T09:30:00Z\",\n \"updated_at\": \"2024-01-15T09:30:00Z\",\n \"last_login\": \"2024-01-15T09:30:00Z\",\n \"phone_number\": \"phone_number\"\n }\n ]\n}",
+ "headers": {
+ "Content-Type": "application/json"
+ }
+ },
+ "uuid": "8a221b24-aed6-4bfe-bfdb-c4329d8e2181",
+ "persistent": true,
+ "priority": 3,
+ "metadata": {
+ "mocklab": {
+ "created": {
+ "at": "2020-01-01T00:00:00.000Z",
+ "via": "SYSTEM"
+ }
+ }
+ },
+ "postServeActions": []
+ },
+ {
+ "id": "fae3f220-6c07-455b-b799-d153a5d10715",
+ "name": "Get a member - default",
+ "request": {
+ "urlPathTemplate": "/members/{user_id}",
+ "method": "GET",
+ "headers": {
+ "Authorization": {
+ "matches": "Bearer .+"
+ }
+ },
+ "pathParameters": {
+ "user_id": {
+ "equalTo": "user_id"
+ }
+ },
+ "queryParameters": {
+ "fields": {
+ "equalTo": "fields"
+ },
+ "include_fields": {
+ "equalTo": "true"
+ }
+ }
+ },
+ "response": {
+ "status": 200,
+ "body": "{\n \"email\": \"roadrunner@acme.com\",\n \"name\": \"roadrunner\",\n \"nickname\": \"beepbeep\",\n \"given_name\": \"Road\",\n \"family_name\": \"Runner\",\n \"user_id\": \"auth0|123234235\",\n \"roles\": [\n {\n \"id\": \"rol_BKI0BKI0BKI0BKI0\",\n \"name\": \"role1\",\n \"description\": \"description\"\n },\n {\n \"id\": \"rol_BKW1BKIfBKd0BaI0\",\n \"name\": \"role2\",\n \"description\": \"description\"\n }\n ],\n \"created_at\": \"2025-05-01T12:00:00Z\",\n \"updated_at\": \"2025-05-02T12:00:00Z\",\n \"last_login\": \"2025-05-03T12:00:00Z\",\n \"phone_number\": \"phone_number\"\n}",
+ "headers": {
+ "Content-Type": "application/json"
+ }
+ },
+ "uuid": "fae3f220-6c07-455b-b799-d153a5d10715",
+ "persistent": true,
+ "priority": 3,
+ "metadata": {
+ "mocklab": {
+ "created": {
+ "at": "2020-01-01T00:00:00.000Z",
+ "via": "SYSTEM"
+ }
+ }
+ }
+ },
+ {
+ "id": "615842a1-853a-4670-8ba3-e4825a6bd0af",
+ "name": "Delete memberships - default",
+ "request": {
+ "urlPathTemplate": "/delete-memberships",
+ "method": "POST",
+ "headers": {
+ "Authorization": {
+ "matches": "Bearer .+"
+ }
+ }
+ },
+ "response": {
+ "status": 200,
+ "body": "\"\"",
+ "headers": {
+ "Content-Type": "application/json"
+ }
+ },
+ "uuid": "615842a1-853a-4670-8ba3-e4825a6bd0af",
+ "persistent": true,
+ "priority": 3,
+ "metadata": {
+ "mocklab": {
+ "created": {
+ "at": "2020-01-01T00:00:00.000Z",
+ "via": "SYSTEM"
+ }
+ }
+ }
+ },
+ {
+ "id": "78503755-437a-4f13-bb75-fbf050b174b1",
+ "name": "List member invitations - default",
+ "request": {
+ "urlPathTemplate": "/member-invitations",
+ "method": "GET",
+ "headers": {
+ "Authorization": {
+ "matches": "Bearer .+"
+ }
+ },
+ "queryParameters": {
+ "fields": {
+ "equalTo": "fields"
+ },
+ "include_fields": {
+ "equalTo": "true"
+ },
+ "from": {
+ "equalTo": "from"
+ },
+ "take": {
+ "equalTo": "1"
+ },
+ "sort": {
+ "equalTo": "sort"
+ }
+ }
+ },
+ "response": {
+ "status": 200,
+ "body": "{\n \"next\": \"next\",\n \"invitations\": [\n {\n \"id\": \"uinv_12345678abcdefgh\",\n \"organization_id\": \"org_12345678abcdefgh\",\n \"inviter\": {\n \"name\": \"Allison the Admin\"\n },\n \"invitee\": {\n \"email\": \"user@example.com\"\n },\n \"identity_provider_id\": \"con_2CZPv6IY0gWzDaQJ\",\n \"created_at\": \"2025-04-11T20:11:45Z\",\n \"expires_at\": \"2025-04-11T20:11:45Z\",\n \"roles\": [\n \"rol_BKW1BKIfBKd0BaI0\"\n ],\n \"invitation_url\": \"https://example.auth0.com/login?invitation=uinv_12345678abcdefgh&organization=org_12345678abcdefgh\",\n \"ticket_id\": \"1asdfasd23usjdef\"\n }\n ]\n}",
+ "headers": {
+ "Content-Type": "application/json"
+ }
+ },
+ "uuid": "78503755-437a-4f13-bb75-fbf050b174b1",
+ "persistent": true,
+ "priority": 3,
+ "metadata": {
+ "mocklab": {
+ "created": {
+ "at": "2020-01-01T00:00:00.000Z",
+ "via": "SYSTEM"
+ }
+ }
+ },
+ "postServeActions": []
+ },
+ {
+ "id": "55c94d5e-e08c-471f-b76f-111cd557f5ca",
+ "name": "Create member invitations - default",
+ "request": {
+ "urlPathTemplate": "/member-invitations",
+ "method": "POST",
+ "headers": {
+ "Authorization": {
+ "matches": "Bearer .+"
+ }
+ }
+ },
+ "response": {
+ "status": 201,
+ "body": "[\n {\n \"id\": \"uinv_12345678abcdefgh\",\n \"organization_id\": \"org_12345678abcdefgh\",\n \"inviter\": {\n \"name\": \"Allison the Admin\"\n },\n \"invitee\": {\n \"email\": \"user@example.com\"\n },\n \"identity_provider_id\": \"con_2CZPv6IY0gWzDaQJ\",\n \"created_at\": \"2025-04-11T20:11:45Z\",\n \"expires_at\": \"2025-04-11T20:11:45Z\",\n \"roles\": [\n \"rol_BKW1BKIfBKd0BaI0\"\n ],\n \"invitation_url\": \"https://example.auth0.com/login?invitation=uinv_12345678abcdefgh&organization=org_12345678abcdefgh\",\n \"ticket_id\": \"1asdfasd23usjdef\"\n }\n]",
+ "headers": {
+ "Content-Type": "application/json"
+ }
+ },
+ "uuid": "55c94d5e-e08c-471f-b76f-111cd557f5ca",
+ "persistent": true,
+ "priority": 3,
+ "metadata": {
+ "mocklab": {
+ "created": {
+ "at": "2020-01-01T00:00:00.000Z",
+ "via": "SYSTEM"
+ }
+ }
+ }
+ },
+ {
+ "id": "1a5a7d10-bc8e-44b0-ab8a-e611721f0d64",
+ "name": "Get a member invitation - default",
+ "request": {
+ "urlPathTemplate": "/member-invitations/{invitation_id}",
+ "method": "GET",
+ "headers": {
+ "Authorization": {
+ "matches": "Bearer .+"
+ }
+ },
+ "pathParameters": {
+ "invitation_id": {
+ "equalTo": "invitation_id"
+ }
+ },
+ "queryParameters": {
+ "fields": {
+ "equalTo": "fields"
+ },
+ "include_fields": {
+ "equalTo": "true"
+ }
+ }
+ },
+ "response": {
+ "status": 200,
+ "body": "{\n \"id\": \"uinv_12345678abcdefgh\",\n \"organization_id\": \"org_12345678abcdefgh\",\n \"inviter\": {\n \"name\": \"Allison the Admin\"\n },\n \"invitee\": {\n \"email\": \"user@example.com\"\n },\n \"identity_provider_id\": \"con_2CZPv6IY0gWzDaQJ\",\n \"created_at\": \"2025-04-11T20:11:45Z\",\n \"expires_at\": \"2025-04-11T20:11:45Z\",\n \"roles\": [\n \"rol_BKW1BKIfBKd0BaI0\"\n ],\n \"invitation_url\": \"https://example.auth0.com/login?invitation=uinv_12345678abcdefgh&organization=org_12345678abcdefgh\",\n \"ticket_id\": \"1asdfasd23usjdef\"\n}",
+ "headers": {
+ "Content-Type": "application/json"
+ }
+ },
+ "uuid": "1a5a7d10-bc8e-44b0-ab8a-e611721f0d64",
+ "persistent": true,
+ "priority": 3,
+ "metadata": {
+ "mocklab": {
+ "created": {
+ "at": "2020-01-01T00:00:00.000Z",
+ "via": "SYSTEM"
+ }
+ }
+ }
+ },
+ {
+ "id": "44e77096-1347-4434-83ae-3fad0ed2847b",
+ "name": "Revoke a member invitation - default",
+ "request": {
+ "urlPathTemplate": "/member-invitations/{invitation_id}",
+ "method": "DELETE",
+ "headers": {
+ "Authorization": {
+ "matches": "Bearer .+"
+ }
+ },
+ "pathParameters": {
+ "invitation_id": {
+ "equalTo": "invitation_id"
+ }
+ }
+ },
+ "response": {
+ "status": 200,
+ "body": "\"\"",
+ "headers": {
+ "Content-Type": "application/json"
+ }
+ },
+ "uuid": "44e77096-1347-4434-83ae-3fad0ed2847b",
+ "persistent": true,
+ "priority": 3,
+ "metadata": {
+ "mocklab": {
+ "created": {
+ "at": "2020-01-01T00:00:00.000Z",
+ "via": "SYSTEM"
+ }
+ }
+ }
+ },
+ {
+ "id": "d7eb85d6-a74e-47c7-b669-d9c33ad0aa81",
+ "name": "List roles - default",
+ "request": {
+ "urlPathTemplate": "/roles",
+ "method": "GET",
+ "headers": {
+ "Authorization": {
+ "matches": "Bearer .+"
+ }
+ },
+ "queryParameters": {
+ "from": {
+ "equalTo": "from"
+ },
+ "take": {
+ "equalTo": "1"
+ },
+ "name": {
+ "equalTo": "name"
+ }
+ }
+ },
+ "response": {
+ "status": 200,
+ "body": "{\n \"roles\": [\n {\n \"id\": \"rol_BKI0BKI0BKI0BKI0\",\n \"name\": \"Admin\",\n \"description\": \"Administrator role with full access\"\n },\n {\n \"id\": \"rol_BKI0BKI0BKI0BKI1\",\n \"name\": \"User\",\n \"description\": \"Standard user role with limited access\"\n }\n ],\n \"next\": \"abc123\"\n}",
+ "headers": {
+ "Content-Type": "application/json"
+ }
+ },
+ "uuid": "d7eb85d6-a74e-47c7-b669-d9c33ad0aa81",
+ "persistent": true,
+ "priority": 3,
+ "metadata": {
+ "mocklab": {
+ "created": {
+ "at": "2020-01-01T00:00:00.000Z",
+ "via": "SYSTEM"
+ }
+ }
+ },
+ "postServeActions": []
+ },
{
"id": "a032561e-549d-47e8-8ebb-dad06d2a6ce4",
"name": "Get Identity Provider configuration - default",
@@ -914,9 +1238,125 @@
}
}
}
+ },
+ {
+ "id": "3b86d015-abf6-4c97-b708-237ed2ad30e3",
+ "name": "List member roles - default",
+ "request": {
+ "urlPathTemplate": "/members/{user_id}/roles",
+ "method": "GET",
+ "headers": {
+ "Authorization": {
+ "matches": "Bearer .+"
+ }
+ },
+ "pathParameters": {
+ "user_id": {
+ "equalTo": "user_id"
+ }
+ },
+ "queryParameters": {
+ "from": {
+ "equalTo": "from"
+ },
+ "take": {
+ "equalTo": "1"
+ }
+ }
+ },
+ "response": {
+ "status": 200,
+ "body": "{\n \"next\": \"next\",\n \"roles\": [\n {\n \"id\": \"rol_SO2j0sFo9NFa3F9w\",\n \"name\": \"role1\",\n \"description\": \"role1 description\"\n },\n {\n \"id\": \"rol_BO2j1sFo9NFa3F9w\",\n \"name\": \"role2\",\n \"description\": \"role2 description\"\n }\n ]\n}",
+ "headers": {
+ "Content-Type": "application/json"
+ }
+ },
+ "uuid": "3b86d015-abf6-4c97-b708-237ed2ad30e3",
+ "persistent": true,
+ "priority": 3,
+ "metadata": {
+ "mocklab": {
+ "created": {
+ "at": "2020-01-01T00:00:00.000Z",
+ "via": "SYSTEM"
+ }
+ }
+ }
+ },
+ {
+ "id": "fc74ad7a-df90-438a-80ba-908648d37c76",
+ "name": "Assign roles to a member - default",
+ "request": {
+ "urlPathTemplate": "/members/{user_id}/roles",
+ "method": "POST",
+ "headers": {
+ "Authorization": {
+ "matches": "Bearer .+"
+ }
+ },
+ "pathParameters": {
+ "user_id": {
+ "equalTo": "user_id"
+ }
+ }
+ },
+ "response": {
+ "status": 200,
+ "body": "\"\"",
+ "headers": {
+ "Content-Type": "application/json"
+ }
+ },
+ "uuid": "fc74ad7a-df90-438a-80ba-908648d37c76",
+ "persistent": true,
+ "priority": 3,
+ "metadata": {
+ "mocklab": {
+ "created": {
+ "at": "2020-01-01T00:00:00.000Z",
+ "via": "SYSTEM"
+ }
+ }
+ }
+ },
+ {
+ "id": "da82679e-4aa8-4fe7-b946-2b37ffeb5fdb",
+ "name": "Remove roles from a member - default",
+ "request": {
+ "urlPathTemplate": "/members/{user_id}/roles",
+ "method": "DELETE",
+ "headers": {
+ "Authorization": {
+ "matches": "Bearer .+"
+ }
+ },
+ "pathParameters": {
+ "user_id": {
+ "equalTo": "user_id"
+ }
+ }
+ },
+ "response": {
+ "status": 200,
+ "body": "\"\"",
+ "headers": {
+ "Content-Type": "application/json"
+ }
+ },
+ "uuid": "da82679e-4aa8-4fe7-b946-2b37ffeb5fdb",
+ "persistent": true,
+ "priority": 3,
+ "metadata": {
+ "mocklab": {
+ "created": {
+ "at": "2020-01-01T00:00:00.000Z",
+ "via": "SYSTEM"
+ }
+ }
+ }
}
],
"meta": {
- "total": 26
+ "total": 37
}
}
\ No newline at end of file
From e3544a7adc62d759c70fd7efb333eceb0fee3afc Mon Sep 17 00:00:00 2001
From: Snehil Kishore
Date: Tue, 16 Jun 2026 17:48:05 +0530
Subject: [PATCH 2/7] chore: Drop Python 3.9 support and bump dev dependencies
Removes Python 3.9 from the test matrix, package classifiers, and the
publish workflow, raising the minimum to 3.10. The unpinned poetry install
in CI fails on 3.9 because a current poetry dependency uses
dataclass(slots=...), which only exists on 3.10+. This aligns with
auth0-python, which already moved its matrix to 3.10-3.13.
Also rolls in the pending Dependabot dev-dependency bumps (mypy,
requests, types-requests, types-python-dateutil, pytest-xdist) via an
updated lock file.
---
.github/workflows/publish.yml | 2 +-
.github/workflows/test.yml | 2 +-
README.md | 2 +-
poetry.lock | 270 ++++++++++++++++++++++++++--------
pyproject.toml | 3 +-
5 files changed, 211 insertions(+), 68 deletions(-)
diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml
index 2843a09..6bb196e 100644
--- a/.github/workflows/publish.yml
+++ b/.github/workflows/publish.yml
@@ -68,7 +68,7 @@ jobs:
- name: Configure Python
uses: actions/setup-python@v6
with:
- python-version: "3.9"
+ python-version: "3.12"
- name: Configure dependencies
run: |
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 8645d7d..6a6379b 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -24,7 +24,7 @@ jobs:
strategy:
matrix:
- python-version: ["3.9", "3.10", "3.11", "3.12"]
+ python-version: ["3.10", "3.11", "3.12"]
steps:
- name: Checkout code
diff --git a/README.md b/README.md
index 38d2eab..4fa5b95 100644
--- a/README.md
+++ b/README.md
@@ -23,7 +23,7 @@
This library supports the following tooling versions:
-- Python >= 3.9
+- Python >= 3.10
### Installation
diff --git a/poetry.lock b/poetry.lock
index 3e2d014..1d60108 100644
--- a/poetry.lock
+++ b/poetry.lock
@@ -278,7 +278,7 @@ description = "Backport of PEP 654 (exception groups)"
optional = false
python-versions = ">=3.7"
groups = ["main", "dev"]
-markers = "python_version < \"3.11\""
+markers = "python_version == \"3.10\""
files = [
{file = "exceptiongroup-1.3.1-py3-none-any.whl", hash = "sha256:a7a39a3bd276781e98394987d3a5701d0c4edffb633bb7a5144577f82c773598"},
{file = "exceptiongroup-1.3.1.tar.gz", hash = "sha256:8b412432c6055b0b7d14c310000ae93352ed6754f70fa8f7c34141f91c4e3219"},
@@ -391,64 +391,177 @@ files = [
{file = "iniconfig-2.1.0.tar.gz", hash = "sha256:3abbd2e30b36733fee78f9c7f7308f2d0050e88f0087fd25c2645f63c773e1c7"},
]
+[[package]]
+name = "librt"
+version = "0.11.0"
+description = "Mypyc runtime library"
+optional = false
+python-versions = ">=3.9"
+groups = ["dev"]
+markers = "platform_python_implementation != \"PyPy\""
+files = [
+ {file = "librt-0.11.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6e94ebfcfa2d5e9926d6c3b9aa4617ffc42a845b4321fb84021b872358c82a0f"},
+ {file = "librt-0.11.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ae627397a2f351560440d872d6f7c8dbb4072e57868e7b2fc5b8b430fe489d45"},
+ {file = "librt-0.11.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:dc329359321b67d24efdf4bc69012b0597001649544db662c001db5a0184794c"},
+ {file = "librt-0.11.0-cp310-cp310-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:7e82e642ab0f7608ce2fe53d76ca2280a9ee33a1b06556142c7c6fe80a86fc33"},
+ {file = "librt-0.11.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:88145c15c67731d54283d135b03244028c750cc9edc334a96a4f5950ebdb2884"},
+ {file = "librt-0.11.0-cp310-cp310-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:9d36a51b3d93320b686588e27123f4995804dbf1bce81df78c02fc3c6eea9280"},
+ {file = "librt-0.11.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d00f3ac06a2a8b246327f11e186a53a100a4d5c7ed52346367e5ec751d51586c"},
+ {file = "librt-0.11.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:461bbceede621f1ffb8839755f8663e886087ee7af16294cab7fb4d782c62eeb"},
+ {file = "librt-0.11.0-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:0cad8a4d6a8ff03c9b76f9414caccd78e7cfbc8a2e12fa334d8e1d9932753783"},
+ {file = "librt-0.11.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f37aa505b3cf60701562eddb32df74b12a9e380c207fd8b06dd157a943ac7ea0"},
+ {file = "librt-0.11.0-cp310-cp310-win32.whl", hash = "sha256:94663a21534637f0e787ec2a2a756022df6e5b7b2335a5cdd7d8e33d68a2af89"},
+ {file = "librt-0.11.0-cp310-cp310-win_amd64.whl", hash = "sha256:dec7db73758c2b54953fd8b7fe348c45188fe26b39ee18446196edd08453a5d4"},
+ {file = "librt-0.11.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:93d95bd45b7d58343d8b90d904450a545144eec19a002511163426f8ab1fae29"},
+ {file = "librt-0.11.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4ee278c769a713638cdacd4c0436d72156e75df3ebc0166ab2b9dc43acc386c9"},
+ {file = "librt-0.11.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f230cb1cbc9faaa616f9a678f530ebcf186e414b6bcbd88b960e4ba1b92428d5"},
+ {file = "librt-0.11.0-cp311-cp311-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:5d63c855d86938d9de93e265c9bd8c705b51ec494de5738340ee93767a686e4b"},
+ {file = "librt-0.11.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:993f028be9e96a08d31df3479ac80d99be374d17f3b78e4796b3fd3c913d4e89"},
+ {file = "librt-0.11.0-cp311-cp311-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:258d73a0aa66a055e65b2e4d1b8cdb23b9d132c5bb915d9547d804fcaed116cc"},
+ {file = "librt-0.11.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:0827efe7854718f04aaddf6496e96960a956e676fe1d0f04eb41511fd8ad06d5"},
+ {file = "librt-0.11.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:7753e57d6e12d019c0d8786f1c09c709f4c3fcc57c3887b24e36e6c06ec938b7"},
+ {file = "librt-0.11.0-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:11bd19822431cc21af9f27374e7ae2e58103c7d98bda823536a6c47f6bb2bb3d"},
+ {file = "librt-0.11.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:22bdf239b219d3993761a148ffa134b19e52e9989c84f845d5d7b71d70a17412"},
+ {file = "librt-0.11.0-cp311-cp311-win32.whl", hash = "sha256:46c60b61e308eb535fbd6fa622b1ee1bb2815691c1ad9c98bf7b84952ec3bc8d"},
+ {file = "librt-0.11.0-cp311-cp311-win_amd64.whl", hash = "sha256:902e546ff044f579ff1c953ff5fce97b636fe9e3943996b2177710c6ef076f73"},
+ {file = "librt-0.11.0-cp311-cp311-win_arm64.whl", hash = "sha256:65ac3bc20f78aa0ee5ae84baa68917f89fef4af63e941084dd019a0d0e749f0c"},
+ {file = "librt-0.11.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b87504f1690a23b9a2cca841191a04f83895d4fc2dd04df91d82b1a04ca2ad46"},
+ {file = "librt-0.11.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40071fc5fe0ce8daa6de616702314a01e1250711682b0523d6ab8d4525910cb3"},
+ {file = "librt-0.11.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:137e79445c896a0ea7b265f52d23954e05b64222ee1af69e2cb34219067cbb67"},
+ {file = "librt-0.11.0-cp312-cp312-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:cca6644054e78746d8d4ef238681f9c34ff8b584fe6b988ecebb8db3b15e622a"},
+ {file = "librt-0.11.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d5b0eea49f5562861ee8d757a32ef7d559c1d35be2aaaa1ec28941d74c9ffc8a"},
+ {file = "librt-0.11.0-cp312-cp312-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:0d1029d7e1ae1a7e647ed6fb5df8c4ce2dffefb7a9f5fd1376a4554d96dac09f"},
+ {file = "librt-0.11.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:bc3ce6b33c5828d9e80592011a5c584cb2ce86edbc4088405f70da47dc1d1b3b"},
+ {file = "librt-0.11.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:936c5995f3514a42111f20099397d8177c79b4d7e70961e396c6f5a0a3566766"},
+ {file = "librt-0.11.0-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:9bc0ca6ad9381cbe8e4aa6e5726e4c80c78115a6e9723c599ed1d73e092bc49d"},
+ {file = "librt-0.11.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:070aa8c26c0a74774317a72df8851facc7f0f012a5b406557ac56992d92e1ec8"},
+ {file = "librt-0.11.0-cp312-cp312-win32.whl", hash = "sha256:6bf14feb84b05ae945277395451998c89c54d0def4070eb5c08de544930b245a"},
+ {file = "librt-0.11.0-cp312-cp312-win_amd64.whl", hash = "sha256:75672f0bc524ede266287d532d7923dbce94c7514ad07627bac3d0c6d92cc4d9"},
+ {file = "librt-0.11.0-cp312-cp312-win_arm64.whl", hash = "sha256:2f10cf143e4a9bb0f4f5af568a00df94a2d69ef41c2579584454bb0fe5cc642c"},
+ {file = "librt-0.11.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:78dc31f7fdfe9c9d0eb0e8f42d139db230e826415bbcabd9f0e9faaaee909894"},
+ {file = "librt-0.11.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:fa475675db22290c3158e1d42326d0f5a65f04f44a0e68c3630a25b53560fb9c"},
+ {file = "librt-0.11.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:621db29691044bdeda22e789e482e1b0f3a985d90e3426c9c6d17606416205ea"},
+ {file = "librt-0.11.0-cp313-cp313-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:a9010e2ed5b3a9e158c5fd966b3ab7e834bb3d3aacc8f66c91dd4b57a3799230"},
+ {file = "librt-0.11.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7c39513d8b7477a2e1ed8c43fc21c524e8d5a0f8d4e8b7b074dbdbe7820a08e2"},
+ {file = "librt-0.11.0-cp313-cp313-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:7aef3cf1d5af86e770ab04bfd993dfc4ae8b8c17f66fb77dd4a7d50de7bbb1a3"},
+ {file = "librt-0.11.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:557183ddc36babe46b27dd60facbd5adb4492181a5be887587d57cda6e092f21"},
+ {file = "librt-0.11.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:83d3e1f72bd42f6c5c0b7daec530c3f829bd02db42c70b8ddf0c2d90a2459930"},
+ {file = "librt-0.11.0-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:4ce1f21fbe589bc1afd7872dece84fb0e1144f794a288e58a10d2c54a55c43be"},
+ {file = "librt-0.11.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:970b09f7044ea2b64c9da42fd3d335666518cfd1c6e8a182c95da73d0214b41e"},
+ {file = "librt-0.11.0-cp313-cp313-win32.whl", hash = "sha256:78fddc31cd4d3caa897ad5d31f856b1faadc9474021ad6cb182b9018793e254e"},
+ {file = "librt-0.11.0-cp313-cp313-win_amd64.whl", hash = "sha256:8ca8aa88751a775870b764e93bad5135385f563cb8dcee399abf034ea4d3cb47"},
+ {file = "librt-0.11.0-cp313-cp313-win_arm64.whl", hash = "sha256:96f044bb325fd9cf1a723015638c219e9143f0dfbc0ca54c565df2b7fc748b44"},
+ {file = "librt-0.11.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:4a017a95e5837dc15a8c5661d60e05daa96b90908b1aa6b7acdf443cd25c8ebd"},
+ {file = "librt-0.11.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:b1ecbd9819deccc39b7542bf4d2a740d8a620694d39989e58661d3763458f8d4"},
+ {file = "librt-0.11.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7da327dacd7be8f8ec36547373550744a3cc0e536d54665cd83f8bcd961200e8"},
+ {file = "librt-0.11.0-cp314-cp314-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:0dc56b1f8d06e60db362cc3fdae206681817f86ce4725d34511473487f12a34b"},
+ {file = "librt-0.11.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:05fb8fb2ab90e21c8d12ea240d744ad514da9baf381ebfa70d91d20d21713175"},
+ {file = "librt-0.11.0-cp314-cp314-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:cae74872be221df4374d10fec61f93ed1513b9546ea84f2c0bf73ab3e9bd0b03"},
+ {file = "librt-0.11.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:32bcc918c0148eb7e3d57385125bac7e5f9e4359d05f07448b09f6f778c2f31c"},
+ {file = "librt-0.11.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:f9743fc99135d5f78d2454435615f6dec0473ca507c26ce9d92b10b562a280d3"},
+ {file = "librt-0.11.0-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:5ba067f4aadae8fda802d91d2124c90c42195ff32d9161d3549e6d05cfe26f96"},
+ {file = "librt-0.11.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:de3bf945454d032f9e390b85c4072e0a0570bf825421c8be0e71209fa65e1abe"},
+ {file = "librt-0.11.0-cp314-cp314-win32.whl", hash = "sha256:d2277a05f6dcb9fd13db9566aac4fabd68c3ea1ea46ee5567d4eef8efa495a2f"},
+ {file = "librt-0.11.0-cp314-cp314-win_amd64.whl", hash = "sha256:ab73e8db5e3f564d812c1f5c3a175930a5f9bc96ccb5e3b22a34d7858b401cf7"},
+ {file = "librt-0.11.0-cp314-cp314-win_arm64.whl", hash = "sha256:aea3caa317752e3a466fa8af45d91ee0ea8c7fdd96e42b0a8dd9b76a7931eba1"},
+ {file = "librt-0.11.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:d1b36540d7aaf9b9101b3a6f376c8d8e9f7a9aec93ed05918f2c69d493ffef72"},
+ {file = "librt-0.11.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:efbb343ab2ce3540f4ecbe6315d677ed70f37cd9a72b1e58066c918ca83acbaa"},
+ {file = "librt-0.11.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:aa0dd688aab3f7914d3e6e5e3554978e0383312fb8e771d84be008a35b9ee548"},
+ {file = "librt-0.11.0-cp314-cp314t-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:f5fb36b8c6c63fdcbb1d526d94c0d1331610d43f4118cc1beb4efef4f3faacb2"},
+ {file = "librt-0.11.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4a9a237d13addb93715b6fee74023d5ee3469b53fce527626c0e088aa585805f"},
+ {file = "librt-0.11.0-cp314-cp314t-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:5ddd17bd87b2c56ddd60e546a7984a2e64c4e8eab92fb4cf3830a48ad5469d51"},
+ {file = "librt-0.11.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:bd43992b4473d42f12ff9e68326079f0696d9d4e6000e8f39a0238d482ba6ee2"},
+ {file = "librt-0.11.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:f8e3e8056dd674e279741485e2e512d6e9a751c7455809d0114e6ebf8d781085"},
+ {file = "librt-0.11.0-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:c1f708d8ae9c56cf38a903c44297243d2ec83fd82b396b977e0144a3e76217e3"},
+ {file = "librt-0.11.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:0add982e0e7b9fc14cf4b33789d5f13f66581889b88c2f58099f6ce8f92617bd"},
+ {file = "librt-0.11.0-cp314-cp314t-win32.whl", hash = "sha256:2b481d846ac894c4e8403c5fd0e87c5d11d6499e404b474602508a224ff531c8"},
+ {file = "librt-0.11.0-cp314-cp314t-win_amd64.whl", hash = "sha256:28edb433edde181112a908c78907af28f964eabc15f4dd16c9d66c834302677c"},
+ {file = "librt-0.11.0-cp314-cp314t-win_arm64.whl", hash = "sha256:dee008f20b542e3cd162ba338a7f9ec0f6d23d395f66fe8aeeec3c9d067ea253"},
+ {file = "librt-0.11.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6bd72d903911d995ab666dbd1871f8b1e80925a699af8063fbf50053329fb05f"},
+ {file = "librt-0.11.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0ef69ac715f3cd8e5cd252cb2aebfa72c015492aacc339d5d7bf8fef3c62c677"},
+ {file = "librt-0.11.0-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:624a40c4a4ad7773315c287276cd024509b2c66ff5904f504bfc08d2c70293ab"},
+ {file = "librt-0.11.0-cp39-cp39-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:41dc19fe150b69716c8ece4f76773a9e8813fe3e35e032a58b4d46423fb8d7c0"},
+ {file = "librt-0.11.0-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4e8bd98ea9c47ae90b319a087ab28dac493f1ffbc1ecd1f28fcdbf3b7e1108d1"},
+ {file = "librt-0.11.0-cp39-cp39-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:84308fc49423ce6475d1c5d1985cd69a8ca9f0325fc7d5f81bb690a3f3625d4e"},
+ {file = "librt-0.11.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:ff0fbaf5f44a21beeb0110f2ab64f45135a9536a834b79c0d1ef018f2786bbfa"},
+ {file = "librt-0.11.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:9c028a9442a18e266955d364ce42259136e79a7ba14d773e0d778d5f70cd56f1"},
+ {file = "librt-0.11.0-cp39-cp39-musllinux_1_2_riscv64.whl", hash = "sha256:9f1692105a02bcf853f355032a5fdc5494358ef83d8fd22d16de375c85cec3f5"},
+ {file = "librt-0.11.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7a80a71e1fda83cc752a9141e87aae7fef279538597564d670e9ce513f286192"},
+ {file = "librt-0.11.0-cp39-cp39-win32.whl", hash = "sha256:140695816ddf3c86eb972981a26f35efd871c44b0c3aed44c8cd01749386617f"},
+ {file = "librt-0.11.0-cp39-cp39-win_amd64.whl", hash = "sha256:92f7ff819c197fc30473190a12c2856f325ac90aabfccbeb2072d28cc2e234e3"},
+ {file = "librt-0.11.0.tar.gz", hash = "sha256:075dc3ef4458a278e0195cbf6ac9d38808d9b906c5a6c7f7f79c3888276a3fb1"},
+]
+
[[package]]
name = "mypy"
-version = "1.14.1"
+version = "1.20.2"
description = "Optional static typing for Python"
optional = false
-python-versions = ">=3.8"
+python-versions = ">=3.10"
groups = ["dev"]
files = [
- {file = "mypy-1.14.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:52686e37cf13d559f668aa398dd7ddf1f92c5d613e4f8cb262be2fb4fedb0fcb"},
- {file = "mypy-1.14.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1fb545ca340537d4b45d3eecdb3def05e913299ca72c290326be19b3804b39c0"},
- {file = "mypy-1.14.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:90716d8b2d1f4cd503309788e51366f07c56635a3309b0f6a32547eaaa36a64d"},
- {file = "mypy-1.14.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2ae753f5c9fef278bcf12e1a564351764f2a6da579d4a81347e1d5a15819997b"},
- {file = "mypy-1.14.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:e0fe0f5feaafcb04505bcf439e991c6d8f1bf8b15f12b05feeed96e9e7bf1427"},
- {file = "mypy-1.14.1-cp310-cp310-win_amd64.whl", hash = "sha256:7d54bd85b925e501c555a3227f3ec0cfc54ee8b6930bd6141ec872d1c572f81f"},
- {file = "mypy-1.14.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f995e511de847791c3b11ed90084a7a0aafdc074ab88c5a9711622fe4751138c"},
- {file = "mypy-1.14.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d64169ec3b8461311f8ce2fd2eb5d33e2d0f2c7b49116259c51d0d96edee48d1"},
- {file = "mypy-1.14.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ba24549de7b89b6381b91fbc068d798192b1b5201987070319889e93038967a8"},
- {file = "mypy-1.14.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:183cf0a45457d28ff9d758730cd0210419ac27d4d3f285beda038c9083363b1f"},
- {file = "mypy-1.14.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f2a0ecc86378f45347f586e4163d1769dd81c5a223d577fe351f26b179e148b1"},
- {file = "mypy-1.14.1-cp311-cp311-win_amd64.whl", hash = "sha256:ad3301ebebec9e8ee7135d8e3109ca76c23752bac1e717bc84cd3836b4bf3eae"},
- {file = "mypy-1.14.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:30ff5ef8519bbc2e18b3b54521ec319513a26f1bba19a7582e7b1f58a6e69f14"},
- {file = "mypy-1.14.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:cb9f255c18052343c70234907e2e532bc7e55a62565d64536dbc7706a20b78b9"},
- {file = "mypy-1.14.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8b4e3413e0bddea671012b063e27591b953d653209e7a4fa5e48759cda77ca11"},
- {file = "mypy-1.14.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:553c293b1fbdebb6c3c4030589dab9fafb6dfa768995a453d8a5d3b23784af2e"},
- {file = "mypy-1.14.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:fad79bfe3b65fe6a1efaed97b445c3d37f7be9fdc348bdb2d7cac75579607c89"},
- {file = "mypy-1.14.1-cp312-cp312-win_amd64.whl", hash = "sha256:8fa2220e54d2946e94ab6dbb3ba0a992795bd68b16dc852db33028df2b00191b"},
- {file = "mypy-1.14.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:92c3ed5afb06c3a8e188cb5da4984cab9ec9a77ba956ee419c68a388b4595255"},
- {file = "mypy-1.14.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:dbec574648b3e25f43d23577309b16534431db4ddc09fda50841f1e34e64ed34"},
- {file = "mypy-1.14.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8c6d94b16d62eb3e947281aa7347d78236688e21081f11de976376cf010eb31a"},
- {file = "mypy-1.14.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d4b19b03fdf54f3c5b2fa474c56b4c13c9dbfb9a2db4370ede7ec11a2c5927d9"},
- {file = "mypy-1.14.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0c911fde686394753fff899c409fd4e16e9b294c24bfd5e1ea4675deae1ac6fd"},
- {file = "mypy-1.14.1-cp313-cp313-win_amd64.whl", hash = "sha256:8b21525cb51671219f5307be85f7e646a153e5acc656e5cebf64bfa076c50107"},
- {file = "mypy-1.14.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:7084fb8f1128c76cd9cf68fe5971b37072598e7c31b2f9f95586b65c741a9d31"},
- {file = "mypy-1.14.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:8f845a00b4f420f693f870eaee5f3e2692fa84cc8514496114649cfa8fd5e2c6"},
- {file = "mypy-1.14.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:44bf464499f0e3a2d14d58b54674dee25c031703b2ffc35064bd0df2e0fac319"},
- {file = "mypy-1.14.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c99f27732c0b7dc847adb21c9d47ce57eb48fa33a17bc6d7d5c5e9f9e7ae5bac"},
- {file = "mypy-1.14.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:bce23c7377b43602baa0bd22ea3265c49b9ff0b76eb315d6c34721af4cdf1d9b"},
- {file = "mypy-1.14.1-cp38-cp38-win_amd64.whl", hash = "sha256:8edc07eeade7ebc771ff9cf6b211b9a7d93687ff892150cb5692e4f4272b0837"},
- {file = "mypy-1.14.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3888a1816d69f7ab92092f785a462944b3ca16d7c470d564165fe703b0970c35"},
- {file = "mypy-1.14.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:46c756a444117c43ee984bd055db99e498bc613a70bbbc120272bd13ca579fbc"},
- {file = "mypy-1.14.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:27fc248022907e72abfd8e22ab1f10e903915ff69961174784a3900a8cba9ad9"},
- {file = "mypy-1.14.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:499d6a72fb7e5de92218db961f1a66d5f11783f9ae549d214617edab5d4dbdbb"},
- {file = "mypy-1.14.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:57961db9795eb566dc1d1b4e9139ebc4c6b0cb6e7254ecde69d1552bf7613f60"},
- {file = "mypy-1.14.1-cp39-cp39-win_amd64.whl", hash = "sha256:07ba89fdcc9451f2ebb02853deb6aaaa3d2239a236669a63ab3801bbf923ef5c"},
- {file = "mypy-1.14.1-py3-none-any.whl", hash = "sha256:b66a60cc4073aeb8ae00057f9c1f64d49e90f918fbcef9a977eb121da8b8f1d1"},
- {file = "mypy-1.14.1.tar.gz", hash = "sha256:7ec88144fe9b510e8475ec2f5f251992690fcf89ccb4500b214b4226abcd32d6"},
+ {file = "mypy-1.20.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:cf5a4db6dca263010e2c7bff081c89383c72d187ba2cf4c44759aac970e2f0c4"},
+ {file = "mypy-1.20.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:7b0e817b518bff7facd7f85ea05b643ad8bdcce684cf29784987b0a7c8e1f997"},
+ {file = "mypy-1.20.2-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:97d7b9a485b40f8ca425460e89bf1da2814625b2da627c0dcc6aa46c92631d14"},
+ {file = "mypy-1.20.2-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1e1c12f6d2db3d78b909b5f77513c11eb7f2dd2782b96a3ab6dffc7d44575c99"},
+ {file = "mypy-1.20.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:89dce27e142d25ffbc154c1819383b69f2e9234dc4ed4766f42e0e8cb264ab5c"},
+ {file = "mypy-1.20.2-cp310-cp310-win_amd64.whl", hash = "sha256:f376e37f9bf2a946872fc5fd1199c99310748e3c26c7a26683f13f8bdb756cbd"},
+ {file = "mypy-1.20.2-cp310-cp310-win_arm64.whl", hash = "sha256:6e2b469efd811707bc530fd1effef0f5d6eebcb7fe376affae69025da4b979a2"},
+ {file = "mypy-1.20.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4077797a273e56e8843d001e9dfe4ba10e33323d6ade647ff260e5cd97d9758c"},
+ {file = "mypy-1.20.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:cdecf62abcc4292500d7858aeae87a1f8f1150f4c4dd08fb0b336ee79b2a6df3"},
+ {file = "mypy-1.20.2-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c566c3a88b6ece59b3d70f65bedef17304f48eb52ff040a6a18214e1917b3254"},
+ {file = "mypy-1.20.2-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0deb80d062b2479f2c87ae568f89845afc71d11bc41b04179e58165fd9f31e98"},
+ {file = "mypy-1.20.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bba9ad231e92a3e424b3e56b65aa17704993425bba97e302c832f9466bb85bac"},
+ {file = "mypy-1.20.2-cp311-cp311-win_amd64.whl", hash = "sha256:baf593f2765fa3a6b1ef95807dbaa3d25b594f6a52adcc506a6b9cb115e1be67"},
+ {file = "mypy-1.20.2-cp311-cp311-win_arm64.whl", hash = "sha256:20175a1c0f49863946ec20b7f63255768058ac4f07d2b9ded6a6b46cfb5a9100"},
+ {file = "mypy-1.20.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4dbfcf869f6b0517f70cf0030ba6ea1d6645e132337a7d5204a18d8d5636c02b"},
+ {file = "mypy-1.20.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4b6481b228d072315b053210b01ac320e1be243dc17f9e5887ef167f23f5fae4"},
+ {file = "mypy-1.20.2-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:34397cdced6b90b836e38182076049fdb41424322e0b0728c946b0939ebdf9f6"},
+ {file = "mypy-1.20.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a5da6976f20cae27059ea8d0c86e7cef3de720e04c4bb9ee18e3690fdb792066"},
+ {file = "mypy-1.20.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:56908d7e08318d39f85b1f0c6cfd47b0cac1a130da677630dac0de3e0623e102"},
+ {file = "mypy-1.20.2-cp312-cp312-win_amd64.whl", hash = "sha256:d52ad8d78522da1d308789df651ee5379088e77c76cb1994858d40a426b343b9"},
+ {file = "mypy-1.20.2-cp312-cp312-win_arm64.whl", hash = "sha256:785b08db19c9f214dc37d65f7c165d19a30fcecb48abfa30f31b01b5acaabb58"},
+ {file = "mypy-1.20.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:edfbfca868cdd6bd8d974a60f8a3682f5565d3f5c99b327640cedd24c4264026"},
+ {file = "mypy-1.20.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:e2877a02380adfcdbc69071a0f74d6e9dbbf593c0dc9d174e1f223ffd5281943"},
+ {file = "mypy-1.20.2-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7488448de6007cd5177c6cea0517ac33b4c0f5ee9b5e9f2be51ce75511a85517"},
+ {file = "mypy-1.20.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bb9c2fa06887e21d6a3a868762acb82aec34e2c6fd0174064f27c93ede68ad15"},
+ {file = "mypy-1.20.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9d56a78b646f2e3daa865bc70cd5ec5a46c50045801ca8ff17a0c43abc97e3ee"},
+ {file = "mypy-1.20.2-cp313-cp313-win_amd64.whl", hash = "sha256:2a4102b03bb7481d9a91a6da8d174740c9c8c4401024684b9ca3b7cc5e49852f"},
+ {file = "mypy-1.20.2-cp313-cp313-win_arm64.whl", hash = "sha256:a95a9248b0c6fd933a442c03c3b113c3b61320086b88e2c444676d3fd1ca3330"},
+ {file = "mypy-1.20.2-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:419413398fe250aae057fd2fe50166b61077083c9b82754c341cf4fd73038f30"},
+ {file = "mypy-1.20.2-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:e73c07f23009962885c197ccb9b41356a30cc0e5a1d0c2ea8fd8fb1362d7f924"},
+ {file = "mypy-1.20.2-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0c64e5973df366b747646fc98da921f9d6eba9716d57d1db94a83c026a08e0fb"},
+ {file = "mypy-1.20.2-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5a65aa591af023864fd08a97da9974e919452cfe19cb146c8a5dc692626445dc"},
+ {file = "mypy-1.20.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:4fef51b01e638974a6e69885687e9bd40c8d1e09a6cd291cca0619625cf1f558"},
+ {file = "mypy-1.20.2-cp314-cp314-win_amd64.whl", hash = "sha256:913485a03f1bcf5d279409a9d2b9ed565c151f61c09f29991e5faa14033da4c8"},
+ {file = "mypy-1.20.2-cp314-cp314-win_arm64.whl", hash = "sha256:c3bae4f855d965b5453784300c12ffc63a548304ac7f99e55d4dc7c898673aa3"},
+ {file = "mypy-1.20.2-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:2de3dcea53babc1c3237a19002bc3d228ce1833278f093b8d619e06e7cc79609"},
+ {file = "mypy-1.20.2-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:52b176444e2e5054dfcbcb8c75b0b719865c96247b37407184bbfca5c353f2c2"},
+ {file = "mypy-1.20.2-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:688c3312e5dadb573a2c69c82af3a298d43ecf9e6d264e0f95df960b5f6ac19c"},
+ {file = "mypy-1.20.2-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:29752dbbf8cc53f89f6ac096d363314333045c257c9c75cbd189ca2de0455744"},
+ {file = "mypy-1.20.2-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:803203d2b6ea644982c644895c2f78b28d0e208bba7b27d9b921e0ec5eb207c6"},
+ {file = "mypy-1.20.2-cp314-cp314t-win_amd64.whl", hash = "sha256:9bcb8aa397ff0093c824182fd76a935a9ba7ad097fcbef80ae89bf6c1731d8ec"},
+ {file = "mypy-1.20.2-cp314-cp314t-win_arm64.whl", hash = "sha256:e061b58443f1736f8a37c48978d7ab581636d6ab03e3d4f99e3fa90463bb9382"},
+ {file = "mypy-1.20.2-py3-none-any.whl", hash = "sha256:a94c5a76ab46c5e6257c7972b6c8cff0574201ca7dc05647e33e795d78680563"},
+ {file = "mypy-1.20.2.tar.gz", hash = "sha256:e8222c26daaafd9e8626dec58ae36029f82585890589576f769a650dd20fd665"},
]
[package.dependencies]
+librt = {version = ">=0.8.0", markers = "platform_python_implementation != \"PyPy\""}
mypy_extensions = ">=1.0.0"
+pathspec = ">=1.0.0"
tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""}
-typing_extensions = ">=4.6.0"
+typing_extensions = [
+ {version = ">=4.6.0", markers = "python_version < \"3.15\""},
+ {version = ">=4.14.0", markers = "python_version >= \"3.15\""},
+]
[package.extras]
dmypy = ["psutil (>=4.0)"]
faster-cache = ["orjson"]
install-types = ["pip"]
mypyc = ["setuptools (>=50)"]
+native-parser = ["ast-serialize (>=0.1.1,<1.0.0)"]
reports = ["lxml"]
[[package]]
@@ -475,6 +588,23 @@ files = [
{file = "packaging-26.0.tar.gz", hash = "sha256:00243ae351a257117b6a241061796684b084ed1c516a08c48a3f7e147a9d80b4"},
]
+[[package]]
+name = "pathspec"
+version = "1.1.1"
+description = "Utility library for gitignore style pattern matching of file paths."
+optional = false
+python-versions = ">=3.9"
+groups = ["dev"]
+files = [
+ {file = "pathspec-1.1.1-py3-none-any.whl", hash = "sha256:a00ce642f577bf7f473932318056212bc4f8bfdf53128c78bbd5af0b9b20b189"},
+ {file = "pathspec-1.1.1.tar.gz", hash = "sha256:17db5ecd524104a120e173814c90367a96a98d07c45b2e10c2f3919fff91bf5a"},
+]
+
+[package.extras]
+hyperscan = ["hyperscan (>=0.7)"]
+optional = ["typing-extensions (>=4)"]
+re2 = ["google-re2 (>=1.1)"]
+
[[package]]
name = "pluggy"
version = "1.5.0"
@@ -688,14 +818,14 @@ testing = ["fields", "hunter", "process-tests", "pytest-xdist", "six", "virtuale
[[package]]
name = "pytest-xdist"
-version = "3.6.1"
+version = "3.8.0"
description = "pytest xdist plugin for distributed testing, most importantly across multiple CPUs"
optional = false
-python-versions = ">=3.8"
+python-versions = ">=3.9"
groups = ["dev"]
files = [
- {file = "pytest_xdist-3.6.1-py3-none-any.whl", hash = "sha256:9ed4adfb68a016610848639bb7e02c9352d5d9f03d04809919e2dafc3be4cca7"},
- {file = "pytest_xdist-3.6.1.tar.gz", hash = "sha256:ead156a4db231eec769737f57668ef58a2084a34b2e55c4a8fa20d861107300d"},
+ {file = "pytest_xdist-3.8.0-py3-none-any.whl", hash = "sha256:202ca578cfeb7370784a8c33d6d05bc6e13b4f25b5053c30a152269fd10f0b88"},
+ {file = "pytest_xdist-3.8.0.tar.gz", hash = "sha256:7e578125ec9bc6050861aa93f2d59f1d8d085595d6551c2c90b6f4fad8d3a9f1"},
]
[package.dependencies]
@@ -724,25 +854,25 @@ six = ">=1.5"
[[package]]
name = "requests"
-version = "2.32.4"
+version = "2.34.2"
description = "Python HTTP for Humans."
optional = false
-python-versions = ">=3.8"
+python-versions = ">=3.10"
groups = ["dev"]
files = [
- {file = "requests-2.32.4-py3-none-any.whl", hash = "sha256:27babd3cda2a6d50b30443204ee89830707d396671944c998b5975b031ac2b2c"},
- {file = "requests-2.32.4.tar.gz", hash = "sha256:27d0316682c8a29834d3264820024b62a36942083d52caf2f14c0591336d3422"},
+ {file = "requests-2.34.2-py3-none-any.whl", hash = "sha256:2a0d60c172f83ac6ab31e4554906c0f3b3588d37b5cb939b1c061f4907e278e0"},
+ {file = "requests-2.34.2.tar.gz", hash = "sha256:f288924cae4e29463698d6d60bc6a4da69c89185ad1e0bcc4104f584e960b9ed"},
]
[package.dependencies]
-certifi = ">=2017.4.17"
+certifi = ">=2023.5.7"
charset_normalizer = ">=2,<4"
idna = ">=2.5,<4"
-urllib3 = ">=1.21.1,<3"
+urllib3 = ">=1.26,<3"
[package.extras]
socks = ["PySocks (>=1.5.6,!=1.5.7)"]
-use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"]
+use-chardet-on-py3 = ["chardet (>=3.0.2,<8)"]
[[package]]
name = "ruff"
@@ -856,26 +986,26 @@ files = [
[[package]]
name = "types-python-dateutil"
-version = "2.9.0.20241206"
+version = "2.9.0.20260518"
description = "Typing stubs for python-dateutil"
optional = false
-python-versions = ">=3.8"
+python-versions = ">=3.10"
groups = ["dev"]
files = [
- {file = "types_python_dateutil-2.9.0.20241206-py3-none-any.whl", hash = "sha256:e248a4bc70a486d3e3ec84d0dc30eec3a5f979d6e7ee4123ae043eedbb987f53"},
- {file = "types_python_dateutil-2.9.0.20241206.tar.gz", hash = "sha256:18f493414c26ffba692a72369fea7a154c502646301ebfe3d56a04b3767284cb"},
+ {file = "types_python_dateutil-2.9.0.20260518-py3-none-any.whl", hash = "sha256:d6a9c5bd0de61460c8fdef8ab2b400f956a1a1075cce08d4e2b4434e478c50b8"},
+ {file = "types_python_dateutil-2.9.0.20260518.tar.gz", hash = "sha256:51f02dc03b61c7f6a07df45797d4dfe8a1aa47f0b7db9ad89f6fd3a1a70e1b51"},
]
[[package]]
name = "types-requests"
-version = "2.32.0.20241016"
+version = "2.33.0.20260518"
description = "Typing stubs for requests"
optional = false
-python-versions = ">=3.8"
+python-versions = ">=3.10"
groups = ["dev"]
files = [
- {file = "types-requests-2.32.0.20241016.tar.gz", hash = "sha256:0d9cad2f27515d0e3e3da7134a1b6f28fb97129d86b867f24d9c726452634d95"},
- {file = "types_requests-2.32.0.20241016-py3-none-any.whl", hash = "sha256:4195d62d6d3e043a4eaaf08ff8a62184584d2e8684e9d2aa178c7915a7da3747"},
+ {file = "types_requests-2.33.0.20260518-py3-none-any.whl", hash = "sha256:626d697d1adaaff76e2044dc8c5c051d8f21abc157bdfe204a75558076fe0bf0"},
+ {file = "types_requests-2.33.0.20260518.tar.gz", hash = "sha256:df7bd3bfe0ca8402dfb841e7d9be714bb5578203283d66d7dc4ef69343449a5e"},
]
[package.dependencies]
@@ -888,11 +1018,25 @@ description = "Backported and Experimental Type Hints for Python 3.8+"
optional = false
python-versions = ">=3.8"
groups = ["main", "dev"]
+markers = "python_version < \"3.15\""
files = [
{file = "typing_extensions-4.13.2-py3-none-any.whl", hash = "sha256:a439e7c04b49fec3e5d3e2beaa21755cadbbdc391694e28ccdd36ca4a1408f8c"},
{file = "typing_extensions-4.13.2.tar.gz", hash = "sha256:e6c81219bd689f51865d9e372991c540bda33a0379d5573cddb9a3a23f7caaef"},
]
+[[package]]
+name = "typing-extensions"
+version = "4.15.0"
+description = "Backported and Experimental Type Hints for Python 3.9+"
+optional = false
+python-versions = ">=3.9"
+groups = ["main", "dev"]
+markers = "python_version >= \"3.15\""
+files = [
+ {file = "typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548"},
+ {file = "typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466"},
+]
+
[[package]]
name = "urllib3"
version = "2.2.3"
@@ -913,5 +1057,5 @@ zstd = ["zstandard (>=0.18.0)"]
[metadata]
lock-version = "2.1"
-python-versions = ">=3.9,<4.0"
-content-hash = "bd9ea8d5d169daa6e5d0025af88d2975e6b25ec91a4b8985134a8d1247f5b146"
+python-versions = ">=3.10,<4.0"
+content-hash = "b24a5e77fb15649f546a09f934dbc9e3a644fe2bc3ea160b5cad78f826976e24"
diff --git a/pyproject.toml b/pyproject.toml
index 0f20aed..e411f75 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -15,7 +15,6 @@ classifiers = [
"Intended Audience :: Developers",
"Programming Language :: Python",
"Programming Language :: Python :: 3",
- "Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
@@ -36,7 +35,7 @@ Repository = 'https://github.com/auth0/myorganization-python'
Homepage = 'https://auth0.com'
[tool.poetry.dependencies]
-python = ">=3.9,<4.0"
+python = ">=3.10,<4.0"
httpx = ">=0.21.2"
pydantic = ">= 1.9.2"
pydantic-core = ">=2.18.2"
From b786afe87fbf3e454aa1dbec4699e22fb7fd3d1e Mon Sep 17 00:00:00 2001
From: Kunal Dawar
Date: Tue, 16 Jun 2026 18:34:21 +0530
Subject: [PATCH 3/7] fix: Remove incorrect path for auth0 __init__.py in
.fernignore
---
.fernignore | 1 -
1 file changed, 1 deletion(-)
diff --git a/.fernignore b/.fernignore
index 3a381e0..39713c2 100644
--- a/.fernignore
+++ b/.fernignore
@@ -11,7 +11,6 @@ src/auth0/myorganization/token_provider.py
src/auth0/myorganization/core/client_wrapper.py
# Root auth0 __init__.pys
-src/auth0/myorganization/__init__.py
src/auth0/__init__.py
# Tests
From 1c0ed7f061d32b15b4d3fea2d5a307f57b3f4d31 Mon Sep 17 00:00:00 2001
From: "fern-api[bot]" <115122769+fern-api[bot]@users.noreply.github.com>
Date: Tue, 16 Jun 2026 18:43:48 +0530
Subject: [PATCH 4/7] SDK regeneration (#14)
Co-authored-by: fern-api <115122769+fern-api[bot]@users.noreply.github.com>
---
CONTRIBUTING.md | 125 ++++++++++++
reference.md | 14 +-
src/auth0/myorganization/__init__.py | 55 ++++--
src/auth0/myorganization/client.py | 12 ++
src/auth0/myorganization/core/http_client.py | 3 +-
.../myorganization/core/http_sse/_api.py | 100 ++++++++--
.../myorganization/core/pydantic_utilities.py | 186 +++---------------
.../myorganization/core/serialization.py | 87 +++++++-
tests/utils/test_http_client.py | 32 +++
tests/wire/conftest.py | 9 +-
.../test_organization_identityProviders.py | 12 +-
wiremock/docker-compose.test.yml | 2 +-
wiremock/wiremock-mappings.json | 180 ++++++++---------
13 files changed, 504 insertions(+), 313 deletions(-)
create mode 100644 CONTRIBUTING.md
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 0000000..af948ce
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,125 @@
+# Contributing
+
+Thanks for your interest in contributing to this SDK! This document provides guidelines for contributing to the project.
+
+## Getting Started
+
+### Prerequisites
+
+- Python 3.9+
+- pip
+- poetry
+
+### Installation
+
+Install the project dependencies:
+
+```bash
+poetry install
+```
+
+### Building
+
+Build the project:
+
+```bash
+poetry build
+```
+
+### Testing
+
+Run the test suite:
+
+```bash
+poetry run pytest
+```
+
+### Linting and Formatting
+
+Check code style:
+
+```bash
+poetry run ruff check .
+poetry run ruff format .
+```
+
+### Type Checking
+
+Run the type checker:
+
+```bash
+poetry run mypy .
+```
+
+## About Generated Code
+
+**Important**: Most files in this SDK are automatically generated by [Fern](https://buildwithfern.com) from the API definition. Direct modifications to generated files will be overwritten the next time the SDK is generated.
+
+### Generated Files
+
+The following directories contain generated code:
+- `src/` - API client classes and types
+- Most Python files in the project
+
+### How to Customize
+
+If you need to customize the SDK, you have two options:
+
+#### Option 1: Use `.fernignore`
+
+For custom code that should persist across SDK regenerations:
+
+1. Create a `.fernignore` file in the project root
+2. Add file patterns for files you want to preserve (similar to `.gitignore` syntax)
+3. Add your custom code to those files
+
+Files listed in `.fernignore` will not be overwritten when the SDK is regenerated.
+
+For more information, see the [Fern documentation on custom code](https://buildwithfern.com/learn/sdks/overview/custom-code).
+
+#### Option 2: Contribute to the Generator
+
+If you want to change how code is generated for all users of this SDK:
+
+1. The Python SDK generator lives in the [Fern repository](https://github.com/fern-api/fern)
+2. Generator code is located at `generators/python-v2/`
+3. Follow the [Fern contributing guidelines](https://github.com/fern-api/fern/blob/main/CONTRIBUTING.md)
+4. Submit a pull request with your changes to the generator
+
+This approach is best for:
+- Bug fixes in generated code
+- New features that would benefit all users
+- Improvements to code generation patterns
+
+## Making Changes
+
+### Workflow
+
+1. Create a new branch for your changes
+2. Make your modifications
+3. Run tests to ensure nothing breaks: `poetry run pytest`
+4. Run linting and formatting: `poetry run ruff check .` and `poetry run ruff format .`
+5. Run type checking: `poetry run mypy .`
+6. Build the project: `poetry build`
+7. Commit your changes with a clear commit message
+8. Push your branch and create a pull request
+
+### Commit Messages
+
+Write clear, descriptive commit messages that explain what changed and why.
+
+### Code Style
+
+This project uses automated code formatting and linting. Run `poetry run ruff format .` and `poetry run ruff check .` before committing to ensure your code meets the project's style guidelines.
+
+## Questions or Issues?
+
+If you have questions or run into issues:
+
+1. Check the [Fern documentation](https://buildwithfern.com)
+2. Search existing [GitHub issues](https://github.com/fern-api/fern/issues)
+3. Open a new issue if your question hasn't been addressed
+
+## License
+
+By contributing to this project, you agree that your contributions will be licensed under the same license as the project.
diff --git a/reference.md b/reference.md
index 906dad5..5b139a7 100644
--- a/reference.md
+++ b/reference.md
@@ -611,8 +611,14 @@ client = Auth0(
client.organization.identity_providers.create(
request=IdpOidcRequest(
- name="oidcIdp",
strategy="oidc",
+ options=IdpOidcOptionsRequest(
+ type="front_channel",
+ client_id="a8f3b2e7-5d1c-4f9a-8b0d-2e1c3a5b6f7d",
+ client_secret="KzQp2sVxR8nTgMjFhYcEWuLoIbDvUoC6A9B1zX7yWqFjHkGrP5sQdLmNp",
+ discovery_url="https://{yourDomain}/.well-known/openid-configuration",
+ ),
+ name="oidcIdp",
domains=[
"mydomain.com"
],
@@ -620,12 +626,6 @@ client.organization.identity_providers.create(
show_as_button=True,
assign_membership_on_login=False,
is_enabled=True,
- options=IdpOidcOptionsRequest(
- type="front_channel",
- client_id="a8f3b2e7-5d1c-4f9a-8b0d-2e1c3a5b6f7d",
- client_secret="KzQp2sVxR8nTgMjFhYcEWuLoIbDvUoC6A9B1zX7yWqFjHkGrP5sQdLmNp",
- discovery_url="https://{yourDomain}/.well-known/openid-configuration",
- ),
),
)
diff --git a/src/auth0/myorganization/__init__.py b/src/auth0/myorganization/__init__.py
index 349b857..bc43d80 100644
--- a/src/auth0/myorganization/__init__.py
+++ b/src/auth0/myorganization/__init__.py
@@ -15,10 +15,10 @@
CreateIdentityProviderResponseContent,
CreateIdpDomainResponseContent,
CreateIdpProvisioningScimTokenResponseContent,
+ CreateMemberInvitationInvitee,
CreateMemberInvitationResponseContent,
CreateOrganizationDomainResponseContent,
DomainIdp,
- DomainVerificationEnum,
ErrorResponseContent,
FedMetadataXml,
GetConfigurationResponseContent,
@@ -29,6 +29,7 @@
GetOrganizationDetailsResponseContent,
GetOrganizationDomainResponseContent,
GetOrganizationMemberResponseContent,
+ GetOrganizationMemberRolesResponseContent,
IdentityProviderConfigAdfs,
IdentityProviderConfigGoogleApps,
IdentityProviderConfigOidc,
@@ -37,7 +38,6 @@
IdentityProviderConfigSamlp,
IdentityProviderConfigWaad,
IdentityProvidersConfig,
- IdentityProvidersConfigDomainAlias,
IdentityProvidersConfigEnabledFeaturesEnum,
IdentityProvidersConfigOrganization,
IdentityProvidersConfigProvisioningMethodsEnum,
@@ -121,7 +121,10 @@
ListDomainIdentityProvidersResponseContent,
ListIdentityProvidersResponseContent,
ListIdpProvisioningScimTokensResponseContent,
+ ListMembersInvitationsResponseContent,
ListOrganizationDomainsResponseContent,
+ ListOrganizationMembersResponseContent,
+ ListRolesResponseContent,
Manual,
MemberInvitation,
MemberInvitationInvitee,
@@ -130,6 +133,7 @@
OrgBranding,
OrgBrandingColors,
OrgDetails,
+ OrgDetailsRead,
OrgDomain,
OrgDomainId,
OrgDomainName,
@@ -137,9 +141,11 @@
OrgId,
OrgMember,
OrgMemberId,
- OrgMemberRole,
- OrgMemberRoleId,
+ OrgMemberIdReadOnly,
OrganizationAccessLevelEnum,
+ OrganizationMemberRolesChangeRequestContent,
+ Role,
+ RoleId,
StartOrganizationDomainVerificationResponseContent,
UpdateIdentityProviderRequestContent,
UpdateIdentityProviderResponseContent,
@@ -158,13 +164,12 @@
UnauthorizedError,
)
from . import organization, organization_details
+ from ._default_clients import DefaultAioHttpClient, DefaultAsyncHttpxClient
from .client import AsyncAuth0, Auth0
from .environment import Auth0Environment
from .version import __version__
_dynamic_imports: typing.Dict[str, str] = {
"AsyncAuth0": ".client",
- "AsyncMyOrganizationClient": ".myorganization_client",
- "AsyncTokenProvider": ".token_provider",
"Auth0": ".client",
"Auth0Environment": ".environment",
"Automatic": ".types",
@@ -177,10 +182,12 @@
"CreateIdentityProviderResponseContent": ".types",
"CreateIdpDomainResponseContent": ".types",
"CreateIdpProvisioningScimTokenResponseContent": ".types",
+ "CreateMemberInvitationInvitee": ".types",
"CreateMemberInvitationResponseContent": ".types",
"CreateOrganizationDomainResponseContent": ".types",
+ "DefaultAioHttpClient": "._default_clients",
+ "DefaultAsyncHttpxClient": "._default_clients",
"DomainIdp": ".types",
- "DomainVerificationEnum": ".types",
"ErrorResponseContent": ".types",
"FedMetadataXml": ".types",
"ForbiddenError": ".errors",
@@ -192,6 +199,7 @@
"GetOrganizationDetailsResponseContent": ".types",
"GetOrganizationDomainResponseContent": ".types",
"GetOrganizationMemberResponseContent": ".types",
+ "GetOrganizationMemberRolesResponseContent": ".types",
"IdentityProviderConfigAdfs": ".types",
"IdentityProviderConfigGoogleApps": ".types",
"IdentityProviderConfigOidc": ".types",
@@ -200,7 +208,6 @@
"IdentityProviderConfigSamlp": ".types",
"IdentityProviderConfigWaad": ".types",
"IdentityProvidersConfig": ".types",
- "IdentityProvidersConfigDomainAlias": ".types",
"IdentityProvidersConfigEnabledFeaturesEnum": ".types",
"IdentityProvidersConfigOrganization": ".types",
"IdentityProvidersConfigProvisioningMethodsEnum": ".types",
@@ -284,17 +291,20 @@
"ListDomainIdentityProvidersResponseContent": ".types",
"ListIdentityProvidersResponseContent": ".types",
"ListIdpProvisioningScimTokensResponseContent": ".types",
+ "ListMembersInvitationsResponseContent": ".types",
"ListOrganizationDomainsResponseContent": ".types",
+ "ListOrganizationMembersResponseContent": ".types",
+ "ListRolesResponseContent": ".types",
"Manual": ".types",
"MemberInvitation": ".types",
"MemberInvitationInvitee": ".types",
"MemberInvitationInviter": ".types",
- "MyOrganizationClient": ".myorganization_client",
"NotFoundError": ".errors",
"OauthScope": ".types",
"OrgBranding": ".types",
"OrgBrandingColors": ".types",
"OrgDetails": ".types",
+ "OrgDetailsRead": ".types",
"OrgDomain": ".types",
"OrgDomainId": ".types",
"OrgDomainName": ".types",
@@ -302,11 +312,12 @@
"OrgId": ".types",
"OrgMember": ".types",
"OrgMemberId": ".types",
- "OrgMemberRole": ".types",
- "OrgMemberRoleId": ".types",
+ "OrgMemberIdReadOnly": ".types",
"OrganizationAccessLevelEnum": ".types",
+ "OrganizationMemberRolesChangeRequestContent": ".types",
+ "Role": ".types",
+ "RoleId": ".types",
"StartOrganizationDomainVerificationResponseContent": ".types",
- "TokenProvider": ".token_provider",
"TooManyRequestsError": ".errors",
"UnauthorizedError": ".errors",
"UpdateIdentityProviderRequestContent": ".types",
@@ -345,8 +356,6 @@ def __dir__():
__all__ = [
"AsyncAuth0",
- "AsyncMyOrganizationClient",
- "AsyncTokenProvider",
"Auth0",
"Auth0Environment",
"Automatic",
@@ -359,10 +368,12 @@ def __dir__():
"CreateIdentityProviderResponseContent",
"CreateIdpDomainResponseContent",
"CreateIdpProvisioningScimTokenResponseContent",
+ "CreateMemberInvitationInvitee",
"CreateMemberInvitationResponseContent",
"CreateOrganizationDomainResponseContent",
+ "DefaultAioHttpClient",
+ "DefaultAsyncHttpxClient",
"DomainIdp",
- "DomainVerificationEnum",
"ErrorResponseContent",
"FedMetadataXml",
"ForbiddenError",
@@ -374,6 +385,7 @@ def __dir__():
"GetOrganizationDetailsResponseContent",
"GetOrganizationDomainResponseContent",
"GetOrganizationMemberResponseContent",
+ "GetOrganizationMemberRolesResponseContent",
"IdentityProviderConfigAdfs",
"IdentityProviderConfigGoogleApps",
"IdentityProviderConfigOidc",
@@ -382,7 +394,6 @@ def __dir__():
"IdentityProviderConfigSamlp",
"IdentityProviderConfigWaad",
"IdentityProvidersConfig",
- "IdentityProvidersConfigDomainAlias",
"IdentityProvidersConfigEnabledFeaturesEnum",
"IdentityProvidersConfigOrganization",
"IdentityProvidersConfigProvisioningMethodsEnum",
@@ -466,17 +477,20 @@ def __dir__():
"ListDomainIdentityProvidersResponseContent",
"ListIdentityProvidersResponseContent",
"ListIdpProvisioningScimTokensResponseContent",
+ "ListMembersInvitationsResponseContent",
"ListOrganizationDomainsResponseContent",
+ "ListOrganizationMembersResponseContent",
+ "ListRolesResponseContent",
"Manual",
"MemberInvitation",
"MemberInvitationInvitee",
"MemberInvitationInviter",
- "MyOrganizationClient",
"NotFoundError",
"OauthScope",
"OrgBranding",
"OrgBrandingColors",
"OrgDetails",
+ "OrgDetailsRead",
"OrgDomain",
"OrgDomainId",
"OrgDomainName",
@@ -484,11 +498,12 @@ def __dir__():
"OrgId",
"OrgMember",
"OrgMemberId",
- "OrgMemberRole",
- "OrgMemberRoleId",
+ "OrgMemberIdReadOnly",
"OrganizationAccessLevelEnum",
+ "OrganizationMemberRolesChangeRequestContent",
+ "Role",
+ "RoleId",
"StartOrganizationDomainVerificationResponseContent",
- "TokenProvider",
"TooManyRequestsError",
"UnauthorizedError",
"UpdateIdentityProviderRequestContent",
diff --git a/src/auth0/myorganization/client.py b/src/auth0/myorganization/client.py
index 815f543..3d124a9 100644
--- a/src/auth0/myorganization/client.py
+++ b/src/auth0/myorganization/client.py
@@ -42,6 +42,9 @@ class Auth0:
timeout : typing.Optional[float]
The timeout to be used, in seconds, for requests. By default the timeout is 60 seconds, unless a custom httpx client is used, in which case this default is not enforced.
+ max_retries : typing.Optional[int]
+ The default maximum number of retries for failed requests. Defaults to 2. Per-request `max_retries` in `request_options` takes precedence over this value.
+
follow_redirects : typing.Optional[bool]
Whether the default httpx client follows redirects or not, this is irrelevant if a custom httpx client is passed in.
@@ -69,6 +72,7 @@ def __init__(
token: typing.Union[str, typing.Callable[[], str]],
headers: typing.Optional[typing.Dict[str, str]] = None,
timeout: typing.Optional[float] = None,
+ max_retries: typing.Optional[int] = None,
follow_redirects: typing.Optional[bool] = True,
httpx_client: typing.Optional[httpx.Client] = None,
logging: typing.Optional[typing.Union[LogConfig, Logger]] = None,
@@ -76,6 +80,7 @@ def __init__(
_defaulted_timeout = (
timeout if timeout is not None else 60 if httpx_client is None else httpx_client.timeout.read
)
+ _defaulted_max_retries = max_retries if max_retries is not None else 2
if tenant_domain is not None:
_tenant_domain = tenant_domain if tenant_domain is not None else "{TENANT}.auth0.com"
base_url = "https://{tenantDomain}/my-org/v1".format(tenantDomain=_tenant_domain)
@@ -89,6 +94,7 @@ def __init__(
if follow_redirects is not None
else httpx.Client(timeout=_defaulted_timeout),
timeout=_defaulted_timeout,
+ max_retries=_defaulted_max_retries,
logging=logging,
)
self._organization_details: typing.Optional[OrganizationDetailsClient] = None
@@ -160,6 +166,9 @@ class AsyncAuth0:
timeout : typing.Optional[float]
The timeout to be used, in seconds, for requests. By default the timeout is 60 seconds, unless a custom httpx client is used, in which case this default is not enforced.
+ max_retries : typing.Optional[int]
+ The default maximum number of retries for failed requests. Defaults to 2. Per-request `max_retries` in `request_options` takes precedence over this value.
+
follow_redirects : typing.Optional[bool]
Whether the default httpx client follows redirects or not, this is irrelevant if a custom httpx client is passed in.
@@ -188,6 +197,7 @@ def __init__(
headers: typing.Optional[typing.Dict[str, str]] = None,
async_token: typing.Optional[typing.Callable[[], typing.Awaitable[str]]] = None,
timeout: typing.Optional[float] = None,
+ max_retries: typing.Optional[int] = None,
follow_redirects: typing.Optional[bool] = True,
httpx_client: typing.Optional[httpx.AsyncClient] = None,
logging: typing.Optional[typing.Union[LogConfig, Logger]] = None,
@@ -195,6 +205,7 @@ def __init__(
_defaulted_timeout = (
timeout if timeout is not None else 60 if httpx_client is None else httpx_client.timeout.read
)
+ _defaulted_max_retries = max_retries if max_retries is not None else 2
if tenant_domain is not None:
_tenant_domain = tenant_domain if tenant_domain is not None else "{TENANT}.auth0.com"
base_url = "https://{tenantDomain}/my-org/v1".format(tenantDomain=_tenant_domain)
@@ -207,6 +218,7 @@ def __init__(
if httpx_client is not None
else _make_default_async_client(timeout=_defaulted_timeout, follow_redirects=follow_redirects),
timeout=_defaulted_timeout,
+ max_retries=_defaulted_max_retries,
logging=logging,
)
self._organization_details: typing.Optional[AsyncOrganizationDetailsClient] = None
diff --git a/src/auth0/myorganization/core/http_client.py b/src/auth0/myorganization/core/http_client.py
index f0a39ca..f686c57 100644
--- a/src/auth0/myorganization/core/http_client.py
+++ b/src/auth0/myorganization/core/http_client.py
@@ -125,8 +125,7 @@ def _retry_timeout_from_retries(retries: int) -> float:
def _should_retry(response: httpx.Response) -> bool:
- retryable_400s = [429, 408, 409]
- return response.status_code >= 500 or response.status_code in retryable_400s
+ return response.status_code >= 500 or response.status_code in [429, 408, 409]
_SENSITIVE_HEADERS = frozenset(
diff --git a/src/auth0/myorganization/core/http_sse/_api.py b/src/auth0/myorganization/core/http_sse/_api.py
index f900b3b..fd13730 100644
--- a/src/auth0/myorganization/core/http_sse/_api.py
+++ b/src/auth0/myorganization/core/http_sse/_api.py
@@ -1,14 +1,17 @@
# This file was auto-generated by Fern from our API Definition.
+import codecs
import re
from contextlib import asynccontextmanager, contextmanager
-from typing import Any, AsyncGenerator, AsyncIterator, Iterator, cast
+from typing import Any, AsyncGenerator, AsyncIterator, Iterator
import httpx
from ._decoders import SSEDecoder
from ._exceptions import SSEError
from ._models import ServerSentEvent
+MAX_LINE_SIZE: int = 1_048_576 # 1 MiB
+
class EventSource:
def __init__(self, response: httpx.Response) -> None:
@@ -45,46 +48,101 @@ def _get_charset(self) -> str:
def response(self) -> httpx.Response:
return self._response
+ @staticmethod
+ def _normalize_sse_line_endings(buf: str) -> str:
+ """Normalize line endings per the SSE spec (\\r\\n → \\n, bare \\r → \\n).
+
+ A trailing \\r is preserved because it may pair with a leading \\n in
+ the next chunk to form a single \\r\\n terminator.
+ """
+ buf = buf.replace("\r\n", "\n")
+ if buf.endswith("\r"):
+ return buf[:-1].replace("\r", "\n") + "\r"
+ return buf.replace("\r", "\n")
+
def iter_sse(self) -> Iterator[ServerSentEvent]:
self._check_content_type()
decoder = SSEDecoder()
charset = self._get_charset()
+ text_decoder = codecs.getincrementaldecoder(charset)(errors="replace")
- buffer = ""
+ buf = ""
for chunk in self._response.iter_bytes():
- # Decode chunk using detected charset
- text_chunk = chunk.decode(charset, errors="replace")
- buffer += text_chunk
-
- # Process complete lines
- while "\n" in buffer:
- line, buffer = buffer.split("\n", 1)
- line = line.rstrip("\r")
+ buf += text_decoder.decode(chunk)
+ buf = self._normalize_sse_line_endings(buf)
+
+ while "\n" in buf:
+ line, buf = buf.split("\n", 1)
sse = decoder.decode(line)
- # when we reach a "\n\n" => line = ''
- # => decoder will attempt to return an SSE Event
if sse is not None:
yield sse
- # Process any remaining data in buffer
- if buffer.strip():
- line = buffer.rstrip("\r")
+ if len(buf) > MAX_LINE_SIZE:
+ raise SSEError(
+ f"SSE line exceeded maximum size of {MAX_LINE_SIZE} characters without encountering a newline"
+ )
+
+ # Flush any remaining bytes from the incremental decoder
+ buf += text_decoder.decode(b"", final=True)
+ buf = buf.replace("\r\n", "\n").replace("\r", "\n")
+
+ if len(buf) > MAX_LINE_SIZE:
+ raise SSEError(
+ f"SSE line exceeded maximum size of {MAX_LINE_SIZE} characters without encountering a newline"
+ )
+
+ while "\n" in buf:
+ line, buf = buf.split("\n", 1)
sse = decoder.decode(line)
if sse is not None:
yield sse
+ if buf.strip():
+ sse = decoder.decode(buf)
+ if sse is not None:
+ yield sse
+
async def aiter_sse(self) -> AsyncGenerator[ServerSentEvent, None]:
self._check_content_type()
decoder = SSEDecoder()
- lines = cast(AsyncGenerator[str, None], self._response.aiter_lines())
- try:
- async for line in lines:
- line = line.rstrip("\n")
+ charset = self._get_charset()
+ text_decoder = codecs.getincrementaldecoder(charset)(errors="replace")
+
+ buf = ""
+ async for chunk in self._response.aiter_bytes():
+ buf += text_decoder.decode(chunk)
+ buf = self._normalize_sse_line_endings(buf)
+
+ while "\n" in buf:
+ line, buf = buf.split("\n", 1)
sse = decoder.decode(line)
if sse is not None:
yield sse
- finally:
- await lines.aclose()
+
+ if len(buf) > MAX_LINE_SIZE:
+ raise SSEError(
+ f"SSE line exceeded maximum size of {MAX_LINE_SIZE} characters without encountering a newline"
+ )
+
+ # Flush any remaining bytes from the incremental decoder
+ buf += text_decoder.decode(b"", final=True)
+ buf = buf.replace("\r\n", "\n").replace("\r", "\n")
+
+ if len(buf) > MAX_LINE_SIZE:
+ raise SSEError(
+ f"SSE line exceeded maximum size of {MAX_LINE_SIZE} characters without encountering a newline"
+ )
+
+ while "\n" in buf:
+ line, buf = buf.split("\n", 1)
+ sse = decoder.decode(line)
+ if sse is not None:
+ yield sse
+
+ if buf.strip():
+ sse = decoder.decode(buf)
+ if sse is not None:
+ yield sse
@contextmanager
diff --git a/src/auth0/myorganization/core/pydantic_utilities.py b/src/auth0/myorganization/core/pydantic_utilities.py
index fea3a08..6587f5e 100644
--- a/src/auth0/myorganization/core/pydantic_utilities.py
+++ b/src/auth0/myorganization/core/pydantic_utilities.py
@@ -135,111 +135,21 @@ def _decimal_encoder(dec_value: Any) -> Any:
Model = TypeVar("Model", bound=pydantic.BaseModel)
-def _get_discriminator_and_variants(type_: Type[Any]) -> Tuple[Optional[str], Optional[List[Type[Any]]]]:
- """
- Extract the discriminator field name and union variants from a discriminated union type.
- Supports Annotated[Union[...], Field(discriminator=...)] patterns.
- Returns (discriminator, variants) or (None, None) if not a discriminated union.
- """
- origin = typing_extensions.get_origin(type_)
-
- if origin is typing_extensions.Annotated:
- args = typing_extensions.get_args(type_)
- if len(args) >= 2:
- inner_type = args[0]
- # Check annotations for discriminator
- discriminator = None
- for annotation in args[1:]:
- if hasattr(annotation, "discriminator"):
- discriminator = getattr(annotation, "discriminator", None)
- break
-
- if discriminator:
- inner_origin = typing_extensions.get_origin(inner_type)
- if inner_origin is Union:
- variants = list(typing_extensions.get_args(inner_type))
- return discriminator, variants
- return None, None
-
-
-def _get_field_annotation(model: Type[Any], field_name: str) -> Optional[Type[Any]]:
- """Get the type annotation of a field from a Pydantic model."""
- if IS_PYDANTIC_V2:
- fields = getattr(model, "model_fields", {})
- field_info = fields.get(field_name)
- if field_info:
- return cast(Optional[Type[Any]], field_info.annotation)
- else:
- fields = getattr(model, "__fields__", {})
- field_info = fields.get(field_name)
- if field_info:
- return cast(Optional[Type[Any]], field_info.outer_type_)
- return None
-
-
-def _find_variant_by_discriminator(
- variants: List[Type[Any]],
- discriminator: str,
- discriminator_value: Any,
-) -> Optional[Type[Any]]:
- """Find the union variant that matches the discriminator value."""
- for variant in variants:
- if not (inspect.isclass(variant) and issubclass(variant, pydantic.BaseModel)):
- continue
-
- disc_annotation = _get_field_annotation(variant, discriminator)
- if disc_annotation and is_literal_type(disc_annotation):
- literal_args = get_args(disc_annotation)
- if literal_args and literal_args[0] == discriminator_value:
- return variant
- return None
-
-
-def _is_string_type(type_: Type[Any]) -> bool:
- """Check if a type is str or Optional[str]."""
- if type_ is str:
- return True
-
- origin = typing_extensions.get_origin(type_)
- if origin is Union:
- args = typing_extensions.get_args(type_)
- # Optional[str] = Union[str, None]
- non_none_args = [a for a in args if a is not type(None)]
- if len(non_none_args) == 1 and non_none_args[0] is str:
- return True
-
- return False
-
-
def parse_sse_obj(sse: "ServerSentEvent", type_: Type[T]) -> T:
"""
Parse a ServerSentEvent into the appropriate type.
- Handles two scenarios based on where the discriminator field is located:
-
- 1. Data-level discrimination: The discriminator (e.g., 'type') is inside the 'data' payload.
- The union describes the data content, not the SSE envelope.
- -> Returns: json.loads(data) parsed into the type
+ This function handles data-level discrimination where the discriminator
+ (e.g., 'type') is inside the 'data' payload. It parses the SSE data field
+ as JSON and deserializes it into the target type.
- Example: ChatStreamResponse with discriminator='type'
- Input: ServerSentEvent(event="message", data='{"type": "content-delta", ...}', id="")
- Output: ContentDeltaEvent (parsed from data, SSE envelope stripped)
-
- 2. Event-level discrimination: The discriminator (e.g., 'event') is at the SSE event level.
- The union describes the full SSE event structure.
- -> Returns: SSE envelope with 'data' field JSON-parsed only if the variant expects non-string
-
- Example: JobStreamResponse with discriminator='event'
- Input: ServerSentEvent(event="ERROR", data='{"code": "FAILED", ...}', id="123")
- Output: JobStreamResponse_Error with data as ErrorData object
-
- But for variants where data is str (like STATUS_UPDATE):
- Input: ServerSentEvent(event="STATUS_UPDATE", data='{"status": "processing"}', id="1")
- Output: JobStreamResponse_StatusUpdate with data as string (not parsed)
+ Note: Protocol-level discrimination (where the discriminator comes from
+ the SSE event: field) is handled at code-generation time and does not
+ use this function.
Args:
sse: The ServerSentEvent object to parse
- type_: The target discriminated union type
+ type_: The target type to deserialize into
Returns:
The parsed object of type T
@@ -248,66 +158,30 @@ def parse_sse_obj(sse: "ServerSentEvent", type_: Type[T]) -> T:
This function is only available in SDK contexts where http_sse module exists.
"""
sse_event = asdict(sse)
- discriminator, variants = _get_discriminator_and_variants(type_)
-
- if discriminator is None or variants is None:
- # Not a discriminated union - parse the data field as JSON
- data_value = sse_event.get("data")
- if isinstance(data_value, str) and data_value:
- try:
- parsed_data = json.loads(data_value)
- return parse_obj_as(type_, parsed_data)
- except json.JSONDecodeError as e:
- _logger.warning(
- "Failed to parse SSE data field as JSON: %s, data: %s",
- e,
- data_value[:100] if len(data_value) > 100 else data_value,
- )
- return parse_obj_as(type_, sse_event)
-
data_value = sse_event.get("data")
+ if isinstance(data_value, str) and data_value:
+ try:
+ parsed_data = json.loads(data_value)
+ return parse_obj_as(type_, parsed_data)
+ except json.JSONDecodeError as e:
+ _logger.warning(
+ "Failed to parse SSE data field as JSON: %s, data: %s",
+ e,
+ data_value[:100] if len(data_value) > 100 else data_value,
+ )
+ return parse_obj_as(type_, sse_event)
- # Check if discriminator is at the top level (event-level discrimination)
- if discriminator in sse_event:
- # Case 2: Event-level discrimination
- # Find the matching variant to check if 'data' field needs JSON parsing
- disc_value = sse_event.get(discriminator)
- matching_variant = _find_variant_by_discriminator(variants, discriminator, disc_value)
-
- if matching_variant is not None:
- # Check what type the variant expects for 'data'
- data_type = _get_field_annotation(matching_variant, "data")
- if data_type is not None and not _is_string_type(data_type):
- # Variant expects non-string data - parse JSON
- if isinstance(data_value, str) and data_value:
- try:
- parsed_data = json.loads(data_value)
- new_object = dict(sse_event)
- new_object["data"] = parsed_data
- return parse_obj_as(type_, new_object)
- except json.JSONDecodeError as e:
- _logger.warning(
- "Failed to parse SSE data field as JSON for event-level discrimination: %s, data: %s",
- e,
- data_value[:100] if len(data_value) > 100 else data_value,
- )
- # Either no matching variant, data is string type, or JSON parse failed
- return parse_obj_as(type_, sse_event)
- else:
- # Case 1: Data-level discrimination
- # The discriminator is inside the data payload - extract and parse data only
- if isinstance(data_value, str) and data_value:
- try:
- parsed_data = json.loads(data_value)
- return parse_obj_as(type_, parsed_data)
- except json.JSONDecodeError as e:
- _logger.warning(
- "Failed to parse SSE data field as JSON for data-level discrimination: %s, data: %s",
- e,
- data_value[:100] if len(data_value) > 100 else data_value,
- )
- return parse_obj_as(type_, sse_event)
+_type_adapter_cache: Dict[int, Any] = {}
+
+
+def _get_type_adapter(type_: Type[Any]) -> Any:
+ key = id(type_)
+ adapter = _type_adapter_cache.get(key)
+ if adapter is None:
+ adapter = pydantic.TypeAdapter(type_) # type: ignore[attr-defined]
+ _type_adapter_cache[key] = adapter
+ return adapter
def parse_obj_as(type_: Type[T], object_: Any) -> T:
@@ -342,8 +216,8 @@ def parse_obj_as(type_: Type[T], object_: Any) -> T:
else:
dealiased_object = convert_and_respect_annotation_metadata(object_=object_, annotation=type_, direction="read")
if IS_PYDANTIC_V2:
- adapter = pydantic.TypeAdapter(type_) # type: ignore[attr-defined]
- return adapter.validate_python(dealiased_object)
+ adapter = _get_type_adapter(type_)
+ return adapter.validate_python(dealiased_object) # type: ignore[no-any-return]
return pydantic.parse_obj_as(type_, dealiased_object)
diff --git a/src/auth0/myorganization/core/serialization.py b/src/auth0/myorganization/core/serialization.py
index c36e865..1d753e2 100644
--- a/src/auth0/myorganization/core/serialization.py
+++ b/src/auth0/myorganization/core/serialization.py
@@ -26,6 +26,75 @@ def __init__(self, *, alias: str) -> None:
self.alias = alias
+# Resolving type hints (typing.get_type_hints) is expensive because it eval/compiles
+# forward-reference annotations. The result is constant for a given type, so we cache it.
+# This is critical for hot paths like SSE event parsing, where the same (often large
+# discriminated-union) type is converted on every single event.
+_type_hints_cache: typing.Dict[typing.Any, typing.Dict[str, typing.Any]] = {}
+
+
+def _get_cached_type_hints(expected_type: typing.Any) -> typing.Dict[str, typing.Any]:
+ try:
+ cached = _type_hints_cache.get(expected_type)
+ except TypeError:
+ # Unhashable type; resolve without caching.
+ return _resolve_type_hints(expected_type)
+ if cached is None:
+ cached = _resolve_type_hints(expected_type)
+ _type_hints_cache[expected_type] = cached
+ return cached
+
+
+def _resolve_type_hints(expected_type: typing.Any) -> typing.Dict[str, typing.Any]:
+ try:
+ return typing_extensions.get_type_hints(expected_type, include_extras=True)
+ except NameError:
+ # The type contains a circular reference, so we use the __annotations__ attribute directly.
+ return getattr(expected_type, "__annotations__", {})
+
+
+# Whether convert_and_respect_annotation_metadata can possibly rewrite anything for a given
+# annotation, i.e. whether any reachable model/TypedDict field carries a FieldMetadata alias.
+# This is constant per type, so we cache it and use it to short-circuit the recursive walk.
+_requires_conversion_cache: typing.Dict[typing.Any, bool] = {}
+
+
+def _requires_conversion(type_: typing.Any) -> bool:
+ try:
+ cached = _requires_conversion_cache.get(type_)
+ except TypeError:
+ # Unhashable annotation; compute without caching.
+ return _compute_requires_conversion(type_, set())
+ if cached is None:
+ cached = _compute_requires_conversion(type_, set())
+ _requires_conversion_cache[type_] = cached
+ return cached
+
+
+def _compute_requires_conversion(type_: typing.Any, seen: typing.Set[typing.Any]) -> bool:
+ clean_type = _remove_annotations(type_)
+
+ try:
+ if clean_type in seen:
+ return False
+ seen = seen | {clean_type}
+ except TypeError:
+ # Unhashable type; skip cycle tracking (the type graph is finite in practice).
+ pass
+
+ # Models / TypedDicts: a field alias here means we must dealias; otherwise recurse into fields.
+ if (inspect.isclass(clean_type) and issubclass(clean_type, pydantic.BaseModel)) or typing_extensions.is_typeddict(
+ clean_type
+ ):
+ annotations = _get_cached_type_hints(clean_type)
+ if _get_alias_to_field_name(annotations):
+ return True
+ return any(_compute_requires_conversion(hint, seen) for hint in annotations.values())
+
+ # Containers / unions: recurse into the type arguments (List/Set/Sequence/Dict/Union/etc.).
+ return any(_compute_requires_conversion(arg, seen) for arg in typing_extensions.get_args(clean_type))
+
+
def convert_and_respect_annotation_metadata(
*,
object_: typing.Any,
@@ -57,6 +126,13 @@ def convert_and_respect_annotation_metadata(
return None
if inner_type is None:
inner_type = annotation
+ # The only thing this function ever rewrites is keys that carry a FieldMetadata
+ # alias. If nothing in the (cached) type graph has such an alias, the conversion is
+ # a content-identity transform, so we can skip the entire recursive walk. This is
+ # the hot path for SSE streaming, where a large discriminated union would otherwise
+ # be traversed on every single event.
+ if not _requires_conversion(annotation):
+ return object_
clean_type = _remove_annotations(inner_type)
# Pydantic models
@@ -160,12 +236,7 @@ def _convert_mapping(
direction: typing.Literal["read", "write"],
) -> typing.Mapping[str, object]:
converted_object: typing.Dict[str, object] = {}
- try:
- annotations = typing_extensions.get_type_hints(expected_type, include_extras=True)
- except NameError:
- # The TypedDict contains a circular reference, so
- # we use the __annotations__ attribute directly.
- annotations = getattr(expected_type, "__annotations__", {})
+ annotations = _get_cached_type_hints(expected_type)
aliases_to_field_names = _get_alias_to_field_name(annotations)
for key, value in object_.items():
if direction == "read" and key in aliases_to_field_names:
@@ -221,12 +292,12 @@ def _remove_annotations(type_: typing.Any) -> typing.Any:
def get_alias_to_field_mapping(type_: typing.Any) -> typing.Dict[str, str]:
- annotations = typing_extensions.get_type_hints(type_, include_extras=True)
+ annotations = _get_cached_type_hints(type_)
return _get_alias_to_field_name(annotations)
def get_field_to_alias_mapping(type_: typing.Any) -> typing.Dict[str, str]:
- annotations = typing_extensions.get_type_hints(type_, include_extras=True)
+ annotations = _get_cached_type_hints(type_)
return _get_field_to_alias_name(annotations)
diff --git a/tests/utils/test_http_client.py b/tests/utils/test_http_client.py
index 1523647..407e6f4 100644
--- a/tests/utils/test_http_client.py
+++ b/tests/utils/test_http_client.py
@@ -10,6 +10,7 @@
AsyncHttpClient,
HttpClient,
_build_url,
+ _should_retry,
get_request_body,
remove_none_from_dict,
)
@@ -660,3 +661,34 @@ async def test_async_base_max_retries_used_as_default(mock_sleep: AsyncMock) ->
assert response.status_code == 200
# 1 initial + 3 retries = 4 total attempts
assert mock_client.request.call_count == 4
+
+
+# ---------------------------------------------------------------------------
+# _should_retry unit tests
+# ---------------------------------------------------------------------------
+
+
+def _make_response(status_code: int) -> httpx.Response:
+ return httpx.Response(status_code=status_code, content=b"")
+
+
+@pytest.mark.parametrize(
+ "status_code",
+ [408, 409, 429, 500, 501, 502, 503, 504, 599],
+)
+def test_should_retry_retryable_status_codes(status_code: int) -> None:
+ """Legacy mode: retries on 408, 409, 429, and all >= 500."""
+ assert _should_retry(_make_response(status_code)) is True
+
+
+@pytest.mark.parametrize(
+ "status_code",
+ [200, 201, 301, 400, 401, 403, 404],
+)
+def test_should_not_retry_non_retryable_status_codes(status_code: int) -> None:
+ assert _should_retry(_make_response(status_code)) is False
+
+
+def test_should_retry_599_upper_boundary() -> None:
+ """Legacy mode retries on >= 500, which includes 599."""
+ assert _should_retry(_make_response(599)) is True
diff --git a/tests/wire/conftest.py b/tests/wire/conftest.py
index 66716d1..c417af0 100644
--- a/tests/wire/conftest.py
+++ b/tests/wire/conftest.py
@@ -60,7 +60,7 @@ def verify_request_count(
test_id: str,
method: str,
url_path: str,
- query_params: Optional[Dict[str, str]],
+ query_params: Optional[Dict[str, Any]],
expected: int,
) -> None:
"""Verifies the number of requests made to WireMock filtered by test ID for concurrency safety."""
@@ -71,7 +71,12 @@ def verify_request_count(
"headers": {"X-Test-Id": {"equalTo": test_id}},
}
if query_params:
- query_parameters = {k: {"equalTo": v} for k, v in query_params.items()}
+ query_parameters = {}
+ for k, v in query_params.items():
+ if isinstance(v, list):
+ query_parameters[k] = {"hasExactly": [{"equalTo": item} for item in v]}
+ else:
+ query_parameters[k] = {"equalTo": v}
request_body["queryParameters"] = query_parameters
response = httpx.post(f"{wiremock_admin_url}/requests/find", json=request_body)
assert response.status_code == 200, "Failed to query WireMock requests"
diff --git a/tests/wire/test_organization_identityProviders.py b/tests/wire/test_organization_identityProviders.py
index 0445eb5..d905140 100644
--- a/tests/wire/test_organization_identityProviders.py
+++ b/tests/wire/test_organization_identityProviders.py
@@ -17,19 +17,19 @@ def test_organization_identityProviders_create() -> None:
client = get_client(test_id)
client.organization.identity_providers.create(
request=IdpOidcRequest(
- name="oidcIdp",
strategy="oidc",
- domains=["mydomain.com"],
- display_name="OIDC IdP",
- show_as_button=True,
- assign_membership_on_login=False,
- is_enabled=True,
options=IdpOidcOptionsRequest(
type="front_channel",
client_id="a8f3b2e7-5d1c-4f9a-8b0d-2e1c3a5b6f7d",
client_secret="KzQp2sVxR8nTgMjFhYcEWuLoIbDvUoC6A9B1zX7yWqFjHkGrP5sQdLmNp",
discovery_url="https://{yourDomain}/.well-known/openid-configuration",
),
+ name="oidcIdp",
+ domains=["mydomain.com"],
+ display_name="OIDC IdP",
+ show_as_button=True,
+ assign_membership_on_login=False,
+ is_enabled=True,
),
)
verify_request_count(test_id, "POST", "/identity-providers", None, 1)
diff --git a/wiremock/docker-compose.test.yml b/wiremock/docker-compose.test.yml
index 58747d5..95f0ae9 100644
--- a/wiremock/docker-compose.test.yml
+++ b/wiremock/docker-compose.test.yml
@@ -5,7 +5,7 @@ services:
- "0:8080" # Use dynamic port to avoid conflicts with concurrent tests
volumes:
- ./wiremock-mappings.json:/home/wiremock/mappings/wiremock-mappings.json
- command: ["--global-response-templating", "--verbose"]
+ command: ["--verbose"]
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/__admin/health"]
interval: 2s
diff --git a/wiremock/wiremock-mappings.json b/wiremock/wiremock-mappings.json
index 13ed5f0..e48106c 100644
--- a/wiremock/wiremock-mappings.json
+++ b/wiremock/wiremock-mappings.json
@@ -1,8 +1,8 @@
{
"mappings": [
{
- "id": "29a326c1-09e0-4f0b-8b3a-55872064dbed",
- "name": "Get Organization details - default",
+ "id": "7e1a7c64-7b52-4634-91d9-6d6f54b94bff",
+ "name": "Get Organization details - getOrgDetailsResponseExample",
"request": {
"urlPathTemplate": "/details",
"method": "GET",
@@ -19,7 +19,7 @@
"Content-Type": "application/json"
}
},
- "uuid": "29a326c1-09e0-4f0b-8b3a-55872064dbed",
+ "uuid": "7e1a7c64-7b52-4634-91d9-6d6f54b94bff",
"persistent": true,
"priority": 3,
"metadata": {
@@ -33,8 +33,8 @@
"postServeActions": []
},
{
- "id": "175cc45b-1346-42bb-baab-e94c1318da4c",
- "name": "Update Organization details - default",
+ "id": "1ef770f7-cd42-42cc-973f-f17501df9506",
+ "name": "Update Organization details - updateOrgDetailsResponseExample",
"request": {
"urlPathTemplate": "/details",
"method": "PATCH",
@@ -51,7 +51,7 @@
"Content-Type": "application/json"
}
},
- "uuid": "175cc45b-1346-42bb-baab-e94c1318da4c",
+ "uuid": "1ef770f7-cd42-42cc-973f-f17501df9506",
"persistent": true,
"priority": 3,
"metadata": {
@@ -64,8 +64,8 @@
}
},
{
- "id": "ddb32f2f-bb17-4551-8c51-a0f78dbb849f",
- "name": "Get My Organization API configuration - default",
+ "id": "6408a1a2-98b8-4c29-b15f-17b2c9b9db75",
+ "name": "Get My Organization API configuration - getOrgDetailsResponseExample",
"request": {
"urlPathTemplate": "/config",
"method": "GET",
@@ -82,7 +82,7 @@
"Content-Type": "application/json"
}
},
- "uuid": "ddb32f2f-bb17-4551-8c51-a0f78dbb849f",
+ "uuid": "6408a1a2-98b8-4c29-b15f-17b2c9b9db75",
"persistent": true,
"priority": 3,
"metadata": {
@@ -96,8 +96,8 @@
"postServeActions": []
},
{
- "id": "bd99fc7f-05db-4c0a-8386-d3665f0719ca",
- "name": "List domains - default",
+ "id": "db02a313-8a43-4071-87d7-0d15bd2d26e0",
+ "name": "List domains - listOrgDomainsResponseExample",
"request": {
"urlPathTemplate": "/domains",
"method": "GET",
@@ -122,7 +122,7 @@
"Content-Type": "application/json"
}
},
- "uuid": "bd99fc7f-05db-4c0a-8386-d3665f0719ca",
+ "uuid": "db02a313-8a43-4071-87d7-0d15bd2d26e0",
"persistent": true,
"priority": 3,
"metadata": {
@@ -136,8 +136,8 @@
"postServeActions": []
},
{
- "id": "0d1dcca2-642a-4199-b3fe-00d5ec1c8bc2",
- "name": "Create a domain - default",
+ "id": "11952e27-c837-49f7-be35-80be3f545a8c",
+ "name": "Create a domain - createOrgDomainResponseExample",
"request": {
"urlPathTemplate": "/domains",
"method": "POST",
@@ -154,7 +154,7 @@
"Content-Type": "application/json"
}
},
- "uuid": "0d1dcca2-642a-4199-b3fe-00d5ec1c8bc2",
+ "uuid": "11952e27-c837-49f7-be35-80be3f545a8c",
"persistent": true,
"priority": 3,
"metadata": {
@@ -167,8 +167,8 @@
}
},
{
- "id": "a3c27ba8-01e3-4c19-8725-d3281492d7a6",
- "name": "Get a domain - default",
+ "id": "4444919f-7bcd-4034-aa50-a59f14c9b216",
+ "name": "Get a domain - getOrgDomainResponseExample",
"request": {
"urlPathTemplate": "/domains/{domain_id}",
"method": "GET",
@@ -190,7 +190,7 @@
"Content-Type": "application/json"
}
},
- "uuid": "a3c27ba8-01e3-4c19-8725-d3281492d7a6",
+ "uuid": "4444919f-7bcd-4034-aa50-a59f14c9b216",
"persistent": true,
"priority": 3,
"metadata": {
@@ -239,8 +239,8 @@
}
},
{
- "id": "8b89e2ae-9635-46f3-b4e8-fc575b9b6157",
- "name": "List Identity Providers - default",
+ "id": "11d47f7f-d5a5-43f5-aea7-569c6ce3bd63",
+ "name": "List Identity Providers - listIdPsResponseExample",
"request": {
"urlPathTemplate": "/identity-providers",
"method": "GET",
@@ -257,7 +257,7 @@
"Content-Type": "application/json"
}
},
- "uuid": "8b89e2ae-9635-46f3-b4e8-fc575b9b6157",
+ "uuid": "11d47f7f-d5a5-43f5-aea7-569c6ce3bd63",
"persistent": true,
"priority": 3,
"metadata": {
@@ -271,8 +271,8 @@
"postServeActions": []
},
{
- "id": "3e11b717-d0f8-4c19-9f25-9aaba50cba21",
- "name": "Create an Identity Provider - default",
+ "id": "a6f57fc1-f7ac-4b02-8f4d-bd3fe46eecd4",
+ "name": "Create an Identity Provider - createIdPResponseExample",
"request": {
"urlPathTemplate": "/identity-providers",
"method": "POST",
@@ -289,7 +289,7 @@
"Content-Type": "application/json"
}
},
- "uuid": "3e11b717-d0f8-4c19-9f25-9aaba50cba21",
+ "uuid": "a6f57fc1-f7ac-4b02-8f4d-bd3fe46eecd4",
"persistent": true,
"priority": 3,
"metadata": {
@@ -302,8 +302,8 @@
}
},
{
- "id": "58ee7dab-8682-4472-892e-bd11d76b0671",
- "name": "Get an Identity Provider - default",
+ "id": "ebff1d9b-9b46-4505-ad12-9dbda71462b0",
+ "name": "Get an Identity Provider - getIdPResponseExample",
"request": {
"urlPathTemplate": "/identity-providers/{idp_id}",
"method": "GET",
@@ -325,7 +325,7 @@
"Content-Type": "application/json"
}
},
- "uuid": "58ee7dab-8682-4472-892e-bd11d76b0671",
+ "uuid": "ebff1d9b-9b46-4505-ad12-9dbda71462b0",
"persistent": true,
"priority": 3,
"metadata": {
@@ -374,8 +374,8 @@
}
},
{
- "id": "97299d05-1531-4f32-8e96-5a64fc5751f8",
- "name": "Update an Identity Provider - default",
+ "id": "44ef7b8f-877a-4ec9-8be1-7204c4c0c994",
+ "name": "Update an Identity Provider - updateIdPResponseExample",
"request": {
"urlPathTemplate": "/identity-providers/{idp_id}",
"method": "PATCH",
@@ -397,7 +397,7 @@
"Content-Type": "application/json"
}
},
- "uuid": "97299d05-1531-4f32-8e96-5a64fc5751f8",
+ "uuid": "44ef7b8f-877a-4ec9-8be1-7204c4c0c994",
"persistent": true,
"priority": 3,
"metadata": {
@@ -410,8 +410,8 @@
}
},
{
- "id": "9925321b-b5a5-4ccc-abb9-04139e218c65",
- "name": "Refresh Identity Provider attribute mapping - default",
+ "id": "1e4d66ac-950b-4cd7-a16d-65e8adb4a94b",
+ "name": "Refresh Identity Provider attribute mapping - getIdPResponseExample",
"request": {
"urlPathTemplate": "/identity-providers/{idp_id}/update-attributes",
"method": "PUT",
@@ -433,7 +433,7 @@
"Content-Type": "application/json"
}
},
- "uuid": "9925321b-b5a5-4ccc-abb9-04139e218c65",
+ "uuid": "1e4d66ac-950b-4cd7-a16d-65e8adb4a94b",
"persistent": true,
"priority": 3,
"metadata": {
@@ -482,8 +482,8 @@
}
},
{
- "id": "8a221b24-aed6-4bfe-bfdb-c4329d8e2181",
- "name": "List members - default",
+ "id": "7d845899-c08f-4508-a7cb-134b5d39faca",
+ "name": "List members - listOrgDomainsResponseExample",
"request": {
"urlPathTemplate": "/members",
"method": "GET",
@@ -514,7 +514,7 @@
"Content-Type": "application/json"
}
},
- "uuid": "8a221b24-aed6-4bfe-bfdb-c4329d8e2181",
+ "uuid": "7d845899-c08f-4508-a7cb-134b5d39faca",
"persistent": true,
"priority": 3,
"metadata": {
@@ -528,8 +528,8 @@
"postServeActions": []
},
{
- "id": "fae3f220-6c07-455b-b799-d153a5d10715",
- "name": "Get a member - default",
+ "id": "9a6aefd1-96f4-48e6-943b-0e62bf9cfd0c",
+ "name": "Get a member - listOrgDomainsResponseExample",
"request": {
"urlPathTemplate": "/members/{user_id}",
"method": "GET",
@@ -559,7 +559,7 @@
"Content-Type": "application/json"
}
},
- "uuid": "fae3f220-6c07-455b-b799-d153a5d10715",
+ "uuid": "9a6aefd1-96f4-48e6-943b-0e62bf9cfd0c",
"persistent": true,
"priority": 3,
"metadata": {
@@ -572,8 +572,8 @@
}
},
{
- "id": "615842a1-853a-4670-8ba3-e4825a6bd0af",
- "name": "Delete memberships - default",
+ "id": "c6126f0a-ce12-4ccd-a21c-8313aebc991f",
+ "name": "Delete memberships - deleteOrganizationMembershipsRequestExample",
"request": {
"urlPathTemplate": "/delete-memberships",
"method": "POST",
@@ -590,7 +590,7 @@
"Content-Type": "application/json"
}
},
- "uuid": "615842a1-853a-4670-8ba3-e4825a6bd0af",
+ "uuid": "c6126f0a-ce12-4ccd-a21c-8313aebc991f",
"persistent": true,
"priority": 3,
"metadata": {
@@ -603,8 +603,8 @@
}
},
{
- "id": "78503755-437a-4f13-bb75-fbf050b174b1",
- "name": "List member invitations - default",
+ "id": "4e72920b-af60-44e5-a6ba-aede11137221",
+ "name": "List member invitations - listMembersInvitationsResponseExample",
"request": {
"urlPathTemplate": "/member-invitations",
"method": "GET",
@@ -638,7 +638,7 @@
"Content-Type": "application/json"
}
},
- "uuid": "78503755-437a-4f13-bb75-fbf050b174b1",
+ "uuid": "4e72920b-af60-44e5-a6ba-aede11137221",
"persistent": true,
"priority": 3,
"metadata": {
@@ -652,8 +652,8 @@
"postServeActions": []
},
{
- "id": "55c94d5e-e08c-471f-b76f-111cd557f5ca",
- "name": "Create member invitations - default",
+ "id": "81839c8d-109e-443d-835e-bd23c6354a48",
+ "name": "Create member invitations - listMembersInvitationsResponseExample",
"request": {
"urlPathTemplate": "/member-invitations",
"method": "POST",
@@ -670,7 +670,7 @@
"Content-Type": "application/json"
}
},
- "uuid": "55c94d5e-e08c-471f-b76f-111cd557f5ca",
+ "uuid": "81839c8d-109e-443d-835e-bd23c6354a48",
"persistent": true,
"priority": 3,
"metadata": {
@@ -683,8 +683,8 @@
}
},
{
- "id": "1a5a7d10-bc8e-44b0-ab8a-e611721f0d64",
- "name": "Get a member invitation - default",
+ "id": "bf390045-ef2a-4a70-8a73-16e2fc5363e0",
+ "name": "Get a member invitation - GetMemberInvitationResponseExample",
"request": {
"urlPathTemplate": "/member-invitations/{invitation_id}",
"method": "GET",
@@ -714,7 +714,7 @@
"Content-Type": "application/json"
}
},
- "uuid": "1a5a7d10-bc8e-44b0-ab8a-e611721f0d64",
+ "uuid": "bf390045-ef2a-4a70-8a73-16e2fc5363e0",
"persistent": true,
"priority": 3,
"metadata": {
@@ -763,8 +763,8 @@
}
},
{
- "id": "d7eb85d6-a74e-47c7-b669-d9c33ad0aa81",
- "name": "List roles - default",
+ "id": "7e78a97c-a095-412c-863f-ef31d9d6c7c0",
+ "name": "List roles - listRolesResponseExample",
"request": {
"urlPathTemplate": "/roles",
"method": "GET",
@@ -792,7 +792,7 @@
"Content-Type": "application/json"
}
},
- "uuid": "d7eb85d6-a74e-47c7-b669-d9c33ad0aa81",
+ "uuid": "7e78a97c-a095-412c-863f-ef31d9d6c7c0",
"persistent": true,
"priority": 3,
"metadata": {
@@ -806,8 +806,8 @@
"postServeActions": []
},
{
- "id": "a032561e-549d-47e8-8ebb-dad06d2a6ce4",
- "name": "Get Identity Provider configuration - default",
+ "id": "8b9f07ca-37e5-4810-82fa-fe76436925f8",
+ "name": "Get Identity Provider configuration - getIdpConfigurationResponseExample",
"request": {
"urlPathTemplate": "/config/identity-providers",
"method": "GET",
@@ -824,7 +824,7 @@
"Content-Type": "application/json"
}
},
- "uuid": "a032561e-549d-47e8-8ebb-dad06d2a6ce4",
+ "uuid": "8b9f07ca-37e5-4810-82fa-fe76436925f8",
"persistent": true,
"priority": 3,
"metadata": {
@@ -838,8 +838,8 @@
"postServeActions": []
},
{
- "id": "1a6cb620-9021-415a-98b0-c777a13f658e",
- "name": "Start domain verification - default",
+ "id": "071dc861-6513-45ca-bbde-07ee67629ad7",
+ "name": "Start domain verification - updateOrgDomainResponseExample",
"request": {
"urlPathTemplate": "/domains/{domain_id}/verify",
"method": "POST",
@@ -861,7 +861,7 @@
"Content-Type": "application/json"
}
},
- "uuid": "1a6cb620-9021-415a-98b0-c777a13f658e",
+ "uuid": "071dc861-6513-45ca-bbde-07ee67629ad7",
"persistent": true,
"priority": 3,
"metadata": {
@@ -874,8 +874,8 @@
}
},
{
- "id": "736aebae-5a32-4a51-b735-1331ee4bd9ab",
- "name": "List Identity Providers for a domain - default",
+ "id": "883745b4-a5d3-4e55-a102-3f6de84187f1",
+ "name": "List Identity Providers for a domain - getOrgDomainIdentityProvidersResponseExample",
"request": {
"urlPathTemplate": "/domains/{domain_id}/identity-providers",
"method": "GET",
@@ -897,7 +897,7 @@
"Content-Type": "application/json"
}
},
- "uuid": "736aebae-5a32-4a51-b735-1331ee4bd9ab",
+ "uuid": "883745b4-a5d3-4e55-a102-3f6de84187f1",
"persistent": true,
"priority": 3,
"metadata": {
@@ -910,8 +910,8 @@
}
},
{
- "id": "79faaaa8-f657-4412-a338-31db2a0c22fc",
- "name": "Associate a domain with an Identity Provider - default",
+ "id": "8d1092ea-dd63-4d47-be98-5400f6d5590b",
+ "name": "Associate a domain with an Identity Provider - createIdPResponseExample",
"request": {
"urlPathTemplate": "/identity-providers/{idp_id}/domains",
"method": "POST",
@@ -933,7 +933,7 @@
"Content-Type": "application/json"
}
},
- "uuid": "79faaaa8-f657-4412-a338-31db2a0c22fc",
+ "uuid": "8d1092ea-dd63-4d47-be98-5400f6d5590b",
"persistent": true,
"priority": 3,
"metadata": {
@@ -985,8 +985,8 @@
}
},
{
- "id": "3ef1a37b-4761-4156-9d5f-1330d174d47b",
- "name": "Get a Provisioning Configuration - default",
+ "id": "c24355de-8f84-4694-bd72-97dd531392b5",
+ "name": "Get a Provisioning Configuration - getIdPResponseExample",
"request": {
"urlPathTemplate": "/identity-providers/{idp_id}/provisioning",
"method": "GET",
@@ -1008,7 +1008,7 @@
"Content-Type": "application/json"
}
},
- "uuid": "3ef1a37b-4761-4156-9d5f-1330d174d47b",
+ "uuid": "c24355de-8f84-4694-bd72-97dd531392b5",
"persistent": true,
"priority": 3,
"metadata": {
@@ -1021,8 +1021,8 @@
}
},
{
- "id": "a58b006c-012a-4283-b025-5b0fc5d9c644",
- "name": "Create a Provisioning Configuration - default",
+ "id": "028859ea-0007-45a9-9463-044b0d9067e3",
+ "name": "Create a Provisioning Configuration - createIdPProvisioningResponseExample",
"request": {
"urlPathTemplate": "/identity-providers/{idp_id}/provisioning",
"method": "POST",
@@ -1044,7 +1044,7 @@
"Content-Type": "application/json"
}
},
- "uuid": "a58b006c-012a-4283-b025-5b0fc5d9c644",
+ "uuid": "028859ea-0007-45a9-9463-044b0d9067e3",
"persistent": true,
"priority": 3,
"metadata": {
@@ -1093,8 +1093,8 @@
}
},
{
- "id": "b52f90fe-1fb8-43af-b6c6-92036c78eafd",
- "name": "Refresh Provisioning Configuration attribute mapping - default",
+ "id": "98cc5ac5-93ef-4cdf-8ef0-9eac5d023886",
+ "name": "Refresh Provisioning Configuration attribute mapping - getIdPResponseExample",
"request": {
"urlPathTemplate": "/identity-providers/{idp_id}/provisioning/update-attributes",
"method": "PUT",
@@ -1116,7 +1116,7 @@
"Content-Type": "application/json"
}
},
- "uuid": "b52f90fe-1fb8-43af-b6c6-92036c78eafd",
+ "uuid": "98cc5ac5-93ef-4cdf-8ef0-9eac5d023886",
"persistent": true,
"priority": 3,
"metadata": {
@@ -1129,8 +1129,8 @@
}
},
{
- "id": "e0c33ec4-40b3-42d5-8a5c-0dd959cdb9ce",
- "name": "List Provisioning SCIM tokens - default",
+ "id": "bcdcd71b-d2a7-4d9a-b4ab-22d5e5c95c46",
+ "name": "List Provisioning SCIM tokens - listOrgDomainsResponseExample",
"request": {
"urlPathTemplate": "/identity-providers/{idp_id}/provisioning/scim-tokens",
"method": "GET",
@@ -1152,7 +1152,7 @@
"Content-Type": "application/json"
}
},
- "uuid": "e0c33ec4-40b3-42d5-8a5c-0dd959cdb9ce",
+ "uuid": "bcdcd71b-d2a7-4d9a-b4ab-22d5e5c95c46",
"persistent": true,
"priority": 3,
"metadata": {
@@ -1165,8 +1165,8 @@
}
},
{
- "id": "97c46081-373a-430e-a4bb-91e718763cd8",
- "name": "Create a Provisioning SCIM token - default",
+ "id": "1fc598f0-4985-4b9b-89cb-6ab5dc54325a",
+ "name": "Create a Provisioning SCIM token - createIdPProvisioningScimTokenResponseExample",
"request": {
"urlPathTemplate": "/identity-providers/{idp_id}/provisioning/scim-tokens",
"method": "POST",
@@ -1188,7 +1188,7 @@
"Content-Type": "application/json"
}
},
- "uuid": "97c46081-373a-430e-a4bb-91e718763cd8",
+ "uuid": "1fc598f0-4985-4b9b-89cb-6ab5dc54325a",
"persistent": true,
"priority": 3,
"metadata": {
@@ -1240,8 +1240,8 @@
}
},
{
- "id": "3b86d015-abf6-4c97-b708-237ed2ad30e3",
- "name": "List member roles - default",
+ "id": "c8ae9a84-d822-47b5-8ec8-a500489495dc",
+ "name": "List member roles - listOrganizationMemberRolesResponseExample",
"request": {
"urlPathTemplate": "/members/{user_id}/roles",
"method": "GET",
@@ -1271,7 +1271,7 @@
"Content-Type": "application/json"
}
},
- "uuid": "3b86d015-abf6-4c97-b708-237ed2ad30e3",
+ "uuid": "c8ae9a84-d822-47b5-8ec8-a500489495dc",
"persistent": true,
"priority": 3,
"metadata": {
@@ -1284,8 +1284,8 @@
}
},
{
- "id": "fc74ad7a-df90-438a-80ba-908648d37c76",
- "name": "Assign roles to a member - default",
+ "id": "c3e57548-ed49-4b95-8fe8-a14e5e0c9492",
+ "name": "Assign roles to a member - assignOrganizationMemberRolesRequestExample",
"request": {
"urlPathTemplate": "/members/{user_id}/roles",
"method": "POST",
@@ -1307,7 +1307,7 @@
"Content-Type": "application/json"
}
},
- "uuid": "fc74ad7a-df90-438a-80ba-908648d37c76",
+ "uuid": "c3e57548-ed49-4b95-8fe8-a14e5e0c9492",
"persistent": true,
"priority": 3,
"metadata": {
@@ -1320,8 +1320,8 @@
}
},
{
- "id": "da82679e-4aa8-4fe7-b946-2b37ffeb5fdb",
- "name": "Remove roles from a member - default",
+ "id": "c1b9e307-010e-4b6d-8d36-d5053dd3e6fd",
+ "name": "Remove roles from a member - unassignOrganizationMemberRolesRequestExample",
"request": {
"urlPathTemplate": "/members/{user_id}/roles",
"method": "DELETE",
@@ -1343,7 +1343,7 @@
"Content-Type": "application/json"
}
},
- "uuid": "da82679e-4aa8-4fe7-b946-2b37ffeb5fdb",
+ "uuid": "c1b9e307-010e-4b6d-8d36-d5053dd3e6fd",
"persistent": true,
"priority": 3,
"metadata": {
From b14901e28f64c59a4ddca8d4939649ace0c5c692 Mon Sep 17 00:00:00 2001
From: "fern-api[bot]" <115122769+fern-api[bot]@users.noreply.github.com>
Date: Tue, 16 Jun 2026 13:15:27 +0000
Subject: [PATCH 5/7] [fern-replay] Initialize Replay
---
.fern/replay.lock | 10 ++++++++++
.fernignore | 3 +++
2 files changed, 13 insertions(+)
create mode 100644 .fern/replay.lock
diff --git a/.fern/replay.lock b/.fern/replay.lock
new file mode 100644
index 0000000..98469bf
--- /dev/null
+++ b/.fern/replay.lock
@@ -0,0 +1,10 @@
+# DO NOT EDIT MANUALLY - Managed by Fern Replay
+version: "1.0"
+generations:
+ - commit_sha: 1c0ed7f061d32b15b4d3fea2d5a307f57b3f4d31
+ tree_hash: 4b6868bf849baafbdbec5aa6de743fafad709fcf
+ timestamp: 2026-06-16T13:15:23.133Z
+ cli_version: unknown
+ generator_versions: {}
+current_generation: 1c0ed7f061d32b15b4d3fea2d5a307f57b3f4d31
+patches: []
diff --git a/.fernignore b/.fernignore
index 39713c2..9aae8ca 100644
--- a/.fernignore
+++ b/.fernignore
@@ -32,3 +32,6 @@ CHANGELOG.md
.github/
LICENSE
NOTICE.txt
+.fern/replay.lock
+.fern/replay.yml
+.gitattributes
From aba015e8d53053ee5ef7431aa6c53463fcae8b4d Mon Sep 17 00:00:00 2001
From: Kunal Dawar
Date: Tue, 16 Jun 2026 19:14:31 +0530
Subject: [PATCH 6/7] fix: Restore custom client and token provider exports in
__init__.py
---
src/auth0/myorganization/__init__.py | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/src/auth0/myorganization/__init__.py b/src/auth0/myorganization/__init__.py
index bc43d80..4522ba2 100644
--- a/src/auth0/myorganization/__init__.py
+++ b/src/auth0/myorganization/__init__.py
@@ -170,6 +170,8 @@
from .version import __version__
_dynamic_imports: typing.Dict[str, str] = {
"AsyncAuth0": ".client",
+ "AsyncMyOrganizationClient": ".myorganization_client",
+ "AsyncTokenProvider": ".token_provider",
"Auth0": ".client",
"Auth0Environment": ".environment",
"Automatic": ".types",
@@ -299,6 +301,7 @@
"MemberInvitation": ".types",
"MemberInvitationInvitee": ".types",
"MemberInvitationInviter": ".types",
+ "MyOrganizationClient": ".myorganization_client",
"NotFoundError": ".errors",
"OauthScope": ".types",
"OrgBranding": ".types",
@@ -318,6 +321,7 @@
"Role": ".types",
"RoleId": ".types",
"StartOrganizationDomainVerificationResponseContent": ".types",
+ "TokenProvider": ".token_provider",
"TooManyRequestsError": ".errors",
"UnauthorizedError": ".errors",
"UpdateIdentityProviderRequestContent": ".types",
@@ -356,6 +360,8 @@ def __dir__():
__all__ = [
"AsyncAuth0",
+ "AsyncMyOrganizationClient",
+ "AsyncTokenProvider",
"Auth0",
"Auth0Environment",
"Automatic",
@@ -485,6 +491,7 @@ def __dir__():
"MemberInvitation",
"MemberInvitationInvitee",
"MemberInvitationInviter",
+ "MyOrganizationClient",
"NotFoundError",
"OauthScope",
"OrgBranding",
@@ -504,6 +511,7 @@ def __dir__():
"Role",
"RoleId",
"StartOrganizationDomainVerificationResponseContent",
+ "TokenProvider",
"TooManyRequestsError",
"UnauthorizedError",
"UpdateIdentityProviderRequestContent",
From 7ba0f540b223f4f5ed408fc1149c95aa2fe414d5 Mon Sep 17 00:00:00 2001
From: Kunal Dawar
Date: Tue, 16 Jun 2026 19:20:21 +0530
Subject: [PATCH 7/7] fix: Add max_retries support to custom client wrapper
---
src/auth0/myorganization/core/client_wrapper.py | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/src/auth0/myorganization/core/client_wrapper.py b/src/auth0/myorganization/core/client_wrapper.py
index 4229ef6..79ab2e7 100644
--- a/src/auth0/myorganization/core/client_wrapper.py
+++ b/src/auth0/myorganization/core/client_wrapper.py
@@ -20,11 +20,13 @@ def __init__(
headers: typing.Optional[typing.Dict[str, str]] = None,
base_url: str,
timeout: typing.Optional[float] = None,
+ max_retries: int = 2,
):
self._token = token
self._headers = headers
self._base_url = base_url
self._timeout = timeout
+ self._max_retries = max_retries
def get_headers(self) -> typing.Dict[str, str]:
# Dynamically get version from package metadata
@@ -61,6 +63,9 @@ def get_base_url(self) -> str:
def get_timeout(self) -> typing.Optional[float]:
return self._timeout
+ def get_max_retries(self) -> int:
+ return self._max_retries
+
class SyncClientWrapper(BaseClientWrapper):
def __init__(
@@ -70,15 +75,17 @@ def __init__(
headers: typing.Optional[typing.Dict[str, str]] = None,
base_url: str,
timeout: typing.Optional[float] = None,
+ max_retries: int = 2,
httpx_client: httpx.Client,
logging: typing.Optional[typing.Union[LogConfig, Logger]] = None,
):
- super().__init__(token=token, headers=headers, base_url=base_url, timeout=timeout)
+ super().__init__(token=token, headers=headers, base_url=base_url, timeout=timeout, max_retries=max_retries)
self.httpx_client = HttpClient(
httpx_client=httpx_client,
base_headers=self.get_headers,
base_timeout=self.get_timeout,
base_url=self.get_base_url,
+ base_max_retries=self.get_max_retries(),
logging_config=logging,
)
@@ -91,17 +98,19 @@ def __init__(
headers: typing.Optional[typing.Dict[str, str]] = None,
base_url: str,
timeout: typing.Optional[float] = None,
+ max_retries: int = 2,
async_token: typing.Optional[typing.Callable[[], typing.Awaitable[str]]] = None,
httpx_client: httpx.AsyncClient,
logging: typing.Optional[typing.Union[LogConfig, Logger]] = None,
):
- super().__init__(token=token, headers=headers, base_url=base_url, timeout=timeout)
+ super().__init__(token=token, headers=headers, base_url=base_url, timeout=timeout, max_retries=max_retries)
self._async_token = async_token
self.httpx_client = AsyncHttpClient(
httpx_client=httpx_client,
base_headers=self.get_headers,
base_timeout=self.get_timeout,
base_url=self.get_base_url,
+ base_max_retries=self.get_max_retries(),
async_base_headers=self.async_get_headers,
logging_config=logging,
)