Ejemplo n.º 1
0
def test_add_qedge_duplicate_key():
    response = ARAXResponse()
    messenger = ARAXMessenger()
    messenger.create_envelope(response)
    assert response.status == 'OK'
    message = response.envelope.message
    messenger.add_qnode(response, {
        'key': 'n00',
        'ids': ['CHEMBL.COMPOUND:CHEMBL112']
    })
    messenger.add_qnode(response, {
        'key': 'n01',
        'categories': ['biolink:Protein']
    })
    messenger.add_qedge(response, {
        'key': 'e00',
        'subject': 'n00',
        'object': 'n01'
    })
    assert response.status == 'OK'
    messenger.add_qedge(
        response, {
            'key': 'e00',
            'subject': 'n00',
            'object': 'n01',
            'predicates': ['biolink:treats']
        })
    print(
        json.dumps(ast.literal_eval(repr(message.query_graph.edges)),
                   sort_keys=True,
                   indent=2))
    assert response.status == 'ERROR'
    assert isinstance(message.query_graph.nodes, dict)
    assert len(message.query_graph.edges) == 1
    assert response.error_code == 'QEdgeDuplicateKey'
Ejemplo n.º 2
0
def QGI_test1():

    #### Some qnode examples
    test_query_graphs = [
        [ { 'id': 'n10', 'curie': 'DOID:9281', 'category': 'disease'}, { 'id': 'n11', 'category': 'chemical_substance'}, { 'id': 'e10', 'source_id': 'n10', 'target_id': 'n11', 'category': 'treats'} ],
        [ { 'id': 'n10', 'curie': 'DOID:9281'}, { 'id': 'n11', 'category': 'protein'}, { 'id': 'e10', 'source_id': 'n10', 'target_id': 'n11'} ],
        [ { 'id': 'n10', 'curie': 'DOID:9281'}, { 'id': 'n11', 'category': 'protein'}, { 'id': 'n12', 'category': 'chemical_substance'},
            { 'id': 'e10', 'source_id': 'n10', 'target_id': 'n11'}, { 'id': 'e11', 'source_id': 'n11', 'target_id': 'n12'} ],
        [ { 'id': 'n10', 'curie': 'DOID:9281'}, { 'id': 'n11', 'category': 'chemical_substance'}, { 'id': 'e10', 'source_id': 'n10', 'target_id': 'n11'} ],
        [ { 'id': 'n10', 'curie': 'DOID:9281', 'category': 'disease'}, { 'id': 'n11', 'category': 'chemical_substance'}, { 'id': 'e10', 'source_id': 'n10', 'target_id': 'n11'} ],
    ]

    #interpreter = ARAXQueryGraphInterpreter()
    #print(json.dumps(interpreter.query_graph_tree,sort_keys=True,indent=2))
    #return

    for test_query_graph in test_query_graphs:

        #### Create a response object for each test
        response = ARAXResponse()

        #### Create a template Message
        messenger = ARAXMessenger()
        messenger.create_envelope(response)
        message = response.envelope.message

        for parameters in test_query_graph:
            if 'n' in parameters['id']:
                messenger.add_qnode(response, parameters)
                if response.status != 'OK':
                    print(response.show(level=ARAXResponse.DEBUG))
                    return response
            elif 'e' in parameters['id']:
                #print(f"++ Adding qedge with {parameters}")
                messenger.add_qedge(response, parameters)
                if response.status != 'OK':
                    print(response.show(level=ARAXResponse.DEBUG))
                    return response
            else:
                response.error(f"Unrecognized component {parameters['id']}")
                return response

        interpreter = ARAXQueryGraphInterpreter()
        interpreter.translate_to_araxi(response)
        if response.status != 'OK':
            print(response.show(level=ARAXResponse.DEBUG))
            return response

        araxi_commands = response.data['araxi_commands']
        for cmd in araxi_commands:
            print(f"  - {cmd}")
