workos 5.39.1__py3-none-any.whl → 5.40.1__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.
workos/async_client.py CHANGED
@@ -2,7 +2,7 @@ from typing import Optional
2
2
  from importlib.metadata import version
3
3
  from workos._base_client import BaseClient
4
4
  from workos.api_keys import AsyncApiKeys
5
- from workos.audit_logs import AuditLogsModule
5
+ from workos.audit_logs import AsyncAuditLogs
6
6
  from workos.directory_sync import AsyncDirectorySync
7
7
  from workos.events import AsyncEvents
8
8
  from workos.fga import FGAModule
@@ -64,10 +64,10 @@ class AsyncClient(BaseClient):
64
64
  return self._sso
65
65
 
66
66
  @property
67
- def audit_logs(self) -> AuditLogsModule:
68
- raise NotImplementedError(
69
- "Audit logs APIs are not yet supported in the async client."
70
- )
67
+ def audit_logs(self) -> AsyncAuditLogs:
68
+ if not getattr(self, "_audit_logs", None):
69
+ self._audit_logs = AsyncAuditLogs(self._http_client)
70
+ return self._audit_logs
71
71
 
72
72
  @property
73
73
  def directory_sync(self) -> AsyncDirectorySync:
workos/audit_logs.py CHANGED
@@ -1,12 +1,44 @@
1
- from typing import Optional, Protocol, Sequence
1
+ from typing import Dict, Literal, Optional, Protocol, Sequence
2
2
 
3
- from workos.types.audit_logs import AuditLogExport
3
+ from workos.types.audit_logs import (
4
+ AuditLogAction,
5
+ AuditLogConfiguration,
6
+ AuditLogExport,
7
+ AuditLogRetention,
8
+ AuditLogSchema,
9
+ AuditLogSchemaListFilters,
10
+ AuditLogActionListFilters,
11
+ )
12
+ from workos.types.audit_logs.audit_log_schema_input import (
13
+ AuditLogSchemaActorInput,
14
+ AuditLogSchemaTargetInput,
15
+ MetadataSchemaInput,
16
+ serialize_schema_options,
17
+ )
4
18
  from workos.types.audit_logs.audit_log_event import AuditLogEvent
5
- from workos.utils.http_client import SyncHTTPClient
6
- from workos.utils.request_helper import REQUEST_METHOD_GET, REQUEST_METHOD_POST
19
+ from workos.types.list_resource import ListMetadata, ListPage, WorkOSListResource
20
+ from workos.typing.sync_or_async import SyncOrAsync
21
+ from workos.utils.http_client import AsyncHTTPClient, SyncHTTPClient
22
+ from workos.utils.pagination_order import PaginationOrder
23
+ from workos.utils.request_helper import (
24
+ DEFAULT_LIST_RESPONSE_LIMIT,
25
+ REQUEST_METHOD_GET,
26
+ REQUEST_METHOD_POST,
27
+ REQUEST_METHOD_PUT,
28
+ )
7
29
 
8
30
  EVENTS_PATH = "audit_logs/events"
9
31
  EXPORTS_PATH = "audit_logs/exports"
32
+ ACTIONS_PATH = "audit_logs/actions"
33
+
34
+
35
+ AuditLogActionsListResource = WorkOSListResource[
36
+ AuditLogAction, AuditLogActionListFilters, ListMetadata
37
+ ]
38
+
39
+ AuditLogSchemasListResource = WorkOSListResource[
40
+ AuditLogSchema, AuditLogSchemaListFilters, ListMetadata
41
+ ]
10
42
 
11
43
 
12
44
  class AuditLogsModule(Protocol):
@@ -18,7 +50,7 @@ class AuditLogsModule(Protocol):
18
50
  organization_id: str,
19
51
  event: AuditLogEvent,
20
52
  idempotency_key: Optional[str] = None,
21
- ) -> None:
53
+ ) -> SyncOrAsync[None]:
22
54
  """Create an Audit Logs event.
23
55
 
24
56
  Kwargs:
@@ -40,7 +72,7 @@ class AuditLogsModule(Protocol):
40
72
  targets: Optional[Sequence[str]] = None,
41
73
  actor_names: Optional[Sequence[str]] = None,
42
74
  actor_ids: Optional[Sequence[str]] = None,
43
- ) -> AuditLogExport:
75
+ ) -> SyncOrAsync[AuditLogExport]:
44
76
  """Trigger the creation of an export of audit logs.
45
77
 
46
78
  Kwargs:
@@ -49,6 +81,7 @@ class AuditLogsModule(Protocol):
49
81
  range_end (str): End date of the date range filter.
50
82
  actions (list): Optional list of actions to filter. (Optional)
51
83
  actor_names (list): Optional list of actors to filter by name. (Optional)
84
+ actor_ids (list): Optional list of actors to filter by ID. (Optional)
52
85
  targets (list): Optional list of targets to filter. (Optional)
53
86
 
54
87
  Returns:
@@ -56,15 +89,129 @@ class AuditLogsModule(Protocol):
56
89
  """
57
90
  ...
58
91
 
59
- def get_export(self, audit_log_export_id: str) -> AuditLogExport:
60
- """Retrieve an created export.
92
+ def get_export(self, audit_log_export_id: str) -> SyncOrAsync[AuditLogExport]:
93
+ """Retrieve a created export.
94
+
61
95
  Args:
62
96
  audit_log_export_id (str): Audit log export unique identifier.
97
+
63
98
  Returns:
64
99
  AuditLogExport: Object that describes the audit log export
65
100
  """
