22#
33# SPDX-License-Identifier: Apache-2.0
44
5+ from typing import Any
56from urllib .parse import quote
67
78from deepset_mcp .api .exceptions import UnexpectedAPIError
8- from deepset_mcp .api .indexes .models import Index , IndexList
9+ from deepset_mcp .api .indexes .models import Index
910from deepset_mcp .api .indexes .protocols import IndexResourceProtocol
1011from deepset_mcp .api .pipeline .models import PipelineValidationResult , ValidationError
1112from deepset_mcp .api .protocols import AsyncClientProtocol
13+ from deepset_mcp .api .shared_models import PaginatedResponse
1214from deepset_mcp .api .transport import raise_for_status
1315
1416
@@ -24,26 +26,45 @@ def __init__(self, client: AsyncClientProtocol, workspace: str) -> None:
2426 self ._client = client
2527 self ._workspace = workspace
2628
27- async def list (self , limit : int = 10 , page_number : int = 1 ) -> IndexList :
28- """List all indexes.
29+ async def list (self , limit : int = 10 , after : str | None = None ) -> PaginatedResponse [ Index ] :
30+ """Lists indexes and returns the first page of results .
2931
30- :param limit: Maximum number of indexes to return.
31- :param page_number: Page number for pagination.
32+ The returned object can be iterated over to fetch subsequent pages.
3233
33- :returns: List of indexes.
34+ :param limit: The maximum number of indexes to return per page.
35+ :param after: The cursor to fetch the next page of results.
36+ :returns: A `PaginatedResponse` object containing the first page of indexes.
3437 """
35- params = {
36- "limit" : limit ,
37- "page_number" : page_number ,
38- }
39-
40- response = await self ._client .request (
41- f"/v1/workspaces/{ quote (self ._workspace , safe = '' )} /indexes" , params = params
38+ # 1. Prepare arguments for the initial API call
39+ # TODO: Pagination in the deepset API is currently implemented in an unintuitive way.
40+ # TODO: The cursor is always time based (created_at) and after signifies indexes older than the current cursor
41+ # TODO: while 'before' signals indexes younger than the current cursor.
42+ # TODO: This is applied irrespective of any sort (e.g. name) that would conflict with this approach.
43+ # TODO: Change this to 'after' once the behaviour is fixed on the deepset API
44+ request_params = {"limit" : limit , "before" : after }
45+ request_params = {k : v for k , v in request_params .items () if v is not None }
46+
47+ # 2. Make the first API call using a private, stateless method
48+ page = await self ._list_api_call (** request_params )
49+
50+ # 3. Inject the logic needed for subsequent fetches into the response object
51+ page ._inject_paginator (
52+ fetch_func = self ._list_api_call ,
53+ # Base args for the *next* fetch don't include initial cursors
54+ base_args = {"limit" : limit },
4255 )
56+ return page
4357
44- raise_for_status (response )
58+ async def _list_api_call (self , ** kwargs : Any ) -> PaginatedResponse [Index ]:
59+ """A private, stateless method that performs the raw API call."""
60+ resp = await self ._client .request (
61+ endpoint = f"v1/workspaces/{ quote (self ._workspace , safe = '' )} /indexes" , method = "GET" , params = kwargs
62+ )
63+ raise_for_status (resp )
64+ if resp .json is None :
65+ raise UnexpectedAPIError (status_code = resp .status_code , message = "Empty response" , detail = None )
4566
46- return IndexList . model_validate ( response .json )
67+ return PaginatedResponse [ Index ]. create_with_cursor_field ( resp .json , "pipeline_index_id" )
4768
4869 async def get (self , index_name : str ) -> Index :
4970 """Get a specific index.
0 commit comments