Ejemplo n.º 1
0
    def encode_execute_response(self, process, inputs, results, lineage=False):
        response_elem = WPS("ExecuteResponse",
            self.encode_process_brief(process),
            WPS("Status",
                WPS("ProcessSucceded"), # TODO: other states
                creationTime=isoformat(now())
            )
        )

        if lineage:
            response_elem.append(
                WPS("DataInputs",

                )
            )

        response_elem.extend((
            WPS("OutputDefinitions", *[
                self.encode_parameter(name, parameter, False)
                for name, parameter in process.outputs.items()
            ]),
            WPS("ProcessOutputs", *[
                self.encode_output(name, process.outputs[name], data)
                for name, data in results.items()
            ])
        ))
        return response_elem
Ejemplo n.º 2
0
def _encode_process_brief(process, elem):
    """ Insert a brief process description into an XML element passed as the
    second argument.
    The brief process description is shared by both the Capabilities and
    ProcessDescriptions XML encoders.
    """
    identifier = getattr(process, 'identifier', type(process).__name__)
    title = getattr(process, 'title', identifier)
    abstract = getattr(process, 'description', process.__doc__)
    version = getattr(process, "version", "1.0.0")
    metadata = getattr(process, "metadata", {})
    profiles = getattr(process, "profiles", [])
    wsdl = getattr(process, "wsdl", None)

    elem.append(OWS("Identifier", identifier))
    elem.append(OWS("Title", title))
    elem.attrib[ns_wps("processVersion")] = version
    if abstract:
        elem.append(OWS("Abstract", abstract))
    elem.extend(_encode_metadata(k, metadata[k]) for k in metadata)
    elem.extend(WPS("Profile", profile) for profile in profiles)
    if wsdl:
        elem.append(WPS("WSDL", **{ns_xlink("href"): wsdl}))

    return elem
Ejemplo n.º 3
0
    def encode_capabilities(processes):
        """ Encode Capabilities XML document. """
        conf = CapabilitiesConfigReader(get_eoxserver_config())

        # Avoid duplicate process offerings ...
        process_set = set()
        process_offerings = []
        for process in processes:
            process_identifier = (getattr(process, 'identifier', None)
                                  or type(process).__name__)
            if process_identifier not in process_set:
                process_offerings.append(encode_process_brief(process))
                process_set.add(process_identifier)

        return WPS(
            "Capabilities",
            OWS(
                "ServiceIdentification",
                OWS("Title", conf.title),
                OWS("Abstract", conf.abstract),
                OWS("Keywords", *(OWS("Keyword", kw) for kw in conf.keywords)),
                OWS("ServiceType", "WPS"),
                OWS("ServiceTypeVersion", "1.0.0"),
                OWS("Fees", conf.fees),
                OWS("AccessConstraints", conf.access_constraints),
            ),
            OWS(
                "ServiceProvider", OWS("ProviderName", conf.provider_name),
                OWS("ProviderSite", **{ns_xlink("href"): conf.provider_site}),
                OWS(
                    "ServiceContact",
                    OWS("IndividualName", conf.individual_name),
                    OWS("PositionName", conf.position_name),
                    OWS(
                        "ContactInfo",
                        OWS("Phone", OWS("Voice", conf.phone_voice),
                            OWS("Facsimile", conf.phone_facsimile)),
                        OWS(
                            "Address", OWS("DeliveryPoint",
                                           conf.delivery_point),
                            OWS("City", conf.city),
                            OWS("AdministrativeArea",
                                conf.administrative_area),
                            OWS("PostalCode", conf.postal_code),
                            OWS("Country", conf.country),
                            OWS("ElectronicMailAddress",
                                conf.electronic_mail_address))))),
            _encode_operations_metadata(conf),
            WPS("ProcessOfferings", *process_offerings),
            WPS("Languages", WPS("Default", OWS("Language", "en-US")),
                WPS("Supported", OWS("Language", "en-US"))),
            # TODO: WPS("WSDL")
            **{
                "service": "WPS",
                "version": "1.0.0",
                ns_xml("lang"): "en-US",
                "updateSequence": conf.update_sequence,
            })
