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/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
+ )
workos/exceptions.py CHANGED
@@ -1,41 +1,42 @@
1
- class ConfigurationException(Exception):
2
- pass
1
+ from typing import Any, Mapping, Optional
2
+
3
+ import httpx
3
4
 
4
5
 
5
6
  # Request related exceptions
6
7
  class BaseRequestException(Exception):
7
- def __init__(self, response, message=None, error=None, error_description=None):
8
- super(BaseRequestException, self).__init__(message)
8
+ def __init__(
9
+ self,
10
+ response: httpx.Response,
11
+ response_json: Optional[Mapping[str, Any]],
12
+ ) -> None:
13
+ super(BaseRequestException, self).__init__(response_json)
9
14
 
10
- self.message = message
11
- self.error = error
12
- self.error_description = error_description
13
- self.extract_and_set_response_related_data(response)
14
-
15
- def extract_and_set_response_related_data(self, response):
16
15
  self.response = response
16
+ self.response_json = response_json
17
17
 
18
- try:
19
- response_json = response.json()
20
- self.message = response_json.get("message")
21
- except ValueError:
22
- self.message = None
18
+ self.message = self.extract_from_json("message", "No message")
19
+ self.error = self.extract_from_json("error", "Unknown")
20
+ self.errors = self.extract_from_json("errors", None)
21
+ self.code = self.extract_from_json("code", None)
22
+ self.error_description = self.extract_from_json("error_description", "Unknown")
23
23
 
24
- headers = response.headers
25
- self.request_id = headers.get("X-Request-ID")
24
+ self.request_id = response.headers.get("X-Request-ID")
26
25
 
27
- def __str__(self):
28
- message = self.message or "No message"
29
- exception = "(message=%s" % message
26
+ def extract_from_json(self, key: str, alt: Optional[str] = None) -> Optional[str]:
27
+ if self.response_json is None:
28
+ return alt
30
29
 
31
- if self.request_id is not None:
32
- exception += ", request_id=%s" % self.request_id
30
+ return self.response_json.get(key, alt)
33
31
 
34
- if self.error is not None:
35
- exception += ", error=%s" % self.error
32
+ def __str__(self) -> str:
33
+ exception = "(message=%s" % self.message
34
+ exception += ", request_id=%s" % self.request_id
36
35
 
37
- if self.error_description is not None:
38
- exception += ", error_description=%s" % self.error_description
36
+ if self.response_json is not None:
37
+ for key, value in self.response_json.items():
38
+ if key != "message":
39
+ exception += ", %s=%s" % (key, value)
39
40
 
40
41
  return exception + ")"
41
42
 
@@ -44,6 +45,24 @@ class AuthorizationException(BaseRequestException):
44
45
  pass
45
46
 
46
47
 
48
+ class EmailVerificationRequiredException(AuthorizationException):
49
+ """Raised when email verification is required before authentication.
50
+
51
+ This exception includes an email_verification_id field that can be used
52
+ to retrieve the email verification object or resend the verification email.
53
+ """
54
+
55
+ def __init__(
56
+ self,
57
+ response: httpx.Response,
58
+ response_json: Optional[Mapping[str, Any]],
59
+ ) -> None:
60
+ super().__init__(response, response_json)
61
+ self.email_verification_id = self.extract_from_json(
62
+ "email_verification_id", None
63
+ )
64
+
65
+
47
66
  class AuthenticationException(BaseRequestException):
48
67
  pass
49
68
 
@@ -52,5 +71,13 @@ class BadRequestException(BaseRequestException):
52
71
  pass
53
72
 
54
73
 
74
+ class ConflictException(BaseRequestException):
75
+ pass
76
+
77
+
78
+ class NotFoundException(BaseRequestException):
79
+ pass
80
+
81
+
55
82
  class ServerException(BaseRequestException):
56
83
  pass