66
101
  ...
67
102
 
103
+ def create_schema(
104
+ self,
105
+ *,
106
+ action: str,
107
+ targets: Sequence[AuditLogSchemaTargetInput],
108
+ actor: Optional[AuditLogSchemaActorInput] = None,
109
+ metadata: Optional[MetadataSchemaInput] = None,
110
+ idempotency_key: Optional[str] = None,
111
+ ) -> SyncOrAsync[AuditLogSchema]:
112
+ """Create an Audit Log schema for an action.
113
+
114
+ Kwargs:
115
+ action (str): The action name for the schema (e.g., 'user.signed_in').
116
+ targets (list): List of target definitions with type and optional metadata.
117
+ Each target has a 'type' and optional 'metadata' mapping property
118
+ names to types (e.g., {"status": "string"}).
119
+ actor (dict): Optional actor definition with metadata schema. (Optional)
120
+ The metadata maps property names to types (e.g., {"role": "string"}).
121
+ metadata (dict): Optional event-level metadata schema. (Optional)
122
+ Maps property names to types (e.g., {"invoice_id": "string"}).
123
+ idempotency_key (str): Idempotency key. (Optional)
124
+
125
+ Returns:
126
+ AuditLogSchema: The created audit log schema
127
+ """
128
+ ...
129
+
130
+ def list_schemas(
131
+ self,
132
+ *,
133
+ action: str,
134
+ limit: int = DEFAULT_LIST_RESPONSE_LIMIT,
135
+ before: Optional[str] = None,
136
+ after: Optional[str] = None,
137
+ order: PaginationOrder = "desc",
138
+ ) -> SyncOrAsync[AuditLogSchemasListResource]:
139
+ """List all schemas for an Audit Log action.
140
+
141
+ Kwargs:
142
+ action (str): The action name to list schemas for.
143
+ limit (int): Maximum number of records to return. (Optional)
144
+ before (str): Pagination cursor to receive records before a provided ID. (Optional)
145
+ after (str): Pagination cursor to receive records after a provided ID. (Optional)
146
+ order (Literal["asc","desc"]): Sort order by created_at timestamp. (Optional)
147
+
148
+ Returns:
149
+ AuditLogSchemasListResource: Paginated list of audit log schemas
150
+ """
151
+ ...
152
+
153
+ def list_actions(
154
+ self,
155
+ *,
156
+ limit: int = DEFAULT_LIST_RESPONSE_LIMIT,
157
+ before: Optional[str] = None,
158
+ after: Optional[str] = None,
159
+ order: PaginationOrder = "desc",
160
+ ) -> SyncOrAsync[AuditLogActionsListResource]:
161
+ """List all registered Audit Log actions.
162
+
163
+ Kwargs:
164
+ limit (int): Maximum number of records to return. (Optional)
165
+ before (str): Pagination cursor to receive records before a provided ID. (Optional)
166
+ after (str): Pagination cursor to receive records after a provided ID. (Optional)
167
+ order (Literal["asc","desc"]): Sort order by created_at timestamp. (Optional)
168
+
169
+ Returns:
170
+ AuditLogActionsListResource: Paginated list of audit log actions
171
+ """
172
+ ...
173
+
174
+ def get_retention(self, organization_id: str) -> SyncOrAsync[AuditLogRetention]:
175
+ """Get the event retention period for an organization.
176
+
177
+ Args:
178
+ organization_id (str): Organization's unique identifier.
179
+
180
+ Returns:
181
+ AuditLogRetention: The retention configuration
182
+ """
183
+ ...
184
+
185
+ def set_retention(
186
+ self,
187
+ *,
188
+ organization_id: str,
189
+ retention_period_in_days: Literal[30, 365],
190
+ ) -> SyncOrAsync[AuditLogRetention]:
191
+ """Set the event retention period for an organization.
192
+
193
+ Kwargs:
194
+ organization_id (str): Organization's unique identifier.
195
+ retention_period_in_days (int): The number of days to retain events (30 or 365).
196
+
197
+ Returns:
198
+ AuditLogRetention: The updated retention configuration
199
+ """
200
+ ...
201
+
202
+ def get_configuration(
203
+ self, organization_id: str
204
+ ) -> SyncOrAsync[AuditLogConfiguration]:
205
+ """Get the audit log configuration for an organization.
206
+
207
+ Args:
208
+ organization_id (str): Organization's unique identifier.
209
+
210
+ Returns:
211
+ AuditLogConfiguration: The complete audit log configuration
212
+ """
213
+ ...
214
+
68
215
 
69
216
  class AuditLogs(AuditLogsModule):
70
217
  _http_client: SyncHTTPClient
@@ -81,7 +228,7 @@ class AuditLogs(AuditLogsModule):
81
228
  ) -> None:
82
229
  json = {"organization_id": organization_id, "event": event}
83
230
 
84
- headers = {}
231
+ headers: Dict[str, str] = {}
85
232
  if idempotency_key:
86
233
  headers["idempotency-key"] = idempotency_key
87
234
 
@@ -118,8 +265,297 @@ class AuditLogs(AuditLogsModule):
118
265
 
119
266
  def get_export(self, audit_log_export_id: str) -> AuditLogExport:
