Exemple #1
0
def check_status(url=None, response=None, sleep_secs=2, verify=False):
    """
    Run owslib.wps check_status with additional exception handling.

    :param verify: Flag to enable SSL verification. Default: False
    :return: OWSLib.wps.WPSExecution object.
    """
    execution = WPSExecution()
    if response:
        logger.debug("using response document ...")
        xml = response
    elif url:
        logger.debug('using status_location url ...')
        xml = requests.get(url, verify=verify).content
    else:
        raise Exception("you need to provide a status-location url or response object.")
    if type(xml) is unicode:
        xml = xml.encode('utf8', errors='ignore')
    execution.checkStatus(response=xml, sleepSecs=sleep_secs)
    if execution.response is None:
        raise Exception("check_status failed!")
    # TODO: workaround for owslib type change of reponse
    if not isinstance(execution.response, etree._Element):
        execution.response = etree.fromstring(execution.response)
    return execution
Exemple #2
0
def check_status(url=None, response=None, sleep_secs=2, verify=False):
    """
    Run owslib.wps check_status with additional exception handling.

    :param verify: Flag to enable SSL verification. Default: False
    :return: OWSLib.wps.WPSExecution object.
    """
    execution = WPSExecution()
    if response:
        LOGGER.debug("using response document ...")
        xml = response
    elif url:
        LOGGER.debug('using status_location url ...')
        xml = requests.get(url, verify=verify).content
    else:
        raise Exception(
            "you need to provide a status-location url or response object.")
    # TODO: see owslib: https://github.com/geopython/OWSLib/pull/477
    execution.checkStatus(response=xml, sleepSecs=sleep_secs)
    if execution.response is None:
        raise Exception("check_status failed!")
    # TODO: workaround for owslib type change of reponse
    if not isinstance(execution.response, etree._Element):
        execution.response = etree.fromstring(execution.response)
    return execution
Exemple #3
0
 def execute_job(self, process_id, wps_inputs, wps_outputs, mode, job_uuid):
     """
     Real execution of the process by active Celery Worker.
     """
     execution = WPSExecution(version="2.0", url="localhost")
     xml_request = execution.buildRequest(process_id,
                                          wps_inputs,
                                          wps_outputs,
                                          mode=mode,
                                          lineage=True)
     wps_request = WPSRequest()
     wps_request.identifier = process_id
     wps_request.set_version("2.0.0")
     request_parser = wps_request._post_request_parser(
         wps_request.WPS.Execute().tag)  # noqa: W0212
     request_parser(xml_request)
     # NOTE:
     #  Setting 'status = false' will disable async execution of 'pywps.app.Process.Process'
     #  but this is needed since this job is running within Celery worker already async
     #  (daemon process can't have children processes)
     #  Because if how the code in PyWPS is made, we have to re-enable creation of status file
     wps_request.status = "false"
     wps_response = super(WorkerService,
                          self).execute(process_id, wps_request, job_uuid)
     wps_response.store_status_file = True
     # update execution status with actual status file and apply required references
     execution = check_wps_status(
         location=wps_response.process.status_location,
         settings=self.settings)
     execution.request = xml_request
     return execution
Exemple #4
0
    def compare_io(self, name, fn, fmt):
        """Start the dummy process, post the request and check the response matches the input data."""

        # Note that `WPSRequest` calls `get_inputs_from_xml` which converts base64 input to bytes
        # See `_get_rawvalue_value`
        client = client_for(Service(processes=[create_fmt_process(name, fn, fmt)]))
        data = get_data(fn, fmt.encoding)

        wps = WPSExecution()
        doc = wps.buildRequest('test-fmt',
                               inputs=[('complex', ComplexDataInput(data, mimeType=fmt.mime_type,
                                                                    encoding=fmt.encoding))],
                               mode='sync')
        resp = client.post_xml(doc=doc)
        assert_response_success(resp)
        wps.parseResponse(resp.xml)
        out = wps.processOutputs[0].data[0]

        if 'gml' in fmt.mime_type:
            xml_orig = etree.tostring(etree.fromstring(data.encode('utf-8'))).decode('utf-8')
            xml_out = etree.tostring(etree.fromstring(out.decode('utf-8'))).decode('utf-8')
            # Not equal because the output includes additional namespaces compared to the origin.
            # self.assertEqual(xml_out, xml_orig)

        else:
            self.assertEqual(out.strip(), data.strip())
 def update(self):
     '''Updates the job in the database from the latest WPS execution status.'''
     
     # create a new execution from the job status URL
     execution = WPSExecution()
     execution.checkStatus(url=self.statusLocation, sleepSecs=0)       
     self._update(execution)
Exemple #6
0
def test_wps_request3():
    # Supply process input argument
    wfsUrl = "http://igsarm-cida-gdp2.er.usgs.gov:8082/geoserver/wfs"
    query = WFSQuery("sample:CONUS_States",
                     propertyNames=['the_geom', "STATE"],
                     filters=["CONUS_States.508", "CONUS_States.469"])
    featureCollection = WFSFeatureCollection(wfsUrl, query)
    processid = 'gov.usgs.cida.gdp.wps.algorithm.FeatureWeightedGridStatisticsAlgorithm'
    inputs = [
        ("FEATURE_ATTRIBUTE_NAME", "STATE"),
        ("DATASET_URI",
         "dods://igsarm-cida-thredds1.er.usgs.gov:8080/thredds/dodsC/dcp/conus_grid.w_meta.ncml"
         ), ("DATASET_ID", "ccsm3_a1b_tmax"), ("DATASET_ID", "ccsm3_a1b_pr"),
        ("DATASET_ID", "ccsm3_a1fi_tmax"),
        ("TIME_START", "1960-01-01T00:00:00.000Z"),
        ("TIME_END", "1960-12-31T00:00:00.000Z"),
        ("REQUIRE_FULL_COVERAGE", "true"), ("DELIMITER", "COMMA"),
        ("STATISTICS", "MEAN"), ("STATISTICS", "MINIMUM"),
        ("STATISTICS", "MAXIMUM"), ("STATISTICS", "WEIGHT_SUM"),
        ("STATISTICS", "VARIANCE"), ("STATISTICS", "STD_DEV"),
        ("STATISTICS", "COUNT"), ("GROUP_BY", "STATISTIC"),
        ("SUMMARIZE_TIMESTEP", "true"),
        ("SUMMARIZE_FEATURE_ATTRIBUTE", "true"),
        ("FEATURE_COLLECTION", featureCollection)
    ]
    output = "OUTPUT"

    # build XML request for WPS process execution
    execution = WPSExecution()
    requestElement = execution.buildRequest(processid, inputs, output=output)
    request = etree.tostring(requestElement)

    # Compare to cached XML request
    _request = open(resource_file('wps_USGSExecuteRequest2.xml'), 'rb').read()
    assert compare_xml(request, _request) is True
Exemple #7
0
def test_wps_response_with_lineage():
    execution = WPSExecution()
    xml = open(resource_file('wps_HummingbirdExecuteResponse1.xml'),
               'rb').read()
    execution.checkStatus(response=xml)
    assert execution.isSucceded()
    assert execution.creationTime == '2018-05-08T14:00:54Z'
    # check lineage input with literal data
    inp = execution.dataInputs[0]
    assert inp.identifier == 'test'
    assert inp.title == 'Select the test you want to run.'
    assert inp.abstract == 'CF-1.6=Climate and Forecast Conventions (CF)'
    assert inp.data[0] == 'CF-1.6'
    # check lineage input with reference
    inp = execution.dataInputs[1]
    assert inp.identifier == 'dataset'
    assert inp.title == 'Upload your NetCDF file here'
    assert inp.abstract == 'or enter a URL pointing to a NetCDF file.'
    assert inp.reference.startswith('https://www.esrl.noaa.gov/')
    # check output with reference
    outp = execution.processOutputs[0]
    assert outp.identifier == 'output'
    assert outp.title == 'Test Report'
    assert outp.abstract == 'Compliance checker test report.'
    assert outp.reference.startswith('http://localhost:8090/wpsoutputs')
