workos 1.5.1__py3-none-any.whl → 5.38.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (150) hide show
  1. workos/__about__.py +1 -1
  2. workos/__init__.py +3 -7
  3. workos/_base_client.py +138 -0
  4. workos/_client_configuration.py +10 -0
  5. workos/api_keys.py +53 -0
  6. workos/async_client.py +144 -0
  7. workos/audit_logs.py +125 -0
  8. workos/client.py +110 -18
  9. workos/directory_sync.py +379 -99
  10. workos/events.py +111 -0
  11. workos/exceptions.py +53 -26
  12. workos/fga.py +649 -0
  13. workos/mfa.py +205 -0
  14. workos/organization_domains.py +179 -0
  15. workos/organizations.py +403 -73
  16. workos/passwordless.py +67 -43
  17. workos/pipes.py +93 -0
  18. workos/portal.py +51 -28
  19. workos/session.py +337 -0
  20. workos/sso.py +311 -101
  21. workos/types/__init__.py +4 -0
  22. workos/types/api_keys/__init__.py +1 -0
  23. workos/types/api_keys/api_keys.py +20 -0
  24. workos/types/audit_logs/__init__.py +6 -0
  25. workos/types/audit_logs/audit_log_event.py +16 -0
  26. workos/types/audit_logs/audit_log_event_actor.py +12 -0
  27. workos/types/audit_logs/audit_log_event_context.py +8 -0
  28. workos/types/audit_logs/audit_log_event_target.py +12 -0
  29. workos/types/audit_logs/audit_log_export.py +18 -0
  30. workos/types/audit_logs/audit_log_metadata.py +4 -0
  31. workos/types/directory_sync/__init__.py +5 -0
  32. workos/types/directory_sync/directory.py +31 -0
  33. workos/types/directory_sync/directory_group.py +16 -0
  34. workos/types/directory_sync/directory_state.py +28 -0
  35. workos/types/directory_sync/directory_type.py +24 -0
  36. workos/types/directory_sync/directory_user.py +50 -0
  37. workos/types/directory_sync/list_filters.py +21 -0
  38. workos/types/events/__init__.py +13 -0
  39. workos/types/events/authentication_payload.py +70 -0
  40. workos/types/events/connection_payload_with_legacy_fields.py +5 -0
  41. workos/types/events/directory_group_membership_payload.py +9 -0
  42. workos/types/events/directory_group_with_previous_attributes.py +6 -0
  43. workos/types/events/directory_payload.py +16 -0
  44. workos/types/events/directory_payload_with_legacy_fields.py +29 -0
  45. workos/types/events/directory_user_with_previous_attributes.py +6 -0
  46. workos/types/events/event.py +324 -0
  47. workos/types/events/event_model.py +103 -0
  48. workos/types/events/event_type.py +59 -0
  49. workos/types/events/list_filters.py +10 -0
  50. workos/types/events/organization_domain_verification_failed_payload.py +14 -0
  51. workos/types/events/previous_attributes.py +3 -0
  52. workos/types/events/session_payload.py +27 -0
  53. workos/types/feature_flags/__init__.py +3 -0
  54. workos/types/feature_flags/feature_flag.py +12 -0
  55. workos/types/feature_flags/list_filters.py +5 -0
  56. workos/types/fga/__init__.py +5 -0
  57. workos/types/fga/authorization_resource_types.py +9 -0
  58. workos/types/fga/authorization_resources.py +10 -0
  59. workos/types/fga/check.py +51 -0
  60. workos/types/fga/list_filters.py +24 -0
  61. workos/types/fga/warnings.py +33 -0
  62. workos/types/fga/warrant.py +49 -0
  63. workos/types/list_resource.py +198 -0
  64. workos/types/metadata.py +4 -0
  65. workos/types/mfa/__init__.py +5 -0
  66. workos/types/mfa/authentication_challenge.py +14 -0
  67. workos/types/mfa/authentication_challenge_verification_response.py +9 -0
  68. workos/types/mfa/authentication_factor.py +70 -0
  69. workos/types/mfa/authentication_factor_totp_and_challenge_response.py +10 -0
  70. workos/types/mfa/enroll_authentication_factor_type.py +8 -0
  71. workos/types/organization_domains/__init__.py +1 -0
  72. workos/types/organization_domains/organization_domain.py +18 -0
  73. workos/types/organizations/__init__.py +6 -0
  74. workos/types/organizations/domain_data_input.py +7 -0
  75. workos/types/organizations/list_filters.py +6 -0
  76. workos/types/organizations/organization.py +13 -0
  77. workos/types/organizations/organization_common.py +12 -0
  78. workos/types/passwordless/__init__.py +2 -0
  79. workos/types/passwordless/passwordless_session.py +12 -0
  80. workos/types/passwordless/passwordless_session_type.py +3 -0
  81. workos/types/pipes/__init__.py +6 -0
  82. workos/types/pipes/pipes.py +34 -0
  83. workos/types/portal/__init__.py +2 -0
  84. workos/types/portal/portal_link.py +7 -0
  85. workos/types/portal/portal_link_intent.py +11 -0
  86. workos/types/portal/portal_link_intent_options.py +9 -0
  87. workos/types/roles/__init__.py +0 -0
  88. workos/types/roles/role.py +27 -0
  89. workos/types/sso/__init__.py +4 -0
  90. workos/types/sso/connection.py +70 -0
  91. workos/types/sso/connection_domain.py +8 -0
  92. workos/types/sso/profile.py +35 -0
  93. workos/types/sso/sso_provider_type.py +10 -0
  94. workos/types/user_management/__init__.py +12 -0
  95. workos/types/user_management/authenticate_with_common.py +66 -0
  96. workos/types/user_management/authentication_response.py +53 -0
  97. workos/types/user_management/email_verification.py +18 -0
  98. workos/types/user_management/impersonator.py +8 -0
  99. workos/types/user_management/invitation.py +26 -0
  100. workos/types/user_management/list_filters.py +29 -0
  101. workos/types/user_management/magic_auth.py +18 -0
  102. workos/types/user_management/oauth_tokens.py +21 -0
  103. workos/types/user_management/organization_membership.py +25 -0
  104. workos/types/user_management/password_hash_type.py +4 -0
  105. workos/types/user_management/password_reset.py +18 -0
  106. workos/types/user_management/screen_hint.py +3 -0
  107. workos/types/user_management/session.py +79 -0
  108. workos/types/user_management/user.py +22 -0
  109. workos/types/user_management/user_management_provider_type.py +11 -0
  110. workos/types/vault/__init__.py +2 -0
  111. workos/types/vault/key.py +25 -0
  112. workos/types/vault/object.py +38 -0
  113. workos/types/webhooks/__init__.py +0 -0
  114. workos/types/webhooks/webhook.py +330 -0
  115. workos/types/webhooks/webhook_model.py +14 -0
  116. workos/types/webhooks/webhook_payload.py +4 -0
  117. workos/types/widgets/__init__.py +2 -0
  118. workos/types/widgets/widget_scope.py +4 -0
  119. workos/types/widgets/widget_token_response.py +7 -0
  120. workos/types/workos_model.py +26 -0
  121. workos/typing/__init__.py +1 -0
  122. workos/typing/literals.py +32 -0
  123. workos/typing/sync_or_async.py +5 -0
  124. workos/typing/untyped_literal.py +37 -0
  125. workos/typing/webhooks.py +18 -0
  126. workos/user_management.py +2400 -0
  127. workos/utils/_base_http_client.py +252 -0
  128. workos/utils/crypto_provider.py +39 -0
  129. workos/utils/http_client.py +214 -0
  130. workos/utils/pagination_order.py +4 -0
  131. workos/utils/request_helper.py +27 -0
  132. workos/vault.py +544 -0
  133. workos/webhooks.py +96 -39
  134. workos/widgets.py +55 -0
  135. {workos-1.5.1.dist-info → workos-5.38.0.dist-info}/LICENSE +1 -1
  136. workos-5.38.0.dist-info/METADATA +107 -0
  137. workos-5.38.0.dist-info/RECORD +141 -0
  138. {workos-1.5.1.dist-info → workos-5.38.0.dist-info}/WHEEL +1 -1
  139. workos/audit_trail.py +0 -172
  140. workos/resources/base.py +0 -36
  141. workos/resources/event.py +0 -42
  142. workos/resources/event_action.py +0 -11
  143. workos/resources/sso.py +0 -53
  144. workos/utils/connection_types.py +0 -17
  145. workos/utils/request.py +0 -95
  146. workos/utils/validation.py +0 -45
  147. workos-1.5.1.dist-info/METADATA +0 -77
  148. workos-1.5.1.dist-info/RECORD +0 -25
  149. /workos/{resources/__init__.py → py.typed} +0 -0
  150. {workos-1.5.1.dist-info → workos-5.38.0.dist-info}/top_level.txt +0 -0