Ejemplo n.º 3
0
def main():

    # Note that most of this is just manually doing what ARAXQuery() would normally do for you
    response = Response()
    from actions_parser import ActionsParser
    actions_parser = ActionsParser()
    actions_list = [
        "create_message",
        "add_qnode(id=n00, curie=CHEMBL.COMPOUND:CHEMBL112)",  # acetaminophen
        "add_qnode(id=n01, type=protein, is_set=true)",
        "add_qedge(id=e00, source_id=n00, target_id=n01)",
        "expand(edge_id=e00, kp=BTE)",
        "return(message=true, store=false)",
    ]

    # Parse the raw action_list into commands and parameters
    result = actions_parser.parse(actions_list)
    response.merge(result)
    if result.status != 'OK':
        print(response.show(level=Response.DEBUG))
        return response
    actions = result.data['actions']

    from ARAX_messenger import ARAXMessenger
    messenger = ARAXMessenger()
    expander = ARAXExpander()
    for action in actions:
        if action['command'] == 'create_message':
            result = messenger.create_message()
            message = result.data['message']
            response.data = result.data
        elif action['command'] == 'add_qnode':
            result = messenger.add_qnode(message, action['parameters'])
        elif action['command'] == 'add_qedge':
            result = messenger.add_qedge(message, action['parameters'])
        elif action['command'] == 'expand':
            result = expander.apply(message, action['parameters'])
        elif action['command'] == 'return':
            break
        else:
            response.error(f"Unrecognized command {action['command']}",
                           error_code="UnrecognizedCommand")
            print(response.show(level=Response.DEBUG))
            return response

        # Merge down this result and end if we're in an error state
        response.merge(result)
        if result.status != 'OK':
            print(response.show(level=Response.DEBUG))
            return response

    # Show the final response
    # print(json.dumps(ast.literal_eval(repr(message.knowledge_graph)),sort_keys=True,indent=2))
    print(response.show(level=Response.DEBUG))
Ejemplo n.º 4
0
def test_add_qedge_multitest():
    # Set up a message with two nodes
    response = ARAXResponse()
    messenger = ARAXMessenger()
    messenger.create_envelope(response)
    assert response.status == 'OK'
    message = response.envelope.message
    messenger.add_qnode(response,{ 'name': 'acetaminophen' })
    assert response.status == 'OK'
    messenger.add_qnode(response,{ 'category': 'biolink:Protein' })
    assert response.status == 'OK'

    # Set up a list of parameters to feed to add_qedge() and what the result should be
    parameters_list = [
        { 'status': 'ERROR', 'parameters': [ 'subject', 'n00' ], 'error_code': 'ParametersNotDict' },
        { 'status': 'OK', 'parameters': { 'subject': 'n00', 'object': 'n01' }, 'error_code': 'OK' },
        { 'status': 'OK', 'parameters': { 'subject': 'n00', 'object': 'n01', 'key': 'e99' }, 'error_code': 'OK' },
        { 'status': 'OK', 'parameters': { 'subject': 'n00', 'object': 'n01', 'key': 'e99', 'predicate': 'physically_interacts_with' }, 'error_code': 'OK' },
        { 'status': 'ERROR', 'parameters': { 'subject': 'n00' }, 'error_code': 'MissingTargetKey' },
        { 'status': 'ERROR', 'parameters': { 'object': 'n00' }, 'error_code': 'MissingSourceKey' },
        { 'status': 'ERROR', 'parameters': { 'subject': 'n99', 'object': 'n01' }, 'error_code': 'UnknownSourceKey' },
        { 'status': 'ERROR', 'parameters': { 'subject': 'n00', 'object': 'n99' }, 'error_code': 'UnknownTargetKey' },
        { 'status': 'ERROR', 'parameters': { 'pickles': 'on the side' }, 'error_code': 'UnknownParameter' },
    ]

    # Loop over all the parameter sets and try to run it
    template_response = copy.deepcopy(response)
    for parameters in parameters_list:
        response = copy.deepcopy(template_response)
        message = response.envelope.message
        print(parameters)
        messenger.add_qedge(response, parameters['parameters'])
        assert response.status == parameters['status']
        if parameters['status'] == 'OK':
            assert len(message.query_graph.edges) == 1
            continue
        assert len(message.query_graph.edges) == 0
        assert response.error_code == parameters['error_code']
