Skip to content

Commit 5a04c49

Browse files
fix: list_client_secrets returns raw list, not paginated response
The API endpoint returns a plain JSON array for client secrets, not a paginated response object. Updated to match the pattern used by other raw-list endpoints (e.g. fga.batch_check, vault.list_object_versions). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 1ad1623 commit 5a04c49

File tree

2 files changed

+9
-100
lines changed

2 files changed

+9
-100
lines changed

src/workos/connect.py

Lines changed: 7 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,8 @@
1-
from functools import partial
21
from typing import Optional, Protocol, Sequence
32

43
from workos.types.connect import ClientSecret, ConnectApplication
54
from workos.types.connect.connect_application import ApplicationType
6-
from workos.types.connect.list_filters import (
7-
ClientSecretListFilters,
8-
ConnectApplicationListFilters,
9-
)
5+
from workos.types.connect.list_filters import ConnectApplicationListFilters
106
from workos.types.list_resource import ListMetadata, ListPage, WorkOSListResource
117
from workos.typing.sync_or_async import SyncOrAsync
128
from workos.utils.http_client import AsyncHTTPClient, SyncHTTPClient
@@ -26,10 +22,6 @@
2622
ConnectApplication, ConnectApplicationListFilters, ListMetadata
2723
]
2824

29-
ClientSecretsListResource = WorkOSListResource[
30-
ClientSecret, ClientSecretListFilters, ListMetadata
31-
]
32-
3325

3426
class ConnectModule(Protocol):
3527
"""Offers methods through the WorkOS Connect service."""
@@ -145,25 +137,14 @@ def create_client_secret(self, application_id: str) -> SyncOrAsync[ClientSecret]
145137
def list_client_secrets(
146138
self,
147139
application_id: str,
148-
*,
149-
limit: int = DEFAULT_LIST_RESPONSE_LIMIT,
150-
before: Optional[str] = None,
151-
after: Optional[str] = None,
152-
order: PaginationOrder = "desc",
153-
) -> SyncOrAsync[ClientSecretsListResource]:
140+
) -> SyncOrAsync[Sequence[ClientSecret]]:
154141
"""List client secrets for a connect application.
155142
156143
Args:
157144
application_id (str): Application ID or client ID.
158145
159-
Kwargs:
160-
limit (int): Maximum number of records to return. (Optional)
161-
before (str): Pagination cursor to receive records before a provided ID. (Optional)
162-
after (str): Pagination cursor to receive records after a provided ID. (Optional)
163-
order (Literal["asc","desc"]): Sort records in either ascending or descending order. (Optional)
164-
165146
Returns:
166-
ClientSecretsListResource: Client secrets list response from WorkOS.
147+
Sequence[ClientSecret]: Client secrets for the application.
167148
"""
168149
...
169150

@@ -297,30 +278,13 @@ def create_client_secret(self, application_id: str) -> ClientSecret:
297278
def list_client_secrets(
298279
self,
299280
application_id: str,
300-
*,
301-
limit: int = DEFAULT_LIST_RESPONSE_LIMIT,
302-
before: Optional[str] = None,
303-
after: Optional[str] = None,
304-
order: PaginationOrder = "desc",
305-
) -> ClientSecretsListResource:
306-
list_params: ClientSecretListFilters = {
307-
"limit": limit,
308-
"before": before,
309-
"after": after,
310-
"order": order,
311-
}
312-
281+
) -> Sequence[ClientSecret]:
313282
response = self._http_client.request(
314283
f"{CONNECT_APPLICATIONS_PATH}/{application_id}/client_secrets",
315284
method=REQUEST_METHOD_GET,
316-
params=list_params,
317285
)
318286

319-
return WorkOSListResource[ClientSecret, ClientSecretListFilters, ListMetadata](
320-
list_method=partial(self.list_client_secrets, application_id),
321-
list_args=list_params,
322-
**ListPage[ClientSecret](**response).model_dump(),
323-
)
287+
return [ClientSecret.model_validate(secret) for secret in response]
324288

