workos 1.13.0__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 (152) 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 +105 -20
  9. workos/directory_sync.py +369 -146
  10. workos/events.py +111 -0
  11. workos/exceptions.py +53 -26
  12. workos/fga.py +649 -0
  13. workos/mfa.py +152 -116
  14. workos/organization_domains.py +179 -0
  15. workos/organizations.py +401 -86
  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 +305 -149
  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.13.0.dist-info → workos-5.38.0.dist-info}/LICENSE +1 -1
  136. {workos-1.13.0.dist-info → workos-5.38.0.dist-info}/METADATA +47 -22
  137. workos-5.38.0.dist-info/RECORD +141 -0
  138. {workos-1.13.0.dist-info → workos-5.38.0.dist-info}/WHEEL +1 -1
  139. workos/audit_trail.py +0 -179
  140. workos/resources/base.py +0 -36
  141. workos/resources/directory_sync.py +0 -28
  142. workos/resources/event.py +0 -42
  143. workos/resources/event_action.py +0 -11
  144. workos/resources/mfa.py +0 -32
  145. workos/resources/sso.py +0 -53
  146. workos/utils/connection_types.py +0 -35
  147. workos/utils/pagiantion_order.py +0 -6
  148. workos/utils/request.py +0 -100
  149. workos/utils/validation.py +0 -60
  150. workos-1.13.0.dist-info/RECORD +0 -29
  151. /workos/{resources/__init__.py → py.typed} +0 -0
  152. {workos-1.13.0.dist-info → workos-5.38.0.dist-info}/top_level.txt +0 -0