workos/directory_sync.py CHANGED
@@ -1,155 +1,435 @@
1
- import workos
2
- from workos.utils.request import (
3
- RequestHelper,
1
+ from typing import Optional, Protocol
2
+
3
+ from workos.types.directory_sync.list_filters import (
4
+ DirectoryGroupListFilters,
5
+ DirectoryListFilters,
6
+ DirectoryUserListFilters,
7
+ )
8
+ from workos.typing.sync_or_async import SyncOrAsync
9
+ from workos.utils.http_client import AsyncHTTPClient, SyncHTTPClient
10
+ from workos.utils.pagination_order import PaginationOrder
11
+ from workos.utils.request_helper import (
12
+ DEFAULT_LIST_RESPONSE_LIMIT,
4
13
  REQUEST_METHOD_DELETE,
5
14
  REQUEST_METHOD_GET,
6
15
  )
7
- from workos.utils.validation import DIRECTORY_SYNC_MODULE, validate_settings
16
+ from workos.types.directory_sync import (
17
+ DirectoryGroup,
18
+ Directory,
19
+ DirectoryUserWithGroups,
20
+ )
21
+ from workos.types.list_resource import ListMetadata, ListPage, WorkOSListResource
8
22
 
9
- RESPONSE_LIMIT = 10
23
+ DirectoryUsersListResource = WorkOSListResource[
24
+ DirectoryUserWithGroups, DirectoryUserListFilters, ListMetadata
25
+ ]
10
26
 
27
+ DirectoryGroupsListResource = WorkOSListResource[
28
+ DirectoryGroup, DirectoryGroupListFilters, ListMetadata
29
+ ]
11
30
 
12
- class DirectorySync(object):
13
- """Offers methods through the WorkOS Directory Sync service."""
31
+ DirectoriesListResource = WorkOSListResource[
32
+ Directory, DirectoryListFilters, ListMetadata
33
+ ]
14
34
 
15
- @validate_settings(DIRECTORY_SYNC_MODULE)
16
- def __init__(self):
17
- pass
18
35
 
19
- @property
20
- def request_helper(self):
21
- if not getattr(self, "_request_helper", None):
22
- self._request_helper = RequestHelper()
23
- return self._request_helper
36
+ class DirectorySyncModule(Protocol):
37
+ """Offers methods through the WorkOS Directory Sync service."""
24
38
 
25
39
  def list_users(
26
- self, directory=None, group=None, limit=RESPONSE_LIMIT, before=None, after=None
27
- ):
40
+ self,
41
+ *,
42
+ directory_id: Optional[str] = None,
43
+ group_id: Optional[str] = None,
44
+ limit: int = DEFAULT_LIST_RESPONSE_LIMIT,
45
+ before: Optional[str] = None,
46
+ after: Optional[str] = None,
47
+ order: PaginationOrder = "desc",
48
+ ) -> SyncOrAsync[DirectoryUsersListResource]:
28
49
  """Gets a list of provisioned Users for a Directory.
29
50
 
30
- Note, either 'directory' or 'group' must be provided.
51
+ Note, either 'directory_id' or 'group_id' must be provided.
31
52
 
32
- Args:
33
- directory (str): Directory unique identifier.
34
- group (str): Directory Group unique identifier.
35
- limit (int): Maximum number of records to return.
36
- before (str): Pagination cursor to receive records before a provided Directory ID.
37
- after (str): Pagination cursor to receive records after a provided Directory ID.
53
+ Kwargs:
54
+ directory_id (str): Directory unique identifier. (Optional)
55
+ group_id (str): Directory Group unique identifier. (Optional)
56
+ limit (int): Maximum number of records to return. (Optional)
57
+ before (str): Pagination cursor to receive records before a provided Directory ID. (Optional)
58
+ after (str): Pagination cursor to receive records after a provided Directory ID. (Optional)
59
+ order (Literal["asc","desc"]): Sort records in either ascending or descending (default) order by created_at timestamp. (Optional)
38
60
 
39
61
  Returns:
40
- dict: Directory Users response from WorkOS.
62
+ DirectoryUsersListResource: Directory Users response from WorkOS.
41
63
  """
