From 22968f0749c66dc626ecf463bab392ae138a2f42 Mon Sep 17 00:00:00 2001 From: KatKatKateryna Date: Wed, 4 Sep 2024 22:49:14 +0100 Subject: [PATCH] URL exceptions handling --- pygeoapi/api/itemtypes.py | 62 ------------- pygeoapi/provider/speckle.py | 20 +++- pygeoapi/provider/speckle_utils/url_utils.py | 96 ++++++++++++-------- pygeoapi/templates/exception.html | 3 + 4 files changed, 80 insertions(+), 101 deletions(-) diff --git a/pygeoapi/api/itemtypes.py b/pygeoapi/api/itemtypes.py index 8a23e30..dce1861 100644 --- a/pygeoapi/api/itemtypes.py +++ b/pygeoapi/api/itemtypes.py @@ -574,68 +574,6 @@ def get_collection_items( if isinstance(url_saved_as_data, str): url_props = url_saved_as_data.lower().split("&") - content['missing_url'] = content['missing_url_href'] = "" - content['requested_data_type'] = "polygons (default)" - content['preserve_attributes'] = "true (default)" - content['speckle_url'] = content['speckle_project_url'] = content['crs_authid'] = content['lat'] = content['lon'] = content['north_degrees'] = content['limit'] = "-" - crsauthid = False - for item in url_props: - # if CRS authid is found, rest will be ignored - try: - - if "speckleurl=" in item: - try: - content['speckle_url'] = item.split("speckleurl=")[1] - if content['speckle_url'][-1] == "/": - content['speckle_url'] = content['speckle_url'][:-1] - content['speckle_project_url'] = content['speckle_url'].split("/models")[0] - except IndexError: - raise KeyError("Provide valid Speckle Model URL") - elif "datatype=" in item: - content['requested_data_type'] = item.split("datatype=")[1] - if content['requested_data_type'] not in ["points", "lines", "polygons", "projectcomments"]: - content['requested_data_type'] = "polygons (default)" - elif "preserveattributes=" in item: - content['preserve_attributes'] = item.split("preserveattributes=")[1] - if content['preserve_attributes'] not in ["true", "false"]: - content['preserve_attributes'] = "true (default)" - elif "crsauthid=" in item: - content['crs_authid'] = item.split("crsauthid=")[1] - crsauthid = True - elif "lat=" in item: - try: - content['lat'] = float(item.split("lat=")[1]) - except: - content['lat'] = f"Invalid input, must be numeric: {item.split('lat=')[1]}" - elif "lon=" in item: - try: - content['lon'] = float(item.split("lon=")[1]) - except: - content['lon'] = f"Invalid input, must be numeric: {item.split('lon=')[1]}" - elif "northdegrees=" in item: - try: - content['north_degrees'] = float(item.split("northdegrees=")[1]) - except: - content['north_degrees'] = f"Invalid input, must be numeric: {item.split('northdegrees=')[1]}" - elif "limit=" in item: - try: - content['limit'] = float(item.split("limit=")[1]) - except: - content['limit'] = f"Invalid input, must be integer: {item.split('limit=')[1]}" - except IndexError: - pass - - if content['speckle_url'] == "-": - content['missing_url'] = "true" - - if crsauthid: - content['lat'] += " (not applied)" - content['lon'] += " (not applied)" - content['north_degrees'] += " (not applied)" - - if content['limit'] == "-": - content['limit'] = f"{api.config['server']['limit']} (default)" - # Set response language to requested provider locale # (if it supports language) and/or otherwise the requested pygeoapi # locale (or fallback default locale) diff --git a/pygeoapi/provider/speckle.py b/pygeoapi/provider/speckle.py index 9273b12..8148811 100644 --- a/pygeoapi/provider/speckle.py +++ b/pygeoapi/provider/speckle.py @@ -126,14 +126,16 @@ class SpeckleProvider(BaseProvider): self.requested_data_type: str = "polygons (default)" # points, lines, polygons, projectcomments self.preserve_attributes: str = "true (default)" - self.lat: float = 48.76755913928929 #51.52486388756923 self.lon: float = 11.408741923664028 #0.1621445437168942 self.north_degrees: float = 0 - self.extent = [-180,-90,180,90] + self.crs_authid = "" self.limit = 10000 + + self.missing_url = "" self.limit_message = "" + self.extent = [-180,-90,180,90] self.material_color_proxies = {} @@ -173,7 +175,7 @@ class SpeckleProvider(BaseProvider): if self.data == "": return - get_set_url_parameters(self) + get_set_url_parameters(self) # possible ValueError # check if it's a new request (self.data was updated and doesn't match self.url) new_request = False @@ -266,6 +268,18 @@ class SpeckleProvider(BaseProvider): if data is None: return {"features":[], "comments":[], "extent": [-180,-90,180,90]} + # add URL parameters + data['speckle_url'] = self.speckle_url + data['requested_data_type'] = self.requested_data_type + data['preserve_attributes'] = self.preserve_attributes + data['crs_authid'] = self.crs_authid + data['lat'] = self.lat + data['lon'] = self.lon + data['north_degrees'] = self.north_degrees + data['limit'] = self.limit + data['missing_url'] = self.missing_url + + data["numberMatched"] = len(data["features"]) if resulttype == "hits": diff --git a/pygeoapi/provider/speckle_utils/url_utils.py b/pygeoapi/provider/speckle_utils/url_utils.py index 1f490c4..21bdab6 100644 --- a/pygeoapi/provider/speckle_utils/url_utils.py +++ b/pygeoapi/provider/speckle_utils/url_utils.py @@ -1,65 +1,89 @@ -from typing import Dict +import inspect def get_set_url_parameters(self: "SpeckleProvider"): + """Parse and save URL parameters.""" from pygeoapi.provider.speckle_utils.crs_utils import create_crs_from_authid - - if ( - isinstance(self.data, str) - and "speckleurl=" in self.data.lower() - and "projects" in self.data - and "models" in self.data - ): - crs_authid = "" + + crsauthid = False + + if (isinstance(self.data, str)): + for item in self.data.lower().split("&"): - # if CRS authid is found, rest will be ignored - if "datatype=" in item: + if "speckleurl=" in item: try: - self.requested_data_type = item.split("datatype=")[1] - if self.requested_data_type not in ["points", "lines", "polygons", "projectcomments"]: - self.requested_data_type = "polygons (default)" + speckle_url = item.split("speckleurl=")[1] + if "/projects/" not in speckle_url or "/models/" not in speckle_url: + raise ValueError(f"Provide valid Speckle Model URL: {item}") + + if speckle_url[-1] == "/": + speckle_url = speckle_url[:-1] + self.speckle_project_url = speckle_url.split("/models")[0] except: - pass - + raise ValueError(f"Provide valid Speckle Model URL: {item}") + + elif "datatype=" in item: + try: + requested_data_type = item.split("datatype=")[1] + if requested_data_type in ["points", "lines", "polygons", "projectcomments"]: + self.requested_data_type = requested_data_type + except: + raise ValueError(f"Provide valid dataType parameter (points/lines/polygons/projectcomments): {item}") + elif "preserveattributes=" in item: try: - self.preserve_attributes = item.split("preserveattributes=")[1] - if self.preserve_attributes not in ["true", "false"]: - self.preserve_attributes = "true (default)" + preserve_attributes = item.split("preserveattributes=")[1] + if preserve_attributes in ["true", "false"]: + self.preserve_attributes = preserve_attributes except: - pass + ValueError(f"Provide valid preserverAttributes parameter (true/false): {item}") - elif "limit=" in item: - try: - self.limit = int(item.split("limit=")[1]) - except: - pass - elif "crsauthid=" in item: crs_authid = item.split("crsauthid=")[1] + if isinstance(crs_authid, str) and len(crs_authid)>3: + crsauthid = True + self.crs_authid = crs_authid + elif "lat=" in item: try: - self.lat = float(item.split("lat=")[1]) + lat = float(item.split("lat=")[1]) + self.lat = lat except: - pass - # raise ValueError(f"Invalid Lat input, must be numeric: {item.split('lat=')[1]}") + raise ValueError(f"Invalid Lat input, must be numeric: {item}") elif "lon=" in item: try: - self.lon = float(item.split("lon=")[1]) + lon = float(item.split("lon=")[1]) + self.lon = lon except: - pass - # raise ValueError(f"Invalid Lon input, must be numeric: {item.split('lon=')[1]}") + raise ValueError(f"Invalid Lon input, must be numeric: {item}") elif "northdegrees=" in item: try: - self.north_degrees = float(item.split("northdegrees=")[1]) + north_degrees = float(item.split("northdegrees=")[1]) + self.north_degrees = north_degrees except: - pass - # raise ValueError(f"Invalid NorthDegrees input, must be numeric: {item.split('northdegrees=')[1]}") + raise ValueError(f"Invalid northDegrees input, must be numeric: {item}") + elif "limit=" in item: + try: + limit = int(item.split("limit=")[1]) + if limit>0: + self.limit = limit + except: + ValueError(f"Invalid limit input, must be a positive integer: {item}") + + + if self.speckle_url == "-": + self.missing_url = "true" + + # if CRS authid is found, rest will be ignored + if crsauthid: + self.lat = str(self.lat) + " (not applied)" + self.lon = str(self.lon) + " (not applied)" + self.north_degrees = str(self.north_degrees) + " (not applied)" # if CRS parameter present, create and assign CRS: - if len(crs_authid)>3: + if len(self.crs_authid)>3: create_crs_from_authid(self) diff --git a/pygeoapi/templates/exception.html b/pygeoapi/templates/exception.html index e0bc3b2..ff4c80a 100644 --- a/pygeoapi/templates/exception.html +++ b/pygeoapi/templates/exception.html @@ -5,4 +5,7 @@

{% trans %}Exception{% endtrans %}

{{ data['description'] }}

+ {% endblock %}