Exemple #8
0
def test_wps_request3():
    # Supply process input arguments
    polygon = [(-102.8184, 39.5273), (-102.8184, 37.418), (-101.2363, 37.418),
               (-101.2363, 39.5273), (-102.8184, 39.5273)]
    featureCollection = GMLMultiPolygonFeatureCollection([polygon])
    processid = 'gov.usgs.cida.gdp.wps.algorithm.FeatureWeightedGridStatisticsAlgorithm'
    inputs = [("FEATURE_ATTRIBUTE_NAME", "the_geom"),
              ("DATASET_URI", "dods://igsarm-cida-thredds1.er.usgs.gov:8080/thredds/dodsC/dcp/conus_grid.w_meta.ncml"),
              ("DATASET_ID", "ccsm3_a1b_tmax"),
              ("TIME_START", "1960-01-01T00:00:00.000Z"),
              ("TIME_END", "1960-12-31T00:00:00.000Z"),
              ("REQUIRE_FULL_COVERAGE", "true"),
              ("DELIMITER", "COMMA"),
              ("STATISTICS", "MEAN"),
              ("STATISTICS", "MINIMUM"),
              ("STATISTICS", "MAXIMUM"),
              ("STATISTICS", "WEIGHT_SUM"),
              ("STATISTICS", "VARIANCE"),
              ("STATISTICS", "STD_DEV"),
              ("STATISTICS", "COUNT"),
              ("GROUP_BY", "STATISTIC"),
              ("SUMMARIZE_TIMESTEP", "false"),
              ("SUMMARIZE_FEATURE_ATTRIBUTE", "false"),
              ("FEATURE_COLLECTION", featureCollection)]
    output = "OUTPUT"
    # build XML request for WPS process execution
    execution = WPSExecution()
    requestElement = execution.buildRequest(processid, inputs, output=output)
    request = etree.tostring(requestElement)
    # Compare to cached XML request
    _request = open(resource_file('wps_USGSExecuteRequest3.xml'), 'rb').read()
    assert compare_xml(request, _request) is True
Exemple #9
0
def check_wps_status(
        location=None,  # type: Optional[str]
        response=None,  # type: Optional[XML]
        sleep_secs=2,  # type: int
        verify=True,  # type: bool
        settings=None,  # type: Optional[AnySettingsContainer]
):  # type: (...) -> WPSExecution
    """
    Run :func:`owslib.wps.WPSExecution.checkStatus` with additional exception handling.

    :param location: job URL or file path where to look for job status.
    :param response: WPS response document of job status.
    :param sleep_secs: number of seconds to sleep before returning control to the caller.
    :param verify: Flag to enable SSL verification.
    :param settings: Application settings to retrieve any additional request parameters as applicable.
    :return: OWSLib.wps.WPSExecution object.
    """
    def _retry_file():
        LOGGER.warning(
            "Failed retrieving WPS status-location, attempting with local file."
        )
        out_path = get_wps_local_status_location(location, settings)
        if not out_path:
            raise HTTPNotFound(
                "Could not find file resource from [{}].".format(location))
        LOGGER.info("Resolved WPS status-location using local file reference.")
        return open(out_path, "r").read()

    execution = WPSExecution()
    if response:
        LOGGER.debug("Retrieving WPS status from XML response document...")
        xml = response
    elif location:
        xml_resp = HTTPNotFound()
        try:
            LOGGER.debug("Attempt to retrieve WPS status-location from URL...")
            xml_resp = request_extra("get",
                                     location,
                                     verify=verify,
                                     settings=settings)
            xml = xml_resp.content
        except Exception as ex:
            LOGGER.debug("Got exception during get status: [%r]", ex)
            xml = _retry_file()
        if xml_resp.status_code == HTTPNotFound.code:
            LOGGER.debug("Got not-found during get status: [%r]", xml)
            xml = _retry_file()
    else:
        raise Exception(
            "Missing status-location URL/file reference or response with XML object."
        )
    if isinstance(xml, str):
        xml = xml.encode("utf8", errors="ignore")
    execution.checkStatus(response=xml, sleepSecs=sleep_secs)
    if execution.response is None:
        raise Exception("Missing response, cannot check status.")
    if not isinstance(execution.response, lxml.etree._Element):  # noqa
        execution.response = lxml.etree.fromstring(execution.response)
    return execution
Exemple #10
0
def collect_outputs(status_location):
    from owslib.wps import WPSExecution
    execution = WPSExecution()
    execution.checkStatus(url=status_location, sleepSecs=0)
    outputs = {}
    for output in execution.processOutputs:
        outputs[output.identifier] = output
    return outputs
Exemple #11
0
    def execute_job(
            self,
            job,  # type: Job
            wps_inputs,  # type: List[WPS_InputData]
            wps_outputs,  # type: List[WPS_OutputRequested]
            remote_process,  # type: Optional[Process]
            headers,  # type: Optional[AnyHeadersContainer]
    ):  # type: (...) -> WPSExecution
        """
        Real execution of the process by active Celery Worker.
        """
        process_id = job.process
        execution = WPSExecution(version="2.0", url="localhost")
        xml_request = execution.buildRequest(process_id,
                                             wps_inputs,
                                             wps_outputs,
                                             mode=job.execution_mode,
                                             lineage=True)
        wps_request = WorkerRequest(http_headers=headers)
        wps_request.identifier = process_id
        wps_request.check_and_set_language(job.accept_language)
        wps_request.set_version("2.0.0")
        request_parser = wps_request._post_request_parser(
            wps_request.WPS.Execute().tag)  # noqa: W0212
        request_parser(
            xml_request
        )  # parses the submitted inputs/outputs data and request parameters

        # NOTE:
        #  Setting 'status = false' will disable async execution of 'pywps.app.Process.Process'
        #  but this is needed since this job is running within Celery worker already async
        #  (daemon process can't have children processes).
        wps_request.status = "false"

        # When 'execute' is called, pywps will in turn call 'prepare_process_for_execution',
        # which then setups and retrieves currently loaded 'local' processes.
        # Since only local processes were defined by 'get_pywps_service',
        # a temporary process must be added for remote providers execution.
        if not remote_process:
            worker_process_id = process_id
        else:
            worker_process_id = f"wps_package-{process_id}-{job.uuid}"
            self.dispatched_processes[worker_process_id] = remote_process

        wps_response = super(WorkerService,
                             self).execute(worker_process_id, wps_request,
                                           job.uuid)
        # re-enable creation of status file so we can find it since we disabled 'status' earlier for sync execution
        wps_response.store_status_file = True
        # update execution status with actual status file and apply required references
        execution = check_wps_status(
            location=wps_response.process.status_location,
            settings=self.settings)
        execution.request = xml_request
        return execution
Exemple #12
0
    def getOWSLibExecutionResponse(cls, instance):
        _e = None
        if instance.execution.response:
            _e = WPSExecution()
            try:
                _e.checkStatus(url=instance.url,
                               response=str(instance.execution.response),
                               sleepSecs=0)
            except:
                pass

        return _e
Exemple #13
0
def test_wps_request9():
    # Process input/output arguments
    processid = "helloworld"
    inputs = [("user", 'Pingu')]

    # Build XML request for WPS process execution
    execution = WPSExecution()
    requestElement = execution.buildRequest(processid, inputs)
    request = etree.tostring(requestElement)

    # Compare to cached XML request
    _request = open(resource_file('wps_EmuExecuteRequest9.xml'), 'rb').read()
    assert compare_xml(request, _request) is True
