Exemplo n.º 1
0
class Process(object):
    """
    :param handler: A callable that gets invoked for each incoming
                    request. It should accept a single
                    :class:`pywps.app.WPSRequest` argument and return a
                    :class:`pywps.app.WPSResponse` object.
    :param string identifier: Name of this process.
    :param string title: Human readable title of process.
    :param string abstract: Brief narrative description of the process.
    :param list keywords: Keywords that characterize a process.
    :param inputs: List of inputs accepted by this process. They
                   should be :class:`~LiteralInput` and :class:`~ComplexInput`
                   and :class:`~BoundingBoxInput`
                   objects.
    :param outputs: List of outputs returned by this process. They
                   should be :class:`~LiteralOutput` and :class:`~ComplexOutput`
                   and :class:`~BoundingBoxOutput`
                   objects.
    :param metadata: List of metadata advertised by this process. They
                     should be :class:`pywps.app.Common.Metadata` objects.
    """
    def __init__(self,
                 handler,
                 identifier,
                 title,
                 abstract='',
                 keywords=[],
                 profile=[],
                 metadata=[],
                 inputs=[],
                 outputs=[],
                 version='None',
                 store_supported=False,
                 status_supported=False,
                 grass_location=None):
        self.identifier = identifier
        self.handler = handler
        self.title = title
        self.abstract = abstract
        self.keywords = keywords
        self.metadata = metadata
        self.profile = profile
        self.version = version
        self.inputs = inputs
        self.outputs = outputs
        self.uuid = None
        self.status_location = ''
        self.status_url = ''
        self.workdir = None
        self._grass_mapset = None
        self.grass_location = grass_location
        self.service = None

        if store_supported:
            self.store_supported = 'true'
        else:
            self.store_supported = 'false'

        if status_supported:
            self.status_supported = 'true'
        else:
            self.status_supported = 'false'

    @property
    def json(self):

        return {
            'version': self.version,
            'identifier': self.identifier,
            'title': self.title,
            'abstract': self.abstract,
            'keywords': self.keywords,
            'metadata': [m for m in self.metadata],
            'inputs': [i.json for i in self.inputs],
            'outputs': [o.json for o in self.outputs],
            'store_supported': self.store_supported,
            'status_supported': self.status_supported,
            'profile': [p for p in self.profile],
        }

    def execute(self, wps_request, uuid):
        self._set_uuid(uuid)
        self. async = False
        response_cls = get_response("execute")
        wps_response = response_cls(wps_request, process=self, uuid=self.uuid)

        LOGGER.debug(
            'Check if status storage and updating are supported by this process'
        )
        if wps_request.store_execute == 'true':
            if self.store_supported != 'true':
                raise StorageNotSupported(
                    'Process does not support the storing of the execute response'
                )

            if wps_request.status == 'true':
                if self.status_supported != 'true':
                    raise OperationNotSupported(
                        'Process does not support the updating of status')

                wps_response.store_status_file = True
                self. async = True
            else:
                wps_response.store_status_file = False

        LOGGER.debug(
            'Check if updating of status is not required then no need to spawn a process'
        )

        wps_response = self._execute_process(self. async, wps_request,
                                             wps_response)

        return wps_response

    def _set_uuid(self, uuid):
        """Set uuid and status location path and url
        """

        self.uuid = uuid
        for inpt in self.inputs:
            inpt.uuid = uuid

        for outpt in self.outputs:
            outpt.uuid = uuid

        file_path = config.get_config_value('server', 'statuspath')

        file_url = config.get_config_value('server', 'statusurl')

        self.status_location = os.path.join(file_path, str(self.uuid)) + '.xml'
        self.status_url = os.path.join(file_url, str(self.uuid)) + '.xml'

    def _execute_process(self, async, wps_request, wps_response):
        """Uses :module:`pywps.processing` module for sending process to
        background BUT first, check for maxprocesses configuration value

        :param async: run in asynchronous mode
        :return: wps_response or None
        """

        maxparallel = int(
            config.get_config_value('server', 'parallelprocesses'))
        running = dblog.get_running().count()
        stored = dblog.get_stored().count()

        # async
        if async:

            # run immedietly
            if running < maxparallel or maxparallel == -1:
                wps_response._update_status(WPS_STATUS.ACCEPTED,
                                            u"PyWPS Request accepted", 0)
                self._run_async(wps_request, wps_response)

            # try to store for later usage
            else:
                maxprocesses = int(
                    config.get_config_value('server', 'maxprocesses'))
                if stored >= maxprocesses:
                    raise ServerBusy(
                        'Maximum number of parallel running processes reached. Please try later.'
                    )
                LOGGER.debug("Store process in job queue, uuid=%s", self.uuid)
                dblog.store_process(self.uuid, wps_request)
                wps_response._update_status(
                    WPS_STATUS.ACCEPTED, u'PyWPS Process stored in job queue',
                    0)

        # not async
        else:
            if running >= maxparallel and maxparallel != -1:
                raise ServerBusy(
                    'Maximum number of parallel running processes reached. Please try later.'
                )
            wps_response._update_status(WPS_STATUS.ACCEPTED,
                                        u"PyWPS Request accepted", 0)
            wps_response = self._run_process(wps_request, wps_response)

        return wps_response