workos/sso.py CHANGED
@@ -1,21 +1,27 @@
1
- import json
2
-
3
- from requests import Request
4
- from warnings import warn
5
-
6
- import workos
7
- from workos.utils.pagiantion_order import Order
8
- from workos.exceptions import ConfigurationException
9
- from workos.resources.sso import WorkOSProfile, WorkOSProfileAndToken
10
- from workos.utils.connection_types import ConnectionType
11
- from workos.utils.request import (
12
- RequestHelper,
1
+ from typing import Optional, Protocol
2
+ from workos._client_configuration import ClientConfiguration
3
+ from workos.types.sso.connection import ConnectionType
4
+ from workos.types.sso.sso_provider_type import SsoProviderType
5
+ from workos.typing.sync_or_async import SyncOrAsync
6
+ from workos.utils.http_client import AsyncHTTPClient, SyncHTTPClient
7
+ from workos.utils.pagination_order import PaginationOrder
8
+ from workos.types.sso import ConnectionWithDomains, Profile, ProfileAndToken
9
+ from workos.utils.request_helper import (
10
+ DEFAULT_LIST_RESPONSE_LIMIT,
13
11
  RESPONSE_TYPE_CODE,
14
12
  REQUEST_METHOD_DELETE,
15
13
  REQUEST_METHOD_GET,
16
14
  REQUEST_METHOD_POST,
15
+ QueryParameters,
16
+ RequestHelper,
17
+ REQUEST_METHOD_PUT,
18
+ )
19
+ from workos.types.list_resource import (
20
+ ListArgs,
21
+ ListMetadata,
22
+ ListPage,
23
+ WorkOSListResource,
17
24
  )
18
- from workos.utils.validation import SSO_MODULE, validate_settings
19
25
 
20
26
  AUTHORIZATION_PATH = "sso/authorize"
21
27
  TOKEN_PATH = "sso/token"
@@ -23,201 +29,229 @@ PROFILE_PATH = "sso/profile"
23
29
 
24
30
  OAUTH_GRANT_TYPE = "authorization_code"
25
31
 
26
- RESPONSE_LIMIT = 10
27
32
 
33
+ class ConnectionsListFilters(ListArgs, total=False):
34
+ connection_type: Optional[ConnectionType]
35
+ domain: Optional[str]
36
+ organization_id: Optional[str]
28
37
 
29
- class SSO(object):
30
- """Offers methods to assist in authenticating through the WorkOS SSO service."""
31
38
 
32
- @validate_settings(SSO_MODULE)
33
- def __init__(self):
34
- pass
39
+ ConnectionsListResource = WorkOSListResource[
40
+ ConnectionWithDomains, ConnectionsListFilters, ListMetadata
41
+ ]
35
42
 
36
- @property
37
- def request_helper(self):
38
- if not getattr(self, "_request_helper", None):
39
- self._request_helper = RequestHelper()
40
- return self._request_helper
43
+
44
+ class SSOModule(Protocol):
45
+ """Offers methods to assist in authenticating through the WorkOS SSO service."""
46
+
47
+ _client_configuration: ClientConfiguration
41
48
 
42
49
  def get_authorization_url(
43
50
  self,
44
- domain=None,
45
- domain_hint=None,
46
- login_hint=None,
47
- redirect_uri=None,
48
- state=None,
49
- provider=None,
50
- connection=None,
51
- organization=None,
52
- ):
51
+ *,
52
+ redirect_uri: str,
53
+ domain_hint: Optional[str] = None,
54
+ login_hint: Optional[str] = None,
55
+ state: Optional[str] = None,
56
+ provider: Optional[SsoProviderType] = None,
57
+ connection_id: Optional[str] = None,
58
+ organization_id: Optional[str] = None,
59
+ ) -> str:
53
60
  """Generate an OAuth 2.0 authorization URL.
54
61
 
55
62
  The URL generated will redirect a User to the Identity Provider configured through
56
63
  WorkOS.
57
64
 
65
+ This method is purposefully designed as synchronous as it does not make any HTTP requests.
66
+
58
67
  Kwargs:
59
- domain (str) - The domain a user is associated with, as configured on WorkOS
60
- redirect_uri (str) - A valid redirect URI, as specified on WorkOS
61
- state (str) - An encoded string passed to WorkOS that'd be preserved through the authentication workflow, passed
68
+ redirect_uri (str) : A valid redirect URI, as specified on WorkOS
69
+ state (str) : An encoded string passed to WorkOS that'd be preserved through the authentication workflow, passed
62
70
  back as a query parameter
63
- provider (ConnectionType) - Authentication service provider descriptor
64
- connection (string) - Unique identifier for a WorkOS Connection
65
- organization (string) - Unique identifier for a WorkOS Organization
71
+ provider (SSOProviderType) : Authentication service provider descriptor
72
+ connection_id (string) : Unique identifier for a WorkOS Connection
73
+ organization_id (string) : Unique identifier for a WorkOS Organization
66
74
 
67
75
  Returns:
68
76
  str: URL to redirect a User to to begin the OAuth workflow with WorkOS
69
77
  """
