Skip to content

Commit a438770

Browse files
committed
Fix bug with get_tasks not returning all information
1 parent 23b7a06 commit a438770

File tree

3 files changed

+82
-59
lines changed

3 files changed

+82
-59
lines changed

meilisearch_python_async/models/task.py

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from datetime import datetime
2-
from typing import Any, Dict, Optional, Union
2+
from typing import Any, Dict, List, Optional, Union
33

44
import pydantic
55
from camel_converter.pydantic_base import CamelBase
@@ -12,17 +12,17 @@ class TaskId(CamelBase):
1212
uid: int
1313

1414

15-
class TaskStatus(TaskId):
15+
class TaskResult(TaskId):
1616
index_uid: Optional[str] = None
1717
status: str
1818
task_type: Union[str, Dict[str, Any]] = Field(..., alias="type")
19-
details: Optional[Dict[str, Any]]
20-
error: Optional[Dict[str, Any]]
21-
canceled_by: Optional[int]
22-
duration: Optional[str]
19+
details: Optional[Dict[str, Any]] = None
20+
error: Optional[Dict[str, Any]] = None
21+
canceled_by: Optional[int] = None
22+
duration: Optional[str] = None
2323
enqueued_at: datetime
24-
started_at: Optional[datetime]
25-
finished_at: Optional[datetime]
24+
started_at: Optional[datetime] = None
25+
finished_at: Optional[datetime] = None
2626

2727
if is_pydantic_2():
2828

@@ -69,6 +69,13 @@ def validate_finished_at(cls, v: str) -> Union[datetime, None]:
6969
return iso_to_date_time(v)
7070

7171

72+
class TaskStatus(CamelBase):
73+
results: List[TaskResult]
74+
limit: int
75+
from_: int = Field(..., alias="from")
76+
next: Optional[int] = None
77+
78+
7279
class TaskInfo(CamelBase):
7380
task_uid: int
7481
index_uid: Optional[str] = None

meilisearch_python_async/task.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
from meilisearch_python_async._http_requests import HttpRequests
1111
from meilisearch_python_async.errors import MeilisearchTaskFailedError, MeilisearchTimeoutError
12-
from meilisearch_python_async.models.task import TaskInfo, TaskStatus
12+
from meilisearch_python_async.models.task import TaskInfo, TaskResult, TaskStatus
1313

1414
if TYPE_CHECKING:
1515
from meilisearch_python_async.client import Client # pragma: no cover
@@ -156,7 +156,7 @@ async def get_tasks(
156156
*,
157157
index_ids: list[str] | None = None,
158158
types: str | list[str] | None = None,
159-
) -> list[TaskStatus]:
159+
) -> TaskStatus:
160160
"""Get multiple tasks.
161161
162162
Args:
@@ -168,7 +168,7 @@ async def get_tasks(
168168
169169
Returns:
170170
171-
A list of all tasks.
171+
Task statuses.
172172
173173
Raises:
174174
@@ -191,10 +191,10 @@ async def get_tasks(
191191
client_ = _get_client(client)
192192
response = await client_.get(url)
193193

194-
return [TaskStatus(**x) for x in response.json()["results"]]
194+
return TaskStatus(**response.json())
195195

196196

197-
async def get_task(client: AsyncClient | Client, task_id: int) -> TaskStatus:
197+
async def get_task(client: AsyncClient | Client, task_id: int) -> TaskResult:
198198
"""Get a single task from it's task id.
199199
200200
Args:
@@ -204,7 +204,7 @@ async def get_task(client: AsyncClient | Client, task_id: int) -> TaskStatus:
204204
205205
Returns:
206206
207-
A list of all tasks.
207+
Results of a task.
208208
209209
Raises:
210210
@@ -223,7 +223,7 @@ async def get_task(client: AsyncClient | Client, task_id: int) -> TaskStatus:
223223
client_ = _get_client(client)
224224
response = await client_.get(f"tasks/{task_id}")
225225

226-
return TaskStatus(**response.json())
226+
return TaskResult(**response.json())
227227

228228