Exemple #14
0
def test_wps_request11_bbox():
    processid = "bbox"
    bbox = BoundingBoxDataInput([51.9, 7.0, 53.0, 8.0])
    inputs = [("bbox", bbox)]

    # Build XML request for WPS process execution
    execution = WPSExecution()
    requestElement = execution.buildRequest(processid, inputs)
    request = etree.tostring(requestElement)

    # Compare to cached XML request
    _request = open(resource_file('wps_EmuExecuteRequest11.xml'), 'rb').read()
    assert compare_xml(request, _request) is True
Exemple #15
0
def test_wps_request5():
    # Process input/output arguments
    processid = "reprojectCoords"
    inputs = [("coords", "http://rsg.pml.ac.uk/wps/testdata/coords.txt"),
              ("outputSRS", "EPSG:32630"), ("inputSRS", "EPSG:4326")]

    # build XML request for WPS process execution
    execution = WPSExecution()
    requestElement = execution.buildRequest(processid, inputs)
    request = etree.tostring(requestElement)

    # Compare to cached XML request
    _request = open(resource_file('wps_PMLExecuteRequest5.xml'), 'rb').read()
    assert compare_xml(request, _request) is True
Exemple #16
0
def run_wps(res_ids,gap):

    if (gap ==''):
        gap = "linear"

    # checks if there is two resource IDs
    resources = res_ids.split("_")

    process_id = 'org.n52.wps.server.r.series_gap_filler_3'
    process_input = [('resource_id',str(resources[0])),('fill_function',str(gap))]

    #setting the WPS URL is set in app.py
    url_wps = GapFillerTool.wps_url + '/WebProcessingService'
    my_engine = WebProcessingService(url_wps, verbose=False, skip_caps=True)
    my_process = my_engine.describeprocess(process_id)

    #executing the process..
    # build execution

    execution = WPSExecution(version=my_engine.version, url=my_engine.url, username=my_engine.username,
                             password=my_engine.password, verbose=my_engine.verbose)

    requestElement = execution.buildRequest(process_id, process_input, 'output')

    request = etree.tostring(requestElement)
    #set store executeresponse to false

    request = request.replace('storeExecuteResponse="true"', 'storeExecuteResponse="false"')

    execution = my_engine.execute(process_id, process_input, 'output', request)

    monitorExecution(execution)

    status = execution.status


    # if the status is successful...
    if status == 'ProcessSucceeded':
        outputs = execution.processOutputs
        output0 = outputs[0]
        reference0 = output0.reference

        # retrieve the data from the reference
        output_data = requests.get(reference0)
        resp = HttpResponse(output_data, content_type="application/json")

        return resp

    else:
        return JsonResponse({'status': 'wps request failed'})
def test_wps_request5():
    # Process input/output arguments
    processid = "reprojectCoords"
    inputs = [("coords", "http://rsg.pml.ac.uk/wps/testdata/coords.txt"),
              ("outputSRS", "EPSG:32630"),
              ("inputSRS", "EPSG:4326")]

    # build XML request for WPS process execution
    execution = WPSExecution()
    requestElement = execution.buildRequest(processid, inputs)
    request = etree.tostring(requestElement)

    # Compare to cached XML request
    _request = open(resource_file('wps_PMLExecuteRequest5.xml'), 'rb').read()
    assert compare_xml(request, _request) is True
def test_wps_request4():
    # Process input/ouutput arguments
    processid = "reprojectImage"
    inputs = [("inputImage", "http://rsg.pml.ac.uk/wps/testdata/elev_srtm_30m.img"),
              ("outputSRS", "EPSG:4326")]
    output = "outputImage"

    # build XML request for WPS process execution
    execution = WPSExecution()
    requestElement = execution.buildRequest(processid, inputs, output=[(output, True)])
    request = etree.tostring(requestElement)

    # Compare to cached XML request
    _request = open(resource_file('wps_PMLExecuteRequest4.xml'), 'rb').read()
    assert compare_xml(request, _request) is True
Exemple #19
0
def test_wps_request4():
    # Process input/ouutput arguments
    processid = "reprojectImage"
    inputs = [("inputImage", "http://rsg.pml.ac.uk/wps/testdata/elev_srtm_30m.img"),
              ("outputSRS", "EPSG:4326")]
    output = "outputImage"

    # build XML request for WPS process execution
    execution = WPSExecution()
    requestElement = execution.buildRequest(processid, inputs, output=output)
    request = etree.tostring(requestElement)

    # Compare to cached XML request
    _request = open(resource_file('wps_PMLExecuteRequest4.xml'), 'rb').read()
    assert compare_xml(request, _request) is True
def test_wps_request8():
    # Process input/ouutput arguments
    processid = "wordcount"
    textdoc = ComplexDataInput("Alice was beginning to get very tired ...")
    inputs = [("text", textdoc), ]
    outputs = [("output", True), ]

    # Build XML request for WPS process execution
    execution = WPSExecution()
    requestElement = execution.buildRequest(processid, inputs, output=outputs, mode=ASYNC, lineage=True)
    request = etree.tostring(requestElement)

    # Compare to cached XML request
    _request = open(resource_file('wps_EmuExecuteRequest8.xml'), 'rb').read()
    assert compare_xml(request, _request) is True
def test_wps_request6():
    # Process input/output arguments

    processid = "v.net.path"
    inputs = [("input", "http://rsg.pml.ac.uk/wps/example/graph.gml"),
              ("file", "1 -960123.1421801624 4665723.56559387 -101288.65106088226 5108200.011823481")]

    # Build XML request for WPS process execution
    execution = WPSExecution()
    requestElement = execution.buildRequest(processid, inputs)
    request = etree.tostring(requestElement)

    # Compare to cached XML request
    _request = open(resource_file('wps_PMLExecuteRequest6.xml'), 'rb').read()
    assert compare_xml(request, _request) is True
Exemple #22
0
def test_wps_request8():
    # Process input/ouutput arguments
    processid = "wordcount"
    textdoc = ComplexDataInput("Alice was beginning to get very tired ...")
    inputs = [("text", textdoc), ]
    outputs = [("output", True), ]

    # Build XML request for WPS process execution
    execution = WPSExecution()
    requestElement = execution.buildRequest(processid, inputs, output=outputs, async=True, lineage=True)
    request = etree.tostring(requestElement)

    # Compare to cached XML request
    _request = open(resource_file('wps_EmuExecuteRequest8.xml'), 'rb').read()
    assert compare_xml(request, _request) is True
Exemple #23
0
def test_wps_ncml():

    client = client_for(Service(processes=[NcMLAgg()], cfgfiles=CFG_FILE))

    resp = client.get(service='wps',
                      request='execute',
                      version='1.0.0',
                      identifier='ncml')

    assert_response_success(resp)

    ex = WPSExecution()
    ex.parseResponse(resp.xml)
    d1, d2, d3 = ex.processOutputs
    ncml = d3.retrieveData()
    assert ncml.strip().startswith("<")
Exemple #24
0
def test_wps_request7():
    # Process input/ouutput arguments
    processid = "wordcount"
    textdoc = ComplexDataInput("http://emu.readthedocs.org/en/latest/index.html")
    inputs = [("text", textdoc), ]
    outputs = [("output", True)]

    # Build XML request for WPS process execution, sync request
    execution = WPSExecution()
    requestElement = execution.buildRequest(processid, inputs, output=outputs, mode=SYNC, lineage=False)
    request = etree.tostring(requestElement)

    # Compare to cached XML request
    _request = open(resource_file('wps_EmuExecuteRequest7.xml'), 'rb').read()
    print(request)
    assert compare_xml(request, _request) is True
Exemple #25
0
def execute_process(client,
                    identifier,
                    inputs,
                    output_names=("output_netcdf", )) -> xr.Dataset:
    """Execute a process using the test client, and return the 'output_netcdf' output as an xarray.Dataset"""
    request_doc = WPS.Execute(OWS.Identifier(identifier),
                              WPS.DataInputs(*inputs),
                              version="1.0.0")
    response = client.post_xml(doc=request_doc)
    assert_response_success(response)

    execution = WPSExecution()
    execution.parseResponse(response.xml)

    outputs = get_file_outputs(execution, output_names=output_names)

    return outputs
