Skip to content

Commit a33e77a

Browse files
committed
Add external_id to user and organization
Add a method to get users by external id. Change organization get by lookup key which no longer works to be get by external id.
1 parent 8def89f commit a33e77a

File tree

6 files changed

+60
-15
lines changed

6 files changed

+60
-15
lines changed

tests/test_organizations.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -109,20 +109,20 @@ def test_get_organization(
109109
assert request_kwargs["method"] == "get"
110110
assert request_kwargs["url"].endswith("/organizations/organization_id")
111111

112-
def test_get_organization_by_lookup_key(
112+
def test_get_organization_by_external_id(
113113
self, mock_organization, capture_and_mock_http_client_request
114114
):
115115
request_kwargs = capture_and_mock_http_client_request(
116116
self.http_client, mock_organization, 200
117117
)
118118

119119
organization = syncify(
120-
self.organizations.get_organization_by_lookup_key(lookup_key="test")
120+
self.organizations.get_organization_by_external_id(external_id="test")
121121
)
122122

123123
assert organization.dict() == mock_organization
124124
assert request_kwargs["method"] == "get"
125-
assert request_kwargs["url"].endswith("/organizations/by_lookup_key/test")
125+
assert request_kwargs["url"].endswith("/organizations/external_id/test")
126126

127127
def test_create_organization_with_domain_data(
128128
self, mock_organization, capture_and_mock_http_client_request

tests/test_user_management.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -392,6 +392,26 @@ def test_get_user(self, mock_user, capture_and_mock_http_client_request):
392392
assert user.profile_picture_url == "https://example.com/profile-picture.jpg"
393393
assert user.last_sign_in_at == "2021-06-25T19:07:33.155Z"
394394

395+
def test_get_user_by_external_id(
396+
self, mock_user, capture_and_mock_http_client_request
397+
):
398+
request_kwargs = capture_and_mock_http_client_request(
399+
self.http_client, mock_user, 200
400+
)
401+
402+
external_id = "external-id"
403+
user = syncify(
404+
self.user_management.get_user_by_external_id(external_id=external_id)
405+
)
406+
407+
assert request_kwargs["url"].endswith(
408+
f"user_management/users/external_id/{external_id}"
409+
)
410+
assert request_kwargs["method"] == "get"
411+
assert user.id == "user_01H7ZGXFP5C6BBQY6Z7277ZCT0"
412+
assert user.profile_picture_url == "https://example.com/profile-picture.jpg"
413+
assert user.last_sign_in_at == "2021-06-25T19:07:33.155Z"
414+
395415
def test_list_users_auto_pagination(
396416
self,
397417
mock_users_multiple_pages,

workos/organizations.py

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -60,13 +60,13 @@ def get_organization(self, organization_id: str) -> SyncOrAsync[Organization]:
6060
"""
6161
...
6262

63-
def get_organization_by_lookup_key(
64-
self, lookup_key: str
63+
def get_organization_by_external_id(
64+
self, external_id: str
6565
) -> SyncOrAsync[Organization]:
66-
"""Gets details for a single Organization by lookup key
66+
"""Gets details for a single Organization by external id
6767
6868
Args:
69-
lookup_key (str): Organization's lookup key
69+
external_id (str): Organization's external id
7070
7171
Returns:
7272
Organization: Organization response from WorkOS
@@ -125,7 +125,6 @@ def delete_organization(self, organization_id: str) -> SyncOrAsync[None]:
125125

126126

127127
class Organizations(OrganizationsModule):
128-
129128
_http_client: SyncHTTPClient
130129

131130
def __init__(self, http_client: SyncHTTPClient):
@@ -167,9 +166,9 @@ def get_organization(self, organization_id: str) -> Organization:
167166

168167
return Organization.model_validate(response)
169168

170-
def get_organization_by_lookup_key(self, lookup_key: str) -> Organization:
169+
def get_organization_by_external_id(self, external_id: str) -> Organization:
171170
response = self._http_client.request(
172-
"organizations/by_lookup_key/{lookup_key}".format(lookup_key=lookup_key),
171+
"organizations/external_id/{external_id}".format(external_id=external_id),
173172
method=REQUEST_METHOD_GET,
174173
)
175174

@@ -237,7 +236,6 @@ def list_organization_roles(self, organization_id: str) -> RoleList:
237236

238237

239238
class AsyncOrganizations(OrganizationsModule):
240-
241239
_http_client: AsyncHTTPClient
242240

243241
def __init__(self, http_client: AsyncHTTPClient):
@@ -279,9 +277,9 @@ async def get_organization(self, organization_id: str) -> Organization:
279277

280278
return Organization.model_validate(response)
281279

282-
async def get_organization_by_lookup_key(self, lookup_key: str) -> Organization:
280+
async def get_organization_by_external_id(self, external_id: str) -> Organization:
283281
response = await self._http_client.request(
284-
"organizations/by_lookup_key/{lookup_key}".format(lookup_key=lookup_key),
282+
"organizations/external_id/{external_id}".format(external_id=external_id),
285283
method=REQUEST_METHOD_GET,
286284
)
287285

workos/types/organizations/organization.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,5 @@
66
class Organization(OrganizationCommon):
77
allow_profiles_outside_organization: bool
88
domains: Sequence[OrganizationDomain]
9-
lookup_key: Optional[str] = None
109
stripe_customer_id: Optional[str] = None
10+
external_id: Optional[str] = None

workos/types/user_management/user.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,4 @@ class User(WorkOSModel):
1515
last_sign_in_at: Optional[str] = None
1616
created_at: str
1717
updated_at: str
18+
external_id: Optional[str] = None

workos/user_management.py

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@
6666

6767
USER_PATH = "user_management/users"
6868
USER_DETAIL_PATH = "user_management/users/{0}"
69+
USER_DETAIL_BY_EXTERNAL_ID_PATH = "user_management/users/external_id/{0}"
6970
ORGANIZATION_MEMBERSHIP_PATH = "user_management/organization_memberships"
7071
ORGANIZATION_MEMBERSHIP_DETAIL_PATH = "user_management/organization_memberships/{0}"
7172
ORGANIZATION_MEMBERSHIP_DEACTIVATE_PATH = (
@@ -137,6 +138,16 @@ def get_user(self, user_id: str) -> SyncOrAsync[User]:
137138
"""
138139
...
139140

141+
def get_user_by_external_id(self, external_id: str) -> SyncOrAsync[User]:
142+
"""Get the details of an existing user.
143+
144+
Args:
145+
external_id (str): The user's external id
146+
Returns:
147+
User: User response from WorkOS.
148+
"""
149+
...
150+
140151
def list_users(
141152
self,
142153
*,
@@ -389,7 +400,6 @@ def get_authorization_url(
389400
)
390401

391402
if connection_id is not None:
392-
393403
params["connection_id"] = connection_id
394404
if organization_id is not None:
395405
params["organization_id"] = organization_id
@@ -860,6 +870,14 @@ def get_user(self, user_id: str) -> User:
860870

861871
return User.model_validate(response)
862872

873+
def get_user_by_external_id(self, external_id: str) -> User:
874+
response = self._http_client.request(
875+
USER_DETAIL_BY_EXTERNAL_ID_PATH.format(external_id),
876+
method=REQUEST_METHOD_GET,
877+
)
878+
879+
return User.model_validate(response)
880+
863881
def list_users(
864882
self,
865883
*,
@@ -1464,6 +1482,14 @@ async def get_user(self, user_id: str) -> User:
14641482

14651483
return User.model_validate(response)
14661484

1485+
async def get_user_by_external_id(self, external_id: str) -> User:
1486+
response = await self._http_client.request(
1487+
USER_DETAIL_BY_EXTERNAL_ID_PATH.format(external_id),
1488+
method=REQUEST_METHOD_GET,
1489+
)
1490+
1491+
return User.model_validate(response)
1492+
14671493
async def list_users(
14681494
self,
14691495
*,

0 commit comments

Comments
 (0)