42
- params = {"limit": limit, "before": before, "after": after}
43
- if group is not None:
44
- params["group"] = group
45
- if directory is not None:
46
- params["directory"] = directory
47
- return self.request_helper.request(
48
- "directory_users",
49
- method=REQUEST_METHOD_GET,
50
- params=params,
51
- token=workos.api_key,
52
- )
64
+ ...
53
65
 
54
66
  def list_groups(
55
- self, directory=None, user=None, limit=RESPONSE_LIMIT, before=None, after=None
56
- ):
67
+ self,
68
+ *,
69
+ directory_id: Optional[str] = None,
70
+ user_id: Optional[str] = None,
71
+ limit: int = DEFAULT_LIST_RESPONSE_LIMIT,
72
+ before: Optional[str] = None,
73
+ after: Optional[str] = None,
74
+ order: PaginationOrder = "desc",
75
+ ) -> SyncOrAsync[DirectoryGroupsListResource]:
57
76
  """Gets a list of provisioned Groups for a Directory .
58
77
 
59
- Note, either 'directory' or 'user' must be provided.
78
+ Note, either 'directory_id' or 'user_id' must be provided.
60
79
 
61
- Args:
62
- directory (str): Directory unique identifier.
63
- user (str): Directory User unique identifier.
64
- limit (int): Maximum number of records to return.
65
- before (str): Pagination cursor to receive records before a provided Directory ID.
66
- after (str): Pagination cursor to receive records after a provided Directory ID.
80
+ Kwargs:
81
+ directory_id (str): Directory unique identifier. (Optional)
82
+ user_id (str): Directory User unique identifier. (Optional)
83
+ limit (int): Maximum number of records to return. (Optional)
84
+ before (str): Pagination cursor to receive records before a provided Directory ID. (Optional)
85
+ after (str): Pagination cursor to receive records after a provided Directory ID. (Optional)
86
+ order (Literal["asc","desc"]): Sort records in either ascending or descending (default) order by created_at timestamp. (Optional)
67
87
 
68
88
  Returns:
69
- dict: Directory Groups response from WorkOS.
89
+ DirectoryGroupsListResource: Directory Groups response from WorkOS.
70
90
  """
