From 7fea4c1d2dd3b7ba18d164c37c17f81bd2d073f1 Mon Sep 17 00:00:00 2001 From: MuddyHope Date: Fri, 31 Jan 2025 21:35:41 -0800 Subject: [PATCH 1/4] Update Documents with Functions --- meilisearch/client.py | 23 +++++++++++++++++++ meilisearch/config.py | 1 + ...est_client_update_document_by_functions.py | 15 ++++++++++++ 3 files changed, 39 insertions(+) create mode 100644 tests/client/test_client_update_document_by_functions.py diff --git a/meilisearch/client.py b/meilisearch/client.py index c635a575..01bd567c 100644 --- a/meilisearch/client.py +++ b/meilisearch/client.py @@ -248,6 +248,29 @@ def multi_search( body={"queries": queries, "federation": federation}, ) + def update_documents_by_function(self, index_uid: str, queries: Dict[str, List[Dict[str, Any]]]) -> Dict[str, Any]: + """Update Documents by function + Parameters + ---------- + index_uid: + The index_uid where you want to update documents of. + queries: + List of dictionaries containing functions with or without filters that you want to use to update documents. + + Returns + ------- + task_info: + TaskInfo instance containing information about a task to track the progress of an asynchronous process. + https://www.meilisearch.com/docs/reference/api/tasks#get-one-task + + Raises + ------ + MeilisearchApiError + An error containing details about why Meilisearch can't process your request. Meilisearch error codes are described here: https://www.meilisearch.com/docs/reference/errors/error_codes#meilisearch-errors + """ + return self.http.post(path=f"{self.config.paths.index}/{index_uid}/{self.config.paths.document}/{self.config.paths.edit}", + body=dict(queries)) + def get_all_stats(self) -> Dict[str, Any]: """Get all stats of Meilisearch diff --git a/meilisearch/config.py b/meilisearch/config.py index 1d40a694..acf5745b 100644 --- a/meilisearch/config.py +++ b/meilisearch/config.py @@ -44,6 +44,7 @@ class Paths: search_cutoff_ms = "search-cutoff-ms" proximity_precision = "proximity-precision" localized_attributes = "localized-attributes" + edit = "edit" def __init__( self, diff --git a/tests/client/test_client_update_document_by_functions.py b/tests/client/test_client_update_document_by_functions.py new file mode 100644 index 00000000..f5ad8013 --- /dev/null +++ b/tests/client/test_client_update_document_by_functions.py @@ -0,0 +1,15 @@ +import pytest + +from meilisearch.errors import MeilisearchApiError +from tests.common import INDEX_UID +from tests.conftest import index_with_documents + +def test_basic_multi_search(client, index_with_documents): + """Delete the document with id.""" + index_with_documents() + response = client.update_documents_by_function( + "indexA", {"function": "if doc.id == \"522681\" {doc = () } else {doc.title = `* ${doc.title} *`}"} + ) + + assert isinstance(response, dict) + assert response['indexUid'] == INDEX_UID From 78901f80904aea5d84296c47e8d46decc727b66b Mon Sep 17 00:00:00 2001 From: MuddyHope Date: Fri, 31 Jan 2025 21:40:35 -0800 Subject: [PATCH 2/4] Update workflow test fixes --- meilisearch/_httprequests.py | 4 +++- meilisearch/client.py | 10 +++++++--- .../client/test_client_update_document_by_functions.py | 6 ++++-- tests/index/test_index_document_meilisearch.py | 1 - 4 files changed, 14 insertions(+), 7 deletions(-) diff --git a/meilisearch/_httprequests.py b/meilisearch/_httprequests.py index 6db5eb96..5b90521f 100644 --- a/meilisearch/_httprequests.py +++ b/meilisearch/_httprequests.py @@ -65,7 +65,9 @@ def send_request( data = ( json.dumps(body, cls=serializer) if serialize_body - else "" if body == "" else "null" + else "" + if body == "" + else "null" ) request = http_method( diff --git a/meilisearch/client.py b/meilisearch/client.py index 01bd567c..629b3b12 100644 --- a/meilisearch/client.py +++ b/meilisearch/client.py @@ -248,7 +248,9 @@ def multi_search( body={"queries": queries, "federation": federation}, ) - def update_documents_by_function(self, index_uid: str, queries: Dict[str, List[Dict[str, Any]]]) -> Dict[str, Any]: + def update_documents_by_function( + self, index_uid: str, queries: Dict[str, List[Dict[str, Any]]] + ) -> Dict[str, Any]: """Update Documents by function Parameters ---------- @@ -268,8 +270,10 @@ def update_documents_by_function(self, index_uid: str, queries: Dict[str, List[D MeilisearchApiError An error containing details about why Meilisearch can't process your request. Meilisearch error codes are described here: https://www.meilisearch.com/docs/reference/errors/error_codes#meilisearch-errors """ - return self.http.post(path=f"{self.config.paths.index}/{index_uid}/{self.config.paths.document}/{self.config.paths.edit}", - body=dict(queries)) + return self.http.post( + path=f"{self.config.paths.index}/{index_uid}/{self.config.paths.document}/{self.config.paths.edit}", + body=dict(queries), + ) def get_all_stats(self) -> Dict[str, Any]: """Get all stats of Meilisearch diff --git a/tests/client/test_client_update_document_by_functions.py b/tests/client/test_client_update_document_by_functions.py index f5ad8013..1180a728 100644 --- a/tests/client/test_client_update_document_by_functions.py +++ b/tests/client/test_client_update_document_by_functions.py @@ -4,12 +4,14 @@ from tests.common import INDEX_UID from tests.conftest import index_with_documents + def test_basic_multi_search(client, index_with_documents): """Delete the document with id.""" index_with_documents() response = client.update_documents_by_function( - "indexA", {"function": "if doc.id == \"522681\" {doc = () } else {doc.title = `* ${doc.title} *`}"} + "indexA", + {"function": 'if doc.id == "522681" {doc = () } else {doc.title = `* ${doc.title} *`}'}, ) assert isinstance(response, dict) - assert response['indexUid'] == INDEX_UID + assert response["indexUid"] == INDEX_UID diff --git a/tests/index/test_index_document_meilisearch.py b/tests/index/test_index_document_meilisearch.py index 88a43142..e89ab6e6 100644 --- a/tests/index/test_index_document_meilisearch.py +++ b/tests/index/test_index_document_meilisearch.py @@ -171,7 +171,6 @@ def test_update_documents_json_custom_serializer(empty_index): def test_update_documents_raw_custom_serializer(empty_index): - documents = [ {"id": uuid4(), "title": "test 1", "when": datetime.now()}, {"id": uuid4(), "title": "Test 2", "when": datetime.now()}, From 3d55e8bcd870fb6a0219af868c0d8d637096b0e5 Mon Sep 17 00:00:00 2001 From: MuddyHope Date: Fri, 31 Jan 2025 22:06:16 -0800 Subject: [PATCH 3/4] Update PR test fixes --- meilisearch/_httprequests.py | 4 +--- .../test_client_update_document_by_functions.py | 10 +++++----- tests/conftest.py | 17 +++++++++++++++++ 3 files changed, 23 insertions(+), 8 deletions(-) diff --git a/meilisearch/_httprequests.py b/meilisearch/_httprequests.py index 5b90521f..6db5eb96 100644 --- a/meilisearch/_httprequests.py +++ b/meilisearch/_httprequests.py @@ -65,9 +65,7 @@ def send_request( data = ( json.dumps(body, cls=serializer) if serialize_body - else "" - if body == "" - else "null" + else "" if body == "" else "null" ) request = http_method( diff --git a/tests/client/test_client_update_document_by_functions.py b/tests/client/test_client_update_document_by_functions.py index 1180a728..8a809908 100644 --- a/tests/client/test_client_update_document_by_functions.py +++ b/tests/client/test_client_update_document_by_functions.py @@ -1,17 +1,17 @@ import pytest -from meilisearch.errors import MeilisearchApiError from tests.common import INDEX_UID -from tests.conftest import index_with_documents -def test_basic_multi_search(client, index_with_documents): - """Delete the document with id.""" +@pytest.mark.usefixtures("enable_edit_documents_by_function") +def test_update_document_by_function(client, index_with_documents): + """Delete the document with id and update document title""" index_with_documents() response = client.update_documents_by_function( - "indexA", + INDEX_UID, {"function": 'if doc.id == "522681" {doc = () } else {doc.title = `* ${doc.title} *`}'}, ) assert isinstance(response, dict) + assert isinstance(response["taskUid"], int) assert response["indexUid"] == INDEX_UID diff --git a/tests/conftest.py b/tests/conftest.py index 6622ca3e..c7843b7f 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -230,6 +230,23 @@ def enable_vector_search(): ) +@fixture +def enable_edit_documents_by_function(): + requests.patch( + f"{common.BASE_URL}/experimental-features", + headers={"Authorization": f"Bearer {common.MASTER_KEY}"}, + json={"editDocumentsByFunction": True}, + timeout=10, + ) + yield + requests.patch( + f"{common.BASE_URL}/experimental-features", + headers={"Authorization": f"Bearer {common.MASTER_KEY}"}, + json={"editDocumentsByFunction": False}, + timeout=10, + ) + + @fixture def new_embedders(): return { From 3697219ca3045982b8919ed94231aef284a1f89c Mon Sep 17 00:00:00 2001 From: MuddyHope Date: Thu, 3 Apr 2025 13:44:37 -0700 Subject: [PATCH 4/4] Merge fix --- tests/conftest.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/conftest.py b/tests/conftest.py index ff5fd288..7a814ff7 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -2,6 +2,7 @@ import json from typing import Optional +import requests from pytest import fixture import meilisearch