Skip to content

Commit 753a826

Browse files
authored
Merge pull request #596 from meilisearch/add_cancel_api_for_v0.30.0
Add task cancel API for v0.30.0
2 parents c54dbf0 + 6d5e36a commit 753a826

File tree

4 files changed

+98
-3
lines changed

4 files changed

+98
-3
lines changed

meilisearch/client.py

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@
1313
from meilisearch.config import Config
1414
from meilisearch.errors import MeiliSearchError
1515
from meilisearch.index import Index
16-
from meilisearch.task import get_task, get_tasks, wait_for_task
16+
from meilisearch.models.task import TaskInfo
17+
from meilisearch.task import cancel_tasks, get_task, get_tasks, wait_for_task
1718

1819

1920
class Client:
@@ -441,6 +442,27 @@ def get_task(self, uid: int) -> dict[str, Any]:
441442
"""
442443
return get_task(self.config, uid)
443444

445+
def cancel_tasks(self, parameters: dict[str, Any]) -> TaskInfo:
446+
"""Cancel a list of enqueued or processing tasks.
447+
448+
Parameters
449+
----------
450+
parameters (optional):
451+
parameters accepted by the cancel tasks route:https://docs.meilisearch.com/reference/api/tasks.html#cancel-tasks.
452+
453+
Returns
454+
-------
455+
task_info:
456+
TaskInfo instance containing information about a task to track the progress of an asynchronous process.
457+
https://docs.meilisearch.com/reference/api/tasks.html#get-one-task
458+
459+
Raises
460+
------
461+
MeiliSearchApiError
462+
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
463+
"""
464+
return cancel_tasks(self.config, parameters=parameters)
465+
444466
def wait_for_task(
445467
self,
446468
uid: int,

meilisearch/models/task.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from __future__ import annotations
22

3-
from typing import Any, Dict, Optional, Union
3+
from typing import Any, Dict, Union
44

55
from camel_converter.pydantic_base import CamelBase
66

@@ -11,7 +11,8 @@ class Task(CamelBase):
1111
status: str
1212
type: str
1313
details: Dict[str, Any]
14-
error: Optional[Dict[str, Any]]
14+
error: Union[Dict[str, Any], None]
15+
canceled_by: Union[int, None]
1516
duration: str
1617
enqueued_at: str
1718
started_at: str

meilisearch/task.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
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
1112

1213

1314
def get_tasks(
@@ -67,6 +68,37 @@ def get_task(config: Config, uid: int) -> dict[str, Any]:
6768
return http.get(f"{config.paths.task}/{uid}")
6869

6970

71+
def cancel_tasks(config: Config, parameters: dict[str, Any]) -> TaskInfo:
72+
"""Cancel a list of enqueued or processing tasks.
73+
74+
Parameters
75+
----------
76+
config:
77+
Config object containing permission and location of Meilisearch.
78+
parameters (optional):
79+
parameters accepted by the cancel tasks https://docs.meilisearch.com/reference/api/tasks.html#cancel-task.
80+
81+
Returns
82+
-------
83+
task_info:
84+
TaskInfo instance containing information about a task to track the progress of an asynchronous process.
85+
https://docs.meilisearch.com/reference/api/tasks.html#get-one-task
86+
87+
Raises
88+
------
89+
MeiliSearchApiError
90+
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
91+
"""
92+
http = HttpRequests(config)
93+
if parameters is None:
94+
parameters = {}
95+
for param in parameters:
96+
if isinstance(parameters[param], list):
97+
parameters[param] = ",".join(parameters[param])
98+
response = http.post(f"{config.paths.task}/cancel?{parse.urlencode(parameters)}")
99+
return TaskInfo(**response)
100+
101+
70102
def wait_for_task(
71103
config: Config,
72104
uid: int,

tests/client/test_client_task_meilisearch.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import pytest
44

5+
from meilisearch.models.task import TaskInfo
56
from tests import common
67

78

@@ -91,3 +92,42 @@ def test_get_task_inexistent(client):
9192
"""Tests getting a task that does not exists."""
9293
with pytest.raises(Exception):
9394
client.get_task("abc")
95+
96+
97+
@pytest.fixture
98+
def create_tasks(empty_index, small_movies):
99+
"""Ensures there are some tasks present for testing."""
100+
index = empty_index()
101+
index.update_ranking_rules(["type", "exactness"])
102+
index.reset_ranking_rules()
103+
index.add_documents(small_movies)
104+
index.add_documents(small_movies)
105+
106+
107+
@pytest.mark.usefixtures("create_tasks")
108+
def test_cancel_tasks(client):
109+
"""Tests cancel a task with uid 1."""
110+
task = client.cancel_tasks({"uids": ["1", "2"]})
111+
client.wait_for_task(task.task_uid)
112+
tasks = client.get_tasks({"types": "taskCancelation"})
113+
114+
assert isinstance(task, TaskInfo)
115+
assert task.task_uid is not None
116+
assert task.index_uid is None
117+
assert task.type == "taskCancelation"
118+
assert "uids" in tasks["results"][0]["details"]["originalFilter"]
119+
assert "uids=1%2C2" in tasks["results"][0]["details"]["originalFilter"]
120+
121+
122+
@pytest.mark.usefixtures("create_tasks")
123+
def test_cancel_every_task(client):
124+
"""Tests cancel every task."""
125+
task = client.cancel_tasks({"statuses": ["enqueued", "processing"]})
126+
client.wait_for_task(task.task_uid)
127+
tasks = client.get_tasks({"types": "taskCancelation"})
128+
129+
assert isinstance(task, TaskInfo)
130+
assert task.task_uid is not None
131+
assert task.index_uid is None
132+
assert task.type == "taskCancelation"
133+
assert "statuses=enqueued%2Cprocessing" in tasks["results"][0]["details"]["originalFilter"]

0 commit comments

Comments
 (0)