71
- params = {"limit": limit, "before": before, "after": after}
72
- if user is not None:
73
- params["user"] = user
74
- if directory is not None:
75
- params["directory"] = directory
76
- return self.request_helper.request(
77
- "directory_groups",
78
- method=REQUEST_METHOD_GET,
79
- params=params,
80
- token=workos.api_key,
81
- )
91
+ ...
82
92
 
83
- def get_user(self, user):
93
+ def list_directories(
94
+ self,
95
+ *,
96
+ search: Optional[str] = None,
97
+ limit: int = DEFAULT_LIST_RESPONSE_LIMIT,
98
+ before: Optional[str] = None,
99
+ after: Optional[str] = None,
100
+ organization_id: Optional[str] = None,
101
+ order: PaginationOrder = "desc",
102
+ ) -> SyncOrAsync[DirectoriesListResource]:
103
+ """Gets details for existing Directories.
104
+
105
+ Kwargs:
106
+ organization_id: ID of an Organization (Optional)
107
+ search (str): Searchable text for a Directory. (Optional)
108
+ limit (int): Maximum number of records to return. (Optional)
109
+ before (str): Pagination cursor to receive records before a provided Directory ID. (Optional)
110
+ after (str): Pagination cursor to receive records after a provided Directory ID. (Optional)
111
+ order (Literal["asc","desc"]): Sort records in either ascending or descending (default) order by created_at timestamp. (Optional)
112
+
113
+ Returns:
114
+ DirectoriesListResource: Directories response from WorkOS.
115
+ """
116
+ ...
117
+
118
+ def get_user(self, user_id: str) -> SyncOrAsync[DirectoryUserWithGroups]:
84
119
  """Gets details for a single provisioned Directory User.
85
120
 
86
121
  Args:
87
- user (str): Directory User unique identifier.
122
+ user_id (str): Directory User unique identifier.
88
123
 
89
124
  Returns:
90
- dict: Directory User response from WorkOS.
125
+ DirectoryUserWithGroups: Directory User response from WorkOS.
91
126
  """
