From 72c7c77bdc2c822758b4fe1d0c22d482f589a82e Mon Sep 17 00:00:00 2001 From: NextGenEng <58440325+THOR300@users.noreply.github.com> Date: Tue, 8 Oct 2024 17:55:26 +0100 Subject: [PATCH] Feature/add concept filters field validation (#128) * Adding a pydantic validation and relating check to ensure that in browse mode concept filters are not set. * Updating validation check and tests. * Updating the version. * Resolving failing test. * updating the error message. --------- Co-authored-by: Mark --- src/cpr_sdk/models/search.py | 9 +++++++ src/cpr_sdk/version.py | 2 +- tests/test_search_adaptors.py | 8 ++++++ tests/test_search_parameters.py | 47 +++++++++++++++++++++++++++++++++ 4 files changed, 65 insertions(+), 1 deletion(-) create mode 100644 tests/test_search_parameters.py diff --git a/src/cpr_sdk/models/search.py b/src/cpr_sdk/models/search.py index 1774d1a..0cd0823 100644 --- a/src/cpr_sdk/models/search.py +++ b/src/cpr_sdk/models/search.py @@ -256,6 +256,15 @@ def validate(self): ) return self + @model_validator(mode="after") + def concept_filters_not_set_if_documents_only(self) -> "SearchParameters": + """Ensure concept_filters are not set if browse mode (documents_only) is set.""" + if self.concept_filters is not None and self.documents_only is True: + raise ValueError( + "Cannot set concept_filters when only searching documents. This is as concept_filters are only applicable to passages." + ) + return self + @field_validator("continuation_tokens") def continuation_tokens_must_be_upper_strings(cls, continuation_tokens): """Validate continuation_tokens match the expected format""" diff --git a/src/cpr_sdk/version.py b/src/cpr_sdk/version.py index 5e37261..7c9454d 100644 --- a/src/cpr_sdk/version.py +++ b/src/cpr_sdk/version.py @@ -1,6 +1,6 @@ _MAJOR = "1" _MINOR = "9" -_PATCH = "0" +_PATCH = "1" _SUFFIX = "" VERSION_SHORT = "{0}.{1}".format(_MAJOR, _MINOR) diff --git a/tests/test_search_adaptors.py b/tests/test_search_adaptors.py index b2a332c..018632b 100644 --- a/tests/test_search_adaptors.py +++ b/tests/test_search_adaptors.py @@ -501,6 +501,13 @@ def test_vespa_search_adaptor__corpus_type_name( {"name": "id", "value": "concept_0_0"}, ], ), + ( + "", + [ + {"name": "parent_concept_ids_flat", "value": "Q0,"}, + {"name": "id", "value": "concept_0_0"}, + ], + ), ], ) def test_vespa_search_adaptor__concept_filter( @@ -513,6 +520,7 @@ def test_vespa_search_adaptor__concept_filter( ConceptFilter.model_validate(concept_filter) for concept_filter in concept_filters ], + documents_only=False, ) response = vespa_search(test_vespa, request) assert response.total_family_hits > 0 diff --git a/tests/test_search_parameters.py b/tests/test_search_parameters.py new file mode 100644 index 0000000..c9e12f7 --- /dev/null +++ b/tests/test_search_parameters.py @@ -0,0 +1,47 @@ +from typing import Optional + +import pytest +from pydantic_core import ValidationError + +from cpr_sdk.models.search import SearchParameters + + +@pytest.mark.parametrize( + "params,expect_error,error_message", + [ + ({"query_string": "the"}, False, None), + ({"query_string": ""}, False, None), + ( + { + "query_string": "", + "documents_only": True, + "all_results": True, + "concept_filters": [{"name": "name", "value": "environment"}], + }, + True, + "Cannot set concept_filters when only searching documents.", + ), + ( + { + "query_string": "", + "documents_only": False, + "concept_filters": [{"name": "name", "value": "environment"}], + }, + False, + None, + ), + ], +) +@pytest.mark.vespa +def test_vespa_search_parameters( + params: dict, expect_error: bool, error_message: Optional[str] +) -> None: + """Test that we can correctly instantiate the SearchParameters object.""" + if expect_error: + with pytest.raises( + ValidationError, + match=error_message, + ): + SearchParameters.model_validate(params) + else: + SearchParameters.model_validate(params)