def _write_response_doc(self, request_uuid, doc): """ Write response document """ try: logstore.write_response(request_uuid, doc) except IOError as e: raise NoApplicableCode( 'Writing Response Document failed with : %s' % e, code=500)
def get_processes_for_request(self, idents: Iterable[str], map_uri: Optional[str]=None) -> Iterable[WPSProcess]: try: return self.get_processes(idents, map_uri) except UnknownProcessError as exc: raise InvalidParameterValue("Unknown process %s" % exc, "identifier") from None except Exception as e: LOGGER.critical("Exception:\n%s",traceback.format_exc()) raise NoApplicableCode(str(e), code=500) from None
def parse_layer_spec(layerspec: str, context: ProcessingContext, allow_selection: bool = False) -> Tuple[str, bool]: """ Parse a layer specification if allow_selection is set to True: 'select' parameter is interpreted has holding a qgis feature request expression :return: A tuple (path, bool) """ u = urlparse(layerspec) p = u.path if u.scheme == 'file': p = context.resolve_path(p) elif u.scheme and u.scheme != 'layer': raise InvalidParameterValue("Bad scheme: %s" % layerspec) if not allow_selection: return p, False has_selection = False qs = parse_qs(u.query) feat_requests = qs.get('select', []) feat_rects = qs.get('rect', []) if feat_rects or feat_requests: has_selection = True layer = context.getMapLayer(p) if not layer: LOGGER.error("No layer path for url %s", u) raise InvalidParameterValue("No layer '%s' found" % u.path, ) if layer.type() != QgsMapLayer.VectorLayer: LOGGER.warning("Can apply selection only to vector layer") else: behavior = QgsVectorLayer.SetSelection try: LOGGER.debug("Applying features selection: %s", qs) # Apply filter rect first if feat_rects: rect = QgsRectangle(feat_rects[-1].split(',')[:4]) layer.selectByRect(rect, behavior=behavior) behavior = QgsVectorLayer.IntersectSelection # Selection by expressions if feat_requests: ftreq = feat_requests[-1] layer.selectByExpression(ftreq, behavior=behavior) except: LOGGER.error(traceback.format_exc()) raise NoApplicableCode("Feature selection failed") return p, has_selection
def input_to_geometry(inp: WPSInput) -> Geometry: """ Handle point from complex input """ data_format = inp.data_format if data_format.mime_type == FORMATS.WKT.mime_type: return wkt_to_geometry(inp.data) elif data_format.mime_type == FORMATS.GEOJSON.mime_type: return json_to_geometry(inp.data) elif data_format.mime_type == FORMATS.GML.mime_type: return gml_to_geometry(inp.data) raise NoApplicableCode("Unsupported data format: %s" % data_format)
def input_to_point( inp: WPSInput ): """ Handle point from complex input """ data_format = inp.data_format geom = None if data_format.mime_type == FORMATS.GEOJSON.mime_type: geom = ogr.CreateGeometryFromJson(inp.data) elif data_format.mime_type == FORMATS.GML.mime_type: geom = ogr.CreateGeometryFromGML(inp.data) if geom: srs = geom.GetSpatialReference() geom = QgsGeometry.fromWkt(geom.ExportToWkt()) if srs: srs = QgsCoordinateReferenceSystem.fromWkt(srs.ExportToWkt()) if srs and srs.isValid(): geom = QgsReferencedPointXY( geom.centroid().asPoint(), srs ) return geom raise NoApplicableCode("Unsupported data format: %s" % data_format)
def openurl(url: str, filename: os.PathLike, max_bytes: int = 0, **kwargs) -> None: """ Open url """ LOGGER.info("Fetching URL %s", url) num_bytes = 0 fail = False try: with open(filename, 'wb') as fh: def _callback(chunk: bytes) -> None: nonlocal num_bytes num_bytes += len(chunk) if num_bytes > max_bytes: raise FileSizeExceeded( 'File size for input exceeded for ref %s', url) fh.write(chunk) client = httpclient.HTTPClient() try: client.fetch(url, user_agent=USER_AGENT, streaming_callback=_callback, **kwargs) except Exception as e: fail = True raise NoApplicableCode("File Reference error %s: %s", url, str(e)) from None finally: client.close() finally: if fail and os.path.exists(filename): os.unlink(filename)
def get_results(self, uuid: str) -> Any: doc = self.executor.get_results(uuid) if doc is None: raise NoApplicableCode('No results found for %s' % uuid, code=404) return doc
################################################################## # Copyright 2016 OSGeo Foundation, # # represented by PyWPS Project Steering Committee, # # licensed under MIT, Please consult LICENSE.txt for details # ################################################################## try: from osgeo import gdal, ogr except ImportError as err: from pyqgiswps.exceptions import NoApplicableCode raise NoApplicableCode('Complex validation requires GDAL/OGR support')
def parse_post_request(handler): """Factory function returing propper parsing function """ try: doc = lxml.etree.fromstring(handler.request.body) except Exception as e: raise NoApplicableCode(e.msg) wpsrequest = WPSRequest() tagname = doc.tag def parse_post_getcapabilities(): """Parse POST GetCapabilities request """ acceptedversions = xpath_ns( doc, '/wps:GetCapabilities/ows:AcceptVersions/ows:Version') acceptedversions = ','.join(map(lambda v: v.text, acceptedversions)) wpsrequest.check_accepted_versions(acceptedversions) def parse_post_describeprocess(): """Parse POST DescribeProcess request """ version = doc.attrib.get('version') wpsrequest.check_and_set_version(version) language = doc.attrib.get('language') wpsrequest.check_and_set_language(language) wpsrequest.operation = 'describeprocess' wpsrequest.identifiers = [ identifier_el.text for identifier_el in xpath_ns(doc, './ows:Identifier') ] def parse_post_execute(): """Parse POST Execute request """ version = doc.attrib.get('version') wpsrequest.check_and_set_version(version) language = doc.attrib.get('language') wpsrequest.check_and_set_language(language) wpsrequest.operation = 'execute' identifier = xpath_ns(doc, './ows:Identifier') if not identifier: raise MissingParameterValue('Process identifier not set', 'Identifier') wpsrequest.identifier = identifier[0].text wpsrequest.lineage = 'false' wpsrequest.store_execute = 'false' wpsrequest.status = 'false' wpsrequest.inputs = get_inputs_from_xml(doc) wpsrequest.outputs = get_output_from_xml(doc) wpsrequest.raw = False if xpath_ns(doc, '/wps:Execute/wps:ResponseForm/wps:RawDataOutput'): wpsrequest.raw = True # executeResponse XML will not be stored wpsrequest.store_execute = 'false' # check if response document tag has been set then retrieve response_document = xpath_ns( doc, './wps:ResponseForm/wps:ResponseDocument') if len(response_document) > 0: wpsrequest.lineage = response_document[0].attrib.get( 'lineage', 'false') wpsrequest.store_execute = response_document[0].attrib.get( 'storeExecuteResponse', 'false') # XXX If storeExecuteResponse is set then we enforce # the status supports wpsrequest.status = wpsrequest.store_execute # Set timeout timeout = response_document[0].attrib.get('timeout') wpsrequest.check_and_set_timeout(timeout) # Set expiration expire = response_document[0].attrib.get('expire') wpsrequest.check_and_set_expiration(expire) if tagname == WPS.GetCapabilities().tag: wpsrequest.operation = 'getcapabilities' parse_post_getcapabilities() elif tagname == WPS.DescribeProcess().tag: wpsrequest.operation = 'describeprocess' parse_post_describeprocess() elif tagname == WPS.Execute().tag: wpsrequest.operation = 'execute' parse_post_execute() else: raise InvalidParameterValue('Unknown request %r' % tagname, 'request') # Return the created WPSRequest object return wpsrequest
async def execute(self, wps_request, wps_response): """ Execute a process :return: wps_response or None """ process = wps_response.process process.uuid = wps_response.uuid # Start request logstore.log_request(process.uuid, wps_request) # Check if we need no store the response wps_response.store = (wps_response.status >= STATUS.STORE_STATUS) # Get request defined timeout timeout = wps_request.timeout apply_future = self._pool.apply_async(self._run_process, args=(process.handler, wps_request, wps_response), timeout=timeout) if wps_response.status == STATUS.STORE_AND_UPDATE_STATUS: # --------------------------------- # Run the processe asynchronously # --------------------------------- async def do_execute_async(): # Handle errors while we are going async try: await apply_future except asyncio.TimeoutError: wps_response.update_status("Timeout Error", None, STATUS.ERROR_STATUS) except MaxRequestsExceeded: wps_response.update_status( "Server busy, please retry later", None, STATUS.ERROR_STATUS) except Exception: # There is no point to let the error go outside LOGGER.error(traceback.format_exc()) wps_response.update_status("Internal Error", None, STATUS.ERROR_STATUS) pass # Fire and forget asyncio.ensure_future(do_execute_async()) wps_response.update_status('Task accepted') return wps_response.document else: # ------------------------------- # Run process and wait for response # ------------------------------- try: return await apply_future except asyncio.TimeoutError: wps_response.update_status("Timeout Error", None, STATUS.ERROR_STATUS) raise NoApplicableCode("Execute Timeout", code=424) except MaxRequestsExceeded: raise NoApplicableCode("Server busy, please retry later", code=509) except RequestBackendError as e: if isinstance(e.response, ProcessException): raise NoApplicableCode("Process Error", code=424) else: raise