Skip to content

Add delete task api for v0.30.0 #598

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Nov 28, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 20 additions & 1 deletion meilisearch/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
from meilisearch.errors import MeiliSearchError
from meilisearch.index import Index
from meilisearch.models.task import TaskInfo
from meilisearch.task import cancel_tasks, get_task, get_tasks, wait_for_task
from meilisearch.task import cancel_tasks, delete_tasks, get_task, get_tasks, wait_for_task


class Client:
Expand Down Expand Up @@ -463,6 +463,25 @@ def cancel_tasks(self, parameters: dict[str, Any]) -> TaskInfo:
"""
return cancel_tasks(self.config, parameters=parameters)

def delete_tasks(self, parameters: dict[str, Any]) -> TaskInfo:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using types in dynamic languages is complex, but I believe we at least can allow or not some parameters. WDYT?

https://github.com/meilisearch/meilisearch-ruby/pull/389/files#diff-34321aa6a7ffc59be7968ad4251433b3f6f30cdd222ed8d54572bf37f0000d7bR8-R13

I have to do that on the ruby side because of the camelCase/snake_case conversion, but it could be an excellent addition to the python SDK... (a issue could be created in this case)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, great idea it could be a really nice addition but I don't know how to do that in python, to be honest.
I will check it and create an issue about it.

"""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,
Expand Down
28 changes: 28 additions & 0 deletions meilisearch/task.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,34 @@ def cancel_tasks(config: Config, parameters: dict[str, Any]) -> TaskInfo:
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,
Expand Down
38 changes: 37 additions & 1 deletion tests/client/test_client_task_meilisearch.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ def test_get_tasks_with_all_plural_parameters(client, empty_index):
{"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):
Expand Down Expand Up @@ -131,3 +131,39 @@ def test_cancel_every_task(client):
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"]
)
9 changes: 9 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -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 = []
Expand Down