70
- params = {
71
- "client_id": workos.client_id,
78
+ params: QueryParameters = {
79
+ "client_id": self._client_configuration.client_id,
72
80
  "redirect_uri": redirect_uri,
73
81
  "response_type": RESPONSE_TYPE_CODE,
74
82
  }
75
83
 
76
- if (
77
- domain is None
78
- and provider is None
79
- and connection is None
80
- and organization is None
81
- ):
84
+ if connection_id is None and organization_id is None and provider is None:
82
85
  raise ValueError(
83
- "Incomplete arguments. Need to specify either a 'connection', 'organization', 'domain', or 'provider'"
86
+ "Incomplete arguments. Need to specify either a 'connection', 'organization', or 'provider'"
84
87
  )
85
88
  if provider is not None:
86
- if not isinstance(provider, ConnectionType):
87
- raise ValueError("'provider' must be of type ConnectionType")
88
- params["provider"] = str(provider.value)
89
- if domain is not None:
90
- warn(
91
- "The 'domain' parameter for 'get_authorization_url' is deprecated. Please use 'organization' instead.",
92
- DeprecationWarning,
93
- )
94
- params["domain"] = domain
89
+ params["provider"] = provider
95
90
  if domain_hint is not None:
96
91
  params["domain_hint"] = domain_hint
97
92
  if login_hint is not None:
98
93
  params["login_hint"] = login_hint
99
- if connection is not None:
100
- params["connection"] = connection
101
- if organization is not None:
102
- params["organization"] = organization
94
+ if connection_id is not None:
95
+ params["connection"] = connection_id
96
+ if organization_id is not None:
97
+ params["organization"] = organization_id
103
98
 
104
99
  if state is not None:
105
100
  params["state"] = state
106
101
 
107
- if redirect_uri is None:
108
- raise ValueError("Incomplete arguments. Need to specify a 'redirect_uri'.")
109
-
110
- prepared_request = Request(
111
- "GET",
112
- self.request_helper.generate_api_url(AUTHORIZATION_PATH),
113
- params=params,
114
- ).prepare()
115
-
116
- return prepared_request.url
102
+ return RequestHelper.build_url_with_query_params(
103
+ base_url=self._client_configuration.base_url,
104
+ path=AUTHORIZATION_PATH,
105
+ **params,
106
+ )
117
107
 
118
- def get_profile(self, accessToken):
108
+ def get_profile(self, access_token: str) -> SyncOrAsync[Profile]:
119
109
  """
120
110
  Verify that SSO has been completed successfully and retrieve the identity of the user.
121
111
 
122
112
  Args:
123
- accessToken (str): the token used to authenticate the API call
113
+ access_token (str): The token used to authenticate the API call
124
114
 
125
115
  Returns:
126
- WorkOSProfile
116
+ Profile
127
117
  """
118
+ ...
128
119
 
129
- token = accessToken
130
-
131
- response = self.request_helper.request(
132
- PROFILE_PATH, method=REQUEST_METHOD_GET, token=token
133
- )
134
-
135
- return WorkOSProfile.construct_from_response(response)
136
-
137
- def get_profile_and_token(self, code):
120
+ def get_profile_and_token(self, code: str) -> SyncOrAsync[ProfileAndToken]:
138
121
  """Get the profile of an authenticated User
139
122
 
140
123
  Once authenticated, using the code returned having followed the authorization URL,
141
124
  get the WorkOS profile of the User.
142
125
 
143
126
  Args:
144
- code (str): Code returned by WorkOS on completion of OAuth 2.0 workflow
127
+ code (str): Code returned by WorkOS on completion of OAuth 2.0 workflow.
145
128
 
146
129
  Returns:
147
- WorkOSProfileAndToken: WorkOSProfileAndToken object representing the User
130
+ ProfileAndToken: WorkOSProfileAndToken object representing the User.
148
131
  """
149
- params = {
150
- "client_id": workos.client_id,
151
- "client_secret": workos.api_key,
152
- "code": code,
153
- "grant_type": OAUTH_GRANT_TYPE,
154
- }
132
+ ...
155
133
 
156
- response = self.request_helper.request(
157
- TOKEN_PATH, method=REQUEST_METHOD_POST, params=params
158
- )
159
-
160
- return WorkOSProfileAndToken.construct_from_response(response)
161
-
162
- def get_connection(self, connection):
134
+ def get_connection(self, connection_id: str) -> SyncOrAsync[ConnectionWithDomains]:
163
135
  """Gets details for a single Connection
164
136
 
165
137
  Args:
166
138
  connection (str): Connection unique identifier
167
139
 
168
140
  Returns:
169
- dict: Connection response from WorkOS.
141
+ ConnectionWithDomains: Connection response from WorkOS.
170
142
  """
171
- return self.request_helper.request(
172
- "connections/{connection}".format(connection=connection),
173
- method=REQUEST_METHOD_GET,
174
- token=workos.api_key,
175
- )
143
+ ...
176
144
 
177
145
  def list_connections(
178
146
  self,
179
- connection_type=None,
180
- domain=None,
181
- organization_id=None,
182
- limit=RESPONSE_LIMIT,
183
- before=None,
184
- after=None,
185
- order=None,
186
- ):
147
+ *,
148
+ connection_type: Optional[ConnectionType] = None,
149
+ domain: Optional[str] = None,
150
+ organization_id: Optional[str] = None,
151
+ limit: int = DEFAULT_LIST_RESPONSE_LIMIT,
152
+ before: Optional[str] = None,
153
+ after: Optional[str] = None,
154
+ order: PaginationOrder = "desc",
155
+ ) -> SyncOrAsync[ConnectionsListResource]:
187
156
  """Gets details for existing Connections.
188
157
 
189
- Args:
158
+ Kwargs:
190
159
  connection_type (ConnectionType): Authentication service provider descriptor. (Optional)
191
160
  domain (str): Domain of a Connection. (Optional)
192
161
  limit (int): Maximum number of records to return. (Optional)
193
162
  before (str): Pagination cursor to receive records before a provided Connection ID. (Optional)
194
163
  after (str): Pagination cursor to receive records after a provided Connection ID. (Optional)
195
- order (Order): Sort records in either ascending or descending order by created_at timestamp.
164
+ order (Literal["asc","desc"]): Sort records in either ascending or descending (default) order by created_at timestamp. (Optional)
165
+
166
+ Returns:
167
+ ConnectionsListResource: Connections response from WorkOS.
168
+ """
169
+ ...
196
170
 