92
- return self.request_helper.request(
93
- "directory_users/{user}".format(user=user),
94
- method=REQUEST_METHOD_GET,
95
- token=workos.api_key,
96
- )
127
+ ...
97
128
 
98
- def get_group(self, group):
129
+ def get_group(self, group_id: str) -> SyncOrAsync[DirectoryGroup]:
99
130
  """Gets details for a single provisioned Directory Group.
100
131
 
101
132
  Args:
102
- group (str): Directory Group unique identifier.
133
+ group_id (str): Directory Group unique identifier.
103
134
 
104
135
  Returns:
105
- dict: Directory Group response from WorkOS.
136
+ DirectoryGroup: Directory Group response from WorkOS.
106
137
  """
107
- return self.request_helper.request(
108
- "directory_groups/{group}".format(group=group),
109
- method=REQUEST_METHOD_GET,
110
- token=workos.api_key,
111
- )
138
+ ...
112
139
 
113
- def list_directories(
114
- self, domain=None, search=None, limit=RESPONSE_LIMIT, before=None, after=None
115
- ):
116
- """Gets details for existing Directories.
140
+ def get_directory(self, directory_id: str) -> SyncOrAsync[Directory]:
141
+ """Gets details for a single Directory
117
142
 
118
143
  Args:
119
- domain (str): Domain of a Directory. (Optional)
120
- search (str): Searchable text for a Directory. (Optional)
121
- limit (int): Maximum number of records to return. (Optional)
122
- before (str): Pagination cursor to receive records before a provided Directory ID. (Optional)
123
- after (str): Pagination cursor to receive records after a provided Directory ID. (Optional)
144
+ directory_id (str): Directory unique identifier.
124
145
 
125
146
  Returns:
