GeezerVisonThe World Wide Web, restored to 800 pixels of glory. | ||||||||||||||||||||||||||||||||||||||
| Home|About|Gaming cabinet|Archives|How it works|Starter sites | ||||||||||||||||||||||||||||||||||||||
GeezerVison is showing github.com — Implement the remaining Audit Logs functionality by birdcar · Pull Request #515 · workos/workos-python Conversation
Contributor
DescriptionThis will update the Audit Logs module to complete the endpoints available in the API reference. Important review calloutThis change creates an Given these changes, and the fact that that warning will be removed, I opted to use the The benefit here is that now, a developer can use Alternates I consideredAs just mentioned, I originally avoided the issue by using a To my mind, this tradeoff is worth it and when they remove the warning in that internal class field at some point we can remove the warning and continue normally. Having said that, I made the change in a separate commit so it would be easily dropped if we decide DocumentationDoes this require changes to the WorkOS Docs? E.g. the API Reference or code snippets need updates. If yes, link a related docs PR and add a docs maintainer as a reviewer. Their approval is required.
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page. All reactions
|
There was an error while loading. Please reload this page.
Greptile SummaryThis PR completes the Audit Logs API implementation by adding support for schemas, actions, retention configuration, and audit log configuration endpoints. The implementation follows the SDK's established patterns with both sync and async variants for all new methods. Key Changes:
Implementation Quality:
Confidence Score: 5/5
Important Files Changed
Sequence DiagramsequenceDiagram
participant Client as Client (Sync/Async)
participant AuditLogs as AuditLogs Module
participant HTTPClient as HTTP Client
participant API as WorkOS API
Note over Client,API: Create Event Flow
Client->>AuditLogs: create_event(organization_id, event, idempotency_key)
AuditLogs->>HTTPClient: POST /audit_logs/events
HTTPClient->>API: HTTP Request with event data
API-->>HTTPClient: 200 OK
HTTPClient-->>AuditLogs: Response
AuditLogs-->>Client: None
Note over Client,API: Schema Management Flow
Client->>AuditLogs: create_schema(action, targets, actor, metadata)
AuditLogs->>HTTPClient: POST /audit_logs/actions/{action}/schemas
HTTPClient->>API: HTTP Request with schema definition
API-->>HTTPClient: 201 Created
HTTPClient-->>AuditLogs: AuditLogSchema JSON
AuditLogs->>AuditLogs: AuditLogSchema.model_validate()
AuditLogs-->>Client: AuditLogSchema object
Note over Client,API: List Actions Flow
Client->>AuditLogs: list_actions(limit, before, after, order)
AuditLogs->>HTTPClient: GET /audit_logs/actions with params
HTTPClient->>API: HTTP Request
API-->>HTTPClient: List response with actions
HTTPClient-->>AuditLogs: Response with data array
AuditLogs->>AuditLogs: WorkOSListResource creation
Note over AuditLogs: Includes AuditLogAction objects<br/>with nested AuditLogSchema
AuditLogs-->>Client: Paginated list resource
Note over Client,API: Retention Configuration Flow
Client->>AuditLogs: set_retention(organization_id, retention_period_in_days)
AuditLogs->>HTTPClient: PUT /organizations/{org_id}/audit_logs_retention
HTTPClient->>API: HTTP Request with retention period
API-->>HTTPClient: 200 OK with retention config
HTTPClient-->>AuditLogs: AuditLogRetention JSON
AuditLogs->>AuditLogs: AuditLogRetention.model_validate()
AuditLogs-->>Client: AuditLogRetention object
Note over Client,API: Configuration Retrieval Flow
Client->>AuditLogs: get_configuration(organization_id)
AuditLogs->>HTTPClient: GET /organizations/{org_id}/audit_log_configuration
HTTPClient->>API: HTTP Request
API-->>HTTPClient: 200 OK with full config
HTTPClient-->>AuditLogs: AuditLogConfiguration JSON
Note over AuditLogs: Includes optional log_stream<br/>with state and type info
AuditLogs->>AuditLogs: AuditLogConfiguration.model_validate()
AuditLogs-->>Client: AuditLogConfiguration object
|
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
tests/test_audit_logs.py, line 7 (link)
style: Check that AsyncAuditLogs is tested. Other test modules use @pytest.mark.sync_and_async(AuditLogs, AsyncAuditLogs) decorator to test both sync and async implementations. Without this marker, only sync tests run.
11 files reviewed, 1 comment
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
Gonna update with that feedback from greptile, una momento |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
11 files reviewed, no comments
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
Alright, this is ready to go whenever ✌️ Gonna move on to other improvements 🔜 |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
Starting in Python 3.14, use of `asyncio.iscoroutinefunction` emits a deprecation warning (c.f. python/cpython#122858). The recommendation is to use inspect.iscoroutinefunction instead.
95e10a3 to
733353f
Compare
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
asked some clarifying questions, neither approving nor rejecting!
Sorry, something went wrong.
There was an error while loading. Please reload this page.
| action: str, | ||
| targets: Sequence[Mapping[str, Any]], | ||
| actor: Optional[Mapping[str, Any]] = None, | ||
| metadata: Optional[Mapping[str, Any]] = None, |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
For targets, actor, and metadata, couldn't these use the schemas AuditLogSchemaTarget, AuditLogSchemaActor, and AuditLogSchemaMetadata, rather than the open-ended mapping of str: Any? (Note that these params are reused in other places in this PR, too, I just picked one example.)
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
So, my initial thinking when implementing this that these arguments were exactly as flexible as the types indicated (e.g. action is literally an arbitrary string, metadata is an arbitrary mapping). Leaving them this way enabled folks to write bog-standard/flexible Python code like:
workos.audit_logs.create_schema( action="document.updated", targets=[ { "type": "document", "metadata": {"title": "string"}, } ], actor={"metadata": {"role": "string"}}, metadata={"invoice_id": "string"}, )
This did lack type safety, but it felt like a type alias was un-necessary redirection (and created the false impression of type safety), and using the direct model (e.g. AuditLogSchemaTarget) would mean folks need to both import those models and then construct the call like so:
from workos.types.audit_logs import ( AuditLogSchemaTarget, AuditLogSchemaActor, AuditLogSchemaMetadata, AuditLogSchemaMetadataProperty, ) workos.audit_logs.create_schema( action="document.updated", targets=[ AuditLogSchemaTarget( type="document", metadata=AuditLogSchemaMetadata( type="object", properties={ "title": AuditLogSchemaMetadataProperty(type="string") }, ), ) ], actor=AuditLogSchemaActor( metadata=AuditLogSchemaMetadata( type="object", properties={ "role": AuditLogSchemaMetadataProperty(type="string") }, ) ), )
I think you'll agree, this feels bad, especially compared with the Node/Typescript implementation.
Having said that, your comment (and the subsequent digging it triggered) reminded me that I can actually provide just a little extra help via a TypedDict, which led me to create types like:
class AuditLogSchemaTargetInput(TypedDict): type: str metadata: NotRequired[MetadataSchemaInput] class AuditLogSchemaActorInput(TypedDict): metadata: MetadataSchemaInput
Which means that now folks get value suggestions in their IDE and also validation that they're constructing the mappings correctly, while still passing normal mappings in:
workos.audit_logs.create_schema( action="document.updated", targets=[ { "type": "document", "metadata": {"title": "string"}, } ], actor={"metadata": {"role": "string"}}, metadata={"invoice_id": "string"}, )
I think this ultimately provides the balance of ergonomics and safety we want.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
sick 🤙
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
(Note that these params are reused in other places in this PR, too, I just picked one example.)
Almost forgot to comment on this as well. The other functions I examined didn't, in practice, benefit from the kind of type safety the create_schema endpoint specifically did. But I'm happy to dig deeper there if you have feelings (or just think we should have type aliases in general).
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
| warnings.filterwarnings( | ||
| "ignore", | ||
| message='Field name "schema" in "AuditLogAction" shadows an attribute', | ||
| category=UserWarning, |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Given these changes, and the fact that that warning will be removed,
As of v2.12, this warning was removed! Do you think we can update our pydantic dependency (from 2.10.4, bleh) and remove this warning? Or does updating our dependency affect downstream users (necessitating a major version bump)?
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
does updating our dependency affect downstream users (necessitating a major version bump)?
Imo, bumping up the minimum Pydantic version wouldn't, on the face of it, require a major SDK version bump, but given the popularity of Pydantic, it's possible that it could break downstream users who are pinned to a lower version.
My 2¢ is that we should leave it for now and then revisit a version bump later when we're dropping support for EOL Python versions.
That said, I'm happy to make that change in a separate PR if you feel strongly about it.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Yeah, let's roll it into the next major bump.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
Introduces TypedDict definitions for the simplified schema input format:
- AuditLogSchemaTargetInput for target definitions
- AuditLogSchemaActorInput for actor definitions
- MetadataSchemaInput for metadata field type mappings
Also adds serialize_schema_options() to transform the simplified format
(e.g., {"status": "string"}) to the full JSON Schema format expected
by the API.
Replaces generic Mapping[str, Any] parameters with the new typed inputs. Uses shared serialize_schema_options() function instead of inline JSON building, reducing duplication between sync and async implementations.
The API can return null for actor in AuditLogSchema (when no custom metadata defined) and for retention_period_in_days in AuditLogRetention (when not configured). Updated models to accept None.
Updates create_schema tests to use the new simplified input format and verifies the serialization to full JSON Schema format. Adds edge case tests for nullable fields (actor in schema, retention_period_in_days).
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
Successfully merging this pull request may close these issues.
There was an error while loading. Please reload this page.