From 633872a525d8ceb2153d28bfa78cdc1930f21ba0 Mon Sep 17 00:00:00 2001 From: Sakshi Mishra Date: Wed, 2 Apr 2025 11:57:49 +0530 Subject: [PATCH] feature/issue-890 Signed-off-by: Sakshi Mishra --- opensearchpy/client/__init__.py | 12 +++++-- test_opensearchpy/test_helpers/test_index.py | 38 +++++++++++++++++++- 2 files changed, 46 insertions(+), 4 deletions(-) diff --git a/opensearchpy/client/__init__.py b/opensearchpy/client/__init__.py index 118cfa7a6..4531172ba 100644 --- a/opensearchpy/client/__init__.py +++ b/opensearchpy/client/__init__.py @@ -2229,6 +2229,7 @@ def search( index: Any = None, params: Any = None, headers: Any = None, + http_method: str = "POST", # New parameter to specify HTTP method ) -> Any: """ Returns results matching a query. @@ -2423,17 +2424,22 @@ def search( be prefixed by their respective types in the response. :arg version: If `true`, returns document version as part of a hit. + :arg http_method: HTTP method to use for the search request. Defaults to "POST". + Can be set to "GET" for read-only environments. """ # from is a reserved word so it cannot be used, use from_ instead if "from_" in params: params["from"] = params.pop("from_") + if http_method not in ["GET", "POST"]: + raise ValueError("http_method must be either 'GET' or 'POST'") + return self.transport.perform_request( - "POST", - _make_path(index, "_search"), + method=http_method, + url=_make_path(index, "_search"), params=params, headers=headers, - body=body, + body=body if http_method == "POST" else None, # Only include body for POST ) @query_params( diff --git a/test_opensearchpy/test_helpers/test_index.py b/test_opensearchpy/test_helpers/test_index.py index 41469a52b..8b9114814 100644 --- a/test_opensearchpy/test_helpers/test_index.py +++ b/test_opensearchpy/test_helpers/test_index.py @@ -25,12 +25,13 @@ # under the License. import string +import pytest from random import choice from typing import Any from pytest import raises -from opensearchpy import Date, Document, Index, IndexTemplate, Text, analyzer +from opensearchpy import Date, Document, Index, IndexTemplate, Text, analyzer, OpenSearch class Post(Document): @@ -62,6 +63,41 @@ def test_search_is_limited_to_index_name() -> None: assert s._index == ["my-index"] +def test_search_with_post_method(mocker): + transport_mock = mocker.Mock() + client = OpenSearch(transport=transport_mock) + + client.search(index="test-index", body={"query": {"match_all": {}}}, http_method="POST") + + transport_mock.perform_request.assert_called_once_with( + method="POST", + url="/test-index/_search", + params=None, + headers=None, + body={"query": {"match_all": {}}} + ) + +def test_search_with_get_method(mocker): + transport_mock = mocker.Mock() + client = OpenSearch(transport=transport_mock) + + client.search(index="test-index", params={"q": "test"}, http_method="GET") + + transport_mock.perform_request.assert_called_once_with( + method="GET", + url="/test-index/_search", + params={"q": "test"}, + headers=None, + body=None + ) + +def test_search_invalid_http_method(mocker): + transport_mock = mocker.Mock() + client = OpenSearch(transport=transport_mock) + + with pytest.raises(ValueError, match="http_method must be either 'GET' or 'POST'"): + client.search(index="test-index", http_method="PUT") + def test_cloned_index_has_copied_settings_and_using() -> None: client = object()