def run_wps(res_ids):
    print"launch wps"
    print res_ids
    # checks if there is two resource IDs
    resources = res_ids.split("_")
    if len(resources) < 2:
        return JsonResponse({'status': 'wps request failed. 2 resources are required, found ' + str(len(resources))})

    process_id = 'org.n52.wps.server.r.linear_regression'
    process_input = [('x_resource_id',str(resources[0])),('y_resource_id',str(resources[1]))]

    #setting the WPS URL is set in app.py
    url_wps = CorrelationPlot.wps_url + '/WebProcessingService'

    my_engine = WebProcessingService(url_wps, verbose=False, skip_caps=True)
    my_process = my_engine.describeprocess(process_id)

    #executing the process..
    # build execution
    execution = WPSExecution(version=my_engine.version, url=my_engine.url, username=my_engine.username,
                             password=my_engine.password, verbose=my_engine.verbose)
    requestElement = execution.buildRequest(process_id, process_input, 'output')
    request = etree.tostring(requestElement)
    #set store executeresponse to false
    request = request.replace('storeExecuteResponse="true"', 'storeExecuteResponse="false"')
    print request

    execution = my_engine.execute(process_id, process_input, 'output', request)

    monitorExecution(execution)
    status = execution.status
    print status

    # if the status is successful...
    if status == 'ProcessSucceeded':
        outputs = execution.processOutputs
        output0 = outputs[0]
        reference0 = output0.reference

        # retrieve the data from the reference
        output_data = requests.get(reference0)
        resp = HttpResponse(output_data, content_type="application/json")
        return resp

    else:
        return JsonResponse({'status': 'wps request failed'})
Exemple #27
0
    def checkStatus(cls, instance):
        if not instance.is_initialized():
            exception = Exception("Not initialized!")
            log.exception("Not initialized!")
            raise exception

        if instance.execution and isinstance(
                instance.execution,
                WebProcessingServiceExecution) and instance.execution.response:
            _e = WPSExecution(version=instance.version,
                              url=instance.url,
                              username=instance.username,
                              password=instance.password,
                              verbose=False)
            _e.request = instance.execution.request
            _e.statusLocation = instance.execution.status_location
            _e.serviceInstance = instance.service_instance
            try:
                _e.checkStatus(sleepSecs=3)
            except:
                log.exception(
                    "Exception while Checking WPS Execution Status {}".format(
                        _e))
            if _e.status:
                cls._update_instance_execution_status(instance, _e)
            else:
                raise Exception("Status check failed")
            return instance.execution.status
        else:
            exception = Exception("No running executions!")
            log.exception("No running executions!")
            raise exception
def execute(identifier, inputs=[], wps_host=None, wps_client=None,
            version='1.0.0'):
    if wps_host:
        wps = WebProcessingService(wps_host, version)
        return wps.execute(identifier, inputs=inputs)
    else:
        y = ''
        for data_input in inputs:
            y += '{0}={1};'.format(data_input[0], data_input[1])
        y = y[:-1]
        response = wps_client.get(
            ('?service=WPS&request=execute&version={0}&'
             'identifier={1}&DataInputs={2}').format(version, identifier, y))
        wps_reader = WPSReader()
        element = wps_reader.readFromString(response.get_data())
        execution = WPSExecution()
        execution._parseExecuteResponse(element)
        return execution
def test_wps_request6():
    # Process input/output arguments

    processid = "v.net.path"
    inputs = [
        ("input", "http://rsg.pml.ac.uk/wps/example/graph.gml"),
        ("file",
         "1 -960123.1421801624 4665723.56559387 -101288.65106088226 5108200.011823481"
         )
    ]

    # Build XML request for WPS process execution
    execution = WPSExecution()
    requestElement = execution.buildRequest(processid, inputs)
    request = etree.tostring(requestElement)

    # Compare to cached XML request
    _request = open(resource_file('wps_PMLExecuteRequest6.xml'), 'rb').read()
    assert compare_xml(request, _request) is True
Exemple #30
0
    def checkStatus(self):
        """
        Sends a request to the status URL checking the progress of the remote 
        process. If the process has finished creates the necessary Output 
        objects to fetch the results and stores them in the resultsLiteral and
        resultsComplex attributes.
        
        :returns: True if the process finished successfully 
                  False if the process is still running
        :rtype: Boolean
        """
        
        self.processError = ""
        self.processErrorCode = ""
        self.processErrorText = ""
        self.status = None                     

        if (self.statusURL == None):
            self.logger.error(self.ERR_05)
            raise Exception(self.ERR_05)

        try: 
            self.execution = WPSExecution()
            self.execution.statusLocation = self.statusURL
            self.execution.checkStatus(sleepSecs=0)
        except Exception as ex:
            mesg = "Unexpected error from OWSLib!! " + str(ex)
            self.logger.error(mesg)
            # This is a work arround !!!!!!!!
            # It is not clear why these calls to OWSLib are failing.
            # Thus RUNNING status is reported back
            self.status = self.RUNNING
            return False
        
        # Check if the process has finished
        if not (self.execution.isComplete()):
            self.status = self.RUNNING
            self.logger.debug("The process hasn't finished yet.")
            self.logger.info(str(self.percentCompleted) + " % of the execution complete.")
            return False
        
        # Check if the process failed
        if not (self.execution.isSucceded()):
            self.status = self.ERROR
            self.processError = self.execution.errors[0]
            self.processErrorText = self.execution.errors[0].text
            self.logger.error(self.ERR_06 + self.processErrorText)
            self.logger.debug("The status URL: " + self.execution.statusLocation)
            raise Exception(self.ERR_06 + self.processErrorText)


        self.logger.debug(self.SUCC_01)
        self.status = self.FINISHED
                    
        return True           
Exemple #31
0
def execute(identifier,
            inputs=[],
            wps_host=None,
            wps_client=None,
            version='1.0.0'):
    if wps_host:
        wps = WebProcessingService(wps_host, version)
        return wps.execute(identifier, inputs=inputs)
    else:
        y = ''
        for data_input in inputs:
            y += '{0}={1};'.format(data_input[0], data_input[1])
        y = y[:-1]
        response = wps_client.get(
            ('?service=WPS&request=execute&version={0}&'
             'identifier={1}&DataInputs={2}').format(version, identifier, y))
        wps_reader = WPSReader()
        element = wps_reader.readFromString(response.get_data())
        execution = WPSExecution()
        execution._parseExecuteResponse(element)
        return execution
Exemple #32
0
def execute_process(client, identifier, inputs,
                    output_names=("output", )) -> xr.Dataset:
    """Execute a process using the test client, and return the 'output_netcdf' output as an xarray.Dataset"""
    request_doc = WPS.Execute(OWS.Identifier(identifier),
                              WPS.DataInputs(*inputs),
                              version="1.0.0")
    response = client.post_xml(doc=request_doc)
    try:
        assert_response_success(response)
    except AssertionError as e:
        exception = response.xpath("//ows:Exception")[0]
        exception_code = exception.get("exceptionCode")
        message = exception[0].text
        output_message = f"{exception_code}: {message}"
        raise ProcessError(output_message) from e

    execution = WPSExecution()
    execution.parseResponse(response.xml)

    outputs = get_outputs(execution, output_names=output_names)

    return outputs
