diff --git a/.code-samples.meilisearch.yaml b/.code-samples.meilisearch.yaml index eb7a5f79..32e170d9 100644 --- a/.code-samples.meilisearch.yaml +++ b/.code-samples.meilisearch.yaml @@ -623,8 +623,8 @@ get_all_tasks_filtering_1: |- client.get_tasks({'indexUid': ['movies']}) get_all_tasks_filtering_2: |- client.get_tasks({ - 'status': ['succeeded', 'failed'], - 'type': ['documentAdditionOrUpdate'] + 'statuses': ['succeeded', 'failed'], + 'types': ['documentAdditionOrUpdate'] }) get_all_tasks_paginating_1: |- client.get_tasks({ diff --git a/README.md b/README.md index 66f1c5a5..03d1d1f3 100644 --- a/README.md +++ b/README.md @@ -197,7 +197,7 @@ index.search( ## 🤖 Compatibility with Meilisearch -This package only guarantees the compatibility with the [version v0.29.0 of Meilisearch](https://github.com/meilisearch/meilisearch/releases/tag/v0.29.0). +This package only guarantees the compatibility with the [version v0.30.0 of Meilisearch](https://github.com/meilisearch/meilisearch/releases/tag/v0.30.0). ## 💡 Learn more diff --git a/meilisearch/client.py b/meilisearch/client.py index 16f73e97..1b2396e4 100644 --- a/meilisearch/client.py +++ b/meilisearch/client.py @@ -13,7 +13,8 @@ from meilisearch.config import Config from meilisearch.errors import MeiliSearchError from meilisearch.index import Index -from meilisearch.task import get_task, get_tasks, wait_for_task +from meilisearch.models.task import TaskInfo +from meilisearch.task import cancel_tasks, delete_tasks, get_task, get_tasks, wait_for_task class Client: @@ -399,6 +400,27 @@ def create_dump(self) -> dict[str, str]: """ return self.http.post(self.config.paths.dumps) + def swap_indexes(self, parameters: list[dict[str, list[str]]]) -> TaskInfo: + """Swap two indexes. + + Parameters + ---------- + indexes: + List of indexes to swap (ex: [{"indexes": ["indexA", "indexB"]}). + + Returns + ------- + task_info: + TaskInfo instance containing information about a task to track the progress of an asynchronous process. + https://docs.meilisearch.com/reference/api/tasks.html#get-one-task + + Raises + ------ + MeiliSearchApiError + 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 + """ + return TaskInfo(**self.http.post(self.config.paths.swap, parameters)) + def get_tasks( self, parameters: dict[str, Any] | None = None ) -> dict[str, list[dict[str, Any]]]: @@ -407,8 +429,7 @@ def get_tasks( Parameters ---------- parameters (optional): - parameters accepted by the get tasks route: https://docs.meilisearch.com/reference/api/tasks.html#get-all-tasks. - `indexUid` should be set as a List. + parameters accepted by the get tasks route: https://docs.meilisearch.com/reference/api/tasks.html#get-tasks. Returns ------- @@ -442,6 +463,46 @@ def get_task(self, uid: int) -> dict[str, Any]: """ return get_task(self.config, uid) + def cancel_tasks(self, parameters: dict[str, Any]) -> TaskInfo: + """Cancel a list of enqueued or processing tasks. + + Parameters + ---------- + parameters (optional): + parameters accepted by the cancel tasks route:https://docs.meilisearch.com/reference/api/tasks.html#cancel-tasks. + + Returns + ------- + task_info: + TaskInfo instance containing information about a task to track the progress of an asynchronous process. + https://docs.meilisearch.com/reference/api/tasks.html#get-one-task + + Raises + ------ + MeiliSearchApiError + 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 + """ + return cancel_tasks(self.config, parameters=parameters) + + def delete_tasks(self, parameters: dict[str, Any]) -> TaskInfo: + """Delete a list of finished tasks. + + Parameters + ---------- + parameters (optional): + parameters accepted by the delete tasks route:https://docs.meilisearch.com/reference/api/tasks.html#delete-task. + Returns + ------- + task_info: + TaskInfo instance containing information about a task to track the progress of an asynchronous process. + https://docs.meilisearch.com/reference/api/tasks.html#get-one-task + Raises + ------ + MeiliSearchApiError + 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 + """ + return delete_tasks(self.config, parameters=parameters) + def wait_for_task( self, uid: int, diff --git a/meilisearch/config.py b/meilisearch/config.py index d48dc323..12d0cae5 100644 --- a/meilisearch/config.py +++ b/meilisearch/config.py @@ -29,6 +29,7 @@ class Paths: dumps = "dumps" pagination = "pagination" faceting = "faceting" + swap = "swap-indexes" def __init__(self, url: str, api_key: str | None = None, timeout: int | None = None) -> None: """ diff --git a/meilisearch/index.py b/meilisearch/index.py index 02ec031e..87f8a010 100644 --- a/meilisearch/index.py +++ b/meilisearch/index.py @@ -49,6 +49,12 @@ def __init__( def delete(self) -> dict[str, Any]: """Delete the index. + Returns + ------- + task_info: + TaskInfo instance containing information about a task to track the progress of an asynchronous process. + https://docs.meilisearch.com/reference/api/tasks.html#get-one-task + Raises ------ MeiliSearchApiError @@ -67,8 +73,8 @@ def update(self, primary_key: str) -> dict[str, Any]: Returns ------- - task: - Dictionary containing a task to track the informations about the progress of an asynchronous process. + task_info: + TaskInfo instance containing information about a task to track the progress of an asynchronous process. https://docs.meilisearch.com/reference/api/tasks.html#get-one-task Raises @@ -116,8 +122,8 @@ def create(config: Config, uid: str, options: dict[str, Any] | None = None) -> d Returns ------- - task: - Dictionary containing a task to track the informations about the progress of an asynchronous process. + task_info: + TaskInfo instance containing information about a task to track the progress of an asynchronous process. https://docs.meilisearch.com/reference/api/tasks.html#get-one-task Raises @@ -136,8 +142,7 @@ def get_tasks(self, parameters: dict[str, Any] | None = None) -> TaskResults: Parameters ---------- parameters (optional): - parameters accepted by the get tasks route: https://docs.meilisearch.com/reference/api/tasks.html#get-all-tasks. - `indexUid` should be set as a List. + parameters accepted by the get tasks route: https://docs.meilisearch.com/reference/api/tasks.html#get-tasks. Returns ------- @@ -154,9 +159,9 @@ def get_tasks(self, parameters: dict[str, Any] | None = None) -> TaskResults: 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 """ if parameters is not None: - parameters.setdefault("indexUid", []).append(self.uid) + parameters.setdefault("indexUids", []).append(self.uid) else: - parameters = {"indexUid": [self.uid]} + parameters = {"indexUids": [self.uid]} tasks = get_tasks(self.config, parameters=parameters) return TaskResults(tasks) @@ -756,8 +761,8 @@ def update_settings(self, body: dict[str, Any]) -> dict[str, Any]: Returns ------- - task: - Dictionary containing a task to track the informations about the progress of an asynchronous process. + task_info: + TaskInfo instance containing information about a task to track the progress of an asynchronous process. https://docs.meilisearch.com/reference/api/tasks.html#get-one-task Raises @@ -776,8 +781,8 @@ def reset_settings(self) -> dict[str, Any]: Returns ------- - task: - Dictionary containing a task to track the informations about the progress of an asynchronous process. + task_info: + TaskInfo instance containing information about a task to track the progress of an asynchronous process. https://docs.meilisearch.com/reference/api/tasks.html#get-one-task Raises @@ -814,8 +819,8 @@ def update_ranking_rules(self, body: list[str]) -> dict[str, Any]: Returns ------- - task: - Dictionary containing a task to track the informations about the progress of an asynchronous process. + task_info: + TaskInfo instance containing information about a task to track the progress of an asynchronous process. https://docs.meilisearch.com/reference/api/tasks.html#get-one-task Raises @@ -830,8 +835,8 @@ def reset_ranking_rules(self) -> dict[str, Any]: Returns ------- - task: - Dictionary containing a task to track the informations about the progress of an asynchronous process. + task_info: + TaskInfo instance containing information about a task to track the progress of an asynchronous process. https://docs.meilisearch.com/reference/api/tasks.html#get-one-task Raises @@ -870,8 +875,8 @@ def update_distinct_attribute(self, body: dict[str, Any]) -> dict[str, Any]: Returns ------- - task: - Dictionary containing a task to track the informations about the progress of an asynchronous process. + task_info: + TaskInfo instance containing information about a task to track the progress of an asynchronous process. https://docs.meilisearch.com/reference/api/tasks.html#get-one-task Raises @@ -886,8 +891,8 @@ def reset_distinct_attribute(self) -> dict[str, Any]: Returns ------- - task: - Dictionary containing a task to track the informations about the progress of an asynchronous process. + task_info: + TaskInfo instance containing information about a task to track the progress of an asynchronous process. https://docs.meilisearch.com/reference/api/tasks.html#get-one-task Raises @@ -926,8 +931,8 @@ def update_searchable_attributes(self, body: list[str]) -> dict[str, Any]: Returns ------- - task: - Dictionary containing a task to track the informations about the progress of an asynchronous process. + task_info: + TaskInfo instance containing information about a task to track the progress of an asynchronous process. https://docs.meilisearch.com/reference/api/tasks.html#get-one-task Raises @@ -942,8 +947,8 @@ def reset_searchable_attributes(self) -> dict[str, Any]: Returns ------- - task: - Dictionary containing a task to track the informations about the progress of an asynchronous process. + task_info: + TaskInfo instance containing information about a task to track the progress of an asynchronous process. https://docs.meilisearch.com/reference/api/tasks.html#get-one-task Raises @@ -982,8 +987,8 @@ def update_displayed_attributes(self, body: list[str]) -> dict[str, Any]: Returns ------- - task: - Dictionary containing a task to track the informations about the progress of an asynchronous process. + task_info: + TaskInfo instance containing information about a task to track the progress of an asynchronous process. https://docs.meilisearch.com/reference/api/tasks.html#get-one-task Raises @@ -998,8 +1003,8 @@ def reset_displayed_attributes(self) -> dict[str, Any]: Returns ------- - task: - Dictionary containing a task to track the informations about the progress of an asynchronous process. + task_info: + TaskInfo instance containing information about a task to track the progress of an asynchronous process. https://docs.meilisearch.com/reference/api/tasks.html#get-one-task Raises @@ -1038,8 +1043,8 @@ def update_stop_words(self, body: list[str]) -> dict[str, Any]: Returns ------- - task: - Dictionary containing a task to track the informations about the progress of an asynchronous process. + task_info: + TaskInfo instance containing information about a task to track the progress of an asynchronous process. https://docs.meilisearch.com/reference/api/tasks.html#get-one-task Raises @@ -1054,8 +1059,8 @@ def reset_stop_words(self) -> dict[str, Any]: Returns ------- - task: - Dictionary containing a task to track the informations about the progress of an asynchronous process. + task_info: + TaskInfo instance containing information about a task to track the progress of an asynchronous process. https://docs.meilisearch.com/reference/api/tasks.html#get-one-task Raises @@ -1094,8 +1099,8 @@ def update_synonyms(self, body: dict[str, list[str]]) -> dict[str, Any]: Returns ------- - task: - Dictionary containing a task to track the informations about the progress of an asynchronous process. + task_info: + TaskInfo instance containing information about a task to track the progress of an asynchronous process. https://docs.meilisearch.com/reference/api/tasks.html#get-one-task Raises @@ -1110,8 +1115,8 @@ def reset_synonyms(self) -> dict[str, Any]: Returns ------- - task: - Dictionary containing a task to track the informations about the progress of an asynchronous process. + task_info: + TaskInfo instance containing information about a task to track the progress of an asynchronous process. https://docs.meilisearch.com/reference/api/tasks.html#get-one-task Raises @@ -1150,8 +1155,8 @@ def update_filterable_attributes(self, body: list[str]) -> dict[str, Any]: Returns ------- - task: - Dictionary containing a task to track the informations about the progress of an asynchronous process. + task_info: + TaskInfo instance containing information about a task to track the progress of an asynchronous process. https://docs.meilisearch.com/reference/api/tasks.html#get-one-task Raises @@ -1166,8 +1171,8 @@ def reset_filterable_attributes(self) -> dict[str, Any]: Returns ------- - task: - Dictionary containing a task to track the informations about the progress of an asynchronous process. + task_info: + TaskInfo instance containing information about a task to track the progress of an asynchronous process. https://docs.meilisearch.com/reference/api/tasks.html#get-one-task Raises @@ -1206,8 +1211,8 @@ def update_sortable_attributes(self, body: list[str]) -> dict[str, Any]: Returns ------- - task: - Dictionary containing a task to track the informations about the progress of an asynchronous process. + task_info: + TaskInfo instance containing information about a task to track the progress of an asynchronous process. https://docs.meilisearch.com/reference/api/tasks.html#get-one-task Raises @@ -1222,8 +1227,8 @@ def reset_sortable_attributes(self) -> dict[str, Any]: Returns ------- - task: - Dictionary containing a task to track the informations about the progress of an asynchronous process. + task_info: + TaskInfo instance containing information about a task to track the progress of an asynchronous process. https://docs.meilisearch.com/reference/api/tasks.html#get-one-task Raises @@ -1262,8 +1267,8 @@ def update_typo_tolerance(self, body: dict[str, Any]) -> dict[str, Any]: Returns ------- - task: - Dictionary containing a task to track the informations about the progress of an asynchronous process. + task_info: + TaskInfo instance containing information about a task to track the progress of an asynchronous process. https://docs.meilisearch.com/reference/api/tasks.html#get-one-task Raises @@ -1278,8 +1283,8 @@ def reset_typo_tolerance(self) -> dict[str, Any]: Returns ------- - task: - Dictionary containing a task to track the informations about the progress of an asynchronous process. + task_info: + TaskInfo instance containing information about a task to track the progress of an asynchronous process. https://docs.meilisearch.com/reference/api/tasks.html#get-one-task Raises @@ -1317,8 +1322,8 @@ def update_pagination_settings(self, body: dict[str, Any]) -> dict[str, Any]: Returns ------- - task: - Dictionary containing a task to track the informations about the progress of an asynchronous process. + task_info: + TaskInfo instance containing information about a task to track the progress of an asynchronous process. https://docs.meilisearch.com/reference/api/tasks.html#get-one-task Raises @@ -1335,8 +1340,8 @@ def reset_pagination_settings(self) -> dict[str, Any]: Returns ------- - task: - Dictionary containing a task to track the informations about the progress of an asynchronous process. + task_info: + TaskInfo instance containing information about a task to track the progress of an asynchronous process. https://docs.meilisearch.com/reference/api/tasks.html#get-one-task Raises @@ -1373,8 +1378,8 @@ def update_faceting_settings(self, body: dict[str, Any]) -> dict[str, Any]: Returns ------- - task: - Dictionary containing a task to track the informations about the progress of an asynchronous process. + task_info: + TaskInfo instance containing information about a task to track the progress of an asynchronous process. https://docs.meilisearch.com/reference/api/tasks.html#get-one-task Raises @@ -1389,8 +1394,8 @@ def reset_faceting_settings(self) -> dict[str, Any]: Returns ------- - task: - Dictionary containing a task to track the informations about the progress of an asynchronous process. + task_info: + TaskInfo instance containing information about a task to track the progress of an asynchronous process. https://docs.meilisearch.com/reference/api/tasks.html#get-one-task Raises diff --git a/meilisearch/models/task.py b/meilisearch/models/task.py index 02572912..c69e84c6 100644 --- a/meilisearch/models/task.py +++ b/meilisearch/models/task.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import Any, Dict, Optional, Union +from typing import Any, Dict, Union from camel_converter.pydantic_base import CamelBase @@ -11,7 +11,8 @@ class Task(CamelBase): status: str type: str details: Dict[str, Any] - error: Optional[Dict[str, Any]] + error: Union[Dict[str, Any], None] + canceled_by: Union[int, None] duration: str enqueued_at: str started_at: str diff --git a/meilisearch/task.py b/meilisearch/task.py index 8358f5ee..7e94b0df 100644 --- a/meilisearch/task.py +++ b/meilisearch/task.py @@ -8,6 +8,7 @@ from meilisearch._httprequests import HttpRequests from meilisearch.config import Config from meilisearch.errors import MeiliSearchTimeoutError +from meilisearch.models.task import TaskInfo def get_tasks( @@ -20,8 +21,7 @@ def get_tasks( config: Config object containing permission and location of Meilisearch. parameters (optional): - parameters accepted by the get tasks route: https://docs.meilisearch.com/reference/api/tasks.html#get-all-tasks. - `indexUid` should be set as a List. + parameters accepted by the get tasks route: https://docs.meilisearch.com/reference/api/tasks.html#get-tasks. Returns ------- @@ -68,6 +68,65 @@ def get_task(config: Config, uid: int) -> dict[str, Any]: return http.get(f"{config.paths.task}/{uid}") +def cancel_tasks(config: Config, parameters: dict[str, Any]) -> TaskInfo: + """Cancel a list of enqueued or processing tasks. + + Parameters + ---------- + config: + Config object containing permission and location of Meilisearch. + parameters (optional): + parameters accepted by the cancel tasks https://docs.meilisearch.com/reference/api/tasks.html#cancel-task. + + Returns + ------- + task_info: + TaskInfo instance containing information about a task to track the progress of an asynchronous process. + https://docs.meilisearch.com/reference/api/tasks.html#get-one-task + + Raises + ------ + MeiliSearchApiError + 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 + """ + http = HttpRequests(config) + if parameters is None: + parameters = {} + for param in parameters: + if isinstance(parameters[param], list): + parameters[param] = ",".join(parameters[param]) + response = http.post(f"{config.paths.task}/cancel?{parse.urlencode(parameters)}") + return TaskInfo(**response) + + +def delete_tasks(config: Config, parameters: dict[str, Any] | None = None) -> TaskInfo: + """Delete a list of enqueued or processing tasks. + Parameters + ---------- + config: + Config object containing permission and location of Meilisearch. + parameters (optional): + parameters accepted by the delete tasks route:https://docs.meilisearch.com/reference/api/tasks.html#delete-task. + Returns + ------- + task_info: + TaskInfo instance containing information about a task to track the progress of an asynchronous process. + https://docs.meilisearch.com/reference/api/tasks.html#get-one-task + Raises + ------ + MeiliSearchApiError + 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 + """ + http = HttpRequests(config) + if parameters is None: + parameters = {} + for param in parameters: + if isinstance(parameters[param], list): + parameters[param] = ",".join(parameters[param]) + response = http.delete(f"{config.paths.task}?{parse.urlencode(parameters)}") + return TaskInfo(**response) + + def wait_for_task( config: Config, uid: int, diff --git a/tests/client/test_client_swap_meilisearch.py b/tests/client/test_client_swap_meilisearch.py new file mode 100644 index 00000000..558a99b3 --- /dev/null +++ b/tests/client/test_client_swap_meilisearch.py @@ -0,0 +1,59 @@ +# pylint: disable=invalid-name + +import pytest + +from meilisearch.errors import MeiliSearchApiError + + +def test_swap_indexes(client, empty_index): + """Tests swap two indexes.""" + indexA = empty_index("index_A") + indexB = empty_index("index_B") + taskA = indexA.add_documents([{"id": 1, "title": "index_A"}]) + taskB = indexB.add_documents([{"id": 1, "title": "index_B"}]) + client.wait_for_task(taskA.task_uid) + client.wait_for_task(taskB.task_uid) + swapTask = client.swap_indexes( + [ + { + "indexes": [indexA.uid, indexB.uid], + }, + ] + ) + task = client.wait_for_task(swapTask.task_uid) + docA = client.index(indexA.uid).get_document(1) + docB = client.index(indexB.uid).get_document(1) + + assert docA.title == indexB.uid + assert docB.title == indexA.uid + assert task["type"] == "indexSwap" + assert "swaps" in task["details"] + + +def test_swap_indexes_with_one_that_does_not_exist(client, empty_index): + """Tests swap indexes with one that does not exist.""" + index = empty_index("index_A") + swapTask = client.swap_indexes( + [ + { + "indexes": [index.uid, "does_not_exist"], + }, + ] + ) + task = client.wait_for_task(swapTask.task_uid) + + assert swapTask.type == "indexSwap" + assert task["error"]["code"] == "index_not_found" + + +def test_swap_indexes_with_itself(client, empty_index): + """Tests swap indexes with itself.""" + index = empty_index() + with pytest.raises(MeiliSearchApiError): + client.swap_indexes( + [ + { + "indexes": [index.uid, index.uid], + }, + ] + ) diff --git a/tests/client/test_client_task_meilisearch.py b/tests/client/test_client_task_meilisearch.py index 2134572e..78dbb8a1 100644 --- a/tests/client/test_client_task_meilisearch.py +++ b/tests/client/test_client_task_meilisearch.py @@ -2,6 +2,7 @@ import pytest +from meilisearch.models.task import TaskInfo from tests import common @@ -29,17 +30,42 @@ def test_get_tasks_empty_parameters(client): assert isinstance(tasks["results"], list) -def test_get_tasks_with_parameters(client): +def test_get_tasks_with_parameters(client, empty_index): """Tests getting the global tasks list after populating an index.""" - tasks = client.get_tasks({"limit": 1, "from": 1}) + empty_index() + tasks = client.get_tasks({"limit": 1}) assert isinstance(tasks, dict) assert len(tasks["results"]) == 1 - assert tasks["results"][0]["uid"] == 1 -def test_get_tasks_with_index_uid(client): +def test_get_tasks_with_all_plural_parameters(client, empty_index): + """Tests getting the global tasks list after populating an index.""" + empty_index() + tasks = client.get_tasks( + {"indexUids": [common.INDEX_UID], "statuses": ["succeeded"], "types": ["indexCreation"]} + ) + assert isinstance(tasks, dict) + assert len(tasks["results"]) >= 1 + + +def test_get_tasks_with_date_parameters(client, empty_index): """Tests getting the global tasks list after populating an index.""" - tasks = client.get_tasks({"limit": 1, "indexUid": [common.INDEX_UID]}) + empty_index() + tasks = client.get_tasks( + { + "beforeEnqueuedAt": "2042-04-02T00:42:42Z", + "beforeStartedAt": "2042-04-02T00:42:42Z", + "beforeFinishedAt": "2042-04-02T00:42:42Z", + } + ) + assert isinstance(tasks, dict) + assert len(tasks["results"]) > 1 + + +def test_get_tasks_with_index_uid(client, empty_index): + """Tests getting the global tasks list after populating an index.""" + empty_index() + tasks = client.get_tasks({"limit": 1, "indexUids": [common.INDEX_UID]}) assert isinstance(tasks, dict) assert len(tasks["results"]) == 1 @@ -50,7 +76,7 @@ def test_get_task(client): client.wait_for_task(response["taskUid"]) task = client.get_task(response["taskUid"]) assert isinstance(task, dict) - assert len(task) == 9 + assert len(task) == 11 assert "uid" in task assert "indexUid" in task assert "status" in task @@ -66,3 +92,78 @@ def test_get_task_inexistent(client): """Tests getting a task that does not exists.""" with pytest.raises(Exception): client.get_task("abc") + + +@pytest.fixture +def create_tasks(empty_index, small_movies): + """Ensures there are some tasks present for testing.""" + index = empty_index() + index.update_ranking_rules(["type", "exactness"]) + index.reset_ranking_rules() + index.add_documents(small_movies) + index.add_documents(small_movies) + + +@pytest.mark.usefixtures("create_tasks") +def test_cancel_tasks(client): + """Tests cancel a task with uid 1.""" + task = client.cancel_tasks({"uids": ["1", "2"]}) + client.wait_for_task(task.task_uid) + tasks = client.get_tasks({"types": "taskCancelation"}) + + assert isinstance(task, TaskInfo) + assert task.task_uid is not None + assert task.index_uid is None + assert task.type == "taskCancelation" + assert "uids" in tasks["results"][0]["details"]["originalFilter"] + assert "uids=1%2C2" in tasks["results"][0]["details"]["originalFilter"] + + +@pytest.mark.usefixtures("create_tasks") +def test_cancel_every_task(client): + """Tests cancel every task.""" + task = client.cancel_tasks({"statuses": ["enqueued", "processing"]}) + client.wait_for_task(task.task_uid) + tasks = client.get_tasks({"types": "taskCancelation"}) + + assert isinstance(task, TaskInfo) + assert task.task_uid is not None + assert task.index_uid is None + assert task.type == "taskCancelation" + assert "statuses=enqueued%2Cprocessing" in tasks["results"][0]["details"]["originalFilter"] + + +def test_delete_tasks_by_uid(client, empty_index, small_movies): + """Tests getting a task of an inexistent operation.""" + index = empty_index() + task_addition = index.add_documents(small_movies) + task_deleted = client.delete_tasks({"uids": task_addition.task_uid}) + client.wait_for_task(task_deleted.task_uid) + with pytest.raises(Exception): + client.get_task(task_addition.task_uid) + task = client.get_task(task_deleted.task_uid) + + assert isinstance(task_deleted, TaskInfo) + assert task_deleted.task_uid is not None + assert task_deleted.index_uid is None + assert task_deleted.type == "taskDeletion" + assert "uids" in task["details"]["originalFilter"] + assert f"uids={task_addition.task_uid}" in task["details"]["originalFilter"] + + +def test_delete_all_tasks(client): + tasks_before = client.get_tasks() + task = client.delete_tasks({"statuses": ["succeeded", "failed", "canceled"]}) + client.wait_for_task(task.task_uid) + tasks_after = client.get_tasks() + + assert isinstance(task, TaskInfo) + assert task.task_uid is not None + assert task.index_uid is None + assert task.type == "taskDeletion" + assert len(tasks_after["results"]) >= 1 + assert len(tasks_before["results"]) == len(tasks_after["results"]) + assert ( + "statuses=succeeded%2Cfailed%2Ccanceled" + in tasks_after["results"][0]["details"]["originalFilter"] + ) diff --git a/tests/conftest.py b/tests/conftest.py index 2911e619..6ff9e490 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -29,6 +29,15 @@ def clear_indexes(client): client.wait_for_task(task["taskUid"]) +@fixture(autouse=True) +def clear_all_tasks(client): + """ + Auto-clears the tasks after each test function run. + Makes all the test functions independent. + """ + client.delete_tasks({"statuses": ["succeeded", "failed", "canceled"]}) + + @fixture(scope="function") def indexes_sample(client): indexes = [] diff --git a/tests/index/test_index_search_meilisearch.py b/tests/index/test_index_search_meilisearch.py index e9d28402..9514a3cc 100644 --- a/tests/index/test_index_search_meilisearch.py +++ b/tests/index/test_index_search_meilisearch.py @@ -6,6 +6,8 @@ def test_basic_search(index_with_documents): response = index_with_documents().search("How to Train Your Dragon") assert isinstance(response, dict) assert response["hits"][0]["id"] == "166428" + assert response["estimatedTotalHits"] is not None + assert "hitsPerPage" is not response 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): assert isinstance(response, dict) assert len(response["hits"]) > 1 + + +def test_custom_search_params_with_pagination_parameters(index_with_documents): + """Tests search with matching strategy param set to last""" + response = index_with_documents().search("", {"hitsPerPage": 1, "page": 1}) + + assert isinstance(response, dict) + assert len(response["hits"]) == 1 + assert response["hitsPerPage"] == 1 + assert response["page"] == 1 + assert response["totalPages"] is not None + assert response["totalHits"] is not None + assert "estimatedTotalHits" is not response + + +def test_custom_search_params_with_pagination_parameters_at_zero(index_with_documents): + """Tests search with matching strategy param set to last""" + response = index_with_documents().search("", {"hitsPerPage": 0, "page": 0}) + + assert isinstance(response, dict) + assert len(response["hits"]) == 0 + assert response["hitsPerPage"] == 0 + assert response["page"] == 0 + assert response["totalPages"] is not None + assert response["totalHits"] is not None + assert "estimatedTotalHits" is not response diff --git a/tests/index/test_index_task_meilisearch.py b/tests/index/test_index_task_meilisearch.py index 4bc0be67..46702667 100644 --- a/tests/index/test_index_task_meilisearch.py +++ b/tests/index/test_index_task_meilisearch.py @@ -37,7 +37,7 @@ def test_get_tasks_with_parameters(empty_index): def test_get_tasks_with_index_uid(empty_index): """Tests getting the tasks list of a populated index.""" index = empty_index() - tasks = index.get_tasks({"limit": 1, "indexUid": [common.INDEX_UID]}) + tasks = index.get_tasks({"limit": 1, "indexUids": [common.INDEX_UID]}) assert isinstance(tasks, TaskResults) assert len(tasks.results) == 1