Exemplo n.º 2
0
class Process(object):
    """
    :param handler: A callable that gets invoked for each incoming
                    request. It should accept a single
                    :class:`~WPSRequest` argument and return a
                    :class:`~WPSResponse` object.
    :param identifier: Name of this process.
    :param inputs: List of inputs accepted by this process. They
                   should be :class:`~LiteralInput` and :class:`~ComplexInput`
                   and :class:`~BoundingBoxInput`
                   objects.
    :param outputs: List of outputs returned by this process. They
                   should be :class:`~LiteralOutput` and :class:`~ComplexOutput`
                   and :class:`~BoundingBoxOutput`
                   objects.
    """
    def __init__(self,
                 handler,
                 identifier,
                 title,
                 abstract='',
                 profile=[],
                 metadata=[],
                 inputs=[],
                 outputs=[],
                 version='None',
                 store_supported=False,
                 status_supported=False):
        self.identifier = identifier
        self.handler = handler
        self.title = title
        self.abstract = abstract
        self.metadata = metadata
        self.profile = profile
        self.version = version
        self.inputs = inputs
        self.outputs = outputs
        self.uuid = None
        self.status_location = ''
        self.status_url = ''
        self.workdir = None

        if store_supported:
            self.store_supported = 'true'
        else:
            self.store_supported = 'false'

        if status_supported:
            self.status_supported = 'true'
        else:
            self.status_supported = 'false'

    def capabilities_xml(self):
        doc = WPS.Process(OWS.Identifier(self.identifier),
                          OWS.Title(self.title))
        if self.abstract:
            doc.append(OWS.Abstract(self.abstract))
        # TODO: See Table 32 Metadata in OGC 06-121r3
        #for m in self.metadata:
        #    doc.append(OWS.Metadata(m))
        if self.profile:
            doc.append(OWS.Profile(self.profile))
        if self.version != 'None':
            doc.attrib[
                '{http://www.opengis.net/wps/1.0.0}processVersion'] = self.version
        else:
            doc.attrib[
                '{http://www.opengis.net/wps/1.0.0}processVersion'] = 'undefined'

        return doc

    def describe_xml(self):
        input_elements = [i.describe_xml() for i in self.inputs]
        output_elements = [i.describe_xml() for i in self.outputs]

        doc = E.ProcessDescription(OWS.Identifier(self.identifier),
                                   OWS.Title(self.title))
        doc.attrib[
            '{http://www.opengis.net/wps/1.0.0}processVersion'] = self.version

        if self.store_supported == 'true':
            doc.attrib['storeSupported'] = self.store_supported

        if self.status_supported == 'true':
            doc.attrib['statusSupported'] = self.status_supported

        if self.abstract:
            doc.append(OWS.Abstract(self.abstract))

        for m in self.metadata:
            doc.append(OWS.Metadata({'{http://www.w3.org/1999/xlink}title':
                                     m}))

        for p in self.profile:
            doc.append(WPS.Profile(p))

        if input_elements:
            doc.append(E.DataInputs(*input_elements))

        doc.append(E.ProcessOutputs(*output_elements))

        return doc

    def execute(self, wps_request, uuid):

        self._set_uuid(uuid)
        async = False
        wps_response = WPSResponse(self, wps_request, self.uuid)

        LOGGER.debug(
            'Check if status storage and updating are supported by this process'
        )
        if wps_request.store_execute == 'true':
            if self.store_supported != 'true':
                raise StorageNotSupported(
                    'Process does not support the storing of the execute response'
                )

            if wps_request.status == 'true':
                if self.status_supported != 'true':
                    raise OperationNotSupported(
                        'Process does not support the updating of status')

                wps_response.status = WPSResponse.STORE_AND_UPDATE_STATUS
                async = True
            else:
                wps_response.status = WPSResponse.STORE_STATUS

        LOGGER.debug(
            'Check if updating of status is not required then no need to spawn a process'
        )

        wps_response = self._execute_process(async, wps_request, wps_response)

        return wps_response

    def _set_uuid(self, uuid):
        """Set uuid and status ocation apth and url
        """

        self.uuid = uuid

        file_path = config.get_config_value('server', 'outputpath')

        file_url = config.get_config_value('server', 'outputurl')

        self.status_location = os.path.join(file_path, str(self.uuid)) + '.xml'
        self.status_url = os.path.join(file_url, str(self.uuid)) + '.xml'

    def _execute_process(self, async, wps_request, wps_response):
        """Uses :module:`multiprocessing` module for sending process to
        background BUT first, check for maxprocesses configuration value

        :param async: run in asynchronous mode
        :return: wps_response or None
        """

        maxparalel = int(config.get_config_value('server',
                                                 'parallelprocesses'))
        running = len(dblog.get_running())
        stored = len(dblog.get_stored())

        # async
        if async:

            # run immedietly
            if running < maxparalel:
                self._run_async(wps_request, wps_response)

            # try to store for later usage
            else:
                wps_response = self._store_process(stored, wps_request,
                                                   wps_response)

        # not async
        else:
            if running < maxparalel:
                wps_response = self._run_process(wps_request, wps_response)
            else:
                raise ServerBusy(
                    'Maximum number of paralel running processes reached. Please try later.'
                )

        return wps_response
