예제 #1
0
    def add_qedge(self, response, input_parameters, describe=False):
        """
        Adds a new QEdge object to the QueryGraph inside the Message object
        :return: ARAXResponse object with execution information
        :rtype: ARAXResponse
        """

        # #### Command definition for autogenerated documentation
        command_definition = {
            'dsl_command': 'add_qedge()',
            'description':
            """The `add_qedge` command adds an additional QEdge to the QueryGraph in the Message object. Currently
                subject and object QNodes must already be present in the QueryGraph. The specified type is not currently checked that it is a
                valid Translator/BioLink relationship type, but it should be.""",
            'parameters': {
                'key': {
                    'is_required':
                    False,
                    'examples': ['e00', 'e01'],
                    'default':
                    '',
                    'type':
                    'string',
                    'description':
                    """Any string that is unique among all QEdge key fields, with recommended format e00, e01, e02, etc.
                        If no value is provided, autoincrementing values beginning for e00 are used.""",
                },
                'subject': {
                    'is_required':
                    True,
                    'examples': ['n00', 'n01'],
                    'type':
                    'string',
                    'description':
                    'key of the source QNode already present in the QueryGraph (e.g. n00, n01)',
                },
                'object': {
                    'is_required':
                    True,
                    'examples': ['n01', 'n02'],
                    'type':
                    'string',
                    'description':
                    'key of the target QNode already present in the QueryGraph (e.g. n01, n02)',
                },
                'predicates': {
                    'is_required':
                    False,
                    'examples': [['biolink:physically_interacts_with'],
                                 ['biolink:participates_in']],
                    'type':
                    'ARAXedge',
                    'description':
                    'A list (n >= 1) of valid BioLink relationship predicates (e.g. [physically_interacts_with], [participates_in])',
                },
                'option_group_id': {
                    'is_required':
                    False,
                    'examples': ['1', 'a', 'b2', 'option'],
                    'type':
                    'string',
                    'description':
                    'A group identifier indicating a group of nodes and edges should either all be included or all excluded. An optional match for all elements in this group. If not included Node will be treated as required.'
                },
                'exclude': {
                    'is_required':
                    False,
                    'enum': ['true', 'false'],
                    'examples': ['true', 'false'],
                    'type':
                    'boolean',
                    'description':
                    'If set to true, results with this node will be excluded. If set to false or not included nodes will be treated as part of a normal query.'
                },
            }
        }

        if describe:
            return command_definition

        #### Extract the message to work on
        message = response.envelope.message
        self.response = response
        self.envelope = response.envelope
        self.messsage = message

        #### Basic checks on arguments
        if not isinstance(input_parameters, dict):
            response.error("Provided parameters is not a dict",
                           error_code="ParametersNotDict")
            return response

        #### Define a complete set of allowed parameters and their defaults
        parameters = {
            'key': None,
            'subject': None,
            'object': None,
            'predicates': None,
            'option_group_id': None,
            'exclude': None,
        }

        #### Loop through the input_parameters and override the defaults and make sure they are allowed
        for key, value in input_parameters.items():
            if key not in parameters:
                response.error(f"Supplied parameter {key} is not permitted",
                               error_code="UnknownParameter")
            else:
                parameters[key] = value
        #### Return if any of the parameters generated an error (showing not just the first one)
        if response.status != 'OK':
            return response

        #### Store these final parameters for convenience
        response.data['parameters'] = parameters
        self.parameters = parameters

        #### Now apply the filters. Order of operations is probably quite important
        #### Scalar value filters probably come first like minimum_confidence, then complex logic filters
        #### based on edge or node properties, and then finally maximum_results
        response.info(
            f"Adding a QueryEdge to Message with parameters {parameters}")

        #### Make sure there's a query_graph already here
        if message.query_graph is None:
            message.query_graph = QueryGraph()
            message.query_graph.nodes = {}
            message.query_graph.edges = {}
        if message.query_graph.edges is None:
            message.query_graph.edges = {}

        #### Create a QEdge
        qedge = QEdge()
        if parameters['key'] is not None:
            key = parameters['key']
            if key in message.query_graph.edges:
                response.error(
                    f"Duplicate key '{key}' specified when trying to create a new QEdge",
                    error_code="QEdgeDuplicateKey")
                return response
        else:
            key = self.__get_next_free_edge_key()

        #### Get the list of available node_keys
        qnodes = message.query_graph.nodes

        #### Add the subject
        if parameters['subject'] is not None:
            if parameters['subject'] not in qnodes:
                response.error(
                    f"While trying to add QEdge, there is no QNode with key {parameters['subject']}",
                    error_code="UnknownSourceKey")
                return response
            qedge.subject = parameters['subject']
        else:
            response.error(
                f"While trying to add QEdge, subject is a required parameter",
                error_code="MissingSourceKey")
            return response

        #### Add the object
        if parameters['object'] is not None:
            if parameters['object'] not in qnodes:
                response.error(
                    f"While trying to add QEdge, there is no QNode with key {parameters['object']}",
                    error_code="UnknownTargetKey")
                return response
            qedge.object = parameters['object']
        else:
            response.error(
                f"While trying to add QEdge, object is a required parameter",
                error_code="MissingTargetKey")
            return response

        #### Add the predicates if any. Need to verify they are allowed predicates. FIXME
        if parameters['predicates'] is not None:
            if isinstance(parameters['predicates'], str):
                qedge.predicates = [parameters['predicates']]
            else:
                qedge.predicates = parameters['predicates']

        if parameters['exclude'] is not None:
            if parameters['exclude'] in {'t', 'T', 'true', 'True'}:
                qedge.exclude = True
            elif parameters['exclude'] in {'f', 'F', 'false', 'False'}:
                qedge.exclude = False
            elif parameters['exclude'] not in {True, False}:
                response.error(
                    f"Supplied input, {parameters['exclude']}, for the 'exclude' parameter is not valid. Acceptable inputs are t, T, f, F, true, True, false, and False.",
                    error_code="UnknownInput")
        else:
            qedge.exclude = False

        if parameters['option_group_id'] is not None:
            qedge.option_group_id = parameters['option_group_id']

        #### Add it to the query_graph edge list
        message.query_graph.edges[key] = qedge

        #### Return the response
        return response
예제 #2
0
def flip_qedge(qedge: QEdge, new_predicates: List[str]):
    qedge.predicates = new_predicates
    original_subject = qedge.subject
    qedge.subject = qedge.object
    qedge.object = original_subject