Ejemplo n.º 5
0
def test_add_qedge_multitest():
    # Set up a message with two nodes
    messenger = ARAXMessenger()
    response = messenger.create_message()
    assert response.status == 'OK'
    message = response.data['message']
    response = messenger.add_qnode(message, {'name': 'acetaminophen'})
    assert response.status == 'OK'
    response = messenger.add_qnode(message, {'type': 'protein'})
    assert response.status == 'OK'

    # Set up a list of parameters to feed to add_qedge() and what the result should be
    parameters_list = [
        {
            'status': 'ERROR',
            'parameters': ['source_id', 'n00'],
            'error_code': 'ParametersNotDict'
        },
        {
            'status': 'OK',
            'parameters': {
                'source_id': 'n00',
                'target_id': 'n01'
            },
            'error_code': 'OK'
        },
        {
            'status': 'OK',
            'parameters': {
                'source_id': 'n00',
                'target_id': 'n01',
                'id': 'e99'
            },
            'error_code': 'OK'
        },
        {
            'status': 'OK',
            'parameters': {
                'source_id': 'n00',
                'target_id': 'n01',
                'id': 'e99',
                'type': 'physically_interacts_with'
            },
            'error_code': 'OK'
        },
        {
            'status': 'ERROR',
            'parameters': {
                'source_id': 'n00'
            },
            'error_code': 'MissingTargetId'
        },
        {
            'status': 'ERROR',
            'parameters': {
                'target_id': 'n00'
            },
            'error_code': 'MissingSourceId'
        },
        {
            'status': 'ERROR',
            'parameters': {
                'source_id': 'n99',
                'target_id': 'n01'
            },
            'error_code': 'UnknownSourceId'
        },
        {
            'status': 'ERROR',
            'parameters': {
                'source_id': 'n00',
                'target_id': 'n99'
            },
            'error_code': 'UnknownTargetId'
        },
        {
            'status': 'ERROR',
            'parameters': {
                'pickles': 'on the side'
            },
            'error_code': 'UnknownParameter'
        },
    ]

    # Loop over all the parameter sets and try to run it
    reference_message = copy.deepcopy(message)
    for parameters in parameters_list:
        message = copy.deepcopy(reference_message)
        print(parameters)
        response = messenger.add_qedge(message, parameters['parameters'])
        assert response.status == parameters['status']
        if parameters['status'] == 'OK':
            assert len(message.query_graph.edges) == 1
            continue
        assert len(message.query_graph.edges) == 0
        assert response.error_code == parameters['error_code']
def main():

    #### Some qnode examples
    test_query_graphs = [
        [{
            'id': 'n10',
            'curie': 'DOID:9281'
        }, {
            'id': 'n11',
            'type': 'protein'
        }, {
            'id': 'e10',
            'source_id': 'n10',
            'target_id': 'n11'
        }],
        [{
            'id': 'n10',
            'curie': 'DOID:9281'
        }, {
            'id': 'n11',
            'type': 'protein'
        }, {
            'id': 'n12',
            'type': 'chemical_substance'
        }, {
            'id': 'e10',
            'source_id': 'n10',
            'target_id': 'n11'
        }, {
            'id': 'e11',
            'source_id': 'n11',
            'target_id': 'n12'
        }],
        [{
            'id': 'n10',
            'curie': 'DOID:9281'
        }, {
            'id': 'n11',
            'type': 'chemical_substance'
        }, {
            'id': 'e10',
            'source_id': 'n10',
            'target_id': 'n11'
        }],
        [{
            'id': 'n10',
            'curie': 'DOID:9281',
            'type': 'disease'
        }, {
            'id': 'n11',
            'type': 'chemical_substance'
        }, {
            'id': 'e10',
            'source_id': 'n10',
            'target_id': 'n11'
        }],
    ]

    #interpreter = ARAXQueryGraphInterpreter()
    #print(json.dumps(interpreter.query_graph_tree,sort_keys=True,indent=2))
    #return

    for test_query_graph in test_query_graphs:

        #### Create a response object for each test
        response = Response()

        #### Create a template Message
        messenger = ARAXMessenger()
        result = messenger.create_message()
        response.merge(result)
        message = messenger.message

        for parameters in test_query_graph:
            if 'n' in parameters['id']:
                result = messenger.add_qnode(message, parameters)
                response.merge(result)
                if result.status != 'OK':
                    print(response.show(level=Response.DEBUG))
                    return response
            elif 'e' in parameters['id']:
                result = messenger.add_qedge(message, parameters)
                response.merge(result)
                if result.status != 'OK':
                    print(response.show(level=Response.DEBUG))
                    return response
            else:
                response.error(f"Unrecognized type {parameters['id']}")
                return response

        interpreter = ARAXQueryGraphInterpreter()
        result = interpreter.translate_to_araxi(message)
        response.merge(result)
        if result.status != 'OK':
            print(response.show(level=Response.DEBUG))
            return response

        araxi_commands = result.data['araxi_commands']
        print(araxi_commands)
