Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .last-synced-sha
Original file line number Diff line number Diff line change
@@ -1 +1 @@
92db0495807c86fbbc4d45bd266a6c1f5bcbb59c
f908f520f9fcd63dfd42ed35b7f141a65b61609b
20 changes: 18 additions & 2 deletions .oagen-manifest.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"version": 2,
"language": "python",
"generatedAt": "2026-04-28T16:15:39.420Z",
"generatedAt": "2026-04-30T20:02:46.665Z",
"files": [
"src/workos/_client.py",
"src/workos/admin_portal/__init__.py",
Expand All @@ -18,6 +18,8 @@
"src/workos/api_keys/models/api_key.py",
"src/workos/api_keys/models/api_key_owner.py",
"src/workos/api_keys/models/api_key_validation_response.py",
"src/workos/api_keys/models/api_key_validation_response_api_key.py",
"src/workos/api_keys/models/api_key_validation_response_api_key_owner.py",
"src/workos/api_keys/models/api_key_with_value.py",
"src/workos/api_keys/models/api_key_with_value_owner.py",
"src/workos/api_keys/models/create_organization_api_key.py",
Expand Down Expand Up @@ -70,7 +72,7 @@
"src/workos/authorization/models/update_authorization_resource.py",
"src/workos/authorization/models/update_organization_role.py",
"src/workos/authorization/models/update_role.py",
"src/workos/authorization/models/user_organization_membership_base_list_data.py",
"src/workos/authorization/models/user_organization_membership_base_with_user.py",
"src/workos/common/__init__.py",
"src/workos/common/models/__init__.py",
"src/workos/common/models/action_authentication_denied.py",
Expand Down Expand Up @@ -202,6 +204,10 @@
"src/workos/common/models/dsync_group_user_added_data.py",
"src/workos/common/models/dsync_group_user_removed.py",
"src/workos/common/models/dsync_group_user_removed_data.py",
"src/workos/common/models/dsync_token_created.py",
"src/workos/common/models/dsync_token_created_data.py",
"src/workos/common/models/dsync_token_deleted.py",
"src/workos/common/models/dsync_token_deleted_data.py",
"src/workos/common/models/dsync_user_created.py",
"src/workos/common/models/dsync_user_deleted.py",
"src/workos/common/models/dsync_user_updated.py",
Expand Down Expand Up @@ -374,6 +380,7 @@
"src/workos/common/models/user_identities_get_item_provider.py",
"src/workos/common/models/user_invite_state.py",
"src/workos/common/models/user_organization_membership_base_list_data_status.py",
"src/workos/common/models/user_organization_membership_base_with_user_status.py",
"src/workos/common/models/user_organization_membership_status.py",
"src/workos/common/models/user_sessions_auth_method.py",
"src/workos/common/models/user_sessions_status.py",
Expand Down Expand Up @@ -468,6 +475,7 @@
"src/workos/groups/models/group.py",
"src/workos/groups/models/groups_order.py",
"src/workos/groups/models/update_group.py",
"src/workos/groups/models/user_organization_membership_base_list_data.py",
"src/workos/multi_factor_auth/__init__.py",
"src/workos/multi_factor_auth/_resource.py",
"src/workos/multi_factor_auth/models/__init__.py",
Expand Down Expand Up @@ -654,6 +662,8 @@
"tests/fixtures/api_key_revoked_data.json",
"tests/fixtures/api_key_revoked_data_owner.json",
"tests/fixtures/api_key_validation_response.json",
"tests/fixtures/api_key_validation_response_api_key.json",
"tests/fixtures/api_key_validation_response_api_key_owner.json",
"tests/fixtures/api_key_with_value.json",
"tests/fixtures/api_key_with_value_owner.json",
"tests/fixtures/application_credentials_list_item.json",
Expand Down Expand Up @@ -819,6 +829,10 @@
"tests/fixtures/dsync_group_user_added_data.json",
"tests/fixtures/dsync_group_user_removed.json",
"tests/fixtures/dsync_group_user_removed_data.json",
"tests/fixtures/dsync_token_created.json",
"tests/fixtures/dsync_token_created_data.json",
"tests/fixtures/dsync_token_deleted.json",
"tests/fixtures/dsync_token_deleted_data.json",
"tests/fixtures/dsync_user_created.json",
"tests/fixtures/dsync_user_deleted.json",
"tests/fixtures/dsync_user_updated.json",
Expand Down Expand Up @@ -916,6 +930,7 @@
"tests/fixtures/list_user_invite.json",
"tests/fixtures/list_user_organization_membership.json",
"tests/fixtures/list_user_organization_membership_base_list_data.json",
"tests/fixtures/list_user_organization_membership_base_with_user.json",
"tests/fixtures/list_user_sessions_list_item.json",
"tests/fixtures/list_webhook_endpoint_json.json",
"tests/fixtures/magic_auth.json",
Expand Down Expand Up @@ -1043,6 +1058,7 @@
"tests/fixtures/user_object.json",
"tests/fixtures/user_organization_membership.json",
"tests/fixtures/user_organization_membership_base_list_data.json",
"tests/fixtures/user_organization_membership_base_with_user.json",
"tests/fixtures/user_sessions_impersonator.json",
"tests/fixtures/user_sessions_list_item.json",
"tests/fixtures/user_updated.json",
Expand Down
6 changes: 6 additions & 0 deletions src/workos/api_keys/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@
from .api_key_validation_response import (
ApiKeyValidationResponse as ApiKeyValidationResponse,
)
from .api_key_validation_response_api_key import (
ApiKeyValidationResponseApiKey as ApiKeyValidationResponseApiKey,
)
from .api_key_validation_response_api_key_owner import (
ApiKeyValidationResponseApiKeyOwner as ApiKeyValidationResponseApiKeyOwner,
)
from .api_key_with_value import ApiKeyWithValue as ApiKeyWithValue
from .api_key_with_value_owner import ApiKeyWithValueOwner as ApiKeyWithValueOwner
from .create_organization_api_key import (
Expand Down
2 changes: 1 addition & 1 deletion src/workos/api_keys/models/api_key.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

@dataclass(slots=True)
class ApiKey:
"""The API Key object if the value is valid, or `null` if invalid."""
"""Api Key model."""

object: Literal["api_key"]
"""Distinguishes the API Key object."""
Expand Down
8 changes: 5 additions & 3 deletions src/workos/api_keys/models/api_key_validation_response.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,23 @@
from typing import Any, Dict, Optional
from workos._types import _raise_deserialize_error

from .api_key import ApiKey
from .api_key_validation_response_api_key import ApiKeyValidationResponseApiKey


@dataclass(slots=True)
class ApiKeyValidationResponse:
"""Api Key Validation Response model."""

api_key: Optional["ApiKey"]
api_key: Optional["ApiKeyValidationResponseApiKey"]

@classmethod
def from_dict(cls, data: Dict[str, Any]) -> "ApiKeyValidationResponse":
"""Deserialize from a dictionary."""
try:
return cls(
api_key=ApiKey.from_dict(cast(Dict[str, Any], _v_api_key))
api_key=ApiKeyValidationResponseApiKey.from_dict(
cast(Dict[str, Any], _v_api_key)
)
if (_v_api_key := data["api_key"]) is not None
else None,
)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# This file is auto-generated by oagen. Do not edit.

from typing import TypeAlias
from .api_key import ApiKey

ApiKeyValidationResponseApiKey: TypeAlias = ApiKey
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# This file is auto-generated by oagen. Do not edit.

from typing import TypeAlias
from workos.common.models.api_key_created_data_owner import ApiKeyCreatedDataOwner

ApiKeyValidationResponseApiKeyOwner: TypeAlias = ApiKeyCreatedDataOwner
26 changes: 13 additions & 13 deletions src/workos/authorization/_resource.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
Role,
RoleAssignment,
RoleList,
UserOrganizationMembershipBaseListData,
UserOrganizationMembershipBaseWithUser,
)
from .models import AuthorizationAssignment, AuthorizationOrder, PermissionsOrder
from .._pagination import AsyncPage, SyncPage
Expand Down Expand Up @@ -924,7 +924,7 @@ def list_memberships_for_resource_by_external_id(
permission_slug: str,
assignment: Optional[Union[AuthorizationAssignment, str]] = None,
request_options: Optional[RequestOptions] = None,
) -> SyncPage[UserOrganizationMembershipBaseListData]:
) -> SyncPage[UserOrganizationMembershipBaseWithUser]:
"""List memberships for a resource by external ID

Returns all organization memberships that have a specific permission on a resource, using the resource's external ID. This is useful for answering "Who can access this resource?" when you only have the external ID.
Expand All @@ -942,7 +942,7 @@ def list_memberships_for_resource_by_external_id(
request_options: Per-request options. Supports extra_headers, timeout, max_retries, and base_url override.

Returns:
SyncPage[UserOrganizationMembershipBaseListData]
SyncPage[UserOrganizationMembershipBaseWithUser]

Raises:
BadRequestError: If the request is malformed (400).
Expand Down Expand Up @@ -970,7 +970,7 @@ def list_memberships_for_resource_by_external_id(
return self._client.request_page(
method="get",
path=f"authorization/organizations/{organization_id}/resources/{resource_type_slug}/{external_id}/organization_memberships",
model=UserOrganizationMembershipBaseListData,
model=UserOrganizationMembershipBaseWithUser,
params=params,
request_options=request_options,
)
Expand Down Expand Up @@ -1254,7 +1254,7 @@ def list_memberships_for_resource(
permission_slug: str,
assignment: Optional[Union[AuthorizationAssignment, str]] = None,
request_options: Optional[RequestOptions] = None,
) -> SyncPage[UserOrganizationMembershipBaseListData]:
) -> SyncPage[UserOrganizationMembershipBaseWithUser]:
"""List organization memberships for resource

