From 3442fae97833693e2809993081c48b2fd2b6fe9f Mon Sep 17 00:00:00 2001 From: Paul Sanders Date: Wed, 10 May 2023 07:43:37 -0400 Subject: [PATCH 1/2] Return task instances from task methods instead of dicts --- meilisearch/client.py | 14 ++--- meilisearch/index.py | 9 +-- meilisearch/task.py | 24 ++++---- tests/client/test_client_dumps.py | 4 +- tests/client/test_client_swap_meilisearch.py | 6 +- tests/client/test_client_task_meilisearch.py | 59 +++++++++----------- 6 files changed, 51 insertions(+), 65 deletions(-) diff --git a/meilisearch/client.py b/meilisearch/client.py index 2ea9ed7a..5cdb83be 100644 --- a/meilisearch/client.py +++ b/meilisearch/client.py @@ -16,7 +16,7 @@ from meilisearch.errors import MeilisearchError from meilisearch.index import Index from meilisearch.models.key import Key, KeysResults -from meilisearch.models.task import TaskInfo +from meilisearch.models.task import Task, TaskInfo, TaskResults from meilisearch.task import TaskHandler @@ -466,9 +466,7 @@ def swap_indexes(self, parameters: List[Dict[str, List[str]]]) -> TaskInfo: """ return TaskInfo(**self.http.post(self.config.paths.swap, parameters)) - def get_tasks( - self, parameters: Optional[Dict[str, Any]] = None - ) -> Dict[str, List[Dict[str, Any]]]: + def get_tasks(self, parameters: Optional[Dict[str, Any]] = None) -> TaskResults: """Get all tasks. Parameters @@ -479,7 +477,7 @@ def get_tasks( Returns ------- task: - Dictionary with limit, from, next and results containing a list of all enqueued, processing, succeeded or failed tasks. + Limit, from, next and results containing a list of all enqueued, processing, succeeded or failed tasks. Raises ------ @@ -488,7 +486,7 @@ def get_tasks( """ return self.task_handler.get_tasks(parameters=parameters) - def get_task(self, uid: int) -> Dict[str, Any]: + def get_task(self, uid: int) -> Task: """Get one task. Parameters @@ -499,7 +497,7 @@ def get_task(self, uid: int) -> Dict[str, Any]: Returns ------- task: - Dictionary containing information about the processed asynchronous task. + Information about the processed asynchronous task. Raises ------ @@ -553,7 +551,7 @@ def wait_for_task( uid: int, timeout_in_ms: int = 5000, interval_in_ms: int = 50, - ) -> Dict[str, Any]: + ) -> Task: """Wait until Meilisearch processes a task until it fails or succeeds. Parameters diff --git a/meilisearch/index.py b/meilisearch/index.py index eaabc3f4..16dfb74b 100644 --- a/meilisearch/index.py +++ b/meilisearch/index.py @@ -170,8 +170,7 @@ def get_tasks(self, parameters: Optional[Dict[str, Any]] = None) -> TaskResults: else: parameters = {"indexUids": [self.uid]} - tasks = self.task_handler.get_tasks(parameters=parameters) - return TaskResults(tasks) + return self.task_handler.get_tasks(parameters=parameters) def get_task(self, uid: int) -> Task: """Get one task through the route of a specific index. @@ -191,8 +190,7 @@ def get_task(self, uid: int) -> Task: 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 """ - task = self.task_handler.get_task(uid) - return Task(**task) + return self.task_handler.get_task(uid) def wait_for_task( self, @@ -221,8 +219,7 @@ def wait_for_task( MeilisearchTimeoutError 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 """ - task = self.task_handler.wait_for_task(uid, timeout_in_ms, interval_in_ms) - return Task(**task) + return self.task_handler.wait_for_task(uid, timeout_in_ms, interval_in_ms) def get_stats(self) -> IndexStats: """Get stats of the index. diff --git a/meilisearch/task.py b/meilisearch/task.py index d9d4ddcd..b79de9e2 100644 --- a/meilisearch/task.py +++ b/meilisearch/task.py @@ -2,13 +2,13 @@ from datetime import datetime from time import sleep -from typing import Any, Dict, List, Optional +from typing import Any, Dict, Optional from urllib import parse from meilisearch._httprequests import HttpRequests from meilisearch.config import Config from meilisearch.errors import MeilisearchTimeoutError -from meilisearch.models.task import TaskInfo +from meilisearch.models.task import Task, TaskInfo, TaskResults class TaskHandler: @@ -27,9 +27,7 @@ def __init__(self, config: Config): self.config = config self.http = HttpRequests(config) - def get_tasks( - self, parameters: Optional[Dict[str, Any]] = None - ) -> Dict[str, List[Dict[str, Any]]]: + def get_tasks(self, parameters: Optional[Dict[str, Any]] = None) -> TaskResults: """Get all tasks. Parameters @@ -40,7 +38,7 @@ def get_tasks( Returns ------- task: - Dictionary with limit, from, next and results containing a list of all enqueued, processing, succeeded or failed tasks. + Limit, from, next and results containing a list of all enqueued, processing, succeeded or failed tasks. Raises ------ @@ -52,9 +50,10 @@ def get_tasks( for param in parameters: if isinstance(parameters[param], list): parameters[param] = ",".join(parameters[param]) - return self.http.get(f"{self.config.paths.task}?{parse.urlencode(parameters)}") + tasks = self.http.get(f"{self.config.paths.task}?{parse.urlencode(parameters)}") + return TaskResults(tasks) - def get_task(self, uid: int) -> Dict[str, Any]: + def get_task(self, uid: int) -> Task: """Get one task. Parameters @@ -72,7 +71,8 @@ def get_task(self, uid: int) -> Dict[str, Any]: 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 self.http.get(f"{self.config.paths.task}/{uid}") + task = self.http.get(f"{self.config.paths.task}/{uid}") + return Task(**task) def cancel_tasks(self, parameters: Optional[Dict[str, Any]] = None) -> TaskInfo: """Cancel a list of enqueued or processing tasks. @@ -132,7 +132,7 @@ def wait_for_task( uid: int, timeout_in_ms: int = 5000, interval_in_ms: int = 50, - ) -> Dict[str, Any]: + ) -> Task: """Wait until the task fails or succeeds in Meilisearch. Parameters @@ -147,7 +147,7 @@ def wait_for_task( Returns ------- task: - Dictionary containing information about the processed asynchronous task. + Information about the processed asynchronous task. Raises ------ @@ -158,7 +158,7 @@ def wait_for_task( elapsed_time = 0.0 while elapsed_time < timeout_in_ms: task = self.get_task(uid) - if task["status"] not in ("enqueued", "processing"): + if task.status not in ("enqueued", "processing"): return task sleep(interval_in_ms / 1000) time_delta = datetime.now() - start_time diff --git a/tests/client/test_client_dumps.py b/tests/client/test_client_dumps.py index 99fc9b88..3cb78c82 100644 --- a/tests/client/test_client_dumps.py +++ b/tests/client/test_client_dumps.py @@ -7,5 +7,5 @@ def test_dump_creation(client, index_with_documents): dump = client.create_dump() client.wait_for_task(dump.task_uid) dump_status = client.get_task(dump.task_uid) - assert dump_status["status"] == "succeeded" - assert dump_status["type"] == "dumpCreation" + assert dump_status.status == "succeeded" + assert dump_status.type == "dumpCreation" diff --git a/tests/client/test_client_swap_meilisearch.py b/tests/client/test_client_swap_meilisearch.py index b03b0d27..dabb7514 100644 --- a/tests/client/test_client_swap_meilisearch.py +++ b/tests/client/test_client_swap_meilisearch.py @@ -26,8 +26,8 @@ def test_swap_indexes(client, empty_index): assert docA.title == indexB.uid assert docB.title == indexA.uid - assert task["type"] == "indexSwap" - assert "swaps" in task["details"] + assert task.type == "indexSwap" + assert "swaps" in task.details 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): task = client.wait_for_task(swapTask.task_uid) assert swapTask.type == "indexSwap" - assert task["error"]["code"] == "index_not_found" + assert task.error["code"] == "index_not_found" def test_swap_indexes_with_itself(client, empty_index): diff --git a/tests/client/test_client_task_meilisearch.py b/tests/client/test_client_task_meilisearch.py index 9550614c..1754fcac 100644 --- a/tests/client/test_client_task_meilisearch.py +++ b/tests/client/test_client_task_meilisearch.py @@ -9,33 +9,29 @@ def test_get_tasks_default(client): """Tests getting the global tasks list.""" tasks = client.get_tasks() - assert isinstance(tasks, dict) - assert "results" in tasks + assert len(tasks.results) >= 1 def test_get_tasks(client, empty_index): """Tests getting the global tasks list after populating an index.""" current_tasks = client.get_tasks() - pre_count = current_tasks["from"] + pre_count = current_tasks.from_ empty_index() tasks = client.get_tasks() - assert isinstance(tasks, dict) - assert tasks["from"] == pre_count + 1 + assert tasks.from_ == pre_count + 1 def test_get_tasks_empty_parameters(client): """Tests getting the global tasks list after populating an index.""" tasks = client.get_tasks({}) - assert isinstance(tasks, dict) - assert isinstance(tasks["results"], list) + assert isinstance(tasks.results, list) def test_get_tasks_with_parameters(client, empty_index): """Tests getting the global tasks list after populating an index.""" empty_index() tasks = client.get_tasks({"limit": 1}) - assert isinstance(tasks, dict) - assert len(tasks["results"]) == 1 + assert len(tasks.results) == 1 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): tasks = client.get_tasks( {"indexUids": [common.INDEX_UID], "statuses": ["succeeded"], "types": ["indexCreation"]} ) - assert isinstance(tasks, dict) - assert len(tasks["results"]) >= 1 + assert len(tasks.results) >= 1 def test_get_tasks_with_date_parameters(client, empty_index): @@ -58,16 +53,14 @@ def test_get_tasks_with_date_parameters(client, empty_index): "beforeFinishedAt": "2042-04-02T00:42:42Z", } ) - assert isinstance(tasks, dict) - assert len(tasks["results"]) > 1 + 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 + assert len(tasks.results) == 1 def test_get_task(client): @@ -75,17 +68,16 @@ def test_get_task(client): response = client.create_index(uid=common.INDEX_UID) client.wait_for_task(response.task_uid) task = client.get_task(response.task_uid) - assert isinstance(task, dict) - assert len(task) == 11 - assert "uid" in task - assert "indexUid" in task - assert "status" in task - assert "type" in task - assert "duration" in task - assert "enqueuedAt" in task - assert "finishedAt" in task - assert "details" in task - assert "startedAt" in task + task_dict = task.__dict__ + assert "uid" in task_dict + assert "index_uid" in task_dict + assert "status" in task_dict + assert "type" in task_dict + assert "duration" in task_dict + assert "enqueued_at" in task_dict + assert "finished_at" in task_dict + assert "details" in task_dict + assert "started_at" in task_dict def test_get_task_inexistent(client): @@ -115,8 +107,8 @@ def test_cancel_tasks(client): 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"] + assert "uids" in tasks.results[0].details["originalFilter"] + assert "uids=1%2C2" in tasks.results[0].details["originalFilter"] @pytest.mark.usefixtures("create_tasks") @@ -130,7 +122,7 @@ def test_cancel_every_task(client): 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"] + assert "statuses=enqueued%2Cprocessing" in tasks.results[0].details["originalFilter"] 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): 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"] + assert "uids" in task.details["originalFilter"] + assert f"uids={task_addition.task_uid}" in task.details["originalFilter"] def test_delete_tasks_by_filter(client): @@ -160,8 +152,7 @@ def test_delete_tasks_by_filter(client): 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_after.results) >= 1 assert ( - "statuses=succeeded%2Cfailed%2Ccanceled" - in tasks_after["results"][0]["details"]["originalFilter"] + "statuses=succeeded%2Cfailed%2Ccanceled" in tasks_after.results[0].details["originalFilter"] ) From 50e58ea79375b06198fa80f04f1437b215e976e0 Mon Sep 17 00:00:00 2001 From: Paul Sanders Date: Wed, 10 May 2023 09:13:43 -0400 Subject: [PATCH 2/2] Update return info in doc strings --- meilisearch/client.py | 7 ++++--- meilisearch/task.py | 7 ++++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/meilisearch/client.py b/meilisearch/client.py index 5cdb83be..1579e0c9 100644 --- a/meilisearch/client.py +++ b/meilisearch/client.py @@ -477,7 +477,8 @@ def get_tasks(self, parameters: Optional[Dict[str, Any]] = None) -> TaskResults: Returns ------- task: - Limit, from, next and results containing a list of all enqueued, processing, succeeded or failed tasks. + TaskResult instance containing limit, from, next and results containing a list of all + enqueued, processing, succeeded or failed tasks. Raises ------ @@ -497,7 +498,7 @@ def get_task(self, uid: int) -> Task: Returns ------- task: - Information about the processed asynchronous task. + Task instance containing information about the processed asynchronous task. Raises ------ @@ -566,7 +567,7 @@ def wait_for_task( Returns ------- task: - Dictionary containing information about the processed asynchronous task. + Task instance containing information about the processed asynchronous task. Raises ------ diff --git a/meilisearch/task.py b/meilisearch/task.py index b79de9e2..274484c7 100644 --- a/meilisearch/task.py +++ b/meilisearch/task.py @@ -38,7 +38,8 @@ def get_tasks(self, parameters: Optional[Dict[str, Any]] = None) -> TaskResults: Returns ------- task: - Limit, from, next and results containing a list of all enqueued, processing, succeeded or failed tasks. + TaskResults instance contining limit, from, next and results containing a list of all + enqueued, processing, succeeded or failed tasks. Raises ------ @@ -64,7 +65,7 @@ def get_task(self, uid: int) -> Task: Returns ------- task: - Dictionary containing information about the status of the asynchronous task. + Task instance containing information about the processed asynchronous task. Raises ------ @@ -147,7 +148,7 @@ def wait_for_task( Returns ------- task: - Information about the processed asynchronous task. + Task instance containing information about the processed asynchronous task. Raises ------