Ejemplo n.º 4
0
    def encode_format(self, frmt):
        elem = WPS("Format",
            WPS("MimeType", frmt.mime_type)
        )

        if frmt.encoding:
            elem.append(WPS("Encoding", frmt.encoding))

        if frmt.encoding:
            elem.append(WPS("Schema", frmt.schema))
Ejemplo n.º 5
0
 def encode_response(self, results):
     """Encode ProcessSucceeded execute response including the output data."""
     elem = self._encode_common(
         WPS("ProcessSucceeded",
             "The processes execution completed successfully."))
     outputs = []
     for result, prm, req in itervalues(results):
         outputs.append(_encode_output(result, prm, req))
     elem.append(WPS("ProcessOutputs", *outputs))
     return elem
Ejemplo n.º 6
0
def _encode_complex(data, prm):
    try:
        payload = prm.encode_xml(data)
    except (ValueError, TypeError) as exc:
        raise InvalidOutputValueError(prm.identifier, exc)

    elem = WPS("ComplexData", **_encode_format_attr(data, prm))
    if isinstance(payload, etree._Element):
        elem.append(payload)
    else:
        elem.text = etree.CDATA(payload)
    return elem
Ejemplo n.º 7
0
def _encode_complex(data, prm):
    """ Encode Data/ComplexData element. """
    try:
        payload = prm.encode_xml(data)
    except (ValueError, TypeError) as exc:
        raise InvalidOutputValueError(prm.identifier, exc)
    elem = WPS("ComplexData", **_encode_format_attr(data, prm))
    if isinstance(payload, etree._Element):
        elem.append(payload)
    else:
        elem.text = etree.CDATA(payload)
    return elem
Ejemplo n.º 8
0
def _encode_output(data, prm, req):
    """ Encode one ProcessOutputs sub-element. """
    elem = encode_output_exec(
        Parameter(prm.identifier, req.title or prm.title, req.abstract
                  or prm.abstract))
    if isinstance(data, Reference):
        elem.append(_encode_output_reference(data, prm))
    elif isinstance(prm, LiteralData):
        elem.append(WPS("Data", _encode_literal(data, prm, req)))
    elif isinstance(prm, BoundingBoxData):
        elem.append(WPS("Data", _encode_bbox(data, prm)))
    elif isinstance(prm, ComplexData):
        elem.append(WPS("Data", _encode_complex(data, prm)))
    return elem
Ejemplo n.º 9
0
 def encode_paused(self, progress=0):
     """ Encode ProcessPaused execute response."""
     return self._encode_common(
         WPS("ProcessPaused",
             "The processes execution is paused.",
             percentCompleted=("%d" %
                               min(99, max(0, int(float(progress)))))))
Ejemplo n.º 10
0
def _encode_raw_input_literal(input_raw, prm):
    """ Encode Data/LiteralData element from a raw (unparsed) input ."""
    attrib = {'dataType': prm.dtype.name}
    uom = input_raw.uom or prm.default_uom
    if prm.uoms:
        attrib['uom'] = uom
    return WPS("LiteralData", input_raw.data, **attrib)
Ejemplo n.º 11
0
 def encode_process_descriptions(processes):
     """ Encode the ProcessDescriptions XML document. """
     _proc = [encode_process_full(p) for p in processes]
     _attr = {
         "service": "WPS",
         "version": "1.0.0",
         ns_xml("lang"): "en-US",
     }
     return WPS("ProcessDescriptions", *_proc, **_attr)
Ejemplo n.º 12
0
 def encode_started(self, progress=0, message=None):
     """ Encode ProcessStarted execute response."""
     if not message:
         message = "The processes execution is in progress."
     return self._encode_common(
         WPS("ProcessStarted",
             message,
             percentCompleted=("%d" %
                               min(99, max(0, int(float(progress)))))))
Ejemplo n.º 13
0
 def encode_failed(self, exception):
     """ Encode ProcessFailed execute response."""
     # NOTE: Some exceptions such as the urllib2.HTTPError have also
     # the 'code' attribute and the duck typing does not work very well.
     # Therefore we need match the exception base type.
     if isinstance(exception, OWS10Exception):
         code = exception.code
         locator = exception.locator
     else:
         code = "NoApplicableCode"
         locator = type(exception).__name__
     message = str(exception)
     exc_attr = {"exceptionCode": str(code)}
     if locator:
         exc_attr["locator"] = str(locator)
     exc_elem = OWS("Exception", OWS("ExceptionText", message), **exc_attr)
     status = WPS("ProcessFailed", WPS("ExceptionReport", exc_elem))
     return self._encode_common(status)