171
+ def update_connection(
172
+ self,
173
+ *,
174
+ connection_id: str,
175
+ saml_options_signing_key: Optional[str] = None,
176
+ saml_options_signing_cert: Optional[str] = None,
177
+ ) -> SyncOrAsync[ConnectionWithDomains]:
178
+ """Updates a single connection
179
+
180
+ Args:
181
+ connection_id (str): Connection unique identifier
182
+ saml_options_signing_key (str): Signing key for the connection (Optional)
183
+ saml_options_signing_cert (str): Signing certificate for the connection (Optional)
197
184
  Returns:
198
- dict: Connections response from WorkOS.
185
+ None
199
186
  """
187
+ ...
188
+
189
+ def delete_connection(self, connection_id: str) -> SyncOrAsync[None]:
190
+ """Deletes a single Connection
191
+
192
+ Args:
193
+ connection_id (str): Connection unique identifier
194
+
195
+ Returns:
196
+ None
197
+ """
198
+ ...
199
+
200
+
201
+ class SSO(SSOModule):
202
+ _http_client: SyncHTTPClient
203
+
204
+ def __init__(
205
+ self, http_client: SyncHTTPClient, client_configuration: ClientConfiguration
206
+ ):
207
+ self._client_configuration = client_configuration
208
+ self._http_client = http_client
209
+
210
+ def get_profile(self, access_token: str) -> Profile:
211
+ response = self._http_client.request(
212
+ PROFILE_PATH,
213
+ method=REQUEST_METHOD_GET,
214
+ headers={**self._http_client.auth_header_from_token(access_token)},
215
+ exclude_default_auth_headers=True,
216
+ )
217
+
218
+ return Profile.model_validate(response)
219
+
220
+ def get_profile_and_token(self, code: str) -> ProfileAndToken:
221
+ json = {
222
+ "client_id": self._http_client.client_id,
223
+ "client_secret": self._http_client.api_key,
224
+ "code": code,
225
+ "grant_type": OAUTH_GRANT_TYPE,
226
+ }
227
+
228
+ response = self._http_client.request(
229
+ TOKEN_PATH, method=REQUEST_METHOD_POST, json=json
230
+ )
231
+
232
+ return ProfileAndToken.model_validate(response)
200
233
 
