def decorator_selector(data_type, data): convert = None if data_type in LITERAL_DATA_TYPES: if data_type == 'string': convert = convert_string elif data_type == 'integer': convert = convert_integer elif data_type == 'float': convert = convert_float elif data_type == 'boolean': convert = convert_boolean elif data_type == 'positiveInteger': convert = convert_positiveInteger elif data_type == 'anyURI': convert = convert_anyURI elif data_type == 'time': convert = convert_time elif data_type == 'scale': convert = convert_scale elif data_type == 'angle': convert = convert_angle elif data_type == 'nonNegativeInteger': convert = convert_positiveInteger else: raise InvalidParameterValue( "Invalid data_type value of LiteralInput " + "set to '{}'".format(data_type)) try: return convert(data) except ValueError: raise InvalidParameterValue( "Could not convert value '{}' to format '{}'".format( data, data_type))
def _handler(self, request, response): # Need to process the elevationOut inputs from a list of strings, into an array of tuples. ranges = [] for elevationrange in request.inputs['elevationOut']: if '-' in elevationrange.data: minrange, maxrange = elevationrange.data.split('-') ranges.append((int(minrange), int(maxrange))) # need to error catch int() and min < max else: raise InvalidParameterValue( 'The value "{}" does not contain a "-" character to define a range, ' 'e.g. 0-100'.format(elevationrange.data)) LOGGER.debug("domains: %s" % (request.inputs['domain'][0].data)) domains = [] for val in request.inputs['domain'][0].data: ## Values appear to be coming in as minY, minX, maxY, maxX domains.append(float(val)) # If minX and maxX are 180, need to reset to 179.9 if domains[1] == -180 and domains[3] == 180: domains[1] = -179.875 domains[3] = 179.9 params = dict() for p in request.inputs: if p == 'elevationOut': params[p] = ranges elif p == 'domain': params[p] = domains else: params[p] = request.inputs[p][0].data # Need to test start and end dates make sense relative to each other if params['startdate'] >= params['enddate'] + timedelta(days=1): raise InvalidParameterValue("The end date is earlier than the start date!") if (params['enddate'] + timedelta(days=1)) - params['startdate'] >= timedelta(days=93): raise InvalidParameterValue("Can only run across a maximum of three months in one go") # Need to test we don't run too far backwards/forwards if params['timeFmt'] == "days": if params['time'] > 20: raise InvalidParameterValue("Can only run NAME over a maximum of 20 days forwards/backwards") else: if params['time'] > 20 * 24: raise InvalidParameterValue("Can only run NAME over a maximum of 20 days forwards/backwards") response.update_status("Processed parameters", 5) outdir, zippedfile, mapfile = run_name(params, response) response.outputs['FileContents'].file = zippedfile + '.zip' response.outputs['runid'].data = outdir response.outputs['ExamplePlot'].file = mapfile response.update_status("done", 100) return response
def translate_elevation(self, elevation_range): if '-' not in elevation_range: raise InvalidParameterValue( f'The value "{elevation_range}" does not contain a "-" character to define a range, e.g. 0-100') mini, maxi = elevation_range.split('-') try: mini = int(mini) maxi = int(maxi) except ValueError: raise InvalidParameterValue(f'The value {elevation_range} is incorrect: cannot find two numbers') if mini >= maxi: raise InvalidParameterValue(f'The value {elevation_range} is incorrect: minimum is not less than maximum') if mini < 0 or maxi < 0: raise InvalidParameterValue(f'The value {elevation_range} is incorrect: Entire range must be above 0') return mini, maxi
def execute(self, identifier, wps_request, uuid): """Parse and perform Execute WPS request call :param identifier: process identifier string :param wps_request: pywps.WPSRequest structure with parsed inputs, still in memory :param uuid: string identifier of the request """ self._set_grass() response = None try: process = self.processes[identifier] # make deep copy of the process instace # so that processes are not overriding each other # just for execute process = copy.deepcopy(process) workdir = os.path.abspath( config.get_config_value('server', 'workdir')) tempdir = tempfile.mkdtemp(prefix='pywps_process_', dir=workdir) process.set_workdir(tempdir) except KeyError: raise InvalidParameterValue("Unknown process '%r'" % identifier, 'Identifier') olddir = os.path.abspath(os.curdir) try: os.chdir(process.workdir) response = self._parse_and_execute(process, wps_request, uuid) finally: os.chdir(olddir) return response
def __init__(self, identifier, title=None, abstract=None, keywords=[], crss=None, dimensions=None, workdir=None, mode=MODE.SIMPLE, min_occurs=1, max_occurs=1, metadata=[], default=None, default_type=SOURCE_TYPE.DATA): BasicIO.__init__(self, identifier, title, abstract, keywords, min_occurs, max_occurs, metadata) BasicBoundingBox.__init__(self, crss, dimensions) DataHandler.__init__(self, workdir=workdir, mode=mode) if default_type != SOURCE_TYPE.DATA: raise InvalidParameterValue( "Source types other than data are not supported.") self._default = default self._default_type = default_type self._set_default_value(default, default_type)
def describe(self, identifiers): if not identifiers: raise MissingParameterValue('', 'identifier') identifier_elements = [] # 'all' keyword means all processes if 'all' in (ident.lower() for ident in identifiers): for process in self.processes: try: identifier_elements.append(self.processes[process].describe_xml()) except Exception as e: raise NoApplicableCode(e) else: for identifier in identifiers: try: process = self.processes[identifier] except KeyError: raise InvalidParameterValue("Unknown process %r" % identifier, "identifier") else: try: identifier_elements.append(process.describe_xml()) except Exception as e: raise NoApplicableCode(e) doc = WPS.ProcessDescriptions( *identifier_elements ) doc.attrib['{http://www.w3.org/2001/XMLSchema-instance}schemaLocation'] = 'http://www.opengis.net/wps/1.0.0 http://schemas.opengis.net/wps/1.0.0/wpsDescribeProcess_response.xsd' doc.attrib['service'] = 'WPS' doc.attrib['version'] = '1.0.0' doc.attrib['{http://www.w3.org/XML/1998/namespace}lang'] = 'en-CA' return xml_response(doc)
def set_data(self, data): """Set data value. input data are converted into target format """ if self.data_type: # TODO: check datatypeabstract class somethings missing here # check if it is a valid data_type if self.data_type.lower() in LITERAL_DATA_TYPES: if self.data_type.lower() == 'string': data = text_type(data) elif self.data_type.lower() == 'integer': data = int(data) elif self.data_type.lower() == 'float': data = float(data) elif self.data_type.lower() == 'boolean': if data.lower() == 'true': data = True else: data = False #data = self.data_type.convert(data) _valid = self.validator(self, self.valid_mode) if not _valid: raise InvalidParameterValue('Input data not valid using ' 'mode %s' % (self.valid_mode)) IOHandler.set_data(self, data)
def execute(self, identifier, wps_request): """Parse and perform Execute WPS request call :param identifier: process identifier string :param wps_request: pywps.WPSRequest structure with parsed inputs, still in memory """ response = None try: process = self.processes[identifier] workdir = config.get_config_value('server', 'workdir') tempdir = tempfile.mkdtemp(prefix='pypws_process_', dir=workdir) process.set_workdir(tempdir) except KeyError: raise InvalidParameterValue("Unknown process '%r'" % identifier) olddir = os.path.abspath(os.curdir) try: os.chdir(process.workdir) response = self._parse_and_execute(process, wps_request) os.chdir(olddir) shutil.rmtree(process.workdir) except Exception as e: os.chdir(olddir) shutil.rmtree(process.workdir) raise e return response
def __init__(self, identifier, title=None, abstract=None, keywords=None, data_type="integer", workdir=None, allowed_values=None, uoms=None, mode=MODE.NONE, min_occurs=1, max_occurs=1, metadata=[], default=None, default_type=SOURCE_TYPE.DATA): BasicIO.__init__(self, identifier, title, abstract, keywords, min_occurs, max_occurs, metadata) BasicLiteral.__init__(self, data_type, uoms) SimpleHandler.__init__(self, workdir, data_type, mode=mode) if default_type != SOURCE_TYPE.DATA: raise InvalidParameterValue( "Source types other than data are not supported.") self.any_value = is_anyvalue(allowed_values) self.allowed_values = [] if not self.any_value: self.allowed_values = make_allowedvalues(allowed_values) self._default = default self._default_type = default_type if default is not None: self.data = default
def _handler(request, response): model = request.inputs['model'][0].data variable = request.inputs['variable'][0].data # Throw manually with temporary bbox solution if request.inputs['min_lon'][0].data < 0: raise InvalidParameterValue( 'Minimum longitude input cannot be below 0') if request.inputs['max_lon'][0].data > 360: raise InvalidParameterValue( 'Maximum longitude input cannot be above 360') if request.inputs['min_lat'][0].data < -90: raise InvalidParameterValue( 'Minimum latitude input cannot be below -90') if request.inputs['max_lat'][0].data > 90: raise InvalidParameterValue( 'Minimum latitude input cannot be above 90') d1 = cftime.Datetime360Day(2010, 1, 1) d2 = cftime.Datetime360Day(2020, 1, 1) nc_files_path = f'xarray' files_path = os.path.join(str(Path.home()), nc_files_path) files = glob.glob(files_path + '/tas*.nc') #response.update_status("Reading through files", 10) files_to_open = get_years(files) new_dataset = open_mfdatasets(files_to_open) #response.update_status("Calculating temporal average", 50) sliced_dataset = new_dataset.sel( time=slice(d1, d2), lon=slice(request.inputs['min_lon'][0].data, request.inputs['max_lon'][0].data), lat=slice(request.inputs['min_lat'][0].data, request.inputs['max_lat'][0].data)) # calculate temporal average across the time axis only mean_array = sliced_dataset.mean(dim='time') print(mean_array) response.update_status("Writing results to a new NetCDF4 file", 50) # result_nc_file = mean_array.to_netcdf('results.nc') response.outputs['output'].nc_file = mean_array.to_netcdf( 'resultsssss.nc') response.update_status("Done.", 100) return response
def _check_valid(self): """Validate this input usig given validator """ validate = self.validator _valid = validate(self, self.valid_mode) if not _valid: raise InvalidParameterValue('Input data not valid using ' 'mode %s' % (self.valid_mode))
def convert_positiveInteger(inpt): """Return value of input""" inpt = convert_integer(inpt) if inpt < 0: raise InvalidParameterValue( 'The value "{}" is not of type positiveInteger'.format(inpt)) else: return inpt
def _check_valid(self): """Validate this input using given validator """ validate = self.validator _valid = validate(self, self.valid_mode) if not _valid: self.data_set = False raise InvalidParameterValue('Input data not valid using ' 'mode {}'.format(self.valid_mode)) self.data_set = True
def check_and_set_language(self, language): """set this.language """ if not language: language = 'None' elif language != 'en-US': raise InvalidParameterValue( 'The requested language "{}" is not supported by this server'.format(language), 'language') else: self.language = language
def input_from_json(json_data): if json_data['type'] == 'complex': inpt = ComplexInput.from_json(json_data) elif json_data['type'] == 'literal': inpt = LiteralInput.from_json(json_data) elif json_data['type'] == 'bbox': inpt = BoundingBoxInput.from_json(json_data) else: raise InvalidParameterValue("Input type not recognized: {}".format(json_data['type'])) return inpt
def data_format(self, data_format): """self data_format setter """ if self._is_supported(data_format): self._data_format = data_format if not data_format.validate or data_format.validate == emptyvalidator: data_format.validate = get_validator(data_format.mime_type) else: raise InvalidParameterValue( "Requested format {}, {}, {} not supported".format( data_format.mime_type, data_format.encoding, data_format.schema), 'mimeType')
def convert_anyURI(inpt): """Return value of input :rtype: url components """ inpt = convert_string(inpt) components = urlparse.urlparse(inpt) if components[0] and components[1]: return components else: raise InvalidParameterValue( 'The value "{}" does not seem to be of type anyURI'.format(inpt))
def _handler(request, response): model = request.inputs['model'][0].data variable = request.inputs['variable'][0].data # Throw manually with temporary bbox solution if request.inputs['min_lon'][0].data < 0: raise InvalidParameterValue('Minimum longitude input cannot be below 0') if request.inputs['max_lon'][0].data > 360: raise InvalidParameterValue('Maximum longitude input cannot be above 360') if request.inputs['min_lat'][0].data < -90: raise InvalidParameterValue('Minimum latitude input cannot be below -90') if request.inputs['max_lat'][0].data > 90: raise InvalidParameterValue('Minimum latitude input cannot be above 90') d1 = cftime.Datetime360Day(2010, 1, 1) d2 = cftime.Datetime360Day(2020, 1, 1) glob_pattern = f'/badc/cmip5/data/cmip5/output1/MOHC/{model}/rcp45/mon/atmos/Amon/r1i1p1/latest/{variable}/*.nc' files = glob.glob(glob_pattern) files_to_open = get_years(files) new_dataset = open_mfdatasets(files_to_open) sliced_dataset = new_dataset.sel(time=slice(d1, d2), lon=slice(request.inputs['min_lon'][0].data, request.inputs['max_lon'][0].data), lat=slice(request.inputs['min_lat'][0].data, request.inputs['max_lat'][0].data)) # calculate temporal average across the time axis only mean_array = sliced_dataset.mean(dim='time') print(mean_array) response.update_status("Writing results to a new NetCDF4 file", 50) output_path = '/tmp/output.nc' response.outputs['output'].nc_file = mean_array.to_netcdf(output_path) print(f'Wrote: {output_path}') response.update_status("Done.", 100) return response
def prepare_process_for_execution(self, identifier): """Prepare the process identified by ``identifier`` for execution. """ try: process = self.processes[identifier] except KeyError: raise InvalidParameterValue("Unknown process '{}'".format(identifier), 'Identifier') # make deep copy of the process instace # so that processes are not overriding each other # just for execute process = copy.deepcopy(process) process.service = self workdir = os.path.abspath(config.get_config_value('server', 'workdir')) tempdir = tempfile.mkdtemp(prefix='pywps_process_', dir=workdir) process.set_workdir(tempdir) return process
def _get_request(self): """HTTP GET request parser """ # service shall be WPS service = _get_get_param(self.http_request, 'service') if service: if str(service).lower() != 'wps': raise InvalidParameterValue( 'parameter SERVICE [{}] not supported'.format(service), 'service') else: raise MissingParameterValue('service', 'service') operation = _get_get_param(self.http_request, 'request') request_parser = self._get_request_parser(operation) request_parser(self.http_request)
def describe(self, identifiers): identifier_elements = [] # 'all' keyword means all processes if 'all' in (ident.lower() for ident in identifiers): for process in self.processes: identifier_elements.append( self.processes[process].describe_xml()) else: for identifier in identifiers: try: process = self.processes[identifier] except KeyError: raise InvalidParameterValue( "Unknown process %r" % identifier, "identifier") else: identifier_elements.append(process.describe_xml()) doc = WPS.ProcessDescriptions(*identifier_elements) return xml_response(doc)
def json(self): processes = [] if 'all' in (ident.lower() for ident in self.identifiers): processes = (self.processes[p].json for p in self.processes) else: for identifier in self.identifiers: if identifier not in self.processes: msg = "Unknown process {}".format(identifier) raise InvalidParameterValue(msg, "identifier") else: processes.append(self.processes[identifier].json) return { 'pywps_version': __version__, 'processes': processes, 'lang': 'en-US' }
def check_and_set_language(self, language): """set this.language """ supported_languages = configuration.get_config_value( 'server', 'language').split(',') supported_languages = [lang.strip() for lang in supported_languages] if not language: # default to the first supported language language = supported_languages[0] if language not in supported_languages: raise InvalidParameterValue( 'The requested language "{}" is not supported by this server'. format(language), 'language', ) self.language = language
def __init__(self, identifier, title=None, abstract=None, keywords=None, data_type="integer", workdir=None, allowed_values=None, uoms=None, mode=MODE.NONE, min_occurs=1, max_occurs=1, metadata=[], default=None, default_type=SOURCE_TYPE.DATA): BasicIO.__init__(self, identifier, title, abstract, keywords, min_occurs, max_occurs, metadata) BasicLiteral.__init__(self, data_type, uoms) SimpleHandler.__init__(self, workdir, data_type, mode=mode) if default_type != SOURCE_TYPE.DATA: raise InvalidParameterValue( "Source types other than data are not supported.") self.any_value = False self.values_reference = None self.allowed_values = [] if allowed_values: if not isinstance(allowed_values, (tuple, list)): allowed_values = [allowed_values] self.any_value = any(is_anyvalue(a) for a in allowed_values) for value in allowed_values: if is_values_reference(value): self.values_reference = value break self.allowed_values = make_allowedvalues(allowed_values) self._default = default self._default_type = default_type if default is not None: self.data = default
def create_complex_inputs(self, source, inputs): """Create new ComplexInput as clone of original ComplexInput because of inputs can be more than one, take it just as Prototype. :param source: The process's input definition. :param inputs: The request input data. :return collections.deque: """ outinputs = deque(maxlen=source.max_occurs) for inpt in inputs: data_input = source.clone() frmt = data_input.supported_formats[0] if 'mimeType' in inpt: if inpt['mimeType']: frmt = data_input.get_format(inpt['mimeType']) else: frmt = data_input.data_format if frmt: data_input.data_format = frmt else: raise InvalidParameterValue( 'Invalid mimeType value {} for input {}'.format( inpt.get('mimeType'), source.identifier), 'mimeType') data_input.method = inpt.get('method', 'GET') data_input.process(inpt) outinputs.append(data_input) if len(outinputs) < source.min_occurs: description = "At least {} inputs are required. You provided {}.".format( source.min_occurs, len(outinputs), ) raise MissingParameterValue(description=description, locator=source.identifier) return outinputs
def create_complex_inputs(self, source, inputs): """Create new ComplexInput as clone of original ComplexInput because of inputs can be more then one, take it just as Prototype :return collections.deque: """ outinputs = deque(maxlen=source.max_occurs) for inpt in inputs: data_input = source.clone() frmt = data_input.supported_formats[0] if 'mimeType' in inpt: if inpt['mimeType']: frmt = data_input.get_format(inpt['mimeType']) else: frmt = data_input.data_format if frmt: data_input.data_format = frmt else: raise InvalidParameterValue( 'Invalid mimeType value %s for input %s' %\ (inpt.get('mimeType'), source.identifier), 'mimeType') data_input.method = inpt.get('method', 'GET') # get the referenced input otherwise get the value of the field href = inpt.get('href', None) complex_data_handler = self._get_complex_input_handler(href) complex_data_handler(data_input, inpt) outinputs.append(data_input) if len(outinputs) < source.min_occurs: raise MissingParameterValue(locator = source.identifier) return outinputs
def _get_request(self): """HTTP GET request parser """ # WSDL request wsdl = _get_get_param(self.http_request, 'WSDL') if wsdl is not None: # TODO: fix #57 then remove the exception raise NoApplicableCode('WSDL not implemented') # service shall be WPS service = _get_get_param(self.http_request, 'service', aslist=False) if service: if str(service).lower() != 'wps': raise InvalidParameterValue( 'parameter SERVICE [%s] not supported' % service) else: raise MissingParameterValue('service', 'service') operation = _get_get_param(self.http_request, 'request', aslist=False) request_parser = self._get_request_parser(operation) request_parser(self.http_request)
def _parse_and_execute(self, process, wps_request): """Parse and execute request """ # check if datainputs is required and has been passed if process.inputs: if wps_request.inputs is None: raise MissingParameterValue('', 'datainputs') # check if all mandatory inputs have been passed data_inputs = {} for inpt in process.inputs: if inpt.identifier not in wps_request.inputs: if inpt.min_occurs > 0: raise MissingParameterValue(inpt.identifier, inpt.identifier) else: data_inputs[inpt.identifier] = inpt.clone() # Replace the dicts with the dict of Literal/Complex inputs # set the input to the type defined in the process if isinstance(inpt, ComplexInput): data_inputs[inpt.identifier] = self.create_complex_inputs(inpt, wps_request.inputs[inpt.identifier]) elif isinstance(inpt, LiteralInput): data_inputs[inpt.identifier] = self.create_literal_inputs(inpt, wps_request.inputs[inpt.identifier]) elif isinstance(inpt, BoundingBoxInput): data_inputs[inpt.identifier] = self.create_bbox_inputs(inpt, wps_request.inputs[inpt.identifier]) wps_request.inputs = data_inputs # set as_reference to True for all the outputs specified as reference # if the output is not required to be raw if not wps_request.raw: for wps_outpt in wps_request.outputs: is_reference = wps_request.outputs[wps_outpt].get('asReference', 'false') if is_reference.lower() == 'true': # check if store is supported if process.store_supported == 'false': raise StorageNotSupported('The storage of data is not supported for this process.') is_reference = True else: is_reference = False for outpt in process.outputs: if outpt.identifier == wps_outpt: outpt.as_reference = is_reference # catch error generated by process code try: wps_response = process.execute(wps_request) except Exception as e: raise NoApplicableCode('Service error: %s' % e) # get the specified output as raw if wps_request.raw: for outpt in wps_request.outputs: for proc_outpt in process.outputs: if outpt == proc_outpt.identifier: return Response(proc_outpt.data) # if the specified identifier was not found raise error raise InvalidParameterValue('') return wps_response
def _parse_and_execute(self, process, wps_request, uuid): """Parse and execute request """ LOGGER.debug('Checking if all mandatory inputs have been passed') data_inputs = {} for inpt in process.inputs: # Replace the dicts with the dict of Literal/Complex inputs # set the input to the type defined in the process. request_inputs = None if inpt.identifier in wps_request.inputs: request_inputs = wps_request.inputs[inpt.identifier] if not request_inputs: if inpt.data_set: data_inputs[inpt.identifier] = [inpt.clone()] else: if isinstance(inpt, ComplexInput): data_inputs[inpt.identifier] = self.create_complex_inputs( inpt, request_inputs) elif isinstance(inpt, LiteralInput): data_inputs[inpt.identifier] = self.create_literal_inputs( inpt, request_inputs) elif isinstance(inpt, BoundingBoxInput): data_inputs[inpt.identifier] = self.create_bbox_inputs( inpt, request_inputs) for inpt in process.inputs: if inpt.identifier not in data_inputs: if inpt.min_occurs > 0: LOGGER.error('Missing parameter value: %s', inpt.identifier) raise MissingParameterValue(inpt.identifier, inpt.identifier) wps_request.inputs = data_inputs # set as_reference to True for all the outputs specified as reference # if the output is not required to be raw if not wps_request.raw: for wps_outpt in wps_request.outputs: is_reference = wps_request.outputs[wps_outpt].get( 'asReference', 'false') if is_reference.lower() == 'true': # check if store is supported if process.store_supported == 'false': raise StorageNotSupported( 'The storage of data is not supported for this process.' ) is_reference = True else: is_reference = False for outpt in process.outputs: if outpt.identifier == wps_outpt: outpt.as_reference = is_reference # catch error generated by process code try: wps_response = process.execute(wps_request, uuid) except Exception as e: e_follow = e if not isinstance(e, NoApplicableCode): e_follow = NoApplicableCode('Service error: %s' % e) if wps_request.raw: resp = Response(e_follow.get_body(), mimetype='application/xml') resp.call_on_close(process.clean) return resp else: raise e_follow # get the specified output as raw if wps_request.raw: for outpt in wps_request.outputs: for proc_outpt in process.outputs: if outpt == proc_outpt.identifier: return Response(proc_outpt.data) # if the specified identifier was not found raise error raise InvalidParameterValue('') return wps_response
def _post_request_parser(self, tagname): """Factory function returing propper parsing function """ wpsrequest = self def parse_post_getcapabilities(doc): """Parse POST GetCapabilities request """ acceptedversions = self.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(doc): """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 self.xpath_ns(doc, './ows:Identifier')] def parse_post_execute(doc): """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 = self.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 self.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 = self.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') wpsrequest.status = response_document[ 0].attrib.get('status', 'false') if tagname == self.WPS.GetCapabilities().tag: self.operation = 'getcapabilities' return parse_post_getcapabilities elif tagname == self.WPS.DescribeProcess().tag: self.operation = 'describeprocess' return parse_post_describeprocess elif tagname == self.WPS.Execute().tag: self.operation = 'execute' return parse_post_execute else: raise InvalidParameterValue( 'Unknown request {}'.format(tagname), 'request')