Ejemplo n.º 14
0
def _encode_input(data, prm, raw):
    """ Encode one DataInputs sub-element. """
    elem = encode_input_exec(raw)
    if isinstance(raw, InputReference):
        elem.append(_encode_input_reference(raw))
    elif isinstance(prm, LiteralData):
        elem.append(WPS("Data", _encode_raw_input_literal(raw, prm)))
    elif isinstance(prm, BoundingBoxData):
        if data is None:
            data = prm.parse(raw.data)
        elem.append(WPS("Data", _encode_bbox(data, prm)))
    elif isinstance(prm, ComplexData):
        if data is None:
            data = prm.parse(data=raw.data,
                             mime_type=raw.mime_type,
                             encoding=raw.encoding,
                             schema=raw.schema)
        elem.append(WPS("Data", _encode_complex(data, prm)))
    return elem
Ejemplo n.º 15
0
def _encode_literal(data, prm, req):
    """ Encode Data/LiteralData element. """
    attrib = {'dataType': prm.dtype.name}
    uom = req.uom or prm.default_uom
    if prm.uoms:
        attrib['uom'] = uom
    try:
        encoded_data = prm.encode(data, uom)
    except (ValueError, TypeError) as exc:
        raise InvalidOutputValueError(prm.identifier, exc)
    return WPS("LiteralData", encoded_data, **attrib)
Ejemplo n.º 16
0
def _encode_common_response(process, status_elem, inputs, raw_inputs, resp_doc):
    """Encode common execute response part shared by all specific responses."""
    inputs = inputs or {}
    conf = CapabilitiesConfigReader(get_eoxserver_config())
    url = conf.http_service_url
    if url[-1] == "?":
        url = url[:-1]
    elem = WPS("ExecuteResponse",
        encode_process_brief(process),
        WPS("Status", status_elem, creationTime=isoformat(now())),
        {
            "service": "WPS",
            "version": "1.0.0",
            ns_xml("lang"): "en-US",
            "serviceInstance": (
                "%s?service=WPS&version=1.0.0&request=GetCapabilities" % url
            )
        },
    )

    if resp_doc.lineage:
        inputs_data = []
        for id_, prm in process.inputs:
            if isinstance(prm, RequestParameter):
                continue
            prm = fix_parameter(id_, prm)
            data = inputs.get(id_)
            rawinp = raw_inputs.get(prm.identifier)
            if rawinp is not None:
                inputs_data.append(_encode_input(data, prm, rawinp))
        elem.append(WPS("DataInputs", *inputs_data))

        outputs_def = []
        for id_, prm in process.outputs:
            prm = fix_parameter(id_, prm)
            outdef = resp_doc.get(prm.identifier)
            if outdef is not None:
                outputs_def.append(encode_output_def(outdef))
        elem.append(WPS("OutputDefinitions", *outputs_def))

    return elem
Ejemplo n.º 17
0
def _encode_common_response(process, status_elem, inputs, raw_inputs,
                            resp_doc):
    """Encode common execute response part shared by all specific responses."""
    inputs = inputs or {}
    conf = CapabilitiesConfigReader(get_eoxserver_config())
    url = conf.http_service_url
    if url[-1] == "?":
        url = url[:-1]
    elem = WPS(
        "ExecuteResponse",
        encode_process_brief(process),
        WPS("Status", status_elem, creationTime=isoformat(now())),
        {
            "service":
            "WPS",
            "version":
            "1.0.0",
            ns_xml("lang"):
            "en-US",
            "serviceInstance":
            ("%s?service=WPS&version=1.0.0&request=GetCapabilities" % url)
        },
    )

    if resp_doc.lineage:
        inputs_data = []
        for id_, prm in process.inputs:
            if isinstance(prm, RequestParameter):
                continue
            prm = fix_parameter(id_, prm)
            data = inputs.get(id_)
            rawinp = raw_inputs.get(prm.identifier)
            if rawinp is not None:
                inputs_data.append(_encode_input(data, prm, rawinp))
        elem.append(WPS("DataInputs", *inputs_data))

        outputs_def = []
        for id_, prm in process.outputs:
            prm = fix_parameter(id_, prm)
            outdef = resp_doc.get(prm.identifier)
            if outdef is not None:
                outputs_def.append(encode_output_def(outdef))
        elem.append(WPS("OutputDefinitions", *outputs_def))

    return elem