def test_wps_request3():
    # Supply process input argument
    wfsUrl = "http://igsarm-cida-gdp2.er.usgs.gov:8082/geoserver/wfs"
    query = WFSQuery("sample:CONUS_States",
                     propertyNames=['the_geom', "STATE"],
                     filters=["CONUS_States.508", "CONUS_States.469"])
    featureCollection = WFSFeatureCollection(wfsUrl, query)
    processid = 'gov.usgs.cida.gdp.wps.algorithm.FeatureWeightedGridStatisticsAlgorithm'
    inputs = [("FEATURE_ATTRIBUTE_NAME", "STATE"),
              ("DATASET_URI", "dods://igsarm-cida-thredds1.er.usgs.gov:8080/thredds/dodsC/dcp/conus_grid.w_meta.ncml"),
              ("DATASET_ID", "ccsm3_a1b_tmax"),
              ("DATASET_ID", "ccsm3_a1b_pr"),
              ("DATASET_ID", "ccsm3_a1fi_tmax"),
              ("TIME_START", "1960-01-01T00:00:00.000Z"),
              ("TIME_END", "1960-12-31T00:00:00.000Z"),
              ("REQUIRE_FULL_COVERAGE", "true"),
              ("DELIMITER", "COMMA"),
              ("STATISTICS", "MEAN"),
              ("STATISTICS", "MINIMUM"),
              ("STATISTICS", "MAXIMUM"),
              ("STATISTICS", "WEIGHT_SUM"),
              ("STATISTICS", "VARIANCE"),
              ("STATISTICS", "STD_DEV"),
              ("STATISTICS", "COUNT"),
              ("GROUP_BY", "STATISTIC"),
              ("SUMMARIZE_TIMESTEP", "true"),
              ("SUMMARIZE_FEATURE_ATTRIBUTE", "true"),
              ("FEATURE_COLLECTION", featureCollection)
              ]
    output = "OUTPUT"

    # build XML request for WPS process execution
    execution = WPSExecution()
    requestElement = execution.buildRequest(processid, inputs, output=output)
    request = etree.tostring(requestElement)

    # Compare to cached XML request
    _request = open(resource_file('wps_USGSExecuteRequest2.xml'), 'rb').read()
    assert compare_xml(request, _request) is True
def execute(identifier,
            inputs=[],
            wps_host=None,
            wps_client=None,
            version='1.0.0'):
    """WPS execute response.

    Parameters
    ----------
    identifer : string
    inputs : list of tuples
    wps_host : string
    wps_client : pywps.tests.WpsClient
    version : string

    Returns
    -------
    out : list of ?

    """

    if wps_host:
        wps = WebProcessingService(wps_host, version)
        return wps.execute(identifier, inputs=inputs)
    else:
        y = ''
        for data_input in inputs:
            y += '{0}={1};'.format(data_input[0], data_input[1])
        y = y[:-1]
        response = wps_client.get(
            ('?service=WPS&request=execute&version={0}&'
             'identifier={1}&DataInputs={2}').format(version, identifier, y))
        wps_reader = WPSReader()
        element = wps_reader.readFromString(response.get_data())
        execution = WPSExecution()
        execution._parseExecuteResponse(element)
        return execution
Exemple #35
0
def check_status(url=None, response=None, sleep_secs=2, verify=False):
    """
    Run owslib.wps check_status with additional exception handling.

    :param verify: Flag to enable SSL verification. Default: False
    :return: OWSLib.wps.WPSExecution object.
    """
    execution = WPSExecution()
    if response:
        LOGGER.debug("using response document ...")
        xml = response
    elif url:
        LOGGER.debug('using status_location url ...')
        xml = requests.get(url, verify=verify).content
    else:
        raise Exception("you need to provide a status-location url or response object.")
    # TODO: see owslib: https://github.com/geopython/OWSLib/pull/477
    execution.checkStatus(response=xml, sleepSecs=sleep_secs)
    if execution.response is None:
        raise Exception("check_status failed!")
    # TODO: workaround for owslib type change of reponse
    if not isinstance(execution.response, etree._Element):
        execution.response = etree.fromstring(execution.response)
    return execution
Exemple #36
0
def test_wps_response_with_lineage():
    execution = WPSExecution()
    xml = open(resource_file('wps_HummingbirdExecuteResponse1.xml'), 'rb').read()
    execution.checkStatus(response=xml)
    assert execution.isSucceded()
    assert execution.creationTime == '2018-05-08T14:00:54Z'
    # check lineage input with literal data
    inp = execution.dataInputs[0]
    assert inp.identifier == 'test'
    assert inp.title == 'Select the test you want to run.'
    assert inp.abstract == 'CF-1.6=Climate and Forecast Conventions (CF)'
    assert inp.data[0] == 'CF-1.6'
    # check lineage input with reference
    inp = execution.dataInputs[1]
    assert inp.identifier == 'dataset'
    assert inp.title == 'Upload your NetCDF file here'
    assert inp.abstract == 'or enter a URL pointing to a NetCDF file.'
    assert inp.reference.startswith('https://www.esrl.noaa.gov/')
    # check output with reference
    outp = execution.processOutputs[0]
    assert outp.identifier == 'output'
    assert outp.title == 'Test Report'
    assert outp.abstract == 'Compliance checker test report.'
    assert outp.reference.startswith('http://localhost:8090/wpsoutputs')