Exemplo n.º 3
0
class Process(object):
    """
    :param handler: A callable that gets invoked for each incoming
                    request. It should accept a single
                    :class:`pywps.app.WPSRequest` argument and return a
                    :class:`pywps.app.WPSResponse` object.
    :param string identifier: Name of this process.
    :param string title: Human readable title of process.
    :param string abstract: Brief narrative description of the process.
    :param list keywords: Keywords that characterize a process.
    :param inputs: List of inputs accepted by this process. They
                   should be :class:`~LiteralInput` and :class:`~ComplexInput`
                   and :class:`~BoundingBoxInput`
                   objects.
    :param outputs: List of outputs returned by this process. They
                   should be :class:`~LiteralOutput` and :class:`~ComplexOutput`
                   and :class:`~BoundingBoxOutput`
                   objects.
    :param metadata: List of metadata advertised by this process. They
                     should be :class:`pywps.app.Common.Metadata` objects.
    """
    def __init__(self,
                 handler,
                 identifier,
                 title,
                 abstract='',
                 keywords=[],
                 profile=[],
                 metadata=[],
                 inputs=[],
                 outputs=[],
                 version='None',
                 store_supported=False,
                 status_supported=False,
                 grass_location=None):
        self.identifier = identifier
        self.handler = handler
        self.title = title
        self.abstract = abstract
        self.keywords = keywords
        self.metadata = metadata
        self.profile = profile
        self.version = version
        self.inputs = inputs
        self.outputs = outputs
        self.uuid = None
        self.status_location = ''
        self.status_url = ''
        self.workdir = None
        self._grass_mapset = None
        self.grass_location = grass_location
        self.service = None

        if store_supported:
            self.store_supported = 'true'
        else:
            self.store_supported = 'false'

        if status_supported:
            self.status_supported = 'true'
        else:
            self.status_supported = 'false'

    def capabilities_xml(self):
        doc = WPS.Process(OWS.Identifier(self.identifier),
                          OWS.Title(self.title))
        if self.abstract:
            doc.append(OWS.Abstract(self.abstract))
        if self.keywords:
            kws = map(OWS.Keyword, self.keywords)
            doc.append(OWS.Keywords(*kws))
        for m in self.metadata:
            doc.append(OWS.Metadata(dict(m)))
        if self.profile:
            doc.append(OWS.Profile(self.profile))
        if self.version != 'None':
            doc.attrib[
                '{http://www.opengis.net/wps/1.0.0}processVersion'] = self.version
        else:
            doc.attrib[
                '{http://www.opengis.net/wps/1.0.0}processVersion'] = 'undefined'

        return doc

    def describe_xml(self):
        input_elements = [i.describe_xml() for i in self.inputs]
        output_elements = [i.describe_xml() for i in self.outputs]

        doc = E.ProcessDescription(OWS.Identifier(self.identifier),
                                   OWS.Title(self.title))
        doc.attrib[
            '{http://www.opengis.net/wps/1.0.0}processVersion'] = self.version

        if self.store_supported == 'true':
            doc.attrib['storeSupported'] = self.store_supported

        if self.status_supported == 'true':
            doc.attrib['statusSupported'] = self.status_supported

        if self.abstract:
            doc.append(OWS.Abstract(self.abstract))

        if self.keywords:
            kws = map(OWS.Keyword, self.keywords)
            doc.append(OWS.Keywords(*kws))

        for m in self.metadata:
            doc.append(OWS.Metadata(dict(m)))

        for p in self.profile:
            doc.append(WPS.Profile(p))

        if input_elements:
            doc.append(E.DataInputs(*input_elements))

        doc.append(E.ProcessOutputs(*output_elements))

        return doc

    def execute(self, wps_request, uuid):
        self._set_uuid(uuid)
        self. async = False
        response_cls = get_response("execute")
        wps_response = response_cls(wps_request, process=self, uuid=self.uuid)

        LOGGER.debug(
            'Check if status storage and updating are supported by this process'
        )
        if wps_request.store_execute == 'true':
            if self.store_supported != 'true':
                raise StorageNotSupported(
                    'Process does not support the storing of the execute response'
                )

            if wps_request.status == 'true':
                if self.status_supported != 'true':
                    raise OperationNotSupported(
                        'Process does not support the updating of status')

                wps_response.status = STATUS.STORE_AND_UPDATE_STATUS
                self. async = True
            else:
                wps_response.status = STATUS.STORE_STATUS

        LOGGER.debug(
            'Check if updating of status is not required then no need to spawn a process'
        )

        wps_response = self._execute_process(self. async, wps_request,
                                             wps_response)

        return wps_response

    def _set_uuid(self, uuid):
        """Set uuid and status location path and url
        """

        self.uuid = uuid
        for inpt in self.inputs:
            inpt.uuid = uuid

        for outpt in self.outputs:
            outpt.uuid = uuid

        file_path = config.get_config_value('server', 'outputpath')

        file_url = config.get_config_value('server', 'outputurl')

        self.status_location = os.path.join(file_path, str(self.uuid)) + '.xml'
        self.status_url = os.path.join(file_url, str(self.uuid)) + '.xml'

    def _execute_process(self, async, wps_request, wps_response):
        """Uses :module:`pywps.processing` module for sending process to
        background BUT first, check for maxprocesses configuration value

        :param async: run in asynchronous mode
        :return: wps_response or None
        """

        maxparallel = int(
            config.get_config_value('server', 'parallelprocesses'))
        running = dblog.get_running().count()
        stored = dblog.get_stored().count()

        # async
        if async:

            # run immedietly
            if running < maxparallel or maxparallel == -1:
                self._run_async(wps_request, wps_response)

            # try to store for later usage
            else:
                wps_response = self._store_process(stored, wps_request,
                                                   wps_response)

        # not async
        else:
            if running < maxparallel or maxparallel == -1:
                wps_response = self._run_process(wps_request, wps_response)
            else:
                raise ServerBusy(
                    'Maximum number of parallel running processes reached. Please try later.'
                )

        return wps_response