Skip to content

Commit eb92dae

Browse files
authored
refactor: make index more consistent (#175)
1 parent c99e631 commit eb92dae

6 files changed

Lines changed: 79 additions & 67 deletions

File tree

src/deepset_mcp/api/README.md

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -161,13 +161,13 @@ from deepset_mcp.api.client import AsyncDeepsetClient
161161

162162
async with AsyncDeepsetClient() as client:
163163
indexes = client.indexes(workspace="your-workspace")
164-
164+
165165
# List all indexes
166166
index_list = await indexes.list()
167-
167+
168168
# Get a specific index
169169
index = await indexes.get("my-index")
170-
170+
171171
# Create a new index
172172
index_yaml = """
173173
document_store:
@@ -178,14 +178,14 @@ async with AsyncDeepsetClient() as client:
178178
converter:
179179
type: TextFileToDocument
180180
"""
181-
181+
182182
await indexes.create(
183-
name="my-new-index",
183+
index_name="my-new-index",
184184
yaml_config=index_yaml,
185185
description="My document index"
186186
)
187-
188-
updated_yaml = """
187+
188+
updated_yaml = """
189189
document_store:
190190
type: OpenSearchDocumentStore
191191
indexing_pipeline:
@@ -194,13 +194,13 @@ async with AsyncDeepsetClient() as client:
194194
converter:
195195
type: TextFileToDocument
196196
"""
197-
198-
# Update an existing index
199-
await indexes.update(
200-
index_name="my-index",
201-
updated_index_name="my-renamed-index",
202-
yaml_config=updated_yaml
203-
)
197+
198+
# Update an existing index
199+
await indexes.update(
200+
index_name="my-index",
201+
updated_index_name="my-renamed-index",
202+
yaml_config=updated_yaml
203+
)
204204
```
205205

206206
### Pipeline Templates

src/deepset_mcp/api/indexes/models.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from datetime import datetime
66
from typing import Any
77

8-
from pydantic import BaseModel
8+
from pydantic import BaseModel, Field
99
from rich.repr import Result
1010

1111
from deepset_mcp.api.shared_models import DeepsetUser
@@ -27,7 +27,7 @@ class Index(BaseModel):
2727
pipeline_index_id: str
2828
name: str
2929
description: str | None = None
30-
config_yaml: str
30+
yaml_config: str = Field(alias="config_yaml")
3131
workspace_id: str
3232
settings: dict[str, Any]
3333
desired_status: str
@@ -56,7 +56,7 @@ def __rich_repr__(self) -> Result:
5656
else None,
5757
)
5858
yield "last_edited_at", self.last_edited_at.strftime("%m/%d/%Y %I:%M:%S %p") if self.last_edited_at else None
59-
yield "config_yaml", self.config_yaml if self.config_yaml is not None else "Get full index to see config."
59+
yield "yaml_config", self.yaml_config if self.yaml_config is not None else "Get full index to see config."
6060

6161

6262
class IndexList(BaseModel):

src/deepset_mcp/api/indexes/resource.py

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
#
33
# SPDX-License-Identifier: Apache-2.0
44

5+
from urllib.parse import quote
6+
57
from deepset_mcp.api.exceptions import UnexpectedAPIError
68
from deepset_mcp.api.indexes.models import Index, IndexList
79
from deepset_mcp.api.indexes.protocols import IndexResourceProtocol
@@ -35,7 +37,9 @@ async def list(self, limit: int = 10, page_number: int = 1) -> IndexList:
3537
"page_number": page_number,
3638
}
3739

38-
response = await self._client.request(f"/v1/workspaces/{self._workspace}/indexes", params=params)
40+
response = await self._client.request(
41+
f"/v1/workspaces/{quote(self._workspace, safe='')}/indexes", params=params
42+
)
3943

4044
raise_for_status(response)
4145

@@ -48,28 +52,32 @@ async def get(self, index_name: str) -> Index:
4852
4953
:returns: Index details.
5054
"""
51-
response = await self._client.request(f"/v1/workspaces/{self._workspace}/indexes/{index_name}")
55+
response = await self._client.request(
56+
f"/v1/workspaces/{quote(self._workspace, safe='')}/indexes/{quote(index_name, safe='')}"
57+
)
5258

5359
raise_for_status(response)
5460

5561
return Index.model_validate(response.json)
5662

57-
async def create(self, name: str, yaml_config: str, description: str | None = None) -> Index:
63+
async def create(self, index_name: str, yaml_config: str, description: str | None = None) -> Index:
5864
"""Create a new index with the given name and configuration.
5965
60-
:param name: Name of the index
66+
:param index_name: Name of the index
6167
:param yaml_config: YAML configuration for the index
6268
:param description: Optional description for the index
6369
:returns: Created index details
6470
"""
6571
data = {
66-
"name": name,
72+
"name": index_name,
6773
"config_yaml": yaml_config,
6874
}
6975
if description is not None:
7076
data["description"] = description
7177

72-
response = await self._client.request(f"v1/workspaces/{self._workspace}/indexes", method="POST", data=data)
78+
response = await self._client.request(
79+
f"v1/workspaces/{quote(self._workspace, safe='')}/indexes", method="POST", data=data
80+
)
7381

7482
raise_for_status(response)
7583

@@ -95,7 +103,9 @@ async def update(
95103
raise ValueError("At least one of updated_index_name or yaml_config must be provided")
96104

97105
response = await self._client.request(
98-
f"/v1/workspaces/{self._workspace}/indexes/{index_name}", method="PATCH", data=data
106+
f"/v1/workspaces/{quote(self._workspace, safe='')}/indexes/{quote(index_name, safe='')}",
107+
method="PATCH",
108+
data=data,
99109
)
100110

101111
raise_for_status(response)
@@ -107,7 +117,9 @@ async def delete(self, index_name: str) -> None:
107117
108118
:param index_name: Name of the index to delete.
109119
"""
110-
response = await self._client.request(f"/v1/workspaces/{self._workspace}/indexes/{index_name}", method="DELETE")
120+
response = await self._client.request(
121+
f"/v1/workspaces/{quote(self._workspace, safe='')}/indexes/{quote(index_name, safe='')}", method="DELETE"
122+
)
111123

112124
raise_for_status(response)
113125

@@ -119,7 +131,7 @@ async def deploy(self, index_name: str) -> PipelineValidationResult:
119131
:raises UnexpectedAPIError: If the API returns an unexpected status code.
120132
"""
121133
resp = await self._client.request(
122-
endpoint=f"v1/workspaces/{self._workspace}/indexes/{index_name}/deploy",
134+
endpoint=f"v1/workspaces/{quote(self._workspace, safe='')}/indexes/{quote(index_name, safe='')}/deploy",
123135
method="POST",
124136
)
125137

test/integration/test_integration_index_resource.py

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ def valid_index_config() -> str:
2020
"""Return a valid index YAML configuration for testing."""
2121
return json.dumps(
2222
{
23-
"config_yaml": """
23+
"yaml_config": """
2424
components:
2525
file_classifier:
2626
type: haystack.components.routers.file_type_router.FileTypeRouter
@@ -212,14 +212,14 @@ async def test_create_index(
212212
# Create a new index
213213
config = json.loads(valid_index_config)
214214
await index_resource.create(
215-
name=default_index_name, yaml_config=config["config_yaml"], description="Test index description"
215+
index_name=default_index_name, yaml_config=config["yaml_config"], description="Test index description"
216216
)
217217

218218
# Verify the index was created by retrieving it
219219
index: Index = await index_resource.get(index_name=default_index_name)
220220

221221
assert index.name == default_index_name
222-
assert index.config_yaml == config["config_yaml"]
222+
assert index.yaml_config == config["yaml_config"]
223223

224224

225225
@pytest.mark.asyncio
@@ -234,7 +234,7 @@ async def test_list_indexes(
234234
for i in range(3):
235235
index_name = f"test-list-index-{i}"
236236
index_names.append(index_name)
237-
await index_resource.create(name=index_name, yaml_config=config["config_yaml"])
237+
await index_resource.create(index_name=index_name, yaml_config=config["yaml_config"])
238238

239239
# Test listing without pagination
240240
indexes = await index_resource.list(limit=10)
@@ -268,12 +268,12 @@ async def test_get_index(
268268
"""Test getting a single index by name."""
269269
# Create an index to retrieve
270270
config = json.loads(valid_index_config)
271-
await index_resource.create(name=default_index_name, yaml_config=config["config_yaml"])
271+
await index_resource.create(index_name=default_index_name, yaml_config=config["yaml_config"])
272272

273273
# Test getting the index
274274
index: Index = await index_resource.get(index_name=default_index_name)
275275
assert index.name == default_index_name
276-
assert index.config_yaml == config["config_yaml"]
276+
assert index.yaml_config == config["yaml_config"]
277277

278278

279279
@pytest.mark.asyncio
@@ -287,7 +287,7 @@ async def test_update_index(
287287

288288
# Create an index to update
289289
config = json.loads(valid_index_config)
290-
await index_resource.create(name=original_name, yaml_config=config["config_yaml"])
290+
await index_resource.create(index_name=original_name, yaml_config=config["yaml_config"])
291291

292292
# Update the index name
293293
await index_resource.update(
@@ -300,15 +300,15 @@ async def test_update_index(
300300
assert updated_index.name == updated_name
301301

302302
# Update the index config
303-
modified_yaml = config["config_yaml"].replace("split_length: 250", "split_length: 300")
303+
modified_yaml = config["yaml_config"].replace("split_length: 250", "split_length: 300")
304304
await index_resource.update(
305305
index_name=updated_name,
306306
yaml_config=modified_yaml,
307307
)
308308

309309
# Verify the config was updated
310310
updated_index = await index_resource.get(index_name=updated_name)
311-
assert updated_index.config_yaml == modified_yaml
311+
assert updated_index.yaml_config == modified_yaml
312312

313313

314314
@pytest.mark.asyncio
@@ -333,7 +333,7 @@ async def test_delete_index(
333333

334334
# Create an index to delete
335335
config = json.loads(valid_index_config)
336-
await index_resource.create(name=index_name, yaml_config=config["config_yaml"])
336+
await index_resource.create(index_name=index_name, yaml_config=config["yaml_config"])
337337

338338
# Verify the index exists
339339
index: Index = await index_resource.get(index_name=index_name)
@@ -357,7 +357,7 @@ async def test_deploy_index_success(
357357

358358
# Create an index to deploy
359359
config = json.loads(valid_index_config)
360-
await index_resource.create(name=index_name, yaml_config=config["config_yaml"])
360+
await index_resource.create(index_name=index_name, yaml_config=config["yaml_config"])
361361

362362
# Deploy the index
363363
result = await index_resource.deploy(index_name=index_name)

test/unit/api/indexes/test_index_resource.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,9 @@ async def test_create_index_successful(
192192
)
193193

194194
resource = IndexResource(fake_client, workspace)
195-
result = await resource.create(name="test-index", yaml_config="yaml: content", description="Test description")
195+
result = await resource.create(
196+
index_name="test-index", yaml_config="yaml: content", description="Test description"
197+
)
196198

197199
assert isinstance(result, Index)
198200
assert result.name == "test-index"
@@ -239,7 +241,7 @@ async def test_create_index_invalid_request(
239241
"""Test that creating an index with invalid parameters raises an error."""
240242
resource = IndexResource(fake_client, workspace)
241243
with pytest.raises(BadRequestError):
242-
await resource.create(name="invalid-index", yaml_config="invalid: yaml")
244+
await resource.create(index_name="invalid-index", yaml_config="invalid: yaml")
243245

244246
async def test_update_nonexistent_index(
245247
self, fake_client: BaseFakeClient, workspace: str, fake_update_404_response: None

test/unit/tools/test_indexes.py

Lines changed: 26 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,13 @@
22
#
33
# SPDX-License-Identifier: Apache-2.0
44

5-
from datetime import datetime
65

76
import pytest
87

98
from deepset_mcp.api.exceptions import BadRequestError, ResourceNotFoundError, UnexpectedAPIError
10-
from deepset_mcp.api.indexes.models import Index, IndexList, IndexStatus
9+
from deepset_mcp.api.indexes.models import Index, IndexList
1110
from deepset_mcp.api.indexes.protocols import IndexResourceProtocol
1211
from deepset_mcp.api.pipeline.models import PipelineValidationResult, ValidationError
13-
from deepset_mcp.api.shared_models import DeepsetUser
1412
from deepset_mcp.tools.indexes import create_index, deploy_index, get_index, list_indexes, update_index
1513
from test.unit.conftest import BaseFakeClient
1614

@@ -94,34 +92,34 @@ def indexes(self, workspace: str) -> FakeIndexResource:
9492
def create_test_index(
9593
name: str = "test_index",
9694
description: str | None = "Test index description",
97-
config_yaml: str = "config: value",
95+
yaml_config: str = "config: value",
9896
) -> Index:
9997
"""Helper function to create a complete Index object for testing."""
100-
user = DeepsetUser(user_id="u1", given_name="Test", family_name="User")
101-
status = IndexStatus(
102-
pending_file_count=0,
103-
failed_file_count=0,
104-
indexed_no_documents_file_count=0,
105-
indexed_file_count=10,
106-
total_file_count=10,
107-
)
10898

109-
return Index(
110-
pipeline_index_id="idx_123",
111-
name=name,
112-
description=description,
113-
config_yaml=config_yaml,
114-
workspace_id="ws_123",
115-
settings={"key": "value"},
116-
desired_status="DEPLOYED",
117-
deployed_at=datetime(2023, 1, 1, 12, 0),
118-
last_edited_at=datetime(2023, 1, 2, 14, 30),
119-
max_index_replica_count=3,
120-
created_at=datetime(2023, 1, 1, 10, 0),
121-
updated_at=datetime(2023, 1, 2, 14, 30),
122-
created_by=user,
123-
last_edited_by=user,
124-
status=status,
99+
return Index.model_validate(
100+
{
101+
"pipeline_index_id": "idx_123",
102+
"name": name,
103+
"description": description,
104+
"config_yaml": yaml_config,
105+
"workspace_id": "ws_123",
106+
"settings": {"key": "value"},
107+
"desired_status": "DEPLOYED",
108+
"deployed_at": "2023-01-01T12:00:00Z",
109+
"last_edited_at": "2023-01-02T14:30:00Z",
110+
"max_index_replica_count": 3,
111+
"created_at": "2023-01-01T10:00:00Z",
112+
"updated_at": "2023-01-02T14:30:00Z",
113+
"created_by": {"user_id": "u1", "given_name": "Test", "family_name": "User"},
114+
"last_edited_by": {"user_id": "u1", "given_name": "Test", "family_name": "User"},
115+
"status": {
116+
"pending_file_count": 0,
117+
"failed_file_count": 0,
118+
"indexed_no_documents_file_count": 0,
119+
"indexed_file_count": 10,
120+
"total_file_count": 10,
121+
},
122+
}
125123
)
126124

127125

0 commit comments

Comments
 (0)