Returns all organization memberships that have a specific permission on a resource instance. This is useful for answering "Who can access this resource?".
Expand All @@ -1270,7 +1270,7 @@ def list_memberships_for_resource(
request_options: Per-request options. Supports extra_headers, timeout, max_retries, and base_url override.

Returns:
SyncPage[UserOrganizationMembershipBaseListData]
SyncPage[UserOrganizationMembershipBaseWithUser]

Raises:
BadRequestError: If the request is malformed (400).
Expand Down Expand Up @@ -1298,7 +1298,7 @@ def list_memberships_for_resource(
return self._client.request_page(
method="get",
path=f"authorization/resources/{resource_id}/organization_memberships",
model=UserOrganizationMembershipBaseListData,
model=UserOrganizationMembershipBaseWithUser,
params=params,
request_options=request_options,
)
Expand Down Expand Up @@ -2590,7 +2590,7 @@ async def list_memberships_for_resource_by_external_id(
permission_slug: str,
assignment: Optional[Union[AuthorizationAssignment, str]] = None,
request_options: Optional[RequestOptions] = None,
) -> AsyncPage[UserOrganizationMembershipBaseListData]:
) -> AsyncPage[UserOrganizationMembershipBaseWithUser]:
"""List memberships for a resource by external ID

Returns all organization memberships that have a specific permission on a resource, using the resource's external ID. This is useful for answering "Who can access this resource?" when you only have the external ID.
Expand All @@ -2608,7 +2608,7 @@ async def list_memberships_for_resource_by_external_id(
request_options: Per-request options. Supports extra_headers, timeout, max_retries, and base_url override.

Returns:
AsyncPage[UserOrganizationMembershipBaseListData]
AsyncPage[UserOrganizationMembershipBaseWithUser]

Raises:
BadRequestError: If the request is malformed (400).
Expand Down Expand Up @@ -2636,7 +2636,7 @@ async def list_memberships_for_resource_by_external_id(
return await self._client.request_page(
method="get",
path=f"authorization/organizations/{organization_id}/resources/{resource_type_slug}/{external_id}/organization_memberships",
model=UserOrganizationMembershipBaseListData,
model=UserOrganizationMembershipBaseWithUser,
params=params,
request_options=request_options,
)
Expand Down Expand Up @@ -2920,7 +2920,7 @@ async def list_memberships_for_resource(
permission_slug: str,
assignment: Optional[Union[AuthorizationAssignment, str]] = None,
request_options: Optional[RequestOptions] = None,
) -> AsyncPage[UserOrganizationMembershipBaseListData]:
) -> AsyncPage[UserOrganizationMembershipBaseWithUser]:
"""List organization memberships for resource

Returns all organization memberships that have a specific permission on a resource instance. This is useful for answering "Who can access this resource?".
Expand All @@ -2936,7 +2936,7 @@ async def list_memberships_for_resource(
request_options: Per-request options. Supports extra_headers, timeout, max_retries, and base_url override.

Returns:
AsyncPage[UserOrganizationMembershipBaseListData]
AsyncPage[UserOrganizationMembershipBaseWithUser]

Raises:
BadRequestError: If the request is malformed (400).
Expand Down Expand Up @@ -2964,7 +2964,7 @@ async def list_memberships_for_resource(
return await self._client.request_page(
method="get",
path=f"authorization/resources/{resource_id}/organization_memberships",
model=UserOrganizationMembershipBaseListData,
model=UserOrganizationMembershipBaseWithUser,
params=params,
request_options=request_options,
)
Expand Down
4 changes: 2 additions & 2 deletions src/workos/authorization/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,6 @@
)
from .update_organization_role import UpdateOrganizationRole as UpdateOrganizationRole
from .update_role import UpdateRole as UpdateRole
from .user_organization_membership_base_list_data import (
UserOrganizationMembershipBaseListData as UserOrganizationMembershipBaseListData,
from .user_organization_membership_base_with_user import (
UserOrganizationMembershipBaseWithUser as UserOrganizationMembershipBaseWithUser,
)
Comment on lines 33 to 38
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Breaking removal of UserOrganizationMembershipBaseListData from authorization exports

UserOrganizationMembershipBaseListData has been entirely removed from workos.authorization.models and the underlying file deleted from the authorization/models/ directory. Any existing consumer that imports this class from its documented location (from workos.authorization.models import UserOrganizationMembershipBaseListData) will receive an ImportError after upgrading. The class is now only available from workos.groups.models.

Without a re-export shim (e.g. from workos.groups.models import UserOrganizationMembershipBaseListData as UserOrganizationMembershipBaseListData in the old __init__.py) or a deprecation warning, this constitutes a hard breaking change. Consider whether a major version bump or a compatibility alias is needed.

Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# This file is auto-generated by oagen. Do not edit.

from __future__ import annotations

from dataclasses import dataclass
from datetime import datetime
from enum import Enum
from typing import cast
from typing import Any, Dict, Literal, Optional
from workos._types import _raise_deserialize_error
from workos._types import _format_datetime, _parse_datetime

from workos.user_management.models.user import User
from workos.common.models.user_organization_membership_base_with_user_status import (
UserOrganizationMembershipBaseWithUserStatus,
)


@dataclass(slots=True)
class UserOrganizationMembershipBaseWithUser:
"""User Organization Membership Base With User model."""

object: Literal["organization_membership"]
"""Distinguishes the organization membership object."""
id: str
"""The unique ID of the organization membership."""
user_id: str
"""The ID of the user."""
organization_id: str
"""The ID of the organization which the user belongs to."""
status: "UserOrganizationMembershipBaseWithUserStatus"
"""The status of the organization membership. One of `active`, `inactive`, or `pending`."""
directory_managed: bool
"""Whether this organization membership is managed by a directory sync connection."""
created_at: datetime
"""An ISO 8601 timestamp."""
updated_at: datetime
"""An ISO 8601 timestamp."""
user: "User"
"""The user that belongs to the organization through this membership."""
organization_name: Optional[str] = None
"""The name of the organization which the user belongs to."""
custom_attributes: Optional[Dict[str, Any]] = None
"""An object containing IdP-sourced attributes from the linked [Directory User](https://workos.com/docs/reference/directory-sync/directory-user) or [SSO Profile](https://workos.com/docs/reference/sso/profile). Directory User attributes take precedence when both are linked."""

@classmethod
def from_dict(
cls, data: Dict[str, Any]
) -> "UserOrganizationMembershipBaseWithUser":
"""Deserialize from a dictionary."""
try:
return cls(
object=data.get("object", "organization_membership"),
id=data["id"],
user_id=data["user_id"],
organization_id=data["organization_id"],
status=UserOrganizationMembershipBaseWithUserStatus(data["status"]),
directory_managed=data["directory_managed"],
created_at=_parse_datetime(data["created_at"]),
updated_at=_parse_datetime(data["updated_at"]),
user=User.from_dict(cast(Dict[str, Any], data["user"])),
organization_name=data.get("organization_name"),
custom_attributes=data.get("custom_attributes"),
)
except (KeyError, ValueError) as e:
_raise_deserialize_error("UserOrganizationMembershipBaseWithUser", e)

def to_dict(self) -> Dict[str, Any]:
"""Serialize to a dictionary."""
result: Dict[str, Any] = {}
result["object"] = self.object
result["id"] = self.id
result["user_id"] = self.user_id
result["organization_id"] = self.organization_id
result["status"] = (
self.status.value if isinstance(self.status, Enum) else self.status
)
result["directory_managed"] = self.directory_managed
result["created_at"] = _format_datetime(self.created_at)
result["updated_at"] = _format_datetime(self.updated_at)
result["user"] = self.user.to_dict()
if self.organization_name is not None:
result["organization_name"] = self.organization_name
if self.custom_attributes is not None:
result["custom_attributes"] = self.custom_attributes
return result
7 changes: 7 additions & 0 deletions src/workos/common/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,10 @@
from .models import DsyncGroupUserAddedData as DsyncGroupUserAddedData
from .models import DsyncGroupUserRemoved as DsyncGroupUserRemoved
from .models import DsyncGroupUserRemovedData as DsyncGroupUserRemovedData
from .models import DsyncTokenCreated as DsyncTokenCreated
from .models import DsyncTokenCreatedData as DsyncTokenCreatedData
from .models import DsyncTokenDeleted as DsyncTokenDeleted
from .models import DsyncTokenDeletedData as DsyncTokenDeletedData
from .models import DsyncUserCreated as DsyncUserCreated
from .models import DsyncUserDeleted as DsyncUserDeleted
from .models import DsyncUserUpdated as DsyncUserUpdated
Expand Down Expand Up @@ -357,6 +361,9 @@
from .models import (
UserOrganizationMembershipBaseListDataStatus as UserOrganizationMembershipBaseListDataStatus,
)
from .models import (
UserOrganizationMembershipBaseWithUserStatus as UserOrganizationMembershipBaseWithUserStatus,
)
from .models import UserOrganizationMembershipStatus as UserOrganizationMembershipStatus
from .models import UserSessionsAuthMethod as UserSessionsAuthMethod
from .models import UserSessionsStatus as UserSessionsStatus
Expand Down
Loading
Loading