120
267
  response = self._http_client.request(
121
- "{0}/{1}".format(EXPORTS_PATH, audit_log_export_id),
268
+ f"{EXPORTS_PATH}/{audit_log_export_id}",
269
+ method=REQUEST_METHOD_GET,
270
+ )
271
+
272
+ return AuditLogExport.model_validate(response)
273
+
274
+ def create_schema(
275
+ self,
276
+ *,
277
+ action: str,
278
+ targets: Sequence[AuditLogSchemaTargetInput],
279
+ actor: Optional[AuditLogSchemaActorInput] = None,
280
+ metadata: Optional[MetadataSchemaInput] = None,
281
+ idempotency_key: Optional[str] = None,
282
+ ) -> AuditLogSchema:
283
+ json = serialize_schema_options(targets, actor, metadata)
284
+
285
+ headers: Dict[str, str] = {}
286
+ if idempotency_key:
287
+ headers["idempotency-key"] = idempotency_key
288
+
289
+ response = self._http_client.request(
290
+ f"{ACTIONS_PATH}/{action}/schemas",
291
+ method=REQUEST_METHOD_POST,
292
+ json=json,
293
+ headers=headers,
294
+ )
295
+
296
+ return AuditLogSchema.model_validate(response)
297
+
298
+ def list_schemas(
299
+ self,
300
+ *,
301
+ action: str,
302
+ limit: int = DEFAULT_LIST_RESPONSE_LIMIT,
303
+ before: Optional[str] = None,
304
+ after: Optional[str] = None,
305
+ order: PaginationOrder = "desc",
306
+ ) -> AuditLogSchemasListResource:
307
+ list_params: AuditLogSchemaListFilters = {
308
+ "limit": limit,
309
+ "before": before,
310
+ "after": after,
311
+ "order": order,
312
+ }
313
+
314
+ response = self._http_client.request(
315
+ f"{ACTIONS_PATH}/{action}/schemas",
316
+ method=REQUEST_METHOD_GET,
317
+ params=list_params,
318
+ )
319
+
320
+ return WorkOSListResource[
321
+ AuditLogSchema, AuditLogSchemaListFilters, ListMetadata
322
+ ](
323
+ list_method=lambda **kwargs: self.list_schemas(action=action, **kwargs),
324
+ list_args=list_params,
325
+ **ListPage[AuditLogSchema](**response).model_dump(),
326
+ )
327
+
328
+ def list_actions(
329
+ self,
330
+ *,
331
+ limit: int = DEFAULT_LIST_RESPONSE_LIMIT,
332
+ before: Optional[str] = None,
333
+ after: Optional[str] = None,
334
+ order: PaginationOrder = "desc",
335
+ ) -> AuditLogActionsListResource:
336
+ list_params: AuditLogActionListFilters = {
337
+ "limit": limit,
338
+ "before": before,
339
+ "after": after,
340
+ "order": order,
341
+ }
342
+
343
+ response = self._http_client.request(
344
+ ACTIONS_PATH,
345
+ method=REQUEST_METHOD_GET,
346
+ params=list_params,
347
+ )
348
+
349
+ return WorkOSListResource[
350
+ AuditLogAction, AuditLogActionListFilters, ListMetadata
351
+ ](
352
+ list_method=self.list_actions,
353
+ list_args=list_params,
354
+ **ListPage[AuditLogAction](**response).model_dump(),
355
+ )
356
+
357
+ def get_retention(self, organization_id: str) -> AuditLogRetention:
358
+ response = self._http_client.request(
359
+ f"organizations/{organization_id}/audit_logs_retention",
360
+ method=REQUEST_METHOD_GET,
361
+ )
362
+
363
+ return AuditLogRetention.model_validate(response)
364
+
365
+ def set_retention(
366
+ self,
367
+ *,
368
+ organization_id: str,
369
+ retention_period_in_days: Literal[30, 365],
370
+ ) -> AuditLogRetention:
371
+ json = {"retention_period_in_days": retention_period_in_days}
372
+
373
+ response = self._http_client.request(
374
+ f"organizations/{organization_id}/audit_logs_retention",
375
+ method=REQUEST_METHOD_PUT,
376
+ json=json,
377
+ )
378
+
379
+ return AuditLogRetention.model_validate(response)
380
+
381
+ def get_configuration(self, organization_id: str) -> AuditLogConfiguration:
382
+ response = self._http_client.request(
383
+ f"organizations/{organization_id}/audit_log_configuration",
384
+ method=REQUEST_METHOD_GET,
385
+ )
386
+
387
+ return AuditLogConfiguration.model_validate(response)
388
+
389
+
390
+ class AsyncAuditLogs(AuditLogsModule):
391
+ _http_client: AsyncHTTPClient
392
+
393
+ def __init__(self, http_client: AsyncHTTPClient):
394
+ self._http_client = http_client
395
+
396
+ async def create_event(
397
+ self,
398
+ *,
399
+ organization_id: str,
400
+ event: AuditLogEvent,
401
+ idempotency_key: Optional[str] = None,
402
+ ) -> None:
403
+ json = {"organization_id": organization_id, "event": event}
404
+
405
+ headers: Dict[str, str] = {}
406
+ if idempotency_key:
407
+ headers["idempotency-key"] = idempotency_key
408
+
409
+ await self._http_client.request(
410
+ EVENTS_PATH, method=REQUEST_METHOD_POST, json=json, headers=headers
411
+ )
412
+
413
+ async def create_export(
414
+ self,
415
+ *,
416
+ organization_id: str,
417
+ range_start: str,
418
+ range_end: str,
419
+ actions: Optional[Sequence[str]] = None,
420
+ targets: Optional[Sequence[str]] = None,
421
+ actor_names: Optional[Sequence[str]] = None,
422
+ actor_ids: Optional[Sequence[str]] = None,
423
+ ) -> AuditLogExport:
424
+ json = {
425
+ "actions": actions,
426
+ "actor_ids": actor_ids,
427
+ "actor_names": actor_names,
428
+ "organization_id": organization_id,
429
+ "range_start": range_start,
430
+ "range_end": range_end,
431
+ "targets": targets,
432
+ }
433
+
434
+ response = await self._http_client.request(
435
+ EXPORTS_PATH, method=REQUEST_METHOD_POST, json=json
436
+ )
437
+
438
+ return AuditLogExport.model_validate(response)
439
+
440
+ async def get_export(self, audit_log_export_id: str) -> AuditLogExport:
441
+ response = await self._http_client.request(
442
+ f"{EXPORTS_PATH}/{audit_log_export_id}",
122
443
  method=REQUEST_METHOD_GET,
123
444
  )
