def create_concept_graphs(example_indices, typedb_session, infer=True): """ Builds an in-memory graph for each example, with an example_id as an anchor for each example subgraph. Args: example_indices: The values used to anchor the subgraph queries within the entire knowledge graph typedb_session: TypeDB Session Returns: In-memory graphs of TypeDB subgraphs """ graphs = [] options = TypeDBOptions.core() options.infer = infer for example_id in example_indices: print(f'Creating graph for example {example_id}') graph_query_handles = get_query_handles(example_id) with typedb_session.transaction(TransactionType.READ, options) as tx: # Build a graph from the queries, samplers, and query graphs graph = build_graph_from_queries(graph_query_handles, tx) obfuscate_labels(graph, TYPES_AND_ROLES_TO_OBFUSCATE) graph.name = example_id graphs.append(graph) return graphs
def test_exception_is_raised_when_there_are_no_results_for_any_query(self): g1 = nx.MultiDiGraph() g1.add_node('x') query_sampler_variable_graph_tuples = [('match $x id V123;', mock_sampler, g1)] class MockTransactionEmpty: def query(self, query, infer=True): return [] mock_tx = MockTransactionEmpty() with self.assertRaises(RuntimeError) as context: build_graph_from_queries(query_sampler_variable_graph_tuples, mock_tx) self.assertEqual(f'The graph from queries: {[query_sampler_variable_graph_tuple[0] for query_sampler_variable_graph_tuple in query_sampler_variable_graph_tuples]}\n' f'could not be created, since none of these queries returned results', str(context.exception))
def test_warning_given_when_one_query_gives_no_results(self): g1 = nx.MultiDiGraph() g1.add_node('x') g2 = nx.MultiDiGraph() g2.add_node('y') query_sampler_variable_graph_tuples = [('match $x id V123;', mock_sampler, g1), ('match $y id V123;', mock_sampler, g2)] class MockTransaction2: def query(self, query, infer=True): if query == 'match $x id V123;': return [MockConceptMap({'x': MockThing('V123', MockType('V4123', 'person', 'ENTITY'))})] elif query == 'match $y id V123;': return [] mock_tx = MockTransaction2() with self.assertWarns(UserWarning) as context: build_graph_from_queries(query_sampler_variable_graph_tuples, mock_tx) self.assertEqual(f'There were no results for query: \n\"match $y id V123;\"\nand so nothing will be added to the graph for this query', str(context.warning))
def test_graph_is_built_from_grakn_as_expected(self): g1 = nx.MultiDiGraph() g1.add_node('x') g2 = nx.MultiDiGraph() g2.add_node('x') g2.add_node('n') g2.add_edge('x', 'n', type='has') g3 = nx.MultiDiGraph() g3.add_node('x') g3.add_node('r') g3.add_node('y') g3.add_edge('r', 'x', type='child') g3.add_edge('r', 'y', type='parent') query_sampler_variable_graph_tuples = [('match $x isa person;', mock_sampler, g1), ('match $x isa person, has name $n;', mock_sampler, g2), ('match $x isa person; $r(child: $x, parent: $y);', mock_sampler, g3), # TODO Add functionality for loading schema at a later date # ('match $x sub person; $x sub $type;', g4), # ('match $x sub $y;', g5), ] with self._client.session(self._database, SessionType.DATA) as session: with session.transaction(TransactionType.WRITE) as tx: tx.query(ITBuildGraphFromQueriesWithRealGrakn.SCHEMA) tx.query(ITBuildGraphFromQueriesWithRealGrakn.DATA) tx.commit() with session.transaction(TransactionType.READ) as tx: combined_graph = build_graph_from_queries(query_sampler_variable_graph_tuples, tx) person_exp = build_thing(next(tx.query().match('match $x isa person;')).get('x')) name_exp = build_thing(next(tx.query().match('match $x isa name;')).get('x')) parentship_exp = build_thing(next(tx.query().match('match $x isa parentship;')).get('x')) expected_combined_graph = nx.MultiDiGraph() expected_combined_graph.add_node(person_exp, type='person') expected_combined_graph.add_node(name_exp, type='name', value_type='string', value='Bob') expected_combined_graph.add_node(parentship_exp, type='parentship') expected_combined_graph.add_edge(parentship_exp, person_exp, type='child') expected_combined_graph.add_edge(parentship_exp, person_exp, type='parent') expected_combined_graph.add_edge(person_exp, name_exp, type='has') self.assertGraphsEqual(expected_combined_graph, combined_graph)
def __getitem__(self, idx): print(type(self._typedb_session)) example_id = self._example_indices[idx] print(f"Fetching subgraph for example {example_id}") graph_query_handles = self.get_query_handles_for_id(example_id) options = TypeDBOptions.core() options.infer = self._infer with self.typedb_session.transaction(TransactionType.READ, options=options) as tx: # Build a graph from the queries, samplers, and query graphs graph = build_graph_from_queries(graph_query_handles, tx) graph.name = example_id if self._transform: graph = self._transform(graph) return graph
def test_graph_is_built_as_expected(self): g1 = nx.MultiDiGraph() g1.add_node('x') g2 = nx.MultiDiGraph() g2.add_node('x') g2.add_node('n') g2.add_edge('x', 'n', type='has') g3 = nx.MultiDiGraph() g3.add_node('x') g3.add_node('r') g3.add_node('y') g3.add_edge('r', 'x', type='child') g3.add_edge('r', 'y', type='parent') query_sampler_variable_graph_tuples = [('match $x id V123;', mock_sampler, g1), ('match $x id V123, has name $n;', mock_sampler, g2), ('match $x id V123; $r(child: $x, parent: $y);', mock_sampler, g3), # TODO Add functionality for loading schema at a later date # ('match $x sub person; $x sub $type;', g4), # ('match $x sub $y;', g5), ] mock_tx = MockTransaction() combined_graph = build_graph_from_queries(query_sampler_variable_graph_tuples, mock_tx) person_exp = Thing('V123', 'person', 'entity') parentship_exp = Thing('V567', 'parentship', 'relation') name_exp = Thing('V987', 'name', 'attribute', value_type='string', value='Bob') expected_combined_graph = nx.MultiDiGraph() expected_combined_graph.add_node(person_exp, type='person') expected_combined_graph.add_node(name_exp, type='name', value_type='string', value='Bob') expected_combined_graph.add_node(parentship_exp, type='parentship') expected_combined_graph.add_edge(parentship_exp, person_exp, type='child') expected_combined_graph.add_edge(parentship_exp, person_exp, type='parent') expected_combined_graph.add_edge(person_exp, name_exp, type='has') self.assertGraphsEqual(expected_combined_graph, combined_graph)
def test_graph_is_built_as_expected(self): g1 = nx.MultiDiGraph() g1.add_node('x') g2 = nx.MultiDiGraph() g2.add_node('x') g2.add_node('n') g2.add_edge('x', 'n', type='has') g3 = nx.MultiDiGraph() g3.add_node('x') g3.add_node('r') g3.add_node('y') g3.add_edge('r', 'x', type='child') g3.add_edge('r', 'y', type='parent') query_sampler_variable_graph_tuples = [ ('match $x iid V123;', mock_sampler, g1), ('match $x iid V123, has name $n;', mock_sampler, g2), ('match $x iid V123; $r(child: $x, parent: $y);', mock_sampler, g3), # TODO Add functionality for loading schema at a later date # ('match $x sub person; $x sub $type;', g4), # ('match $x sub $y;', g5), ] class MockTransaction: def query(self): return MockQueryManager() class MockQueryManager: def match(self, query): if query == 'match $x iid V123;': return [ MockConceptMap({ 'x': MockThing('V123', MockType('V4123', 'person', 'ENTITY')) }) ] elif query == 'match $x iid V123, has name $n;': return [ MockConceptMap({ 'x': MockThing('V123', MockType('V4123', 'person', 'ENTITY')), 'n': MockAttribute( 'V987', 'Bob', MockAttributeType( 'V555', 'name', 'ATTRIBUTE', AttributeType.ValueType.STRING)) }) ] elif query == 'match $x iid V123; $r(child: $x, parent: $y);': return [ MockConceptMap({ 'x': MockThing('V123', MockType('V4123', 'person', 'ENTITY')), 'y': MockThing('V123', MockType('V4123', 'person', 'ENTITY')), 'r': MockThing( 'V567', MockType('V9876', 'parentship', 'RELATION')) }) ] else: raise NotImplementedError mock_tx = MockTransaction() combined_graph = build_graph_from_queries( query_sampler_variable_graph_tuples, mock_tx) person_exp = Thing('V123', 'person', 'entity') parentship_exp = Thing('V567', 'parentship', 'relation') name_exp = Thing('V987', 'name', 'attribute', value_type=AttributeType.ValueType.STRING, value='Bob') expected_combined_graph = nx.MultiDiGraph() expected_combined_graph.add_node(person_exp, type='person') expected_combined_graph.add_node( name_exp, type='name', value_type=AttributeType.ValueType.STRING, value='Bob') expected_combined_graph.add_node(parentship_exp, type='parentship') expected_combined_graph.add_edge(parentship_exp, person_exp, type='child') expected_combined_graph.add_edge(parentship_exp, person_exp, type='parent') expected_combined_graph.add_edge(person_exp, name_exp, type='has') self.assertGraphsEqual(expected_combined_graph, combined_graph)