From d74eeabee86551cbbd2eae7ef87a55e4737932bb Mon Sep 17 00:00:00 2001 From: Matthias Bodenbenner <m.bodenbenner@wzl-mq.rwth-aachen.de> Date: Mon, 8 Jan 2024 08:02:22 +0100 Subject: [PATCH] implemented resolving requests of profiles --- src/http/server.py | 25 ++++++++++++++----------- src/soil/component.py | 23 +++++++++++++++++++++++ src/soil/element.py | 12 ++++++++++++ 3 files changed, 49 insertions(+), 11 deletions(-) diff --git a/src/http/server.py b/src/http/server.py index 06ae409..a947643 100644 --- a/src/http/server.py +++ b/src/http/server.py @@ -19,6 +19,7 @@ from ..soil.figure import Figure from ..soil.function import Function from ..soil.measurement import Measurement from ..soil.parameter import Parameter +from ..soil.semantics import Semantics from ..soil.stream import StreamScheduler from ..utils import root_logger from ..utils import serialize @@ -125,9 +126,8 @@ class HTTPServer(object): return queried_attributes def prepare_response(self, body: Union[Dict, rdflib.Graph], element: Element, status: int = 200, - query: MultiDict = None): + query: MultiDict = None, semantic: bool = False): dataformat = self._dataformat - semantic = False if query is not None and 'format' in query and query['format'] in ['json', 'xml', 'turtle']: dataformat = query['format'] if query is not None and 'semantic' in query and query['semantic'] in ['data', 'metadata', 'profile']: @@ -171,6 +171,7 @@ class HTTPServer(object): logger.info("GET Request from {}".format(request.url)) logger.debug('Request: {}'.format(request)) logger.debug('Query Parameters: {}'.format(request.query_string)) + splitted_request = HTTPServer.parse_uuids(request) keys = self._filter_query(request.query) # determine whether a semantic answer is expected @@ -178,14 +179,16 @@ class HTTPServer(object): if request.query is not None and 'semantic' in request.query and request.query['semantic'] in ['data', 'metadata', 'profile']: semantic = request.query['semantic'] - # retrieving the element - try: - item = self.root[HTTPServer.parse_uuids(request)] - except KeyError as e: - logger.error(traceback.format_exc()) - response = {'error': str(e)} - logger.error('Response: {}'.format(response)) - return self.prepare_response(response, None, status=404, query=request.query) + if len(splitted_request) > 0 and splitted_request[0] == Semantics.prefix: + item, semantic = self.root.resolve_semantic_path(splitted_request[1:]) + else: + try: + item = self.root[splitted_request] + except KeyError as e: + logger.error(traceback.format_exc()) + response = {'error': str(e)} + logger.error('Response: {}'.format(response)) + return self.prepare_response(response, None, status=404, query=request.query) # serializing the element try: @@ -200,7 +203,7 @@ class HTTPServer(object): response = {'error': str(e)} status = 500 logger.error('Response: {}'.format(response)) - return self.prepare_response(response, item, status=status, query=request.query) + return self.prepare_response(response, item, status=status, query=request.query, semantic=semantic is not None) async def post(self, request): logger.info("POST Request from {}".format(request.url)) diff --git a/src/soil/component.py b/src/soil/component.py index 77fdcdf..4c507d6 100644 --- a/src/soil/component.py +++ b/src/soil/component.py @@ -393,3 +393,26 @@ class Component(Element): else: raise DeviceException('The provided kind of semantic information cannot be returned.') return result + + def resolve_semantic_path(self, path: List[str]): + if len(path) == 0: + raise ChildNotFoundException('Could not resolve the semantic path.') + + # first try to resolve whether it is a path to a profile + if path[0] == f'{self._profilename}Shape': + if len(path) == 1: + return self, 'profile' + else: + for child in self.children: + try: + return child.resolve_semantic_path(path) + except ChildNotFoundException: + continue + + # TODO resolve data or metadata terms + + raise ChildNotFoundException('Could not resolve the semantic path.') + + + + diff --git a/src/soil/element.py b/src/soil/element.py index 9d2d646..c248859 100644 --- a/src/soil/element.py +++ b/src/soil/element.py @@ -5,6 +5,7 @@ from typing import Any, Dict, List import rdflib +from .error import ChildNotFoundException from ..utils.constants import BASE_UUID_PATTERN, HTTP_GET from ..utils.error import SerialisationException @@ -110,3 +111,14 @@ class Element(ABC): @abstractmethod def serialize_semantics(self, kind: str) -> rdflib.Graph: ... + + def resolve_semantic_path(self, path: List[str]) -> ('Element', str): + if len(path) == 0: + raise ChildNotFoundException('Could not resolve the semantic path.') + + if path[0] == f'{self._profilename}Shape' and len(path) == 1: + return self, 'profile' + else: + raise ChildNotFoundException('Could not resolve the semantic path.') + + # TODO resolve data or metadata terms -- GitLab