124
445
 
125
446
  return AuditLogExport.model_validate(response)
447
+
448
+ async def create_schema(
449
+ self,
450
+ *,
451
+ action: str,
452
+ targets: Sequence[AuditLogSchemaTargetInput],
453
+ actor: Optional[AuditLogSchemaActorInput] = None,
454
+ metadata: Optional[MetadataSchemaInput] = None,
455
+ idempotency_key: Optional[str] = None,
456
+ ) -> AuditLogSchema:
457
+ json = serialize_schema_options(targets, actor, metadata)
458
+
459
+ headers: Dict[str, str] = {}
460
+ if idempotency_key:
461
+ headers["idempotency-key"] = idempotency_key
462
+
463
+ response = await self._http_client.request(
464
+ f"{ACTIONS_PATH}/{action}/schemas",
465
+ method=REQUEST_METHOD_POST,
466
+ json=json,
467
+ headers=headers,
468
+ )
469
+
470
+ return AuditLogSchema.model_validate(response)
471
+
472
+ async def list_schemas(
473
+ self,
474
+ *,
475
+ action: str,
476
+ limit: int = DEFAULT_LIST_RESPONSE_LIMIT,
477
+ before: Optional[str] = None,
478
+ after: Optional[str] = None,
479
+ order: PaginationOrder = "desc",
480
+ ) -> AuditLogSchemasListResource:
481
+ list_params: AuditLogSchemaListFilters = {
482
+ "limit": limit,
483
+ "before": before,
484
+ "after": after,
485
+ "order": order,
486
+ }
487
+
488
+ response = await self._http_client.request(
489
+ f"{ACTIONS_PATH}/{action}/schemas",
490
+ method=REQUEST_METHOD_GET,
491
+ params=list_params,
492
+ )
493
+
494
+ return WorkOSListResource[
495
+ AuditLogSchema, AuditLogSchemaListFilters, ListMetadata
496
+ ](
497
+ list_method=lambda **kwargs: self.list_schemas(action=action, **kwargs),
498
+ list_args=list_params,
499
+ **ListPage[AuditLogSchema](**response).model_dump(),
500
+ )
501
+
502
+ async def list_actions(
503
+ self,
504
+ *,
505
+ limit: int = DEFAULT_LIST_RESPONSE_LIMIT,
506
+ before: Optional[str] = None,
507
+ after: Optional[str] = None,
508
+ order: PaginationOrder = "desc",
509
+ ) -> AuditLogActionsListResource:
510
+ list_params: AuditLogActionListFilters = {
511
+ "limit": limit,
512
+ "before": before,
513
+ "after": after,
514
+ "order": order,
515
+ }
516
+
517
+ response = await self._http_client.request(
518
+ ACTIONS_PATH,
519
+ method=REQUEST_METHOD_GET,
520
+ params=list_params,
521
+ )
522
+
523
+ return WorkOSListResource[
524
+ AuditLogAction, AuditLogActionListFilters, ListMetadata
525
+ ](
526
+ list_method=self.list_actions,
527
+ list_args=list_params,
528
+ **ListPage[AuditLogAction](**response).model_dump(),
529
+ )
530
+
531
+ async def get_retention(self, organization_id: str) -> AuditLogRetention:
532
+ response = await self._http_client.request(
533
+ f"organizations/{organization_id}/audit_logs_retention",
534
+ method=REQUEST_METHOD_GET,
535
+ )
536
+
537
+ return AuditLogRetention.model_validate(response)
538
+
539
+ async def set_retention(
540
+ self,
541
+ *,
542
+ organization_id: str,
543
+ retention_period_in_days: Literal[30, 365],
544
+ ) -> AuditLogRetention:
545
+ json = {"retention_period_in_days": retention_period_in_days}
546
+
547
+ response = await self._http_client.request(
548
+ f"organizations/{organization_id}/audit_logs_retention",
549
+ method=REQUEST_METHOD_PUT,
550
+ json=json,
551
+ )
552
+
553
+ return AuditLogRetention.model_validate(response)
554
+
555
+ async def get_configuration(self, organization_id: str) -> AuditLogConfiguration:
556
+ response = await self._http_client.request(
557
+ f"organizations/{organization_id}/audit_log_configuration",
558
+ method=REQUEST_METHOD_GET,
559
+ )
560
+
561
+ return AuditLogConfiguration.model_validate(response)
@@ -1,6 +1,12 @@
1
+ from .audit_log_action import *
2
+ from .audit_log_configuration import *
1
3
  from .audit_log_event_actor import *