Ejemplo n.º 7
0
def main():

    #### Create a response object
    response = Response()

    #### Some qnode examples
    test_query_graphs = [
        [{
            'id': 'n10',
            'curie': 'DOID:9281'
        }, {
            'id': 'n11',
            'type': 'protein'
        }, {
            'id': 'e10',
            'source_id': 'n10',
            'target_id': 'n11'
        }],
        [{
            'id': 'n10',
            'curie': 'DOID:9281'
        }, {
            'id': 'n11',
            'type': 'protein'
        }, {
            'id': 'n12',
            'type': 'drug'
        }, {
            'id': 'e10',
            'source_id': 'n10',
            'target_id': 'n11'
        }, {
            'id': 'e11',
            'source_id': 'n11',
            'target_id': 'n12'
        }],
    ]

    for test_query_graph in test_query_graphs:

        #### Create a template Message
        messenger = ARAXMessenger()
        result = messenger.create_message()
        response.merge(result)
        message = messenger.message

        for parameters in test_query_graph:
            if 'n' in parameters['id']:
                result = messenger.add_qnode(message, parameters)
                response.merge(result)
                if result.status != 'OK':
                    print(response.show(level=Response.DEBUG))
                    return response
            elif 'e' in parameters['id']:
                result = messenger.add_qedge(message, parameters)
                response.merge(result)
                if result.status != 'OK':
                    print(response.show(level=Response.DEBUG))
                    return response
            else:
                response.error(f"Unrecognized type {parameters['id']}")
                return response

        interpreter = ARAXQueryGraphInterpreter()
        result = interpreter.translate_to_araxi(message)
        response.merge(result)
        if result.status != 'OK':
            print(response.show(level=Response.DEBUG))
            return response

        araxi_commands = result.data['araxi_commands']
        print(araxi_commands)

        #### Show the final result
        print('-------------------------')
        print(response.show(level=Response.DEBUG))