Exemple #37
0
class WPSClient:
    """ 
    This class manages the WPS request, status checking and results 
    processing cycle. 
    
    .. attribute:: logger
        Reference to logging object
        
    .. attribute:: logFormat
        String formating log output
        
    .. attribute:: processName
        Name of the process to invoke
    
    .. attribute:: inputs
        Array of pair lists composed by the input name and the respective value
    
    .. attribute:: outputs
        Array of pair lists composed by the output name and a boolean indicating return
        by reference (True) or data (False)
         
    .. attribute:: wps
        WPSExecution object used to communicate with the WPS server
               
    .. attribute:: execution
        WebProcessingService object used to invoke process execution on the remote WPS server
            
    .. attribute:: statusURL
        URL of the remote XML file where the process updates its status and 
        writes its results after completion
    
    .. attribute:: processId
        Identifier of the remote process, part of statusURL used to identify
        the results stored locally
    
    .. attribute:: percentCompleted
        Percentage of process completion, as reported in the status XML file
        
    .. attribute:: statusMessage
        Last status message returned during asynchronous execution
    
    .. attribute:: map
        Object of type MapFile used to generate the map file publishing complex
        outputs through MapServer
    
    .. attribute:: epsg
        EPSG code of the primary coordinate system used to publish complex 
        outputs
     
    .. attribute:: dataSets
        Array with output dataSets, created during map file generation
               
    .. attribute:: logFile
        Path to the log file
        
    .. attribute:: logLevel
        Level of logging
    
    .. attribute:: pathFilesGML
        Path where to store the GML files with complex outputs
    
    .. attribute:: mapServerURL
        URL of the MapServer instance to use
    
    .. attribute:: mapFilesPath
        Path where to write the map file (folder used by MapServer)
    
    .. attribute:: mapTemplate
        Path to the MapServer map template folder
    
    .. attribute:: imagePath
        Path to the MapServer image folder
    
    .. attribute:: imageURL
        URL to MapServer images folder
    
    .. attribute:: otherProjs
        String listing EPSG codes of further coordinate systems with which to
        publish the complex outputs
    """
    
    logger = None
    logFormat = "[WPSClient][%(asctime)s] %(levelname)s: %(message)s"
    
    processName = None
    inputs = None
    outputs = None
    wps = None
    execution = None
    statusURL = None
    processId = None
    percentCompleted = 0
    statusMessage = None
    map  = None
    epsg = None
    dataSets = []
    
    #Configs
    logFile      = None
    logLevel     = None
    pathFilesGML = None
    mapServerURL = None
    mapFilesPath = None
    mapTemplate  = None
    imagePath    = None
    imageURL     = None
    otherProjs   = None
    
    meta_fees = "none"
    meta_accessconstraints = "none"
    meta_keywordlist = ""
    meta_addresstype = ""
    meta_address = ""
    meta_city = ""
    meta_stateorprovince = ""
    meta_postcode = ""
    meta_country = ""
    meta_contactelectronicmailaddress = ""
    meta_contactperson = ""
    meta_contactorganization = ""
    meta_contactposition = ""
    meta_role = ""
    meta_contactvoicetelephone = ""
    meta_contactfacsimiletelephone = ""
    meta_contactinstructions = ""
    meta_hoursofservice = ""

    RUNNING = 1
    FINISHED = 2
    ERROR = 3
    
    #Messages
    WARN_02 = "Output "
    WARN_03 = " not added to the map file, possibly non complex output."
    WARN_04 = "No spatial layers found, no map file was written."
    ERR_04  = "EXECUTE request failed:\n"
    ERR_05  = "Incomplete request -- missing URL"
    ERR_06  = "The process failed with the following message:\n"
    ERR_07  = "Failed to save map file to disk:\n"
    ERR_08  = "Cannot generate a map file with the outputs specified."
    SUCC_01 = "The process has finished successfully.\nProcessing the results..."
    SUCC_02 = "Wrote map file to disk:\n"
    
    def __init__(self, logger = None):
         
        self.loadConfigs()
        
        if (logger == None):
            self.setupLogging()
            
        
    def init(self, serverAddress, processName, inputs, outputs):
        """
        Initialises the WPSClient object with the required arguments to create
        the WPS request.
        
        :param serverAddress: string with the address of the remote WPS server
        :param processName: string with process name
        :param inputNames: list of strings with input names
        :param inputValues: list of strings with input values
        :param outputNames: list of strings with output names       
        """
        
        # Loading this stuff here probably doesn't make sense
        # Check at a later data if __init__ is run from an external model (that includes this one)
        self.loadConfigs()
        self.setupLogging()
        
        self.processName = processName
        self.inputs = inputs
        self.outputs = outputs
        
        self.wps = WebProcessingService(serverAddress, verbose=False, skip_caps=True)       
        
        
    def initFromURL(self, url, outputs):
        """
        Initialises the WPSClient with the status URL address of a running 
        remote process. Used when a request has already been sent.
        
        :param url: string with the status URL address of a remote process      
        """
        
        # Loading this stuff here probably doesn't make sense
        # Check at a later data if __init__ is run from an external model (tha includes this one)
        self.loadConfigs()
        self.setupLogging()
        
        # Note that the outputs are not used
        self.statusURL = url
        self.outputs = outputs
        self.processId = self.decodeId(url)
        
    def loadConfigs(self):
        """ 
        Loads default attribute values from the configuration file. 
        """
        
        parser = SafeConfigParser()
        currDir = os.path.dirname(os.path.realpath(__file__))
        parentDir = os.path.abspath(os.path.join(currDir, os.pardir))
        parser.read(os.path.join(parentDir, 'WPSClient.cfg'))
    
        self.logFile      = parser.get('Logging',   'logFile')
        self.logLevel     = parser.get('Logging',   'logLevel')
        self.pathFilesGML = parser.get('Data',      'GMLfilesPath')
        self.mapServerURL = parser.get('MapServer', 'MapServerURL')
        self.mapFilesPath = parser.get('MapServer', 'mapFilesPath')
        self.mapTemplate  = parser.get('MapServer', 'mapTemplate')
        self.imagePath    = parser.get('MapServer', 'imagePath')
        self.imageURL     = parser.get('MapServer', 'imageURL')
        self.otherProjs   = parser.get('MapServer', 'otherProjs')
        
        if parser.has_option('MapServer', 'meta_fees'):
            self.meta_fees = parser.get('MapServer', 'meta_fees')
        if parser.has_option('MapServer', 'meta_accessconstraints'):
            self.meta_accessconstraints = parser.get('MapServer', 'meta_accessconstraints')
        if parser.has_option('MapServer', 'meta_keywordlist'):
            self.meta_keywordlist = parser.get('MapServer', 'meta_keywordlist')
        if parser.has_option('MapServer', 'meta_addresstype'):
            self.meta_addresstype = parser.get('MapServer', 'meta_addresstype')
        if parser.has_option('MapServer', 'meta_address'):
            self.meta_address = parser.get('MapServer', 'meta_address')
        if parser.has_option('MapServer', 'meta_city'):
            self.meta_city = parser.get('MapServer', 'meta_city')
        if parser.has_option('MapServer', 'meta_stateorprovince'):
            self.meta_stateorprovince = parser.get('MapServer', 'meta_stateorprovince')
        if parser.has_option('MapServer', 'meta_postcode'):
            self.meta_postcode = parser.get('MapServer', 'meta_postcode')
        if parser.has_option('MapServer', 'meta_country'):
            self.meta_country = parser.get('MapServer', 'meta_country')
        if parser.has_option('MapServer', 'meta_contactelectronicmailaddress'):
            self.meta_contactelectronicmailaddress = parser.get('MapServer', 'meta_contactelectronicmailaddress')
        if parser.has_option('MapServer', 'meta_contactperson'):
            self.meta_contactperson = parser.get('MapServer', 'meta_contactperson')
        if parser.has_option('MapServer', 'meta_contactorganization'):
            self.meta_contactorganization   = parser.get('MapServer', 'meta_contactorganization')
        if parser.has_option('MapServer', 'meta_contactposition'):
            self.meta_contactposition = parser.get('MapServer', 'meta_contactposition')
        if parser.has_option('MapServer', 'meta_role'):
            self.meta_role = parser.get('MapServer', 'meta_role')
        if parser.has_option('MapServer', 'meta_contactvoicetelephone'):
            self.meta_contactvoicetelephone = parser.get('MapServer', 'meta_contactvoicetelephone')
        if parser.has_option('MapServer', 'meta_contactfacsimiletelephone'):
            self.meta_contactfacsimiletelephone = parser.get('MapServer', 'meta_contactfacsimiletelephone')
        if parser.has_option('MapServer', 'meta_contactinstructions'):
            self.meta_contactinstructions = parser.get('MapServer', 'meta_contactinstructions')
        if parser.has_option('MapServer', 'meta_hoursofservice'):
            self.meta_hoursofservice = parser.get('MapServer', 'meta_hoursofservice')

        
    def setupLogging(self):
        """
        Sets up the logging file.
        """
        
        formatter = logging.Formatter(self.logFormat)
        
        self.logger = logging.getLogger(__name__)
        self.logger.setLevel(self.logLevel)

        if(self.logFile == None):
            ch_stream = logging.StreamHandler()
            #ch_stream.setLevel(logging.INFO)
            ch_stream.setFormatter(formatter)
            self.logger.addHandler(ch_stream)
            
        else:
            ch_file = logging.FileHandler(self.logFile, 'a')
            #ch_file.setLevel(self.logLevel)
            ch_file.setFormatter(formatter)
            self.logger.addHandler(ch_file)            
        
    def decodeId(self, url):
        """
        Decodes the remote process identifier from the status URL.
        
        :param: string with the status URL address of a remote process
        :returns: string with the process identifier  
        """
        
        s = url.split("/")
        return s[len(s) - 1].split(".")[0] 
    
    def getPercentCompleted(self):
        """
        :returns: process execution progress in percentage   
        """
        if (self.execution is not None): 
            return self.execution.percentCompleted
        else:
            return None
        
    def getStatusMessage(self):
        """
        :returns: last status message returned by the server   
        """
        if (self.execution is not None):
            return self.execution.statusMessage
        else:
            return None
        
    def getProcessErrorCode(self):
        """
        :returns: last error code returned by the server   
        """
        if (self.processError is not None):
            return self.processError.code
        else:
            return None
        
    def getProcessErrorText(self):
        """
        :returns: last error message returned by the server   
        """
        if (self.processError is not None):
            return self.processError.text
        else:
            return None
            
    def sendRequest(self):
        """
        Uses the wps object to start the process execution. Stores the
        status URL and the process in the statusURL and processId attributes.
        
        :returns: string with the status URL, None in case of error
        """
        
        execOutputs = []
        for key in self.outputs:
            execOutputs.append((key, "True"))
        
        self.execution = self.wps.execute(self.processName, self.inputs, execOutputs)
        
        self.logger.info("The request sent: \n" + self.execution.request)
        self.logger.debug("The status URL: " + self.execution.statusLocation)
        
        if len(self.execution.errors) > 0:
            self.logger.error(self.ERR_04 + self.execution.errors[0].code + self.execution.errors[0].text)
            raise Exception(self.ERR_04 + self.execution.errors[0].code + self.execution.errors[0].text)
            return None
        
        self.statusURL = self.execution.statusLocation
        self.processId = self.decodeId(self.statusURL)
        
        return self.statusURL  

    def checkStatus(self):
        """
        Sends a request to the status URL checking the progress of the remote 
        process. If the process has finished creates the necessary Output 
        objects to fetch the results and stores them in the resultsLiteral and
        resultsComplex attributes.
        
        :returns: True if the process finished successfully 
                  False if the process is still running
        :rtype: Boolean
        """
        
        self.processError = ""
        self.processErrorCode = ""
        self.processErrorText = ""
        self.status = None                     

        if (self.statusURL == None):
            self.logger.error(self.ERR_05)
            raise Exception(self.ERR_05)

        try: 
            self.execution = WPSExecution()
            self.execution.statusLocation = self.statusURL
            self.execution.checkStatus(sleepSecs=0)
        except Exception as ex:
            mesg = "Unexpected error from OWSLib!! " + str(ex)
            self.logger.error(mesg)
            # This is a work arround !!!!!!!!
            # It is not clear why these calls to OWSLib are failing.
            # Thus RUNNING status is reported back
            self.status = self.RUNNING
            return False
        
        # Check if the process has finished
        if not (self.execution.isComplete()):
            self.status = self.RUNNING
            self.logger.debug("The process hasn't finished yet.")
            self.logger.info(str(self.percentCompleted) + " % of the execution complete.")
            return False
        
        # Check if the process failed
        if not (self.execution.isSucceded()):
            self.status = self.ERROR
            self.processError = self.execution.errors[0]
            self.processErrorText = self.execution.errors[0].text
            self.logger.error(self.ERR_06 + self.processErrorText)
            self.logger.debug("The status URL: " + self.execution.statusLocation)
            raise Exception(self.ERR_06 + self.processErrorText)


        self.logger.debug(self.SUCC_01)
        self.status = self.FINISHED
                    
        return True           
            
        
    def generateMapFile(self):
        """
        Creates the MapFile object that encodes a map file publishing the 
        complex outputs and writes it to disk.
        
        :returns: string with the path to the map file generated. None if no
        map file was generated (no complex outputs present).
        """
        
        if(self.outputs is None) or (len(self.outputs) != len(self.execution.processOutputs)):
            self.logger.error(self.ERR_08)
            raise Exception(self.ERR_08)
        
        #self.map = UMN.MapFile(self.processId)
        self.map = MapFile(self.processId)
        
        self.map.shapePath    = self.pathFilesGML
        self.map.epsgCode     = self.epsg
        self.map.mapTemplate  = self.mapTemplate
        self.map.imagePath    = self.imagePath
        self.map.imageURL     = self.imageURL
        self.map.mapServerURL = self.mapServerURL
        self.map.mapFilesPath = self.mapFilesPath
        self.map.otherProjs   = self.otherProjs
        
        self.map.meta_fees = self.meta_fees
        self.map.meta_accessconstraints = self.meta_accessconstraints
        self.map.meta_keywordlist = self.meta_keywordlist
        self.map.meta_addresstype = self.meta_addresstype
        self.map.meta_address = self.meta_address
        self.map.meta_city = self.meta_city
        self.map.meta_stateorprovince = self.meta_stateorprovince
        self.map.meta_postcode = self.meta_postcode
        self.map.meta_country = self.meta_country
        self.map.meta_contactelectronicmailaddress = self.meta_contactelectronicmailaddress
        self.map.meta_contactperson = self.meta_contactperson
        self.map.meta_contactorganization = self.meta_contactorganization
        self.map.meta_contactposition = self.meta_contactposition
        self.map.meta_role = self.meta_role
        self.map.meta_contactvoicetelephone = self.meta_contactvoicetelephone
        self.map.meta_contactfacsimiletelephone = self.meta_contactfacsimiletelephone
        self.map.meta_contactinstructions = self.meta_contactinstructions
        self.map.meta_hoursofservice = self.meta_hoursofservice
        
        for output in self.execution.processOutputs:
            
            output.writeToDisk(self.pathFilesGML);
            
            providedTitle = self.outputs[output.identifier]
            dataSet = DataSet(output.filePath, providedTitle, output.identifier)
            self.dataSets.append(dataSet)
            
            layerEPSG = dataSet.getEPSG()
            if (layerEPSG == None):
               layerEPSG = self.map.epsgCode
                                   
            if dataSet.dataType == dataSet.TYPE_VECTOR:
                #* style = UMN.MapStyle()
                style = MapStyle()
                #* layer = UMN.VectorLayer(
                layer = VectorLayer(
                    output.filePath, 
                    dataSet.getBBox(), 
                    layerEPSG, 
                    output.identifier,
                    providedTitle)
                type = str(dataSet.getGeometryType())
                if type <> None:
                    layer.layerType = type
                else:
                    layer.layerType = "Polygon"
                self.logger.debug("The layer type: " + str(dataSet.getGeometryType()))
                layer.addStyle(style)
                self.map.addLayer(layer)
                self.logger.debug("Generated layer " + layer.name + " of type " + layer.layerType + ".")
                  
            elif dataSet.dataType == dataSet.TYPE_RASTER:
                #layer = UMN.RasterLayer(
                layer = RasterLayer(
                    output.filePath, 
                    dataSet.getBBox(), 
                    layerEPSG, 
                    output.identifier,
                    providedTitle)
                layer.setBounds(dataSet.getMaxValue(), dataSet.getMinValue())
                self.map.addLayer(layer)
                self.logger.debug("Generated layer " + layer.name + " of type raster.")
                
            else:
                self.logger.warning(self.WARN_02 + output.identifier + self.WARN_03)
                
            self.logger.debug("Guessed mime type for this layer: " + str(dataSet.getMimeType()))
            
            print "The pixel res: " + str(dataSet.getPixelRes())
                
        if (len(self.map.layers) > 0):
                    
            try :
                self.map.writeToDisk()
            except Exception, e:
                self.logger.error(self.ERR_07 + str(e))
                raise Exception(self.ERR_07 + str(e))
                return
            
            self.logger.info(self.SUCC_02 + self.map.filePath())
            return self.map.filePath()
        
        else:
Exemple #38
0
    def wps_execute(self, version, accept):
        wps_url = get_wps_url(self.settings)
        if version == "1.0.0":
            test_content = "Test file in Docker - WPS KVP"
            wps_method = "GET"
        elif version == "2.0.0":
            test_content = "Test file in Docker - WPS XML"
            wps_method = "POST"
        else:
            raise ValueError("Invalid WPS version: {}".format(version))
        test_content += " {} request - Accept {}".format(wps_method, accept.split("/")[-1].upper())

        with contextlib.ExitStack() as stack_exec:
            # setup
            dir_name = tempfile.gettempdir()
            tmp_path = tempfile.NamedTemporaryFile(dir=dir_name, mode="w", suffix=".txt")
            tmp_file = stack_exec.enter_context(tmp_path)  # noqa
            tmp_file.write(test_content)
            tmp_file.seek(0)
            for mock_exec in mocked_execute_process():
                stack_exec.enter_context(mock_exec)

            # execute
            if version == "1.0.0":
                wps_inputs = ["file={}@mimeType={}".format(tmp_file.name, CONTENT_TYPE_TEXT_PLAIN)]
                wps_params = {
                    "service": "WPS",
                    "request": "Execute",
                    "version": version,
                    "identifier": self.process_id,
                    "DataInputs": wps_inputs,
                }
                wps_headers = {"Accept": accept}
                wps_data = None
            else:
                wps_inputs = [("file", ComplexDataInput(tmp_file.name, mimeType=CONTENT_TYPE_TEXT_PLAIN))]
                wps_outputs = [(self.out_key, True)]  # as reference
                wps_exec = WPSExecution(version=version, url=wps_url)
                wps_req = wps_exec.buildRequest(self.process_id, wps_inputs, wps_outputs)
                wps_data = lxml.etree.tostring(wps_req)
                wps_headers = {"Accept": accept, "Content-Type": CONTENT_TYPE_APP_XML}
                wps_params = None
            resp = mocked_sub_requests(self.app, wps_method, wps_url,
                                       params=wps_params, data=wps_data, headers=wps_headers, only_local=True)
            assert resp.status_code in [200, 201], \
                "Failed with: [{}]\nTest: [{}]\nReason:\n{}".format(resp.status_code, test_content, resp.text)

            # parse response status
            if accept == CONTENT_TYPE_APP_XML:
                assert resp.content_type in CONTENT_TYPE_ANY_XML, test_content
                xml = lxml.etree.fromstring(str2bytes(resp.text))
                status_url = xml.get("statusLocation")
                job_id = status_url.split("/")[-1]
            elif accept == CONTENT_TYPE_APP_JSON:
                assert resp.content_type == CONTENT_TYPE_APP_JSON, test_content
                status_url = resp.json["location"]
                job_id = resp.json["jobID"]
            assert status_url
            assert job_id

            # job monitoring
            result = self.monitor_job(status_url)

        self.validate_outputs(job_id, result, test_content)