2
4
  from .audit_log_event_context import *
3
5
  from .audit_log_event_target import *
4
6
  from .audit_log_event import *
5
7
  from .audit_log_export import *
6
8
  from .audit_log_metadata import *
9
+ from .audit_log_retention import *
10
+ from .audit_log_schema import *
11
+ from .audit_log_schema_input import *
12
+ from .list_filters import *
@@ -0,0 +1,28 @@
1
+ import warnings
2
+ from typing import Literal
3
+
4
+ from workos.types.audit_logs.audit_log_schema import AuditLogSchema
5
+ from workos.types.workos_model import WorkOSModel
6
+
7
+ # Suppress Pydantic warning about 'schema' shadowing BaseModel.schema()
8
+ # (a deprecated method replaced by model_json_schema() in Pydantic v2)
9
+ warnings.filterwarnings(
10
+ "ignore",
11
+ message='Field name "schema" in "AuditLogAction" shadows an attribute',
12
+ category=UserWarning,
13
+ )
14
+
15
+
16
+ class AuditLogAction(WorkOSModel):
17
+ """Representation of a WorkOS audit log action.
18
+
19
+ An audit log action represents a configured action type that can be
20
+ used in audit log events. Each action has an associated schema that
21
+ defines the structure of events for that action.
22
+ """
23
+
24
+ object: Literal["audit_log_action"]
25
+ name: str
26
+ schema: AuditLogSchema # type: ignore[assignment]
27
+ created_at: str
28
+ updated_at: str
@@ -0,0 +1,41 @@
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
+ AuditLogStreamType = Literal[
8
+ "Datadog", "Splunk", "S3", "GoogleCloudStorage", "GenericHttps"
9
+ ]
10
+
11
+ AuditLogStreamState = Literal["active", "inactive", "error", "invalid"]
12
+
13
+ AuditLogTrailState = Literal["active", "inactive", "disabled"]
14
+
15
+
16
+ class AuditLogStream(WorkOSModel):
17
+ """Representation of a WorkOS audit log stream.
18
+
19
+ An audit log stream sends audit log events to an external destination
20
+ such as Datadog, Splunk, S3, Google Cloud Storage, or a custom HTTPS endpoint.
21
+ """
22
+
23
+ id: str
24
+ type: LiteralOrUntyped[AuditLogStreamType]
25
+ state: LiteralOrUntyped[AuditLogStreamState]
26
+ last_synced_at: Optional[str] = None
27
+ created_at: str
28
+
29
+
30
+ class AuditLogConfiguration(WorkOSModel):
31
+ """Representation of a WorkOS audit log configuration for an organization.
32
+
33
+ The audit log configuration provides a single view of an organization's
34
+ audit logging setup, including retention settings, state, and optional
35
+ log stream configuration.
36
+ """
37
+
38
+ organization_id: str
39
+ retention_period_in_days: int
40
+ state: LiteralOrUntyped[AuditLogTrailState]
41
+ log_stream: Optional[AuditLogStream] = None
@@ -0,0 +1,13 @@
1
+ from typing import Optional
2
+
3
+ from workos.types.workos_model import WorkOSModel
4
+
5
+
6
+ class AuditLogRetention(WorkOSModel):
7
+ """Representation of a WorkOS audit log retention configuration.
8
+
9
+ Specifies how long audit log events are retained for an organization.
10
+ Valid values are 30 and 365 days, or None if not configured.
11
+ """
12
+
13
+ retention_period_in_days: Optional[int] = None
@@ -0,0 +1,49 @@
1
+ from typing import Dict, Literal, Optional, Sequence
2
+
3
+ from workos.types.workos_model import WorkOSModel
4
+
5
+
6
+ class AuditLogSchemaMetadataProperty(WorkOSModel):
7
+ """A property definition within an audit log schema metadata object."""
8
+
9
+ type: Literal["string", "boolean", "number"]
10
+
11
+
12
+ class AuditLogSchemaMetadata(WorkOSModel):
13
+ """The metadata definition for an audit log schema.
14
+
15
+ Represents a JSON Schema object type with property definitions.
16
+ """
17
+
18
+ type: Literal["object"]
19
+ properties: Optional[Dict[str, AuditLogSchemaMetadataProperty]] = None
20
+
21
+
22
+ class AuditLogSchemaTarget(WorkOSModel):
23
+ """A target definition within an audit log schema."""
24
+
25
+ type: str
26
+ metadata: Optional[AuditLogSchemaMetadata] = None
27
+
28
+
29
+ class AuditLogSchemaActor(WorkOSModel):
30
+ """The actor definition within an audit log schema."""
31
+
32
+ metadata: AuditLogSchemaMetadata
33
+
34
+
35
+ class AuditLogSchema(WorkOSModel):
36
+ """Representation of a WorkOS audit log schema.
37
+
38
+ Audit log schemas define the structure and validation rules
39
+ for audit log events, including the allowed targets, actor metadata,
40
+ and event-level metadata.
41
+ """
42
+
43
+ object: Literal["audit_log_schema"] = "audit_log_schema"
44
+ version: int
45
+ targets: Sequence[AuditLogSchemaTarget]
46
+ actor: Optional[AuditLogSchemaActor] = None
47
+ metadata: Optional[AuditLogSchemaMetadata] = None
48
+ created_at: Optional[str] = None
49
+ updated_at: Optional[str] = None
@@ -0,0 +1,78 @@
1
+ from typing import Any, Dict, Literal, Mapping, Optional, Sequence
2
+
3
+ from typing_extensions import NotRequired, TypedDict
4
+
5
+ MetadataSchemaInput = Mapping[str, Literal["string", "number", "boolean"]]
6
+
7
+
8
+ class AuditLogSchemaTargetInput(TypedDict):
9
+ """Input type for target definitions when creating an audit log schema.
10
+
11
+ Attributes:
12
+ type: The target type identifier (e.g., "team", "user", "document").
13
+ metadata: Optional simplified metadata schema mapping property names to types.
14
+ """
15
+
16
+ type: str
17
+ metadata: NotRequired[MetadataSchemaInput]
18
+
19
+
20
+ class AuditLogSchemaActorInput(TypedDict):
21
+ """Input type for actor definition when creating an audit log schema.
22
+
23
+ Attributes:
24
+ metadata: Simplified metadata schema mapping property names to types.
25
+ """
26
+
27
+ metadata: MetadataSchemaInput
28
+
29
+
30
+ def _serialize_metadata(
31
+ metadata: Optional[MetadataSchemaInput],
32
+ ) -> Optional[Dict[str, Any]]:
33
+ """Transform simplified metadata to full JSON Schema format.
34
+
35
+ Transforms {"role": "string"} to:
36
+ {"type": "object", "properties": {"role": {"type": "string"}}}
37
+ """
38
+ if not metadata:
39
+ return None
40
+
41
+ properties: Dict[str, Dict[str, str]] = {}
42
+ for key, type_value in metadata.items():
43
+ properties[key] = {"type": type_value}
44
+
45
+ return {"type": "object", "properties": properties}
46
+
47
+
48
+ def serialize_schema_options(
49
+ targets: Sequence[AuditLogSchemaTargetInput],
50
+ actor: Optional[AuditLogSchemaActorInput] = None,
51
+ metadata: Optional[MetadataSchemaInput] = None,
52
+ ) -> Dict[str, Any]:
53
+ """Serialize schema options from simplified format to API format.
54
+
55
+ Transforms the simplified input format (matching JS SDK ergonomics)
56
+ to the full JSON Schema format expected by the API.
57
+ """
58
+ result: Dict[str, Any] = {
59
+ "targets": [
60
+ {
61
+ "type": target["type"],
62
+ **(
63
+ {"metadata": _serialize_metadata(target.get("metadata"))}
64
+ if target.get("metadata")
65
+ else {}
66
+ ),
67
+ }
68
+ for target in targets
69
+ ],
70
+ }
71
+
72
+ if actor is not None:
73
+ result["actor"] = {"metadata": _serialize_metadata(actor["metadata"])}
74
+
75
+ if metadata is not None:
76
+ result["metadata"] = _serialize_metadata(metadata)
77
+
78
+ return result
@@ -0,0 +1,13 @@
1
+ from workos.types.list_resource import ListArgs
2
+
3
+
4
+ class AuditLogActionListFilters(ListArgs, total=False):
5
+ """Filters for listing audit log actions."""
6
+
7
+ pass
8
+
9
+
10
+ class AuditLogSchemaListFilters(ListArgs, total=False):
11
+ """Filters for listing audit log schemas."""
12
+
13
+ pass
@@ -17,6 +17,7 @@ from typing import (
17
17
  cast,
18
18
  )
