def from_json(cls, driver=None, uri=None, user=None, password=None, j_data=None, node_label="node", edge_label="edge", holistic=False): """Create a Neo4jGraph from a json-like dictionary.""" graph = cls(driver=driver, uri=uri, user=user, password=password, node_label=node_label, edge_label=edge_label) if holistic: query = generic.load_graph_from_json(j_data, graph._node_label, graph._edge_label) graph.execute(query) else: graph.add_nodes_from([(n["id"], attrs_from_json(n["attrs"])) for n in j_data["nodes"]]) graph.add_edges_from([(e["from"], e["to"], attrs_from_json(e["attrs"])) for e in j_data["edges"]]) return graph
def update_action_graph_node_attrs(corpus_id): """Handle update of node attrs.""" json_data = request.get_json() node_id = json_data["id"] node_attrs = json_data["attrs"] corpus = get_corpus(corpus_id) response = json.dumps({'success': False}), 404, { 'ContentType': 'application/json' } if corpus is not None: if node_id in corpus.action_graph.nodes(): try: for k, v in node_attrs.items(): new_v = [] for vv in v["data"]: new_v.append(vv.strip()) node_attrs[k]["data"] = new_v attrs = attrs_from_json(node_attrs) corpus.action_graph.set_node_attrs(node_id, attrs) response = json.dumps({'success': True}), 200, { 'ContentType': 'application/json' } update_last_modified(corpus_id) except: pass return response
def load_graph_from_json(json_data, node_label, edge_label, literal_id=True, generate_var_names=True): query = "" if len(json_data["nodes"]) > 0: query += "CREATE" # Add nodes nodes = [] if (generate_var_names): var_names = { n["id"]: "n_{}".format(i + 1) for i, n in enumerate( json_data["nodes"]) } else: var_names = { n["id"]: "n_{}".format(n["id"]) for n in json_data["nodes"] } for node_data in json_data["nodes"]: node_id = node_data["id"] if literal_id: node_id = "'{}'".format(node_id) attr_repr = generate_attributes( attrs_from_json(node_data["attrs"])) nodes.append( "({}:{} {{ id: {} {} }})".format( var_names[node_data["id"]], node_label, node_id, ", " + attr_repr if len(attr_repr) > 0 else "")) query += ", ".join(nodes) + "," # Add edges edges = [] for edge_data in json_data["edges"]: attr_repr = generate_attributes( attrs_from_json(edge_data["attrs"])) edges.append( "({})-[:{} {{ {} }}]->({})".format( var_names[edge_data["from"]], edge_label, attr_repr, var_names[edge_data["to"]])) query += ", ".join(edges) return query
def load_graph_from_json(json_data, node_label, edge_label, literal_id=True, generate_var_names=True): query = "" if len(json_data["nodes"]) > 0: query += "CREATE" # Add nodes nodes = [] if (generate_var_names): var_names = { n["id"]: "n_{}".format(i + 1) for i, n in enumerate(json_data["nodes"]) } else: var_names = { n["id"]: "n_{}".format(n["id"]) for n in json_data["nodes"] } for node_data in json_data["nodes"]: node_id = node_data["id"] if literal_id: node_id = "'{}'".format(node_id) attr_repr = generate_attributes(attrs_from_json(node_data["attrs"])) nodes.append("({}:{} {{ id: {} {} }})".format( var_names[node_data["id"]], node_label, node_id, ", " + attr_repr if len(attr_repr) > 0 else "")) query += ", ".join(nodes) + "," # Add edges edges = [] for edge_data in json_data["edges"]: attr_repr = generate_attributes(attrs_from_json(edge_data["attrs"])) edges.append("({})-[:{} {{ {} }}]->({})".format( var_names[edge_data["from"]], edge_label, attr_repr, var_names[edge_data["to"]])) query += ", ".join(edges) return query
def from_json(cls, driver=None, uri=None, user=None, password=None, j_data=None, node_label="node", edge_label="edge", holistic=False): """Create a Neo4jGraph from a json-like dictionary.""" graph = cls( driver=driver, uri=uri, user=user, password=password, node_label=node_label, edge_label=edge_label) if holistic: query = cypher.load_graph_from_json( j_data, graph._node_label, graph._edge_label) graph.execute(query) else: graph.add_nodes_from([ (n["id"], attrs_from_json(n["attrs"])) for n in j_data["nodes"]]) graph.add_edges_from([ (e["from"], e["to"], attrs_from_json(e["attrs"])) for e in j_data["edges"]]) return graph
def load_graph_from_json_apoc(tx, json_data, node_label, edge_label, tmp_dir=None): # store json-file somewhere, generate attr repr. if tmp_dir is None: tmp_dir = "/var/lib/neo4j/import/" path = tmp_dir + "kami_tmp.json" # fd, path = tempfile.mkstemp(prefix=tmp_dir) # try: with open(path, 'w+') as tmp: for n in json_data["nodes"]: n["attrs"] = generate_attributes_json( attrs_from_json(n["attrs"])) n["attrs"]["id"] = n["id"] for e in json_data["edges"]: e["attrs"] = generate_attributes_json( attrs_from_json(e["attrs"])) json.dump(json_data, tmp) # load nodes node_query = ( "WITH 'file:///{}' AS url\n".format(path) + "CALL apoc.load.json(url) YIELD value\n" + "UNWIND value.nodes AS node\n" + "MERGE (n:{} {{ id: node.id }}) ON CREATE\n".format(node_label) + "\tSET n = node.attrs\n" ) tx.run(node_query) # load edges edge_query = ( "WITH 'file:///{}' AS url\n".format(path) + "CALL apoc.load.json(url) YIELD value\n" + "UNWIND value.edges AS edge\n" + "MATCH (u:{} {{ id: edge.from }}), (v:{} {{ id: edge.to }}) \n".format( node_label, node_label) + "MERGE (u)-[rel:{}]->(v)\n ON CREATE\n".format(edge_label) + "\tSET rel = edge.attrs\n" ) tx.run(edge_query)
def load_graph_from_json_apoc(tx, json_data, node_label, edge_label, tmp_dir=None): # store json-file somewhere, generate attr repr. if tmp_dir is None: tmp_dir = "/var/lib/neo4j/import/" path = tmp_dir + "kami_tmp.json" # fd, path = tempfile.mkstemp(prefix=tmp_dir) # try: with open(path, 'w+') as tmp: for n in json_data["nodes"]: n["attrs"] = generate_attributes_json(attrs_from_json(n["attrs"])) n["attrs"]["id"] = n["id"] for e in json_data["edges"]: e["attrs"] = generate_attributes_json(attrs_from_json(e["attrs"])) json.dump(json_data, tmp) # load nodes node_query = ( "WITH 'file:///{}' AS url\n".format(path) + "CALL apoc.load.json(url) YIELD value\n" + "UNWIND value.nodes AS node\n" + "MERGE (n:{} {{ id: node.id }}) ON CREATE\n".format(node_label) + "\tSET n = node.attrs\n") tx.run(node_query) # load edges edge_query = ( "WITH 'file:///{}' AS url\n".format(path) + "CALL apoc.load.json(url) YIELD value\n" + "UNWIND value.edges AS edge\n" + "MATCH (u:{} {{ id: edge.from }}), (v:{} {{ id: edge.to }}) \n". format(node_label, node_label) + "MERGE (u)-[rel:{}]->(v)\n ON CREATE\n".format(edge_label) + "\tSET rel = edge.attrs\n") tx.run(edge_query)
def set_node_attrs_from_json(self, node, attrs, update=False): """Set node attributes from json repr of attrs. node : Id of the node whose attrs should be set attrs : dict Dictionary containing attrs update : optional If is set to False, updates only the attributes whose keys are in 'attrs', all the attributes not mentioned in 'attrs' stay the same. Otherwise, overwrites all the attributes (default: False) """ return self.set_node_attrs(node, attrs_from_json(attrs), update)
def set_edge_attrs_from_json(self, source, target, attrs, update=False): """Set edge attributes. source : Id of the source node of the edge target : Id of the target node of the edge attrs : dict Dictionary containing attrs update : optional If is set to False, updates only the attributes whose keys are in 'attrs', all the attributes not mentioned in 'attrs' stay the same. Otherwise, overwrites all the attributes (default: False) """ return self.set_edge_attrs(source, target, attrs_from_json(attrs))
def _init_from_data(kb, data, instantiated=False): """Init knowledge base from json data.""" if data is not None: if "action_graph" in data.keys(): # ag = copy.deepcopy(ag) # print("Loading action graph...") start = time.time() kb._hierarchy.add_graph_from_json(kb._action_graph_id, data["action_graph"], {"type": "action_graph"}) if "versioning" in data: kb._versioning = VersionedHierarchy.from_json( kb._hierarchy, data["versioning"]) if "action_graph_typing" in data.keys(): ag_typing = copy.deepcopy(data["action_graph_typing"]) else: raise KamiException( "Error loading knowledge base from json: " "action graph should be typed by the meta-model!") # print("Setting action graph typing...") start = time.time() kb._hierarchy.add_typing(kb._action_graph_id, "meta_model", ag_typing) # print("Finished after: ", time.time() - start) if not instantiated: # print("Loading action graph semmantics...") start = time.time() if "action_graph_semantics" in data.keys(): ag_semantics = copy.deepcopy( data["action_graph_semantics"]) else: ag_semantics = dict() kb._hierarchy.add_relation(kb._action_graph_id, "semantic_action_graph", ag_semantics) # print("Finished after: ", time.time() - start) else: if kb._action_graph_id not in kb._hierarchy.graphs(): kb.create_empty_action_graph() # Nuggets related init # print("Adding nuggets...") start = time.time() if "nuggets" in data.keys(): for nugget_data in data["nuggets"]: nugget_graph_id = kb._id + "_" + nugget_data["id"] if "graph" not in nugget_data.keys() or\ "typing" not in nugget_data.keys() or\ "template_rel" not in nugget_data.keys(): raise KamiException( "Error loading knowledge base from json: " "nugget data shoud contain typing by" " action graph and template relation!") attrs = {} if "attrs" in nugget_data.keys(): attrs = attrs_from_json(nugget_data["attrs"]) attrs["type"] = "nugget" attrs["nugget_id"] = nugget_data["id"] if not instantiated: attrs["corpus_id"] = kb._id else: attrs["model_id"] = kb._id attrs["corpus_id"] = kb._corpus_id kb._hierarchy.add_graph_from_json(nugget_graph_id, nugget_data["graph"], attrs) kb._hierarchy.add_typing(nugget_graph_id, kb._action_graph_id, nugget_data["typing"]) kb._hierarchy.add_relation(nugget_graph_id, nugget_data["template_rel"][0], nugget_data["template_rel"][1]) if not instantiated: if "semantic_rels" in nugget_data.keys(): for s_nugget_id, rel in nugget_data[ "semantic_rels"].items(): kb._hierarchy.add_relation(nugget_graph_id, s_nugget_id, rel) # print("Finished after: ", time.time() - start) else: if kb._action_graph_id not in kb._hierarchy.graphs(): kb.create_empty_action_graph()