Ejemplo n.º 18
0
def _encode_bbox(data, prm):
    """ Encode Data/BoundingBoxData element. """
    try:
        lower, upper, crs = prm.encode_xml(data)
    except (ValueError, TypeError) as exc:
        raise InvalidOutputValueError(prm.identifier, exc)

    return WPS(
        "BoundingBoxData",
        OWS("LowerCorner", lower),
        OWS("UpperCorner", upper),
        crs=crs,
        #dimension="%d"%prm.dimension,
    )
Ejemplo n.º 19
0
def encode_output_def(outdef):
    """ Encode execute response Output (definition) element. """
    attrib = {}
    if outdef.uom is not None:
        attrib['uom'] = outdef.uom
    if outdef.crs is not None:
        attrib['crs'] = outdef.crs
    if outdef.mime_type is not None:
        attrib['mimeType'] = outdef.mime_type
    if outdef.encoding is not None:
        attrib['encoding'] = outdef.encoding
    if outdef.schema is not None:
        attrib['schema'] = outdef.schema
    if outdef.as_reference is not None:
        attrib['asReference'] = 'true' if outdef.as_reference else 'false'
    return WPS("Output", *_encode_param_common(outdef, False), **attrib)
Ejemplo n.º 20
0
def _encode_allowed_value(avobj):
    """ Encode process description LiteralData allowed values definition.
    Based on the type of the allowed value definition either AnyValue,
    ValuesReference, or AllowedValues element is returned.
    """
    enum, ranges, elist = None, [], []

    if isinstance(avobj, AllowedAny):
        return OWS("AnyValue")
    elif isinstance(avobj, AllowedByReference):
        return WPS(
            "ValuesReference", **{
                ns_ows("reference"): avobj.url,
                "valuesForm": avobj.url,
            })
    elif isinstance(avobj, AllowedEnum):
        enum = avobj
    elif isinstance(avobj, AllowedRange):
        ranges = [avobj]
    elif isinstance(avobj, AllowedRangeCollection):
        enum, ranges = avobj.enum, avobj.ranges
    else:
        raise TypeError("Invalid allowed value object! OBJ=%r" % avobj)

    dtype = avobj.dtype
    ddtype = dtype.get_diff_dtype()

    if enum is not None:
        elist.extend(OWS("Value", dtype.encode(v)) for v in enum.values)
    for range_ in ranges:
        attr, elms = {}, []
        if range_.closure != 'closed':
            attr = {ns_ows("rangeClosure"): range_.closure}
        if range_.minval is not None:
            elms.append(OWS("MinimumValue", dtype.encode(range_.minval)))
        if range_.maxval is not None:
            elms.append(OWS("MaximumValue", dtype.encode(range_.maxval)))
        if range_.spacing is not None:
            elms.append(OWS("Spacing", ddtype.encode(range_.spacing)))
        elist.append(OWS("Range", *elms, **attr))

    return OWS("AllowedValues", *elist)
Ejemplo n.º 21
0
def _encode_output_reference(ref, prm):
    """ Encode ProcessOutputs/Reference element. """
    #TODO proper output reference encoding
    mime_type = getattr(ref, 'mime_type', None)
    encoding = getattr(ref, 'encoding', None)
    schema = getattr(ref, 'schema', None)
    if mime_type is None and hasattr(prm, 'default_format'):
        default_format = prm.default_format
        mime_type = default_format.mime_type
        encoding = default_format.encoding
        schema = default_format.schema
    attr = {
        #ns_xlink("href"): ref.href,
        'href': ref.href,
    }
    if mime_type:
        attr['mimeType'] = mime_type
    if encoding is not None:
        attr['encoding'] = encoding
    if schema is not None:
        attr['schema'] = schema
    return WPS("Reference", **attr)