201
- # This method used to accept `connection_type` as a string, so we try
202
- # to convert strings to a `ConnectionType` to support existing callers.
203
- #
204
- # TODO: Remove support for string values of `ConnectionType` in the next
205
- # major version.
206
- if connection_type is not None and isinstance(connection_type, str):
207
- try:
208
- connection_type = ConnectionType[connection_type]
209
-
210
- warn(
211
- "Passing a string value as the 'connection_type' parameter for 'list_connections' is deprecated and will be removed in the next major version. Please pass a 'ConnectionType' instead.",
212
- DeprecationWarning,
213
- )
214
- except KeyError:
215
- raise ValueError("'connection_type' must be a member of ConnectionType")
216
-
217
- params = {
218
- "connection_type": (
219
- connection_type.value if connection_type is not None else None
220
- ),
234
+ def get_connection(self, connection_id: str) -> ConnectionWithDomains:
235
+ response = self._http_client.request(
236
+ f"connections/{connection_id}",
237
+ method=REQUEST_METHOD_GET,
238
+ )
239
+
240
+ return ConnectionWithDomains.model_validate(response)
241
+
242
+ def list_connections(
243
+ self,
244
+ *,
245
+ connection_type: Optional[ConnectionType] = None,
246
+ domain: Optional[str] = None,
247
+ organization_id: Optional[str] = None,
248
+ limit: int = DEFAULT_LIST_RESPONSE_LIMIT,
249
+ before: Optional[str] = None,
250
+ after: Optional[str] = None,
251
+ order: PaginationOrder = "desc",
252
+ ) -> ConnectionsListResource:
253
+ params: ConnectionsListFilters = {
254
+ "connection_type": connection_type,
221
255
  "domain": domain,
222
256
  "organization_id": organization_id,
223
257
  "limit": limit,
@@ -225,25 +259,147 @@ class SSO(object):
225
259
  "after": after,
226
260
  "order": order,
227
261
  }
228
- if order is not None:
229
- if not isinstance(order, Order):
230
- raise ValueError("'order' must be of asc or desc order")
231
- params["order"] = str(order.value)
232
- return self.request_helper.request(
262
+
263
+ response = self._http_client.request(
233
264
  "connections",
234
265
  method=REQUEST_METHOD_GET,
235
266
  params=params,
236
- token=workos.api_key,
237
267
  )
238
268
 
239
- def delete_connection(self, connection):
240
- """Deletes a single Connection
269
+ return WorkOSListResource[
270
+ ConnectionWithDomains, ConnectionsListFilters, ListMetadata
271
+ ](
272
+ list_method=self.list_connections,
273
+ list_args=params,
274
+ **ListPage[ConnectionWithDomains](**response).model_dump(),
275
+ )
241
276
 
242
- Args:
243
- connection (str): Connection unique identifier
244
- """
245
- return self.request_helper.request(
246
- "connections/{connection}".format(connection=connection),
277
+ def update_connection(
278
+ self,
279
+ *,
280
+ connection_id: str,
281
+ saml_options_signing_key: Optional[str] = None,
282
+ saml_options_signing_cert: Optional[str] = None,
283
+ ) -> ConnectionWithDomains:
284
+ json = {
285
+ "options": {
286
+ "signing_key": saml_options_signing_key,
287
+ "signing_cert": saml_options_signing_cert,
288
+ }
289
+ }
290
+
291
+ response = self._http_client.request(
292
+ f"connections/{connection_id}",
293
+ method=REQUEST_METHOD_PUT,
294
+ json=json,
295
+ )
296
+
297
+ return ConnectionWithDomains.model_validate(response)
298
+
299
+ def delete_connection(self, connection_id: str) -> None:
300
+ self._http_client.request(
301
+ f"connections/{connection_id}", method=REQUEST_METHOD_DELETE
302
+ )
303
+
304
+
305
+ class AsyncSSO(SSOModule):
306
+ _http_client: AsyncHTTPClient
307
+
308
+ def __init__(
309
+ self, http_client: AsyncHTTPClient, client_configuration: ClientConfiguration
310
+ ):
311
+ self._client_configuration = client_configuration
312
+ self._http_client = http_client
313
+
314
+ async def get_profile(self, access_token: str) -> Profile:
315
+ response = await self._http_client.request(
316
+ PROFILE_PATH,
317
+ method=REQUEST_METHOD_GET,
318
+ headers={**self._http_client.auth_header_from_token(access_token)},
319
+ exclude_default_auth_headers=True,
320
+ )
321
+
322
+ return Profile.model_validate(response)
323
+
324
+ async def get_profile_and_token(self, code: str) -> ProfileAndToken:
325
+ json = {
326
+ "client_id": self._http_client.client_id,
327
+ "client_secret": self._http_client.api_key,
328
+ "code": code,
329
+ "grant_type": OAUTH_GRANT_TYPE,
330
+ }
331
+
332
+ response = await self._http_client.request(
333
+ TOKEN_PATH, method=REQUEST_METHOD_POST, json=json
334
+ )
335
+
336
+ return ProfileAndToken.model_validate(response)
337
+
338
+ async def get_connection(self, connection_id: str) -> ConnectionWithDomains:
339
+ response = await self._http_client.request(
340
+ f"connections/{connection_id}",
341
+ method=REQUEST_METHOD_GET,
342
+ )
343
+
344
+ return ConnectionWithDomains.model_validate(response)
345
+
346
+ async def list_connections(
347
+ self,
348
+ *,
349
+ connection_type: Optional[ConnectionType] = None,
350
+ domain: Optional[str] = None,
351
+ organization_id: Optional[str] = None,
352
+ limit: int = DEFAULT_LIST_RESPONSE_LIMIT,
353
+ before: Optional[str] = None,
354
+ after: Optional[str] = None,
355
+ order: PaginationOrder = "desc",
356
+ ) -> ConnectionsListResource:
357
+ params: ConnectionsListFilters = {
358
+ "connection_type": connection_type,
359
+ "domain": domain,
360
+ "organization_id": organization_id,
361
+ "limit": limit,
362
+ "before": before,
363
+ "after": after,
364
+ "order": order,
365
+ }
366
+
367
+ response = await self._http_client.request(
368
+ "connections", method=REQUEST_METHOD_GET, params=params
369
+ )
370
+
371
+ return WorkOSListResource[
372
+ ConnectionWithDomains, ConnectionsListFilters, ListMetadata
373
+ ](
374
+ list_method=self.list_connections,
375
+ list_args=params,
376
+ **ListPage[ConnectionWithDomains](**response).model_dump(),
377
+ )
378
+
379
+ async def update_connection(
380
+ self,
381
+ *,
382
+ connection_id: str,
383
+ saml_options_signing_key: Optional[str] = None,
384
+ saml_options_signing_cert: Optional[str] = None,
385
+ ) -> ConnectionWithDomains:
386
+ json = {
387
+ "options": {
388
+ "signing_key": saml_options_signing_key,
389
+ "signing_cert": saml_options_signing_cert,
390
+ }
391
+ }
392
+
393
+ response = await self._http_client.request(
394
+ f"connections/{connection_id}",
395
+ method=REQUEST_METHOD_PUT,
396
+ json=json,
397
+ )
398
+
399
+ return ConnectionWithDomains.model_validate(response)
400
+
401
+ async def delete_connection(self, connection_id: str) -> None:
402
+ await self._http_client.request(
403
+ f"connections/{connection_id}",
247
404
  method=REQUEST_METHOD_DELETE,
248
- token=workos.api_key,
249
405
  )
@@ -0,0 +1,4 @@
1
+ from .audit_logs.audit_log_event import AuditLogEvent as AuditLogEvent
2
+ from .organizations.domain_data_input import DomainDataInput as DomainDataInput
3
+ from .fga.warrant import WarrantWrite as WarrantWrite
4
+ from .fga.check import WarrantCheckInput as WarrantCheckInput
@@ -0,0 +1 @@
1
+ from .api_keys import ApiKey as ApiKey # noqa: F401
@@ -0,0 +1,20 @@
1
+ from typing import Literal, Optional, Sequence
2
+
3
+ from workos.types.workos_model import WorkOSModel
4
+
5
+
6
+ class ApiKeyOwner(WorkOSModel):
7
+ type: str
8
+ id: str
9
+
10
+
11
+ class ApiKey(WorkOSModel):
12
+ object: Literal["api_key"]
13
+ id: str
14
+ owner: ApiKeyOwner
15
+ name: str
16
+ obfuscated_value: str
17
+ last_used_at: Optional[str] = None
18
+ permissions: Sequence[str]
19
+ created_at: str
20
+ updated_at: str
@@ -0,0 +1,6 @@
1
+ from .audit_log_event_actor import *
2
+ from .audit_log_event_context import *
3
+ from .audit_log_event_target import *
4
+ from .audit_log_event import *
5
+ from .audit_log_export import *
6
+ from .audit_log_metadata import *
@@ -0,0 +1,16 @@
1
+ from typing_extensions import NotRequired, Sequence, TypedDict
2
+
3
+ from workos.types.audit_logs.audit_log_event_actor import AuditLogEventActor
4
+ from workos.types.audit_logs.audit_log_event_context import AuditLogEventContext
5
+ from workos.types.audit_logs.audit_log_metadata import AuditLogMetadata
6
+ from workos.types.audit_logs.audit_log_event_target import AuditLogEventTarget
7
+
8
+
9
+ class AuditLogEvent(TypedDict):
10
+ action: str
11
+ version: NotRequired[int]
12
+ occurred_at: str # ISO-8601 datetime of when an event occurred
13
+ actor: AuditLogEventActor
14
+ targets: Sequence[AuditLogEventTarget]
15
+ context: AuditLogEventContext
16
+ metadata: NotRequired[AuditLogMetadata]
@@ -0,0 +1,12 @@
1
+ from typing_extensions import NotRequired, TypedDict
2
+
3
+ from workos.types.audit_logs.audit_log_metadata import AuditLogMetadata
4
+
5
+
6
+ class AuditLogEventActor(TypedDict):
7
+ """Describes the entity that generated the event."""
8
+
9
+ id: str
10
+ metadata: NotRequired[AuditLogMetadata]
11
+ name: NotRequired[str]
12
+ type: str
@@ -0,0 +1,8 @@
1
+ from typing_extensions import NotRequired, TypedDict
2
+
3
+
4
+ class AuditLogEventContext(TypedDict):
5
+ """Attributes of audit log event context."""
6
+
7
+ location: str
8
+ user_agent: NotRequired[str]
@@ -0,0 +1,12 @@
1
+ from typing_extensions import NotRequired, TypedDict
2
+
3
+ from workos.types.audit_logs.audit_log_metadata import AuditLogMetadata
4
+
5
+
6
+ class AuditLogEventTarget(TypedDict):
7
+ """Describes the entity that was targeted by the event."""
8
+
9
+ id: str
10
+ metadata: NotRequired[AuditLogMetadata]
11
+ name: NotRequired[str]
12
+ type: str
@@ -0,0 +1,18 @@
1
+ from typing import Literal, Optional
2
+
3
+ from workos.types.workos_model import WorkOSModel
4
+ from workos.typing.literals import LiteralOrUntyped
5
+
6
+
7
+ AuditLogExportState = Literal["error", "pending", "ready"]
8
+
9
+
10
+ class AuditLogExport(WorkOSModel):
11
+ """Representation of a WorkOS audit logs export."""
12
+
13
+ object: Literal["audit_log_export"]
14
+ id: str
15
+ created_at: str
16
+ updated_at: str
17
+ state: LiteralOrUntyped[AuditLogExportState]
18
+ url: Optional[str] = None
@@ -0,0 +1,4 @@
1
+ from typing import Any, Mapping
2
+
3
+
4
+ AuditLogMetadata = Mapping[str, Any]