Skip to content

Commit baa62f7

Browse files
Merge #750
750: Return task instances from task methods instead of dicts r=alallema a=sanders41 # Pull Request ## Related issue Relates to #747 ## What does this PR do? - Returns an appropriate task class instance from task methods instead of dicts ## PR checklist Please check if your PR fulfills the following requirements: - [x] Does this PR fix an existing issue, or have you listed the changes applied in the PR description (and why they are needed)? - [x] Have you read the contributing guidelines? - [x] Have you made sure that the title is accurate and descriptive of the changes? Thank you so much for contributing to Meilisearch! Co-authored-by: Paul Sanders <[email protected]>
2 parents 616bb91 + 50e58ea commit baa62f7

File tree

6 files changed

+55
-67
lines changed

6 files changed

+55
-67
lines changed

meilisearch/client.py

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
from meilisearch.errors import MeilisearchError
1717
from meilisearch.index import Index
1818
from meilisearch.models.key import Key, KeysResults
19-
from meilisearch.models.task import TaskInfo
19+
from meilisearch.models.task import Task, TaskInfo, TaskResults
2020
from meilisearch.task import TaskHandler
2121

2222

@@ -466,9 +466,7 @@ def swap_indexes(self, parameters: List[Dict[str, List[str]]]) -> TaskInfo:
466466
"""
467467
return TaskInfo(**self.http.post(self.config.paths.swap, parameters))
468468

469-
def get_tasks(
470-
self, parameters: Optional[Dict[str, Any]] = None
471-
) -> Dict[str, List[Dict[str, Any]]]:
469+
def get_tasks(self, parameters: Optional[Dict[str, Any]] = None) -> TaskResults:
472470
"""Get all tasks.
473471
474472
Parameters
@@ -479,7 +477,8 @@ def get_tasks(
479477
Returns
480478
-------
481479
task:
482-
Dictionary with limit, from, next and results containing a list of all enqueued, processing, succeeded or failed tasks.
480+
TaskResult instance containing limit, from, next and results containing a list of all
481+
enqueued, processing, succeeded or failed tasks.
483482
484483
Raises
485484
------
@@ -488,7 +487,7 @@ def get_tasks(
488487
"""
489488
return self.task_handler.get_tasks(parameters=parameters)
490489

491-
def get_task(self, uid: int) -> Dict[str, Any]:
490+
def get_task(self, uid: int) -> Task:
492491
"""Get one task.
493492
494493
Parameters
@@ -499,7 +498,7 @@ def get_task(self, uid: int) -> Dict[str, Any]:
499498
Returns
500499
-------
501500
task:
502-
Dictionary containing information about the processed asynchronous task.
501+
Task instance containing information about the processed asynchronous task.
503502
504503
Raises
505504
------
@@ -553,7 +552,7 @@ def wait_for_task(
553552
uid: int,
554553
timeout_in_ms: int = 5000,
555554
interval_in_ms: int = 50,
556-
) -> Dict[str, Any]:
555+
) -> Task:
557556
"""Wait until Meilisearch processes a task until it fails or succeeds.
558557
559558
Parameters
@@ -568,7 +567,7 @@ def wait_for_task(
568567
Returns
569568
-------
570569
task:
571-
Dictionary containing information about the processed asynchronous task.
570+
Task instance containing information about the processed asynchronous task.
572571
573572
Raises
574573
------

meilisearch/index.py

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -170,8 +170,7 @@ def get_tasks(self, parameters: Optional[Dict[str, Any]] = None) -> TaskResults:
170170
else:
171171
parameters = {"indexUids": [self.uid]}
172172

173-
tasks = self.task_handler.get_tasks(parameters=parameters)
174-
return TaskResults(tasks)
173+
return self.task_handler.get_tasks(parameters=parameters)
175174

176175
def get_task(self, uid: int) -> Task:
177176
"""Get one task through the route of a specific index.
@@ -191,8 +190,7 @@ def get_task(self, uid: int) -> Task:
191190
MeilisearchApiError
192191
An error containing details about why Meilisearch can't process your request. Meilisearch error codes are described here: https://docs.meilisearch.com/errors/#meilisearch-errors
193192
"""
194-
task = self.task_handler.get_task(uid)
195-
return Task(**task)
193+
return self.task_handler.get_task(uid)
196194

197195
def wait_for_task(
198196
self,
@@ -221,8 +219,7 @@ def wait_for_task(
221219
MeilisearchTimeoutError
222220
An error containing details about why Meilisearch can't process your request. Meilisearch error codes are described here: https://docs.meilisearch.com/errors/#meilisearch-errors
223221
"""
224-
task = self.task_handler.wait_for_task(uid, timeout_in_ms, interval_in_ms)
225-
return Task(**task)
222+
return self.task_handler.wait_for_task(uid, timeout_in_ms, interval_in_ms)
226223

227224
def get_stats(self) -> IndexStats:
228225
"""Get stats of the index.

meilisearch/task.py

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@
22

33
from datetime import datetime
44
from time import sleep
5-
from typing import Any, Dict, List, Optional
5+
from typing import Any, Dict, Optional
66
from urllib import parse
77

88
from meilisearch._httprequests import HttpRequests
99
from meilisearch.config import Config
1010
from meilisearch.errors import MeilisearchTimeoutError
11-
from meilisearch.models.task import TaskInfo
11+
from meilisearch.models.task import Task, TaskInfo, TaskResults
1212

1313

1414
class TaskHandler:
@@ -27,9 +27,7 @@ def __init__(self, config: Config):
2727
self.config = config
2828
self.http = HttpRequests(config)
2929

30-
def get_tasks(
31-
self, parameters: Optional[Dict[str, Any]] = None
32-
) -> Dict[str, List[Dict[str, Any]]]:
30+
def get_tasks(self, parameters: Optional[Dict[str, Any]] = None) -> TaskResults:
3331
"""Get all tasks.
3432
3533
Parameters
@@ -40,7 +38,8 @@ def get_tasks(
4038
Returns
4139
-------
4240
task:
43-
Dictionary with limit, from, next and results containing a list of all enqueued, processing, succeeded or failed tasks.
41+
TaskResults instance contining limit, from, next and results containing a list of all
42+
enqueued, processing, succeeded or failed tasks.
4443
4544
Raises
4645
------
@@ -52,9 +51,10 @@ def get_tasks(
5251
for param in parameters:
5352
if isinstance(parameters[param], list):
5453
parameters[param] = ",".join(parameters[param])
55-
return self.http.get(f"{self.config.paths.task}?{parse.urlencode(parameters)}")
54+
tasks = self.http.get(f"{self.config.paths.task}?{parse.urlencode(parameters)}")
55+
return TaskResults(tasks)
5656

57-
def get_task(self, uid: int) -> Dict[str, Any]:
57+
def get_task(self, uid: int) -> Task:
5858
"""Get one task.
5959
6060
Parameters
@@ -65,14 +65,15 @@ def get_task(self, uid: int) -> Dict[str, Any]:
6565
Returns
6666
-------
6767
task:
68-
Dictionary containing information about the status of the asynchronous task.
68+
Task instance containing information about the processed asynchronous task.
6969
7070
Raises
7171
------
7272
MeilisearchApiError
7373
An error containing details about why Meilisearch can't process your request. Meilisearch error codes are described here: https://docs.meilisearch.com/errors/#meilisearch-errors
7474
"""
75-
return self.http.get(f"{self.config.paths.task}/{uid}")
75+
task = self.http.get(f"{self.config.paths.task}/{uid}")
76+
return Task(**task)
7677

7778
def cancel_tasks(self, parameters: Optional[Dict[str, Any]] = None) -> TaskInfo:
7879
"""Cancel a list of enqueued or processing tasks.
@@ -132,7 +133,7 @@ def wait_for_task(
132133
uid: int,
133134
timeout_in_ms: int = 5000,
134135
interval_in_ms: int = 50,
135-
) -> Dict[str, Any]:
136+
) -> Task:
136137
"""Wait until the task fails or succeeds in Meilisearch.
137138
138139
Parameters
@@ -147,7 +148,7 @@ def wait_for_task(
147148
Returns
148149
-------
149150
task:
150-
Dictionary containing information about the processed asynchronous task.
151+
Task instance containing information about the processed asynchronous task.
151152
152153
Raises
153154
------
@@ -158,7 +159,7 @@ def wait_for_task(
158159
elapsed_time = 0.0
159160
while elapsed_time < timeout_in_ms:
160161
task = self.get_task(uid)
161-
if task["status"] not in ("enqueued", "processing"):
162+
if task.status not in ("enqueued", "processing"):
162163
return task
163164
sleep(interval_in_ms / 1000)
164165
time_delta = datetime.now() - start_time

tests/client/test_client_dumps.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,5 @@ def test_dump_creation(client, index_with_documents):
77
dump = client.create_dump()
88
client.wait_for_task(dump.task_uid)
99
dump_status = client.get_task(dump.task_uid)
10-
assert dump_status["status"] == "succeeded"
11-
assert dump_status["type"] == "dumpCreation"
10+
assert dump_status.status == "succeeded"
11+
assert dump_status.type == "dumpCreation"

tests/client/test_client_swap_meilisearch.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ def test_swap_indexes(client, empty_index):
2626

2727
assert docA.title == indexB.uid
2828
assert docB.title == indexA.uid
29-
assert task["type"] == "indexSwap"
30-
assert "swaps" in task["details"]
29+
assert task.type == "indexSwap"
30+
assert "swaps" in task.details
3131

3232

3333
def test_swap_indexes_with_one_that_does_not_exist(client, empty_index):
@@ -43,7 +43,7 @@ def test_swap_indexes_with_one_that_does_not_exist(client, empty_index):
4343
task = client.wait_for_task(swapTask.task_uid)
4444

4545
assert swapTask.type == "indexSwap"
46-
assert task["error"]["code"] == "index_not_found"
46+
assert task.error["code"] == "index_not_found"
4747

4848

4949
def test_swap_indexes_with_itself(client, empty_index):

tests/client/test_client_task_meilisearch.py

Lines changed: 25 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -9,33 +9,29 @@
99
def test_get_tasks_default(client):
1010
"""Tests getting the global tasks list."""
1111
tasks = client.get_tasks()
12-
assert isinstance(tasks, dict)
13-
assert "results" in tasks
12+
assert len(tasks.results) >= 1
1413

1514

1615
def test_get_tasks(client, empty_index):
1716
"""Tests getting the global tasks list after populating an index."""
1817
current_tasks = client.get_tasks()
19-
pre_count = current_tasks["from"]
18+
pre_count = current_tasks.from_
2019
empty_index()
2120
tasks = client.get_tasks()
22-
assert isinstance(tasks, dict)
23-
assert tasks["from"] == pre_count + 1
21+
assert tasks.from_ == pre_count + 1
2422

2523

2624
def test_get_tasks_empty_parameters(client):
2725
"""Tests getting the global tasks list after populating an index."""
2826
tasks = client.get_tasks({})
29-
assert isinstance(tasks, dict)
30-
assert isinstance(tasks["results"], list)
27+
assert isinstance(tasks.results, list)
3128

3229

3330
def test_get_tasks_with_parameters(client, empty_index):
3431
"""Tests getting the global tasks list after populating an index."""
3532
empty_index()
3633
tasks = client.get_tasks({"limit": 1})
37-
assert isinstance(tasks, dict)
38-
assert len(tasks["results"]) == 1
34+
assert len(tasks.results) == 1
3935

4036

4137
def test_get_tasks_with_all_plural_parameters(client, empty_index):
@@ -44,8 +40,7 @@ def test_get_tasks_with_all_plural_parameters(client, empty_index):
4440
tasks = client.get_tasks(
4541
{"indexUids": [common.INDEX_UID], "statuses": ["succeeded"], "types": ["indexCreation"]}
4642
)
47-
assert isinstance(tasks, dict)
48-
assert len(tasks["results"]) >= 1
43+
assert len(tasks.results) >= 1
4944

5045

5146
def test_get_tasks_with_date_parameters(client, empty_index):
@@ -58,34 +53,31 @@ def test_get_tasks_with_date_parameters(client, empty_index):
5853
"beforeFinishedAt": "2042-04-02T00:42:42Z",
5954
}
6055
)
61-
assert isinstance(tasks, dict)
62-
assert len(tasks["results"]) > 1
56+
assert len(tasks.results) > 1
6357

6458

6559
def test_get_tasks_with_index_uid(client, empty_index):
6660
"""Tests getting the global tasks list after populating an index."""
6761
empty_index()
6862
tasks = client.get_tasks({"limit": 1, "indexUids": [common.INDEX_UID]})
69-
assert isinstance(tasks, dict)
70-
assert len(tasks["results"]) == 1
63+
assert len(tasks.results) == 1
7164

7265

7366
def test_get_task(client):
7467
"""Tests getting the tasks list of an empty index."""
7568
response = client.create_index(uid=common.INDEX_UID)
7669
client.wait_for_task(response.task_uid)
7770
task = client.get_task(response.task_uid)
78-
assert isinstance(task, dict)
79-
assert len(task) == 11
80-
assert "uid" in task
81-
assert "indexUid" in task
82-
assert "status" in task
83-
assert "type" in task
84-
assert "duration" in task
85-
assert "enqueuedAt" in task
86-
assert "finishedAt" in task
87-
assert "details" in task
88-
assert "startedAt" in task
71+
task_dict = task.__dict__
72+
assert "uid" in task_dict
73+
assert "index_uid" in task_dict
74+
assert "status" in task_dict
75+
assert "type" in task_dict
76+
assert "duration" in task_dict
77+
assert "enqueued_at" in task_dict
78+
assert "finished_at" in task_dict
79+
assert "details" in task_dict
80+
assert "started_at" in task_dict
8981

9082

9183
def test_get_task_inexistent(client):
@@ -115,8 +107,8 @@ def test_cancel_tasks(client):
115107
assert task.task_uid is not None
116108
assert task.index_uid is None
117109
assert task.type == "taskCancelation"
118-
assert "uids" in tasks["results"][0]["details"]["originalFilter"]
119-
assert "uids=1%2C2" in tasks["results"][0]["details"]["originalFilter"]
110+
assert "uids" in tasks.results[0].details["originalFilter"]
111+
assert "uids=1%2C2" in tasks.results[0].details["originalFilter"]
120112

121113

122114
@pytest.mark.usefixtures("create_tasks")
@@ -130,7 +122,7 @@ def test_cancel_every_task(client):
130122
assert task.task_uid is not None
131123
assert task.index_uid is None
132124
assert task.type == "taskCancelation"
133-
assert "statuses=enqueued%2Cprocessing" in tasks["results"][0]["details"]["originalFilter"]
125+
assert "statuses=enqueued%2Cprocessing" in tasks.results[0].details["originalFilter"]
134126

135127

136128
def test_delete_tasks_by_uid(client, empty_index, small_movies):
@@ -147,8 +139,8 @@ def test_delete_tasks_by_uid(client, empty_index, small_movies):
147139
assert task_deleted.task_uid is not None
148140
assert task_deleted.index_uid is None
149141
assert task_deleted.type == "taskDeletion"
150-
assert "uids" in task["details"]["originalFilter"]
151-
assert f"uids={task_addition.task_uid}" in task["details"]["originalFilter"]
142+
assert "uids" in task.details["originalFilter"]
143+
assert f"uids={task_addition.task_uid}" in task.details["originalFilter"]
152144

153145

154146
def test_delete_tasks_by_filter(client):
@@ -160,8 +152,7 @@ def test_delete_tasks_by_filter(client):
160152
assert task.task_uid is not None
161153
assert task.index_uid is None
162154
assert task.type == "taskDeletion"
163-
assert len(tasks_after["results"]) >= 1
155+
assert len(tasks_after.results) >= 1
164156
assert (
165-
"statuses=succeeded%2Cfailed%2Ccanceled"
166-
in tasks_after["results"][0]["details"]["originalFilter"]
157+
"statuses=succeeded%2Cfailed%2Ccanceled" in tasks_after.results[0].details["originalFilter"]
167158
)

0 commit comments

Comments
 (0)