Ejemplo n.º 22
0
    def encode_process_brief(self, process):
        elem = WPS("Process",
            OWS("Identifier", process.identifier),
            OWS("Title", getattr(process, "title", None) or process.identifier),
            OWS("Abstract", getattr(process, "description", ""))
        )

        elem.extend([
            OWS("Metadata", metadata)
            for metadata in getattr(process, "metadata", [])
        ])

        elem.extend([
            OWS("Profile", profile)
            for profile in getattr(process, "profiles", [])
        ])

        version = getattr(process, "version", None)
        if version:
            elem.attr[ns_wps("processVersion")] = version

        return elem
Ejemplo n.º 23
0
def encode_process_brief(process):
    """ Encode a brief process description (Process element) of the
    Capabilities XML document.
    """
    return _encode_process_brief(process, WPS("Process"))
Ejemplo n.º 24
0
def encode_output_exec(prm):
    """ Encode common part of the execute response Output (data) element. """
    return WPS("Output", *_encode_param_common(prm))
Ejemplo n.º 25
0
def encode_input_exec(prm):
    """ Encode common part of the execute response Input (data) element. """
    return WPS("Input", *_encode_param_common(prm, False))
Ejemplo n.º 26
0
 def encode_accepted(self):
     """ Encode ProcessAccepted execute response."""
     return self._encode_common(
         WPS("ProcessAccepted",
             "The processes was accepted for execution."))
Ejemplo n.º 27
0
    def encode_parameter(self, name, parameter, is_input):
        # support for the shorthand
        if is_literal_type(parameter):
            parameter = LiteralData(name, parameter)

        # TODO: minOccurs/maxOccurs correct
        elem = WPS("Input" if is_input else "Output",
            OWS("Identifier", parameter.identifier or name)
        )

        if parameter.title:
            elem.append(OWS("Title", parameter.title))
        if parameter.description:
            elem.append(OWS("Abstract", parameter.description))

        if isinstance(parameter, LiteralData):
            data_elem = WPS("LiteralData" if is_input else "LiteralOutput")

            literal_type_name = parameter.type_name
            if literal_type_name:
                data_elem.append(
                    OWS("DataType", literal_type_name, **{
                        ns_ows("reference"): "http://www.w3.org/TR/xmlschema-2/#%s" % literal_type_name
                    })
                )

            if parameter.uoms:
                data_elem.append(
                    WPS("UOMs",
                        WPS("Default",
                            OWS("UOM", parameter.uoms[0])
                        ),
                        WPS("Supported", *[
                            OWS("UOM", uom) for uom in parameter.uoms
                        ])
                    )
                )

            if is_input and parameter.allowed_values:
                data_elem.append(
                    OWS("AllowedValues", *[
                        OWS("AllowedValue", str(allowed_value))
                        for allowed_value in parameter.allowed_values
                    ])
                )
            elif is_input and parameter.values_reference:
                data_elem.append(
                    WPS("ValuesReference", **{
                        ns_ows("reference"): parameter.values_reference,
                        "valuesForm": parameter.values_reference
                    })
                )
            elif is_input:
                data_elem.append(OWS("AnyValue"))

            if is_input and parameter.default is not None:
                elem.attrib["minOccurs"] = "0"
                data_elem.append(
                    WPS("Default", str(parameter.default))
                )

        elif isinstance(parameter, ComplexData):
            formats = parameter.formats
            if isinstance(formats, Format):
                formats = (formats,)

            data_elem = WPS("ComplexData" if is_input else "ComplexOutput",
                WPS("Default",
                    self.encode_format(formats[0])
                ),
                WPS("Supported", *[
                    self.encode_format(frmt) for frmt in formats
                ])
            )

        elif isinstance(parameter, BoundingBoxData):
            # TODO: implement
            data_elem = WPS("BoundingBoxData" if is_input else "BoundingBoxOutput")

        elem.append(data_elem)
        return elem
Ejemplo n.º 28
0
def _encode_input_reference(ref):
    """ Encode DataInputs/Reference element. """
    #TODO proper input reference encoding
    return WPS("Reference", **{ns_xlink("href"): ref.href})