126
- dict: Directories response from WorkOS.
147
+ Directory: Directory response from WorkOS
127
148
  """
128
- params = {
129
- "domain": domain,
130
- "search": search,
149
+ ...
150
+
151
+ def delete_directory(self, directory_id: str) -> SyncOrAsync[None]:
152
+ """Delete one existing Directory.
153
+
154
+ Args:
155
+ directory_id (str): Directory unique identifier.
156
+
157
+ Returns:
158
+ None
159
+ """
160
+ ...
161
+
162
+
163
+ class DirectorySync(DirectorySyncModule):
164
+ _http_client: SyncHTTPClient
165
+
166
+ def __init__(self, http_client: SyncHTTPClient) -> None:
167
+ self._http_client = http_client
168
+
169
+ def list_users(
170
+ self,
171
+ *,
172
+ directory_id: Optional[str] = None,
173
+ group_id: Optional[str] = None,
174
+ limit: int = DEFAULT_LIST_RESPONSE_LIMIT,
175
+ before: Optional[str] = None,
176
+ after: Optional[str] = None,
177
+ order: PaginationOrder = "desc",
178
+ ) -> DirectoryUsersListResource:
179
+
180
+ list_params: DirectoryUserListFilters = {
181
+ "limit": limit,
182
+ "before": before,
183
+ "after": after,
184
+ "order": order,
185
+ }
186
+
187
+ if group_id is not None:
188
+ list_params["group"] = group_id
189
+ if directory_id is not None:
190
+ list_params["directory"] = directory_id
191
+
192
+ response = self._http_client.request(
193
+ "directory_users",
194
+ method=REQUEST_METHOD_GET,
195
+ params=list_params,
196
+ )
197
+
198
+ return WorkOSListResource(
199
+ list_method=self.list_users,
200
+ list_args=list_params,
201
+ **ListPage[DirectoryUserWithGroups](**response).model_dump(),
202
+ )
203
+
204
+ def list_groups(
205
+ self,
206
+ *,
207
+ directory_id: Optional[str] = None,
208
+ user_id: Optional[str] = None,
209
+ limit: int = DEFAULT_LIST_RESPONSE_LIMIT,
210
+ before: Optional[str] = None,
211
+ after: Optional[str] = None,
212
+ order: PaginationOrder = "desc",
213
+ ) -> DirectoryGroupsListResource:
214
+ list_params: DirectoryGroupListFilters = {
215
+ "limit": limit,
216
+ "before": before,
217
+ "after": after,
218
+ "order": order,
219
+ }
220
+
221
+ if user_id is not None:
222
+ list_params["user"] = user_id
223
+ if directory_id is not None:
224
+ list_params["directory"] = directory_id
225
+
226
+ response = self._http_client.request(
227
+ "directory_groups",
228
+ method=REQUEST_METHOD_GET,
229
+ params=list_params,
230
+ )
231
+
232
+ return WorkOSListResource[
233
+ DirectoryGroup, DirectoryGroupListFilters, ListMetadata
234
+ ](
235
+ list_method=self.list_groups,
236
+ list_args=list_params,
237
+ **ListPage[DirectoryGroup](**response).model_dump(),
238
+ )
239
+
240
+ def get_user(self, user_id: str) -> DirectoryUserWithGroups:
241
+ response = self._http_client.request(
242
+ "directory_users/{user}".format(user=user_id),
243
+ method=REQUEST_METHOD_GET,
244
+ )
245
+
246
+ return DirectoryUserWithGroups.model_validate(response)
247
+
248
+ def get_group(self, group_id: str) -> DirectoryGroup:
249
+ response = self._http_client.request(
250
+ "directory_groups/{group}".format(group=group_id),
251
+ method=REQUEST_METHOD_GET,
252
+ )
253
+ return DirectoryGroup.model_validate(response)
254
+
255
+ def get_directory(self, directory_id: str) -> Directory:
256
+ response = self._http_client.request(
257
+ "directories/{directory}".format(directory=directory_id),
258
+ method=REQUEST_METHOD_GET,
259
+ )
260
+
261
+ return Directory.model_validate(response)
262
+
263
+ def list_directories(
264
+ self,
265
+ *,
266
+ search: Optional[str] = None,
267
+ limit: int = DEFAULT_LIST_RESPONSE_LIMIT,
268
+ before: Optional[str] = None,
269
+ after: Optional[str] = None,
270
+ organization_id: Optional[str] = None,
271
+ order: PaginationOrder = "desc",
272
+ ) -> DirectoriesListResource:
273
+ list_params: DirectoryListFilters = {
131
274
  "limit": limit,
132
275
  "before": before,
133
276
  "after": after,
277
+ "order": order,
278
+ "organization_id": organization_id,
279
+ "search": search,
134
280
  }
135
- return self.request_helper.request(
281
+
282
+ response = self._http_client.request(
136
283
  "directories",
137
284
  method=REQUEST_METHOD_GET,
138
- params=params,
139
- token=workos.api_key,
285
+ params=list_params,
286
+ )
287
+ return WorkOSListResource[Directory, DirectoryListFilters, ListMetadata](
288
+ list_method=self.list_directories,
289
+ list_args=list_params,
290
+ **ListPage[Directory](**response).model_dump(),
140
291
  )
141
292
 
142
- def delete_directory(self, directory):
143
- """Delete one existing Directory.
293
+ def delete_directory(self, directory_id: str) -> None:
294
+ self._http_client.request(
295
+ "directories/{directory}".format(directory=directory_id),
296
+ method=REQUEST_METHOD_DELETE,
297
+ )
144
298
 
145
- Args:
146
- directory (str): The ID of the directory to be deleted. (Required)
147
299
 