325289
def delete_client_secret(self, client_secret_id: str) -> None:
326290
self._http_client.request(
@@ -447,30 +411,13 @@ async def create_client_secret(self, application_id: str) -> ClientSecret:
447411
async def list_client_secrets(
448412
self,
449413
application_id: str,
450-
*,
451-
limit: int = DEFAULT_LIST_RESPONSE_LIMIT,
452-
before: Optional[str] = None,
453-
after: Optional[str] = None,
454-
order: PaginationOrder = "desc",
455-
) -> ClientSecretsListResource:
456-
list_params: ClientSecretListFilters = {
457-
"limit": limit,
458-
"before": before,
459-
"after": after,
460-
"order": order,
461-
}
462-
414+
) -> Sequence[ClientSecret]:
463415
response = await self._http_client.request(
464416
f"{CONNECT_APPLICATIONS_PATH}/{application_id}/client_secrets",
465417
method=REQUEST_METHOD_GET,
466-
params=list_params,
467418
)
468419

469-
return WorkOSListResource[ClientSecret, ClientSecretListFilters, ListMetadata](
470-
list_method=partial(self.list_client_secrets, application_id),
471-
list_args=list_params,
472-
**ListPage[ClientSecret](**response).model_dump(),
473-
)
420+
return [ClientSecret.model_validate(secret) for secret in response]
474421

475422
async def delete_client_secret(self, client_secret_id: str) -> None:
476423
await self._http_client.request(

tests/test_connect.py

Lines changed: 2 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -45,17 +45,7 @@ def mock_client_secret(self):
4545

4646
@pytest.fixture
4747
def mock_client_secrets(self):
48-
secret_list = [MockClientSecret(id=f"cs_{i}").dict() for i in range(10)]
49-
return {
50-
"data": secret_list,
51-
"list_metadata": {"before": None, "after": None},
52-
"object": "list",
53-
}
54-
55-
@pytest.fixture
56-
def mock_client_secrets_multiple_data_pages(self):
57-
secrets_list = [MockClientSecret(id=f"cs_{i + 1}").dict() for i in range(40)]
58-
return list_response_of(data=secrets_list)
48+
return [MockClientSecret(id=f"cs_{i}").dict() for i in range(10)]
5949

6050
# --- Application Tests ---
6151

@@ -250,9 +240,7 @@ def test_list_client_secrets(
250240
assert request_kwargs["url"].endswith(
251241
"/connect/applications/app_01ABC/client_secrets"
252242
)
253-
assert (
254-
list(map(lambda x: x.dict(), response.data)) == mock_client_secrets["data"]
255-
)
243+
assert [secret.dict() for secret in response] == mock_client_secrets
256244

257245
def test_delete_client_secret(self, capture_and_mock_http_client_request):
258246
request_kwargs = capture_and_mock_http_client_request(
@@ -269,29 +257,3 @@ def test_delete_client_secret(self, capture_and_mock_http_client_request):
269257
assert request_kwargs["url"].endswith("/connect/client_secrets/cs_01ABC")
270258
assert request_kwargs["method"] == "delete"
271259
assert response is None
272-
273-
def test_list_client_secrets_auto_pagination_for_single_page(
274-
self,
275-
mock_client_secrets,
276-
test_auto_pagination: TestAutoPaginationFunction,
277-
):
278-
test_auto_pagination(
279-
http_client=self.http_client,
280-
list_function=self.connect.list_client_secrets,
281-
expected_all_page_data=mock_client_secrets["data"],
282-
list_function_params={"application_id": "app_01ABC"},
283-
url_path_keys=["application_id"],
284-
)
285-
286-
def test_list_client_secrets_auto_pagination_for_multiple_pages(
287-
self,
288-
mock_client_secrets_multiple_data_pages,
289-
test_auto_pagination: TestAutoPaginationFunction,
290-
):
291-
test_auto_pagination(
292-
http_client=self.http_client,
293-
list_function=self.connect.list_client_secrets,
294-
expected_all_page_data=mock_client_secrets_multiple_data_pages["data"],
295-
list_function_params={"application_id": "app_01ABC"},
296-
url_path_keys=["application_id"],
297-
)

0 commit comments

Comments
 (0)