-
Notifications
You must be signed in to change notification settings - Fork 29
FGA_2: listResources(), get/update/delete resource_by_external_id #569
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
swaroopAkkineniWorkos
merged 5 commits into
ENT-5224-python-sdk-for-fga-worktree-fuck-around
from
fga-pr3
Feb 24, 2026
Merged
Changes from 1 commit
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
63f2f60
FGA_2: listResources(), get/update/delete resource_by_external_id
swaroopAkkineniWorkos a906ec2
moar
swaroopAkkineniWorkos 30bc17e
moar
swaroopAkkineniWorkos a70971b
merge conflcits
swaroopAkkineniWorkos fa295f5
moar
swaroopAkkineniWorkos File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -8,6 +8,7 @@ | |
| ) | ||
| from workos.types.authorization.organization_role import OrganizationRole | ||
| from workos.types.authorization.permission import Permission | ||
| from workos.types.authorization.resource import Resource | ||
| from workos.types.authorization.role import Role, RoleList | ||
| from workos.types.list_resource import ( | ||
| ListArgs, | ||
|
|
@@ -28,6 +29,15 @@ | |
| ) | ||
|
|
||
| AUTHORIZATION_PERMISSIONS_PATH = "authorization/permissions" | ||
| AUTHORIZATION_ORGANIZATIONS_PATH = "authorization/organizations" | ||
|
|
||
|
|
||
| class ResourceListFilters(ListArgs, total=False): | ||
| organization_id: str | ||
| resource_type_slug: Optional[str] | ||
|
|
||
|
|
||
| ResourcesListResource = WorkOSListResource[Resource, ResourceListFilters, ListMetadata] | ||
|
|
||
| _role_adapter: TypeAdapter[Role] = TypeAdapter(Role) | ||
|
|
||
|
|
@@ -161,6 +171,45 @@ def add_environment_role_permission( | |
| permission_slug: str, | ||
| ) -> SyncOrAsync[EnvironmentRole]: ... | ||
|
|
||
| # Resources (External ID) + List | ||
|
|
||
| def get_resource_by_external_id( | ||
| self, | ||
| organization_id: str, | ||
| resource_type: str, | ||
| external_id: str, | ||
| ) -> SyncOrAsync[Resource]: ... | ||
|
|
||
| def update_resource_by_external_id( | ||
| self, | ||
| organization_id: str, | ||
| resource_type: str, | ||
| external_id: str, | ||
| *, | ||
| name: Optional[str] = None, | ||
| description: Optional[str] = None, | ||
| ) -> SyncOrAsync[Resource]: ... | ||
|
|
||
| def delete_resource_by_external_id( | ||
| self, | ||
| organization_id: str, | ||
| resource_type: str, | ||
| external_id: str, | ||
| *, | ||
| cascade_delete: Optional[bool] = None, | ||
| ) -> SyncOrAsync[None]: ... | ||
|
|
||
| def list_resources( | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add in search |
||
| self, | ||
| organization_id: str, | ||
| *, | ||
| resource_type_slug: Optional[str] = None, | ||
| limit: int = DEFAULT_LIST_RESPONSE_LIMIT, | ||
| before: Optional[str] = None, | ||
| after: Optional[str] = None, | ||
| order: PaginationOrder = "desc", | ||
| ) -> SyncOrAsync[ResourcesListResource]: ... | ||
|
|
||
|
|
||
| class Authorization(AuthorizationModule): | ||
| _http_client: SyncHTTPClient | ||
|
|
@@ -437,6 +486,97 @@ def add_environment_role_permission( | |
|
|
||
| return EnvironmentRole.model_validate(response) | ||
|
|
||
| # Resources (External ID) + List | ||
|
|
||
| def get_resource_by_external_id( | ||
| self, | ||
| organization_id: str, | ||
| resource_type: str, | ||
| external_id: str, | ||
| ) -> Resource: | ||
| response = self._http_client.request( | ||
| f"{AUTHORIZATION_ORGANIZATIONS_PATH}/{organization_id}/resources/{resource_type}/{external_id}", | ||
| method=REQUEST_METHOD_GET, | ||
| ) | ||
|
|
||
| return Resource.model_validate(response) | ||
|
|
||
| def update_resource_by_external_id( | ||
| self, | ||
| organization_id: str, | ||
| resource_type: str, | ||
| external_id: str, | ||
| *, | ||
| name: Optional[str] = None, | ||
| description: Optional[str] = None, | ||
| ) -> Resource: | ||
| json: Dict[str, Any] = {} | ||
| if name is not None: | ||
| json["name"] = name | ||
| if description is not None: | ||
| json["description"] = description | ||
|
|
||
| response = self._http_client.request( | ||
| f"{AUTHORIZATION_ORGANIZATIONS_PATH}/{organization_id}/resources/{resource_type}/{external_id}", | ||
| method=REQUEST_METHOD_PATCH, | ||
| json=json, | ||
| ) | ||
|
|
||
| return Resource.model_validate(response) | ||
|
|
||
| def delete_resource_by_external_id( | ||
| self, | ||
| organization_id: str, | ||
| resource_type: str, | ||
| external_id: str, | ||
| *, | ||
| cascade_delete: Optional[bool] = None, | ||
| ) -> None: | ||
| path = f"{AUTHORIZATION_ORGANIZATIONS_PATH}/{organization_id}/resources/{resource_type}/{external_id}" | ||
| params: Dict[str, bool] = {} | ||
| if cascade_delete is not None: | ||
| params["cascade_delete"] = cascade_delete | ||
|
|
||
| self._http_client.request( | ||
| path, | ||
| method=REQUEST_METHOD_DELETE, | ||
| params=params if params else None, | ||
| ) | ||
|
|
||
| def list_resources( | ||
| self, | ||
| organization_id: str, | ||
| *, | ||
| resource_type_slug: Optional[str] = None, | ||
| limit: int = DEFAULT_LIST_RESPONSE_LIMIT, | ||
| before: Optional[str] = None, | ||
| after: Optional[str] = None, | ||
| order: PaginationOrder = "desc", | ||
| ) -> ResourcesListResource: | ||
| list_params: ResourceListFilters = { | ||
| "organization_id": organization_id, | ||
| "limit": limit, | ||
| "before": before, | ||
| "after": after, | ||
| "order": order, | ||
| } | ||
| if resource_type_slug is not None: | ||
| list_params["resource_type_slug"] = resource_type_slug | ||
|
|
||
| query_params = {k: v for k, v in list_params.items() if k != "organization_id"} | ||
|
|
||
| response = self._http_client.request( | ||
| f"{AUTHORIZATION_ORGANIZATIONS_PATH}/{organization_id}/resources", | ||
| method=REQUEST_METHOD_GET, | ||
| params=query_params, | ||
| ) | ||
|
|
||
| return WorkOSListResource[Resource, ResourceListFilters, ListMetadata]( | ||
| list_method=self.list_resources, | ||
| list_args=list_params, | ||
| **ListPage[Resource](**response).model_dump(), | ||
| ) | ||
|
|
||
|
|
||
| class AsyncAuthorization(AuthorizationModule): | ||
| _http_client: AsyncHTTPClient | ||
|
|
@@ -712,3 +852,94 @@ async def add_environment_role_permission( | |
| ) | ||
|
|
||
| return EnvironmentRole.model_validate(response) | ||
|
|
||
| # Resources (External ID) + List | ||
|
|
||
| async def get_resource_by_external_id( | ||
| self, | ||
| organization_id: str, | ||
| resource_type: str, | ||
| external_id: str, | ||
| ) -> Resource: | ||
| response = await self._http_client.request( | ||
| f"{AUTHORIZATION_ORGANIZATIONS_PATH}/{organization_id}/resources/{resource_type}/{external_id}", | ||
| method=REQUEST_METHOD_GET, | ||
| ) | ||
|
|
||
| return Resource.model_validate(response) | ||
|
|
||
| async def update_resource_by_external_id( | ||
| self, | ||
| organization_id: str, | ||
| resource_type: str, | ||
| external_id: str, | ||
| *, | ||
| name: Optional[str] = None, | ||
| description: Optional[str] = None, | ||
| ) -> Resource: | ||
| json: Dict[str, Any] = {} | ||
| if name is not None: | ||
| json["name"] = name | ||
| if description is not None: | ||
| json["description"] = description | ||
|
|
||
| response = await self._http_client.request( | ||
| f"{AUTHORIZATION_ORGANIZATIONS_PATH}/{organization_id}/resources/{resource_type}/{external_id}", | ||
| method=REQUEST_METHOD_PATCH, | ||
| json=json, | ||
| ) | ||
|
|
||
| return Resource.model_validate(response) | ||
|
|
||
| async def delete_resource_by_external_id( | ||
| self, | ||
| organization_id: str, | ||
| resource_type: str, | ||
| external_id: str, | ||
| *, | ||
| cascade_delete: Optional[bool] = None, | ||
| ) -> None: | ||
| path = f"{AUTHORIZATION_ORGANIZATIONS_PATH}/{organization_id}/resources/{resource_type}/{external_id}" | ||
| params: Dict[str, bool] = {} | ||
| if cascade_delete is not None: | ||
| params["cascade_delete"] = cascade_delete | ||
|
|
||
| await self._http_client.request( | ||
| path, | ||
| method=REQUEST_METHOD_DELETE, | ||
| params=params if params else None, | ||
| ) | ||
|
|
||
| async def list_resources( | ||
| self, | ||
| organization_id: str, | ||
| *, | ||
| resource_type_slug: Optional[str] = None, | ||
| limit: int = DEFAULT_LIST_RESPONSE_LIMIT, | ||
| before: Optional[str] = None, | ||
| after: Optional[str] = None, | ||
| order: PaginationOrder = "desc", | ||
| ) -> ResourcesListResource: | ||
| list_params: ResourceListFilters = { | ||
| "organization_id": organization_id, | ||
| "limit": limit, | ||
| "before": before, | ||
| "after": after, | ||
| "order": order, | ||
| } | ||
| if resource_type_slug is not None: | ||
| list_params["resource_type_slug"] = resource_type_slug | ||
|
|
||
| query_params = {k: v for k, v in list_params.items() if k != "organization_id"} | ||
|
|
||
| response = await self._http_client.request( | ||
| f"{AUTHORIZATION_ORGANIZATIONS_PATH}/{organization_id}/resources", | ||
| method=REQUEST_METHOD_GET, | ||
| params=query_params, | ||
| ) | ||
|
|
||
| return WorkOSListResource[Resource, ResourceListFilters, ListMetadata]( | ||
| list_method=self.list_resources, | ||
| list_args=list_params, | ||
| **ListPage[Resource](**response).model_dump(), | ||
| ) | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
follow pattern in update #563