148
- Returns:
149
- dict: Directories response from WorkOS.
150
- """
151
- return self.request_helper.request(
152
- "directories/{directory}".format(directory=directory),
300
+ class AsyncDirectorySync(DirectorySyncModule):
301
+ """Offers methods through the WorkOS Directory Sync service."""
302
+
303
+ _http_client: AsyncHTTPClient
304
+
305
+ def __init__(self, http_client: AsyncHTTPClient):
306
+ self._http_client = http_client
307
+
308
+ async def list_users(
309
+ self,
310
+ *,
311
+ directory_id: Optional[str] = None,
312
+ group_id: Optional[str] = None,
313
+ limit: int = DEFAULT_LIST_RESPONSE_LIMIT,
314
+ before: Optional[str] = None,
315
+ after: Optional[str] = None,
316
+ order: PaginationOrder = "desc",
317
+ ) -> DirectoryUsersListResource:
318
+
319
+ list_params: DirectoryUserListFilters = {
320
+ "limit": limit,
321
+ "before": before,
322
+ "after": after,
323
+ "order": order,
324
+ }
325
+
326
+ if group_id is not None:
327
+ list_params["group"] = group_id
328
+ if directory_id is not None:
329
+ list_params["directory"] = directory_id
330
+
331
+ response = await self._http_client.request(
332
+ "directory_users",
333
+ method=REQUEST_METHOD_GET,
334
+ params=list_params,
335
+ )
336
+
337
+ return WorkOSListResource(
338
+ list_method=self.list_users,
339
+ list_args=list_params,
340
+ **ListPage[DirectoryUserWithGroups](**response).model_dump(),
341
+ )
342
+
343
+ async def list_groups(
344
+ self,
345
+ *,
346
+ directory_id: Optional[str] = None,
347
+ user_id: Optional[str] = None,
348
+ limit: int = DEFAULT_LIST_RESPONSE_LIMIT,
349
+ before: Optional[str] = None,
350
+ after: Optional[str] = None,
351
+ order: PaginationOrder = "desc",
352
+ ) -> DirectoryGroupsListResource:
353
+ list_params: DirectoryGroupListFilters = {
354
+ "limit": limit,
355
+ "before": before,
356
+ "after": after,
357
+ "order": order,
358
+ }
359
+ if user_id is not None:
360
+ list_params["user"] = user_id
361
+ if directory_id is not None:
362
+ list_params["directory"] = directory_id
363
+
364
+ response = await self._http_client.request(
365
+ "directory_groups",
366
+ method=REQUEST_METHOD_GET,
367
+ params=list_params,
368
+ )
369
+
370
+ return WorkOSListResource[
371
+ DirectoryGroup, DirectoryGroupListFilters, ListMetadata
372
+ ](
373
+ list_method=self.list_groups,
374
+ list_args=list_params,
375
+ **ListPage[DirectoryGroup](**response).model_dump(),
376
+ )
377
+
378
+ async def get_user(self, user_id: str) -> DirectoryUserWithGroups:
379
+ response = await self._http_client.request(
380
+ "directory_users/{user}".format(user=user_id),
381
+ method=REQUEST_METHOD_GET,
382
+ )
383
+
384
+ return DirectoryUserWithGroups.model_validate(response)
385
+
386
+ async def get_group(self, group_id: str) -> DirectoryGroup:
387
+ response = await self._http_client.request(
388
+ "directory_groups/{group}".format(group=group_id),
389
+ method=REQUEST_METHOD_GET,
390
+ )
391
+ return DirectoryGroup.model_validate(response)
392
+
393
+ async def get_directory(self, directory_id: str) -> Directory:
394
+ response = await self._http_client.request(
395
+ "directories/{directory}".format(directory=directory_id),
396
+ method=REQUEST_METHOD_GET,
397
+ )
398
+
399
+ return Directory.model_validate(response)
400
+
401
+ async def list_directories(
402
+ self,
403
+ *,
404
+ search: Optional[str] = None,
405
+ limit: int = DEFAULT_LIST_RESPONSE_LIMIT,
406
+ before: Optional[str] = None,
407
+ after: Optional[str] = None,
408
+ organization_id: Optional[str] = None,
409
+ order: PaginationOrder = "desc",
410
+ ) -> DirectoriesListResource:
411
+ list_params: DirectoryListFilters = {
412
+ "organization_id": organization_id,
413
+ "search": search,
414
+ "limit": limit,
415
+ "before": before,
416
+ "after": after,
417
+ "order": order,
418
+ }
419
+
420
+ response = await self._http_client.request(
421
+ "directories",
422
+ method=REQUEST_METHOD_GET,
423
+ params=list_params,
424
+ )
425
+ return WorkOSListResource[Directory, DirectoryListFilters, ListMetadata](
426
+ list_method=self.list_directories,
427
+ list_args=list_params,
428
+ **ListPage[Directory](**response).model_dump(),
429
+ )
430
+
431
+ async def delete_directory(self, directory_id: str) -> None:
432
+ await self._http_client.request(
433
+ "directories/{directory}".format(directory=directory_id),
153
434
  method=REQUEST_METHOD_DELETE,
154
- token=workos.api_key,
155
435
  )
workos/events.py ADDED
@@ -0,0 +1,111 @@
1
+ from typing import Optional, Protocol, Sequence
2
+
3
+ from workos.types.events.list_filters import EventsListFilters
4
+ from workos.typing.sync_or_async import SyncOrAsync
5
+ from workos.utils.request_helper import DEFAULT_LIST_RESPONSE_LIMIT, REQUEST_METHOD_GET
6
+ from workos.types.events import Event, EventType
7
+ from workos.utils.http_client import AsyncHTTPClient, SyncHTTPClient
8
+ from workos.types.list_resource import ListAfterMetadata, ListPage, WorkOSListResource
9
+
10
+
11
+ EventsListResource = WorkOSListResource[Event, EventsListFilters, ListAfterMetadata]
12
+
13
+
14
+ class EventsModule(Protocol):
15
+ """Offers methods through the WorkOS Events service."""
16
+
17
+ def list_events(
18
+ self,
19
+ *,
20
+ events: Sequence[EventType],
21
+ limit: int = DEFAULT_LIST_RESPONSE_LIMIT,
22
+ organization_id: Optional[str] = None,
23
+ after: Optional[str] = None,
24
+ range_start: Optional[str] = None,
25
+ range_end: Optional[str] = None,
26
+ ) -> SyncOrAsync[EventsListResource]:
27
+ """Gets a list of Events.
28
+
29
+ Kwargs:
30
+ events (Sequence[EventType]): Filter to only return events of particular types.
31
+ limit (int): Maximum number of records to return. (Optional)
32
+ organization_id (str): Organization ID limits scope of events to a single organization. (Optional)
33
+ after (str): Pagination cursor to receive records after a provided Event ID. (Optional)
34
+ range_start (str): Date range start for stream of events. (Optional)
35
+ range_end (str): Date range end for stream of events. (Optional)
36
+
37
+ Returns:
38
+ EventsListResource: Events response from WorkOS.
39
+ """
40
+ ...
41
+
42
+
43
+ class Events(EventsModule):
44
+ _http_client: SyncHTTPClient
45
+
46
+ def __init__(self, http_client: SyncHTTPClient):
47
+ self._http_client = http_client
48
+
49
+ def list_events(
50
+ self,
51
+ *,
52
+ events: Sequence[EventType],
53
+ limit: int = DEFAULT_LIST_RESPONSE_LIMIT,
54
+ organization_id: Optional[str] = None,
55
+ after: Optional[str] = None,
56
+ range_start: Optional[str] = None,
57
+ range_end: Optional[str] = None,
58
+ ) -> EventsListResource:
59
+ params: EventsListFilters = {
60
+ "events": events,
61
+ "limit": limit,
62
+ "after": after,
63
+ "organization_id": organization_id,
64
+ "range_start": range_start,
65
+ "range_end": range_end,
66
+ }
67
+
68
+ response = self._http_client.request(
69
+ "events", method=REQUEST_METHOD_GET, params=params
70
+ )
71
+ return WorkOSListResource[Event, EventsListFilters, ListAfterMetadata](
72
+ list_method=self.list_events,
73
+ list_args=params,
74
+ **ListPage[Event](**response).model_dump(exclude_unset=True),
75
+ )
76
+
77
+
78
+ class AsyncEvents(EventsModule):
79
+ _http_client: AsyncHTTPClient
80
+
81
+ def __init__(self, http_client: AsyncHTTPClient):
82
+ self._http_client = http_client
83
+
84
+ async def list_events(
85
+ self,
86
+ *,
87
+ events: Sequence[EventType],
88
+ limit: int = DEFAULT_LIST_RESPONSE_LIMIT,
89
+ organization_id: Optional[str] = None,
90
+ after: Optional[str] = None,
91
+ range_start: Optional[str] = None,
92
+ range_end: Optional[str] = None,
93
+ ) -> EventsListResource:
94
+ params: EventsListFilters = {
95
+ "events": events,
96
+ "limit": limit,
97
+ "after": after,
98
+ "organization_id": organization_id,
99
+ "range_start": range_start,
100
+ "range_end": range_end,
101
+ }
102
+
103
+ response = await self._http_client.request(
104
+ "events", method=REQUEST_METHOD_GET, params=params
105
+ )
106
+
107
+ return WorkOSListResource[Event, EventsListFilters, ListAfterMetadata](
108
+ list_method=self.list_events,
109
+ list_args=params,
110
+ **ListPage[Event](**response).model_dump(exclude_unset=True),
111
+ )