From 610b7cc820604ba6436f71b260525d335b7077f2 Mon Sep 17 00:00:00 2001 From: Koen Van Daele Date: Fri, 4 Oct 2019 23:52:45 +0200 Subject: [PATCH] Add match search parameters. Refs #68 --- HISTORY.rst | 2 ++ docs/services.rst | 8 ++++++++ pyramid_skosprovider/utils.py | 10 ++++++++++ tests/test_utils.py | 24 ++++++++++++++++++++++++ 4 files changed, 44 insertions(+) diff --git a/HISTORY.rst b/HISTORY.rst index d56543e..1765b81 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -4,6 +4,8 @@ - Support running a registry per request, as oppesed to per application as before. (#44) - Add JSON-LD output to the REST service. (#63) +- Add support for match and match_type search parameters to search for concepts + that match a certain URI and optionally have a certain type. (#68) - Drop support for Python 3.4, add support for 3.7. This is the last version that will support Python 2. (#66) - Remove the JSON renderers from the utils module. diff --git a/docs/services.rst b/docs/services.rst index a5eefbc..caccabf 100644 --- a/docs/services.rst +++ b/docs/services.rst @@ -134,6 +134,10 @@ The following API can be used by clients: :query sort: Define if you want to sort the results by a given field. Otherwise items are returned in an indeterminate order. Prefix with '+' to sort ascending, '-' to sort descending. eg. ``?sort=-label`` to sort all results descending by label. + :query match: A URI for an external concept. Searches if any of the + providers have a matching concept. + :query match_type: A type of match: exact, close, related, broader, + narrower. Only used if a match URI is present as well. :query providers.ids: A comma separated list of concept scheme id's. The query will only be passed to the providers with these id's. eg. ``?providers.ids=TREES, PARROTS`` will only list concepts from these two providers. @@ -398,6 +402,10 @@ The following API can be used by clients: Expects to be passed an id of a collection in this scheme. Will restrict the search to concepts or collections that are a member of this collection or a narrower concept of a member. + :query match: A URI for an external concept. Searches if any of the + providers have a matching concept. + :query match_type: A type of match: exact, close, related, broader, + narrower. Only used if a match URI is present as well. :query language: Returns the label with the corresponding language-tag if present. If the language is not present for this concept/collection, it falls back to 1) the default language of the provider. 2) 'en' 3) any label. diff --git a/pyramid_skosprovider/utils.py b/pyramid_skosprovider/utils.py index 97b5575..e35ea67 100644 --- a/pyramid_skosprovider/utils.py +++ b/pyramid_skosprovider/utils.py @@ -43,6 +43,15 @@ def _build_collection(self, query): query['collection'] = {'id': coll, 'depth': 'all'} return query + def _build_matches(self, query): + match_uri = self.request.params.get('match', None) + if match_uri is not None: + query['matches'] = {'uri': match_uri} + match_type = self.request.params.get('match_type', None) + if match_type is not None: + query['matches']['type'] = match_type + return query + def __call__(self): if self.mode == 'dijitFilteringSelect' and self.label == '': self.no_result = True @@ -50,6 +59,7 @@ def __call__(self): q = self._build_type(q) q = self._build_label(q) q = self._build_collection(q) + q = self._build_matches(q) return q diff --git a/tests/test_utils.py b/tests/test_utils.py index 2c75c8e..b3a63dc 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -86,6 +86,30 @@ def test_build_collection(self): assert 'collection' in q assert q['collection'] == {'id': 3, 'depth': 'all'} + def test_build_matches(self): + request = self._get_dummy_request({ + 'match': 'https://thingy.org/thing' + }) + qb = self._get_fut(request) + q = qb() + assert isinstance(q, dict) + assert 'matches' in q + assert q['matches'] == {'uri': 'https://thingy.org/thing'} + + def test_build_matches_broader(self): + request = self._get_dummy_request({ + 'match': 'https://thingy.org/thing', + 'match_type': 'exact' + }) + qb = self._get_fut(request) + q = qb() + assert isinstance(q, dict) + assert 'matches' in q + assert q['matches'] == { + 'uri': 'https://thingy.org/thing', + 'type': 'exact' + } + class TestRangeHeaders(unittest.TestCase): def test_parse_range_header(self):