Skip to content

Commit 55ee4ae

Browse files
authored
Merge branch 'bump-meilisearch-v0.30.0' into add_swap_indexes_feature_for_v0.30.0
2 parents 2e800ec + 441b507 commit 55ee4ae

File tree

5 files changed

+125
-3
lines changed

5 files changed

+125
-3
lines changed

meilisearch/client.py

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
from meilisearch.errors import MeiliSearchError
1515
from meilisearch.index import Index
1616
from meilisearch.models.task import TaskInfo
17-
from meilisearch.task import get_task, get_tasks, wait_for_task
17+
from meilisearch.task import cancel_tasks, get_task, get_tasks, wait_for_task
1818

1919

2020
class Client:
@@ -463,6 +463,27 @@ def get_task(self, uid: int) -> dict[str, Any]:
463463
"""
464464
return get_task(self.config, uid)
465465

466+
def cancel_tasks(self, parameters: dict[str, Any]) -> TaskInfo:
467+
"""Cancel a list of enqueued or processing tasks.
468+
469+
Parameters
470+
----------
471+
parameters (optional):
472+
parameters accepted by the cancel tasks route:https://docs.meilisearch.com/reference/api/tasks.html#cancel-tasks.
473+
474+
Returns
475+
-------
476+
task_info:
477+
TaskInfo instance containing information about a task to track the progress of an asynchronous process.
478+
https://docs.meilisearch.com/reference/api/tasks.html#get-one-task
479+
480+
Raises
481+
------
482+
MeiliSearchApiError
483+
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
484+
"""
485+
return cancel_tasks(self.config, parameters=parameters)
486+
466487
def wait_for_task(
467488
self,
468489
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"]

tests/index/test_index_search_meilisearch.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ def test_basic_search(index_with_documents):
66
response = index_with_documents().search("How to Train Your Dragon")
77
assert isinstance(response, dict)
88
assert response["hits"][0]["id"] == "166428"
9+
assert response["estimatedTotalHits"] is not None
10+
assert "hitsPerPage" is not response
911

1012

1113
def test_basic_search_with_empty_params(index_with_documents):
@@ -413,3 +415,29 @@ def test_custom_search_params_with_matching_strategy_last(index_with_documents):
413415

414416
assert isinstance(response, dict)
415417
assert len(response["hits"]) > 1
418+
419+
420+
def test_custom_search_params_with_pagination_parameters(index_with_documents):
421+
"""Tests search with matching strategy param set to last"""
422+
response = index_with_documents().search("", {"hitsPerPage": 1, "page": 1})
423+
424+
assert isinstance(response, dict)
425+
assert len(response["hits"]) == 1
426+
assert response["hitsPerPage"] == 1
427+
assert response["page"] == 1
428+
assert response["totalPages"] is not None
429+
assert response["totalHits"] is not None
430+
assert "estimatedTotalHits" is not response
431+
432+
433+
def test_custom_search_params_with_pagination_parameters_at_zero(index_with_documents):
434+
"""Tests search with matching strategy param set to last"""
435+
response = index_with_documents().search("", {"hitsPerPage": 0, "page": 0})
436+
437+
assert isinstance(response, dict)
438+
assert len(response["hits"]) == 0
439+
assert response["hitsPerPage"] == 0
440+
assert response["page"] == 0
441+
assert response["totalPages"] is not None
442+
assert response["totalHits"] is not None
443+
assert "estimatedTotalHits" is not response

0 commit comments

Comments
 (0)