Ejemplo n.º 8
0
    def __connect_nodes(self, describe=False):
        """
        Connects qnodes and runs expand.
        Allowable parameters: {'edge_predicate': str, 
                                'edge_property': str,
                                'direction': {'above', 'below'}}
        :return:
        """
        message = self.message
        parameters = self.parameters
        # make a list of the allowable parameters (keys), and their possible values (values). Note that the action and corresponding name will always be in the allowable parameters
        if message and parameters and hasattr(message, 'query_graph') and hasattr(message.query_graph, 'nodes'):
            allowable_parameters = {'action': {'connect_nodes'},
                                    'shortest_path': {'true', 'false', 'True', 'False', 't', 'f', 'T', 'F'},
                                    'max_path_length': {int()},
                                    'qnode_keys': set(self.message.query_graph.nodes.keys())
                                }
        else:
            allowable_parameters = {'action': {'connect_nodes'},
                                    'shortest_path': {'true', 'false', 'True', 'False', 't', 'f', 'T', 'F'},
                                    'max_path_length': {'a maximum path length to use to connect qnodes. Defaults to 2.'},
                                    'qnode_keys':{'a list of query node keys to connect'}
                                }

        # A little function to describe what this thing does
        if describe:
            allowable_parameters['brief_description'] = self.command_definitions['connect_nodes']
            return allowable_parameters

        
        # Make sure only allowable parameters and values have been passed
        resp = self.check_params(allowable_parameters)
        # return if bad parameters have been passed
        if self.response.status != 'OK' or resp == -1:
            return self.response


        # Set defaults and check parameters:
        if 'shortest_path' in self.parameters:
            if self.parameters['shortest_path'] in {'true', 'True', 't', 'T'}:
                self.parameters['shortest_path'] = True
            elif self.parameters['shortest_path'] in {'false', 'False', 'f', 'F'}:
                self.parameters['shortest_path'] = False
        else:
            self.parameters['shortest_path'] = True
        if 'qnode_keys' not in self.parameters or len(self.parameters['qnode_keys']) == 0:
            self.parameters['qnode_keys'] = list(set(self.message.query_graph.nodes.keys()))
            if len(self.parameters['qnode_keys']) < 2:
                self.response.error(
                    f"Query graph must have at least 2 nodes to connect.",
                    error_code="QueryGraphError")
        elif len(self.parameters['qnode_keys']) == 1:
            self.response.error(
                f"If qnode keys are provided you must provide at least 2 qnode keys.",
                error_code="ValueError")
        
        if 'max_path_length' not in self.parameters:
            self.parameters['max_path_length'] = 2
        
        if self.parameters['max_path_length'] < 1 or self.parameters['max_path_length'] > 5:
            self.response.error(
                f"Maximum path length must be betwen 1 and 5 inclusive.",
                error_code="ValueError")

        if self.response.status != 'OK':
            return self.response

        expander = ARAXExpander()
        messenger = ARAXMessenger()


        # Expand parameters
        mode = 'ARAX'
        timeout = 60
        kp = 'infores:rtx-kg2'
        prune_threshold = 500

        qnode_key_pairs = [[x[0],x[1],False] for x in combinations(self.parameters['qnode_keys'], 2)]
        edge_n = 1
        node_n = 1
        # FW: old way, try running all pairs through at once
        # for qnode_pair in qnode_key_pairs:
        #     added_connection = False
        #     for n_new_nodes in range(self.parameters['max_path_length']):
        #         new_response = ARAXResponse()
        #         messenger.create_envelope(new_response)
        #         new_response.envelope.message.query_graph.nodes = {k:v for k,v in self.response.envelope.message.query_graph.nodes.items() if k in qnode_pair}
        #         qedge_keys = []
        #         node_pair_list = [qnode_pair[0]]
        #         for i in range(n_new_nodes):
        #             new_qnode_key = f'arax_connect_node_{node_n}'
        #             node_n += 1
        #             # make new names until we find a node key not in the query graph
        #             while new_qnode_key in self.response.envelope.message.query_graph.nodes:
        #                 new_qnode_key = f'arax_connect_node_{node_n}'
        #                 node_n += 1
        #             node_pair_list.append(new_qnode_key)
        #             add_qnode_params = {
        #                 'is_set' : 'true',
        #                 'key' : new_qnode_key
        #             }
        #             new_response = messenger.add_qnode(new_response, add_qnode_params)
        #         node_pair_list.append(qnode_pair[1])
        #         assert len(node_pair_list) == 2 + n_new_nodes
        #         # This zip command grabs nodes next to each other and puts them into tuple pairs
        #         # E.G. [1,2,3,4,5] -> [(1,2),(2,3),(3,4),(4,5)]
        #         new_qnode_key_pairs = list(zip(node_pair_list,node_pair_list[1:]))
        #         for new_qnode_pair in new_qnode_key_pairs:
        #             new_qedge_key = f'connected_edge_{edge_n}'
        #             edge_n += 1
        #             # make new names until we find an edge key not in the query graph
        #             while new_qedge_key in self.response.envelope.message.query_graph.edges:
        #                 new_qedge_key = f'arax_connect_edge_{edge_n}'
        #                 edge_n += 1
        #             qedge_keys.append(new_qedge_key)
        #             add_qedge_params = {
        #                 'key' : new_qedge_key,
        #                 'subject' : new_qnode_pair[0],
        #                 'object' : new_qnode_pair[1]
        #             }
        #             new_response = messenger.add_qedge(new_response, add_qedge_params)
        #         expand_params = {
        #             # FW: commenting to reach out to all kps
        #             #'kp':kp,
        #             'prune_threshold':prune_threshold,
        #             'edge_key':qedge_keys,
        #             'kp_timeout':timeout
        #         }
        #         new_response = expander.apply(new_response, expand_params, mode=mode)
        #         if new_response.status == 'OK' and len(new_response.envelope.message.knowledge_graph.edges) > len(self.response.envelope.message.knowledge_graph.edges):
        #             added_connection = True
        #             # FW: confirm with Eric that this is the correct way to merge response objects
        #             self.response.envelope.message.query_graph.edges.update(new_response.envelope.message.query_graph.edges)
        #             self.response.envelope.message.query_graph.nodes.update(new_response.envelope.message.query_graph.nodes)
        #             self.response.envelope.message.knowledge_graph.edges.update(new_response.envelope.message.knowledge_graph.edges)
        #             self.response.envelope.message.knowledge_graph.nodes.update(new_response.envelope.message.knowledge_graph.nodes)
        #             self.response.merge(new_response)
        #             # FW: If we do not want to stop when we find the shortest connection we could add an option 
        #             # for shortest path and then check that here to deside if we want to break
        #             if self.parameters['shortest_path']:
        #                 break
        #     if not added_connection:
        #         #FW: may want to change this to an error
        #         self.response.warning(f"Could not connect the nodes {qnode_pair[0]} and {qnode_pair[1]} with a max path length of {self.parameters['max_path_length']}.")        
        # FW: New way
        for n_new_nodes in range(self.parameters['max_path_length']):
            added_connection = False
            for qnode_pair in qnode_key_pairs:
                if qnode_pair[2]:
                    continue
                new_response = ARAXResponse()
                messenger.create_envelope(new_response)
                new_response.envelope.message.query_graph.nodes = {k:v for k,v in self.response.envelope.message.query_graph.nodes.items() if k in qnode_pair}
                qedge_keys = []
                node_pair_list = [qnode_pair[0]]
                for i in range(n_new_nodes):
                    new_qnode_key = f'arax_connect_node_{node_n}'
                    node_n += 1
                    # make new names until we find a node key not in the query graph
                    while new_qnode_key in self.response.envelope.message.query_graph.nodes:
                        new_qnode_key = f'arax_connect_node_{node_n}'
                        node_n += 1
                    node_pair_list.append(new_qnode_key)
                    add_qnode_params = {
                        'is_set' : 'true',
                        'key' : new_qnode_key
                    }
                    new_response = messenger.add_qnode(new_response, add_qnode_params)
                node_pair_list.append(qnode_pair[1])
                assert len(node_pair_list) == 2 + n_new_nodes
                # This zip command grabs nodes next to each other and puts them into tuple pairs
                # E.G. [1,2,3,4,5] -> [(1,2),(2,3),(3,4),(4,5)]
                new_qnode_key_pairs = list(zip(node_pair_list,node_pair_list[1:]))
                for new_qnode_pair in new_qnode_key_pairs:
                    new_qedge_key = f'connected_edge_{edge_n}'
                    edge_n += 1
                    # make new names until we find an edge key not in the query graph
                    while new_qedge_key in self.response.envelope.message.query_graph.edges:
                        new_qedge_key = f'arax_connect_edge_{edge_n}'
                        edge_n += 1
                    qedge_keys.append(new_qedge_key)
                    add_qedge_params = {
                        'key' : new_qedge_key,
                        'subject' : new_qnode_pair[0],
                        'object' : new_qnode_pair[1]
                    }
                    new_response = messenger.add_qedge(new_response, add_qedge_params)
                expand_params = {
                    # FW: commenting to reach out to all kps
                    #'kp':kp,
                    'prune_threshold':prune_threshold,
                    'edge_key':qedge_keys,
                    'kp_timeout':timeout
                }
                new_response = expander.apply(new_response, expand_params, mode=mode)
                if new_response.status == 'OK' and len(new_response.envelope.message.knowledge_graph.edges) > len(self.response.envelope.message.knowledge_graph.edges):
                    added_connection = True
                    # FW: confirm with Eric that this is the correct way to merge response objects
                    self.response.envelope.message.query_graph.edges.update(new_response.envelope.message.query_graph.edges)
                    self.response.envelope.message.query_graph.nodes.update(new_response.envelope.message.query_graph.nodes)
                    self.response.envelope.message.knowledge_graph.edges.update(new_response.envelope.message.knowledge_graph.edges)
                    for knode_id, knode in new_response.envelope.message.knowledge_graph.nodes.items():
                        if knode_id in self.response.envelope.message.knowledge_graph.nodes:
                            new_response.envelope.message.knowledge_graph.nodes[knode_id].qnode_keys += self.response.envelope.message.knowledge_graph.nodes[knode_id].qnode_keys
                            self.response.envelope.message.knowledge_graph.nodes[knode_id].qnode_keys = new_response.envelope.message.knowledge_graph.nodes[knode_id].qnode_keys
                    self.response.envelope.message.knowledge_graph.nodes.update(new_response.envelope.message.knowledge_graph.nodes)
                    self.response.merge(new_response)
                    # FW: If we do not want to stop when we find the shortest connection we could add an option 
                    # for shortest path and then check that here to deside if we want to break
                    if self.parameters['shortest_path']:
                        qnode_pair[2] = True
            if not added_connection:
                #FW: may want to change this to an error
                self.response.warning(f"Could not connect the nodes {qnode_pair[0]} and {qnode_pair[1]} with a max path length of {self.parameters['max_path_length']}.") 
        return self.response