Exemple #39
0
    def wps_execute(self, version, accept):
        wps_url = get_wps_url(self.settings)
        if version == "1.0.0":
            test_content = "Test file in Docker - WPS KVP"
            wps_method = "GET"
        elif version == "2.0.0":
            test_content = "Test file in Docker - WPS XML"
            wps_method = "POST"
        else:
            raise ValueError("Invalid WPS version: {}".format(version))
        test_content += " {} request - Accept {}".format(wps_method, accept.split("/")[-1].upper())

        with contextlib.ExitStack() as stack_exec:
            # setup
            dir_name = tempfile.gettempdir()
            tmp_file = stack_exec.enter_context(tempfile.NamedTemporaryFile(dir=dir_name, mode="w", suffix=".txt"))
            tmp_file.write(test_content)
            tmp_file.seek(0)
            for mock_exec in mocked_execute_process():
                stack_exec.enter_context(mock_exec)

            # execute
            if version == "1.0.0":
                wps_inputs = ["file={}@mimeType={}".format(tmp_file.name, CONTENT_TYPE_TEXT_PLAIN)]
                wps_params = {
                    "service": "WPS",
                    "request": "Execute",
                    "version": version,
                    "identifier": self.process_id,
                    "DataInputs": wps_inputs,
                }
                wps_headers = {"Accept": accept}
                wps_data = None
            else:
                wps_inputs = [("file", ComplexDataInput(tmp_file.name, mimeType=CONTENT_TYPE_TEXT_PLAIN))]
                wps_outputs = [(self.out_key, True)]  # as reference
                wps_exec = WPSExecution(version=version, url=wps_url)
                wps_req = wps_exec.buildRequest(self.process_id, wps_inputs, wps_outputs)
                wps_data = xml_util.tostring(wps_req)
                wps_headers = {"Accept": accept, "Content-Type": CONTENT_TYPE_APP_XML}
                wps_params = None
            resp = mocked_sub_requests(self.app, wps_method, wps_url,
                                       params=wps_params, data=wps_data, headers=wps_headers, only_local=True)
            assert resp.status_code in [200, 201], (
                "Failed with: [{}]\nTest: [{}]\nReason:\n{}".format(resp.status_code, test_content, resp.text)
            )

            # parse response status
            if accept == CONTENT_TYPE_APP_XML:
                assert resp.content_type in CONTENT_TYPE_ANY_XML, test_content
                xml_body = xml_util.fromstring(str2bytes(resp.text))
                status_url = xml_body.get("statusLocation")
                job_id = status_url.split("/")[-1].split(".")[0]
            elif accept == CONTENT_TYPE_APP_JSON:
                assert resp.content_type == CONTENT_TYPE_APP_JSON, test_content
                status_url = resp.json["location"]
                job_id = resp.json["jobID"]
            assert status_url
            assert job_id

            if accept == CONTENT_TYPE_APP_XML:
                wps_out_url = self.settings["weaver.wps_output_url"]
                weaver_url = self.settings["weaver.url"]
                assert status_url == f"{wps_out_url}/{job_id}.xml", "Status URL should be XML file for WPS-1 request"
                # remap to employ JSON monitor method (could be done with XML parsing otherwise)
                status_url = f"{weaver_url}/jobs/{job_id}"

            # job monitoring
            results = self.monitor_job(status_url)
            outputs = self.get_outputs(status_url)

            # validate XML status is updated accordingly
            wps_xml_status = os.path.join(self.settings["weaver.wps_output_dir"], job_id + ".xml")
            assert os.path.isfile(wps_xml_status)
            with open(wps_xml_status, "r") as status_file:
                assert "ProcessSucceeded" in status_file.read()

        self.validate_outputs(job_id, results, outputs, test_content)
Exemple #40
0
def test_wps_checkStatus():
    execution = WPSExecution()
    xml = open(resource_file('wps_PMLExecuteResponse5.xml'), 'rb').read()
    execution.checkStatus(response=xml)
    assert execution.isSucceded()
    assert execution.creationTime == '2011-11-08T21:36:55Z'
Exemple #41
0
def check_wps_status(
        location=None,  # type: Optional[str]
        response=None,  # type: Optional[xml_util.XML]
        sleep_secs=2,  # type: int
        verify=True,  # type: bool
        settings=None,  # type: Optional[AnySettingsContainer]
):  # type: (...) -> WPSExecution
    """
    Run :func:`owslib.wps.WPSExecution.checkStatus` with additional exception handling.

    :param location: job URL or file path where to look for job status.
    :param response: WPS response document of job status.
    :param sleep_secs: number of seconds to sleep before returning control to the caller.
    :param verify: flag to enable SSL verification.
    :param settings: application settings to retrieve any additional request parameters as applicable.
    :returns: OWSLib.wps.WPSExecution object.
    """
    def _retry_file():
        # type: () -> str
        LOGGER.warning(
            "Failed retrieving WPS status-location, attempting with local file."
        )
        out_path = get_wps_local_status_location(location, settings)
        if not out_path:
            raise HTTPNotFound(
                f"Could not find file resource from [{location}].")
        LOGGER.info("Resolved WPS status-location using local file reference.")
        with open(out_path, mode="r", encoding="utf-8") as f:
            return f.read()

    execution = WPSExecution()
    if response:
        LOGGER.debug("Retrieving WPS status from XML response document...")
        xml_data = response
    elif location:
        xml_resp = HTTPNotFound()
        xml_data = None
        try:
            LOGGER.debug(
                "Attempt to retrieve WPS status-location from URL [%s]...",
                location)
            xml_resp = request_extra("get",
                                     location,
                                     verify=verify,
                                     settings=settings)
            xml_data = xml_resp.content
        except Exception as ex:
            LOGGER.debug(
                "Got exception during get status: [%r]. Will retry with local reference.",
                ex)
        if xml_resp.status_code != HTTPOk.code:
            LOGGER.debug(
                "WPS XML status not found: [%r]. Retrying with local reference.",
                xml_data)
            xml_data = _retry_file()
    else:
        raise Exception(
            "Missing status-location URL/file reference or response with XML object."
        )
    if isinstance(xml_data, str):
        xml_data = xml_data.encode("utf8", errors="ignore")
    execution.checkStatus(response=xml_data, sleepSecs=sleep_secs)
    if execution.response is None:
        raise Exception("Missing response, cannot check status.")
    if not isinstance(execution.response, xml_util.XML):
        execution.response = xml_util.fromstring(execution.response)
    return execution