19
19
  from typing_extensions import Required, TypedDict
20
+ from workos.types.audit_logs import AuditLogAction, AuditLogSchema
20
21
  from workos.types.directory_sync import (
21
22
  Directory,
22
23
  DirectoryGroup,
@@ -42,6 +43,8 @@ from workos.utils.request_helper import DEFAULT_LIST_RESPONSE_LIMIT
42
43
  ListableResource = TypeVar(
43
44
  # add all possible generics of List Resource
44
45
  "ListableResource",
46
+ AuditLogAction,
47
+ AuditLogSchema,
45
48
  AuthenticationFactor,
46
49
  ConnectionWithDomains,
47
50
  Directory,
@@ -15,6 +15,7 @@ class InvitationCommon(WorkOSModel):
15
15
  expires_at: str
16
16
  organization_id: Optional[str] = None
17
17
  inviter_user_id: Optional[str] = None
18
+ accepted_user_id: Optional[str] = None
18
19
  created_at: str
19
20
  updated_at: str
20
21
 
@@ -1,4 +1,4 @@
1
- from typing import Literal, Sequence, Optional
1
+ from typing import Any, Literal, Mapping, Optional, Sequence
2
2
  from typing_extensions import TypedDict
3
3
 
4
4
  from workos.types.workos_model import WorkOSModel
@@ -21,5 +21,6 @@ class OrganizationMembership(WorkOSModel):
21
21
  role: OrganizationMembershipRole
22
22
  roles: Optional[Sequence[OrganizationMembershipRole]] = None
23
23
  status: LiteralOrUntyped[OrganizationMembershipStatus]
24
+ custom_attributes: Mapping[str, Any]
24
25
  created_at: str
25
26
  updated_at: str
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: workos
3
- Version: 5.39.1
3
+ Version: 5.40.1
4
4
  Summary: WorkOS Python Client
5
5
  Author: WorkOS
6
6
  Author-email: WorkOS <team@workos.com>
@@ -2,8 +2,8 @@ workos/__init__.py,sha256=hOdbO_MJCvpLx8EbRjQg-fvFAB-glJmrmxUZK8kWG0k,167
2
2
  workos/_base_client.py,sha256=UIdpMKXqShq2Pq4_LsrvvID0V5E4KGhlsySBygP9660,3920
3
3
  workos/_client_configuration.py,sha256=FFOVVU5Pd04tNbLGOY_4pnBdGsqA6ficypTcTU8Q3iE,275
4
4
  workos/api_keys.py,sha256=3AljcqAO1uJYP315AZymX184eJ9X_gH7xa_rKU6rMjw,1817
5
- workos/async_client.py,sha256=CHK_4rHxQ88D5_BJsj_5EeSWbcKj_FqGq-CsfIRTSBw,4879
6
- workos/audit_logs.py,sha256=bYoAoNO4FRSaT34UxiVkgTXCVH8givcS2YGhH_9O3NA,3983
5
+ workos/async_client.py,sha256=PZW4DI4LmYNJe0weNQjvOGHaHYdVu7QGaQSAH1i5hL8,4907
6
+ workos/audit_logs.py,sha256=svHTq838MiS_rTyrMNPTRUoUuu1iBnpxIH1Dr6rxbkQ,18225
7
7
  workos/client.py,sha256=WFDREJnzpxu6_Cz-Vd1GfCudQsk1KOeHLiuac_jWgKw,4836
8
8
  workos/directory_sync.py,sha256=mo3NZ8aPGghav2JB73HTtG1uejihfN-9dN41J3OjNFg,15345
9
9
  workos/events.py,sha256=b4JIzMbd5LlVtpOMKVojC70RCHAgmLN3nJ62_2U0GwI,3892
@@ -21,13 +21,19 @@ workos/sso.py,sha256=ZBC3y-IRmxG0jPd0BOj7s7XQkXJoTLUg1fx-h3Gfy4g,13541
21
21
  workos/types/__init__.py,sha256=aYScTXq5jOyp0AYvdWffaj5-zdDuNtCCJtbzt5GM19k,267
22
22
  workos/types/api_keys/__init__.py,sha256=CMjEAI6EAO2En9UUwvEQW6EAVuV6l5wWPvmuKH8oKhs,53
23
23
  workos/types/api_keys/api_keys.py,sha256=eVpXS6hhLCFhIqJ_oQNIbwjL9u0blVykjpQxZEEKDS8,403
24
- workos/types/audit_logs/__init__.py,sha256=daPn8wAVEnlM1fCpOsy3dVZV_0YEp8bA1T_nhk5-pU8,211
24
+ workos/types/audit_logs/__init__.py,sha256=4q8IxKQAD3khdUcjjNo8Eh_OeM49WokvkU0usbeQSmA,415
25
+ workos/types/audit_logs/audit_log_action.py,sha256=bHE7oIlLa9PLfb6MlMVb4IF12rA0LhlM8M-fzqna8GQ,894
26
+ workos/types/audit_logs/audit_log_configuration.py,sha256=Q28wK-HDm70sFH9zPl-8-uY_fODkPvzgFi1cdI6Cc20,1273
25
27
  workos/types/audit_logs/audit_log_event.py,sha256=GVvbu3JJpXW-N16zdWi-0c3W9z_t3JB7Y6-Rc463upw,672
26
28
  workos/types/audit_logs/audit_log_event_actor.py,sha256=vYojEwq4EPwAO01p_9FmVuKg6Cr7lycrWkldB_W26GA,320
27
29
  workos/types/audit_logs/audit_log_event_context.py,sha256=Cc4a5oVrPf9PhydJfMBy5EiSxJqqLdb9D1pYm8T4Pp4,195
28
30
  workos/types/audit_logs/audit_log_event_target.py,sha256=cCK13Ya1n-7QKQKiIW2SjkQLq9AM5JVoWp_Rpxuamfc,327
29
31
  workos/types/audit_logs/audit_log_export.py,sha256=brU6HoNsq-H8jVDd9zRzCDkBnAD95yrFyrekhp3vSlE,466
30
32
  workos/types/audit_logs/audit_log_metadata.py,sha256=GaJrSxYboUpdJPz2jJf2uc4za9zwUrgqwRnTCl1dbpw,71
33
+ workos/types/audit_logs/audit_log_retention.py,sha256=ifeAEFdRH0S3jEol3mo2oqa4GgLSAL0dUr4GjGHVTYI,388
34
+ workos/types/audit_logs/audit_log_schema.py,sha256=Y7JGC5f559k0JbYbTQNcy1F2OzZO-Ud0zvJ2cFB8_ds,1438
35
+ workos/types/audit_logs/audit_log_schema_input.py,sha256=GRYMHh77DljYZRFPXicwZpOMI4qwUyQN63_LfeHQowg,2339
36
+ workos/types/audit_logs/list_filters.py,sha256=7CZ298Rxr-LHOlLMJ2fUmfQge8wBagXEVX8oIi9NHRU,282
31
37
  workos/types/directory_sync/__init__.py,sha256=U26Aq1DCRicStFn7Y4OcPRVjy_03c0C0fAWNi_4_d4s,147
32
38
  workos/types/directory_sync/directory.py,sha256=M7IvlTeKrLj-BpGeX-nafBM6BWUnHb3-1ninObWyuRY,902
33
39
  workos/types/directory_sync/directory_group.py,sha256=4bRB3inN72GfsJEA17OpMEI-_6hhdXFVGpTL0PWaXL0,439
@@ -60,7 +66,7 @@ workos/types/fga/check.py,sha256=6AIHsc2WmsXbpEFZcSTy2hIoSr2rmoLt-8wLWdSrc_E,127
60
66
  workos/types/fga/list_filters.py,sha256=wLQt_AJprmvglZSWv7ZRjwjD4b2vHL0V_7c9u-5u_Uw,640
61
67
  workos/types/fga/warnings.py,sha256=hX2A-PvXpy9rH0E4_-8Hfrv_to0tgL6jqeGzhz-N2yA,910
62
68
  workos/types/fga/warrant.py,sha256=aKO-9t0NGk-9oQs8j_gnG3VfNU6U9IdGCH4EN3imRWs,1016
63
- workos/types/list_resource.py,sha256=VcJaz8qE91y9t-PRI0mTjzPdtyoU8EGAo6-TJGjbqzg,6747
69
+ workos/types/list_resource.py,sha256=mGp8Zs4CpaK0DlMYdI-5-nTbofxY-rPe5pSZP0kNR4U,6854
64
70
  workos/types/metadata.py,sha256=uUqDkGJGyFY3H4JZObSiCfn4jKBue5CBhOqv79TI1n0,52
65
71
  workos/types/mfa/__init__.py,sha256=-gHL2QwZYbqDGPrIMkUrciJm4EiSRz3fJVF55B3rKiM,253
66
72
  workos/types/mfa/authentication_challenge.py,sha256=V8UYutxCAxenaOeqWuPwQU0QcO4HD_0RoQbkG3sqgAU,436
@@ -96,11 +102,11 @@ workos/types/user_management/authenticate_with_common.py,sha256=2mGRfIgoeX5Ee7c_
96
102
  workos/types/user_management/authentication_response.py,sha256=2A6vU8FBEE7bXl5aULB-s80_xsR9caqC9tSr9Yq1NtE,1437
97
103
  workos/types/user_management/email_verification.py,sha256=4EqlN7qZBVTZGKaU9WdCSdgFjOMZtkYWTolE-h_hTXA,399
98
104
  workos/types/user_management/impersonator.py,sha256=_PAPYg_Q1M8wpwtnkQxuA2vtUIwvs_G30vYY91aqw8E,192
99
- workos/types/user_management/invitation.py,sha256=4fK-Fk786MlhzZvvOrZtU_6SCJXmem3xw62SkBE1c-0,721
105
+ workos/types/user_management/invitation.py,sha256=qdQausiwLGCCJBUT8jEYYXoWVDPueFY24_SP0S8BLjQ,764
100
106
  workos/types/user_management/list_filters.py,sha256=9QH4UbU28LaZ1iyiMs8H6heqbWpbCunD2MYmO_qA9pY,756
101
107
  workos/types/user_management/magic_auth.py,sha256=Sda13_uMOC-hHlyGeOXNnCn-HrpwUmtrf2hO5ek9U98,359
102
108
  workos/types/user_management/oauth_tokens.py,sha256=pANk6AyqyRq6hrOrJYQ9AHALVxUbqhGnggzD8PVV-Ew,468
103
- workos/types/user_management/organization_membership.py,sha256=dllONFtD1IZZiyqxnV8lJpJyH55OeOeaHRBDZlcWLwk,735
109
+ workos/types/user_management/organization_membership.py,sha256=bURjhJngjJilLHGhxRT53GFlhA8SJQ3WdJ-Rs33-B8U,790
104
110
  workos/types/user_management/password_hash_type.py,sha256=hT8UagiPJtYJn1pNouuCr8gzcksUDuTRZnyvzDh1vWw,128
105
111
  workos/types/user_management/password_reset.py,sha256=-NJCfEh4Q1xS9fFXJaF_acYeuUc9POqERLh8urMhqt8,403
106
112
  workos/types/user_management/screen_hint.py,sha256=DnPgvjRK-20i82v3YPzggna1rc6yOMyhiqwUdk01L3s,75
@@ -133,6 +139,6 @@ workos/utils/request_helper.py,sha256=9FgeDfz_hiHlbCkuo6bcBjSpdDM5ObRok9-G_jFedd
133
139
  workos/vault.py,sha256=fe2OkFLVV1U4x9E78baWGksPIxg32decAuawEaJ63w4,16417
134
140
  workos/webhooks.py,sha256=CuwBxh6va9VZFVSXOknveGt6CCGDF3em07a-J12DbXI,4790
135
141
  workos/widgets.py,sha256=YAjiffcewHXcPx2kjScGs2-xZpmYsed33UQ6xDTqjJM,1720
136
- workos-5.39.1.dist-info/WHEEL,sha256=eh7sammvW2TypMMMGKgsM83HyA_3qQ5Lgg3ynoecH3M,79
137
- workos-5.39.1.dist-info/METADATA,sha256=9QrcsQwmzvuLNItbr64khE15oFI_jPNwq2UaLfmLm3o,3348
138
- workos-5.39.1.dist-info/RECORD,,
142
+ workos-5.40.1.dist-info/WHEEL,sha256=eh7sammvW2TypMMMGKgsM83HyA_3qQ5Lgg3ynoecH3M,79
143
+ workos-5.40.1.dist-info/METADATA,sha256=1xvfkrr6x1yA4Q7_9eLhhSHSQyHJ3Um5lPmLFDGffdI,3348
144
+ workos-5.40.1.dist-info/RECORD,,