229229
async def wait_for_task(
@@ -233,7 +233,7 @@ async def wait_for_task(
233233
timeout_in_ms: int | None = 5000,
234234
interval_in_ms: int = 50,
235235
raise_for_status: bool = False,
236-
) -> TaskStatus:
236+
) -> TaskResult:
237237
"""Wait until Meilisearch processes a task, and get its status.
238238
239239
Args:
@@ -280,7 +280,7 @@ async def wait_for_task(
280280
if timeout_in_ms:
281281
while elapsed_time < timeout_in_ms:
282282
response = await http_requests.get(url)
283-
status = TaskStatus(**response.json())
283+
status = TaskResult(**response.json())
284284
if status.status in ("succeeded", "failed"):
285285
if raise_for_status and status.status == "failed":
286286
raise MeilisearchTaskFailedError(f"Task {task_id} failed")
@@ -294,7 +294,7 @@ async def wait_for_task(
294294
else:
295295
while True:
296296
response = await http_requests.get(url)
297-
status = TaskStatus(**response.json())
297+
status = TaskResult(**response.json())
298298
if status.status in ("succeeded", "failed"):
299299
return status
300300
await sleep(interval_in_ms / 1000)

tests/test_task.py

Lines changed: 57 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,8 @@ async def test_cancel_statuses(test_client):
3535
assert completed_task.index_uid is None
3636
assert completed_task.status == "succeeded"
3737
assert completed_task.task_type == "taskCancelation"
38-
assert tasks[0].details is not None
39-
assert "statuses=enqueued%2Cprocessing" in tasks[0].details["originalFilter"]
38+
assert tasks.results[0].details is not None
39+
assert "statuses=enqueued%2Cprocessing" in tasks.results[0].details["originalFilter"]
4040

4141

4242
@pytest.mark.usefixtures("create_tasks")
@@ -48,8 +48,8 @@ async def test_cancel_tasks_uids(test_client):
4848

4949
assert completed_task.status == "succeeded"
5050
assert completed_task.task_type == "taskCancelation"
51-
assert tasks[0].details is not None
52-
assert "uids=1%2C2" in tasks[0].details["originalFilter"]
51+
assert tasks.results[0].details is not None
52+
assert "uids=1%2C2" in tasks.results[0].details["originalFilter"]
5353

5454

5555
@pytest.mark.usefixtures("create_tasks")
@@ -62,8 +62,8 @@ async def test_cancel_tasks_index_uids(test_client):
6262

6363
assert completed_task.status == "succeeded"
6464
assert completed_task.task_type == "taskCancelation"
65-
assert tasks[0].details is not None
66-
assert "indexUids=1" in tasks[0].details["originalFilter"]
65+
assert tasks.results[0].details is not None
66+
assert "indexUids=1" in tasks.results[0].details["originalFilter"]
6767

6868

6969
@pytest.mark.usefixtures("create_tasks")
@@ -75,8 +75,8 @@ async def test_cancel_tasks_types(test_client):
7575

7676
assert completed_task.status == "succeeded"
7777
assert completed_task.task_type == "taskCancelation"
78-
assert tasks[0].details is not None
79-
assert "types=taskDeletion" in tasks[0].details["originalFilter"]
78+
assert tasks.results[0].details is not None
79+
assert "types=taskDeletion" in tasks.results[0].details["originalFilter"]
8080

8181

8282
@pytest.mark.usefixtures("create_tasks")
@@ -89,9 +89,10 @@ async def test_cancel_tasks_before_enqueued_at(test_client):
8989

9090
assert completed_task.status == "succeeded"
9191
assert completed_task.task_type == "taskCancelation"
92-
assert tasks[0].details is not None
92+
assert tasks.results[0].details is not None
9393
assert (
94-
f"beforeEnqueuedAt={quote_plus(before.isoformat())}Z" in tasks[0].details["originalFilter"]
94+
f"beforeEnqueuedAt={quote_plus(before.isoformat())}Z"
95+
in tasks.results[0].details["originalFilter"]
9596
)
9697

9798

@@ -105,8 +106,11 @@ async def test_cancel_tasks_after_enqueued_at(test_client):
105106

106107
assert completed_task.status == "succeeded"
107108
assert completed_task.task_type == "taskCancelation"
108-
assert tasks[0].details is not None
109-
assert f"afterEnqueuedAt={quote_plus(after.isoformat())}Z" in tasks[0].details["originalFilter"]
109+
assert tasks.results[0].details is not None
110+
assert (
111+
f"afterEnqueuedAt={quote_plus(after.isoformat())}Z"
112+
in tasks.results[0].details["originalFilter"]
113+
)
110114

111115

112116
@pytest.mark.usefixtures("create_tasks")
@@ -119,9 +123,10 @@ async def test_cancel_tasks_before_started_at(test_client):
119123

120124
assert completed_task.status == "succeeded"
121125
assert completed_task.task_type == "taskCancelation"
122-
assert tasks[0].details is not None
126+
assert tasks.results[0].details is not None
123127
assert (
124-
f"beforeStartedAt={quote_plus(before.isoformat())}Z" in tasks[0].details["originalFilter"]
128+
f"beforeStartedAt={quote_plus(before.isoformat())}Z"
129+
in tasks.results[0].details["originalFilter"]
125130
)
126131

127132

@@ -135,8 +140,11 @@ async def test_cancel_tasks_after_finished_at(test_client):
135140

136141
assert completed_task.status == "succeeded"
137142
assert completed_task.task_type == "taskCancelation"
138-
assert tasks[0].details is not None
139-
assert f"afterFinishedAt={quote_plus(after.isoformat())}Z" in tasks[0].details["originalFilter"]
143+
assert tasks.results[0].details is not None
144+
assert (
145+
f"afterFinishedAt={quote_plus(after.isoformat())}Z"
146+
in tasks.results[0].details["originalFilter"]
147+
)
140148

141149

142150
@pytest.mark.usefixtures("create_tasks")
@@ -148,8 +156,8 @@ async def test_cancel_task_no_params(test_client):
148156

149157
assert completed_task.status == "succeeded"
150158
assert completed_task.task_type == "taskCancelation"
151-
assert tasks[0].details is not None
152-
assert "statuses=enqueued%2Cprocessing" in tasks[0].details["originalFilter"]
159+
assert tasks.results[0].details is not None
160+
assert "statuses=enqueued%2Cprocessing" in tasks.results[0].details["originalFilter"]
153161

154162

155163
@pytest.mark.usefixtures("create_tasks")
@@ -161,8 +169,8 @@ async def test_delete_statuses(test_client):
161169

162170
assert deleted_tasks.status == "succeeded"
163171
assert deleted_tasks.task_type == "taskDeletion"
164-
assert tasks[0].details is not None
165-
assert "statuses=enqueued%2Cprocessing" in tasks[0].details["originalFilter"]
172+
assert tasks.results[0].details is not None
173+
assert "statuses=enqueued%2Cprocessing" in tasks.results[0].details["originalFilter"]
166174

167175

168176
@pytest.mark.usefixtures("create_tasks")
@@ -174,8 +182,8 @@ async def test_delete_tasks(test_client):
174182

175183
assert completed_task.status == "succeeded"
176184
assert completed_task.task_type == "taskDeletion"
177-
assert tasks[0].details is not None
178-
assert "uids=1%2C2" in tasks[0].details["originalFilter"]
185+
assert tasks.results[0].details is not None
186+
assert "uids=1%2C2" in tasks.results[0].details["originalFilter"]
179187

180188

181189
@pytest.mark.usefixtures("create_tasks")
@@ -187,8 +195,8 @@ async def test_delete_tasks_index_uids(test_client):
187195

188196
assert deleted_task.status == "succeeded"
189197
assert deleted_task.task_type == "taskDeletion"
190-
assert tasks[0].details is not None
191-
assert "indexUids=1" in tasks[0].details["originalFilter"]
198+
assert tasks.results[0].details is not None
199+
assert "indexUids=1" in tasks.results[0].details["originalFilter"]
192200

193201

194202
@pytest.mark.usefixtures("create_tasks")
@@ -200,8 +208,8 @@ async def test_delete_tasks_types(test_client):
200208

201209
assert deleted_task.status == "succeeded"
202210
assert deleted_task.task_type == "taskDeletion"
203-
assert tasks[0].details is not None
204-
assert "types=taskDeletion" in tasks[0].details["originalFilter"]
211+
assert tasks.results[0].details is not None
212+
assert "types=taskDeletion" in tasks.results[0].details["originalFilter"]
205213

206214

207215
@pytest.mark.usefixtures("create_tasks")
@@ -214,9 +222,10 @@ async def test_delete_tasks_before_enqueued_at(test_client):
214222

215223
assert deleted_task.status == "succeeded"
216224
assert deleted_task.task_type == "taskDeletion"
217-
assert tasks[0].details is not None
225+
assert tasks.results[0].details is not None
218226
assert (
219-
f"beforeEnqueuedAt={quote_plus(before.isoformat())}Z" in tasks[0].details["originalFilter"]
227+
f"beforeEnqueuedAt={quote_plus(before.isoformat())}Z"
228+
in tasks.results[0].details["originalFilter"]
220229
)
221230

222231

@@ -230,8 +239,11 @@ async def test_delete_tasks_after_enqueued_at(test_client):
230239

231240
assert deleted_task.status == "succeeded"
232241
assert deleted_task.task_type == "taskDeletion"
233-
assert tasks[0].details is not None
234-
assert f"afterEnqueuedAt={quote_plus(after.isoformat())}Z" in tasks[0].details["originalFilter"]
242+
assert tasks.results[0].details is not None
243+
assert (
244+
f"afterEnqueuedAt={quote_plus(after.isoformat())}Z"
245+
in tasks.results[0].details["originalFilter"]
246+
)
235247

236248

237249
@pytest.mark.usefixtures("create_tasks")
@@ -244,9 +256,10 @@ async def test_delete_tasks_before_started_at(test_client):
244256

245257
assert deleted_task.status == "succeeded"
246258
assert deleted_task.task_type == "taskDeletion"
247-
assert tasks[0].details is not None
259+
assert tasks.results[0].details is not None
248260
assert (
249-
f"beforeStartedAt={quote_plus(before.isoformat())}Z" in tasks[0].details["originalFilter"]
261+
f"beforeStartedAt={quote_plus(before.isoformat())}Z"
262+
in tasks.results[0].details["originalFilter"]
250263
)
251264

252265

@@ -260,8 +273,11 @@ async def test_delete_tasks_after_finished_at(test_client):
260273

261274
assert deleted_task.status == "succeeded"
262275
assert deleted_task.task_type == "taskDeletion"
263-
assert tasks[0].details is not None
264-
assert f"afterFinishedAt={quote_plus(after.isoformat())}Z" in tasks[0].details["originalFilter"]
276+
assert tasks.results[0].details is not None
277+
assert (
278+
f"afterFinishedAt={quote_plus(after.isoformat())}Z"
279+
in tasks.results[0].details["originalFilter"]
280+
)
265281

266282

267283
@pytest.mark.usefixtures("create_tasks")
@@ -273,36 +289,36 @@ async def test_delete_no_params(test_client):
273289

274290
assert deleted_tasks.status == "succeeded"
275291
assert deleted_tasks.task_type == "taskDeletion"
276-
assert tasks[0].details is not None
292+
assert tasks.results[0].details is not None
277293
assert (
278294
"statuses=canceled%2Cenqueued%2Cfailed%2Cprocessing%2Csucceeded"
279-
in tasks[0].details["originalFilter"]
295+
in tasks.results[0].details["originalFilter"]
280296
)
281297

282298

283299
async def test_get_tasks(empty_index, small_movies):
284300
index = await empty_index()
285301
tasks = await get_tasks(index.http_client)
286-
current_tasks = len(tasks)
302+
current_tasks = len(tasks.results)
287303
response = await index.add_documents(small_movies)
288304
await wait_for_task(index.http_client, response.task_uid)
289305
response = await index.add_documents(small_movies)
290306
await wait_for_task(index.http_client, response.task_uid)
291307
response = await get_tasks(index.http_client)
292-
assert len(response) >= current_tasks
308+
assert len(response.results) >= current_tasks
293309

294310

295311
async def test_get_tasks_for_index(empty_index, small_movies):
296312
index = await empty_index()
297313
tasks = await get_tasks(index.http_client, index_ids=[index.uid])
298-
current_tasks = len(tasks)
314+
current_tasks = len(tasks.results)
299315
response = await index.add_documents(small_movies)
300316
await wait_for_task(index.http_client, response.task_uid)
301317
response = await index.add_documents(small_movies)
302318
await wait_for_task(index.http_client, response.task_uid)
303319
response = await get_tasks(index.http_client, index_ids=[index.uid])
304-
assert len(response) >= current_tasks
305-
uid = set([x.index_uid for x in response])
320+
assert len(response.results) >= current_tasks
321+
uid = set([x.index_uid for x in response.results])
306322
assert len(uid) == 1
307323
assert next(iter(uid)) == index.uid
308324

0 commit comments

Comments
 (0)