def update_nugget_node_attrs(corpus_id, nugget_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 nugget_id in corpus.nuggets() and\ node_id in corpus.get_nugget(nugget_id).nodes(): try: # Here I actually need to generate rewriting rule corpus.update_nugget_node_attr_from_json( nugget_id, node_id, node_attrs) response = json.dumps({'success': True}), 200, { 'ContentType': 'application/json' } update_last_modified(corpus_id) except: pass return response
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 update_nugget_edge_attrs(corpus_id, nugget_id): """Handle update of node attrs.""" json_data = request.get_json() source = json_data["source"] target = json_data["target"] 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 (source, target) in corpus.action_graph.edges() and\ nugget_id in corpus.nuggets(): # try: # Here I actually need to generate rewriting rule corpus.update_nugget_edge_attr_from_json(nugget_id, source, target, node_attrs) response = json.dumps({'success': True}), 200, { 'ContentType': 'application/json' } update_last_modified(corpus_id) # except: # pass return response
def download_corpus(corpus_id): """Handle corpus download.""" filename = corpus_id.replace(" ", "_") + ".json" corpus = get_corpus(corpus_id) if corpus: # Get action graph layout node_positioning = None json_repr = app.mongo.db.kami_corpora.find_one({"id": corpus_id}) if "node_positioning" in json_repr.keys(): node_positioning = json_repr["node_positioning"] corpus_json = corpus.to_json() if node_positioning is not None: corpus_json["node_positioning"] = node_positioning with open(os.path.join(app.config["UPLOAD_FOLDER"], filename), 'w') as f: json.dump(corpus_json, f) return send_file(os.path.join(app.config["UPLOAD_FOLDER"], filename), as_attachment=True, mimetype='application/json', attachment_filename=filename) else: return render_template("corpus_not_found.html", corpus_id=corpus_id)
def get_corpus_action_nuggets(corpus_id, action_id): corpus = get_corpus(corpus_id) nuggets = corpus.get_mechanism_nuggets(action_id) data = {} for n in nuggets: data[n] = (corpus.get_nugget_desc(n), corpus.get_nugget_type(n)) return jsonify(data), 200
def fetch_definition(corpus_id, gene_id): """Retreive raw definition graphs.""" definition_json = app.mongo.db.kami_new_definitions.find_one({ "corpus_id": corpus_id, "protoform": gene_id }) del definition_json["_id"] corpus = get_corpus(corpus_id) if corpus is not None and definition_json is not None: gene_node_id = corpus.get_protoform_by_uniprot(gene_id) # Find all the subcomponents of the protoform and the graph they induce protoform_subcomponents = corpus.subcomponent_nodes(gene_node_id) protoform_graph = corpus.action_graph.to_d3_json( nodes=protoform_subcomponents) ag_meta_typing = corpus.get_action_graph_typing() protoform_meta_typing = { c: ag_meta_typing[c] for c in protoform_subcomponents } definition_json["protoform_graph"] = protoform_graph definition_json["protoform_meta_typing"] = protoform_meta_typing return jsonify(definition_json), 200 return jsonify({"success": False}), 404
def import_model(corpus_id): """Handler of model import.""" if request.method == "GET": failed = request.args.get('failed') corpus = get_corpus(corpus_id) return render_template('import_model.html', corpus=corpus, failed=failed) else: # check if the post request has the file part annotation = {} if request.form["name"]: annotation["name"] = request.form["name"] if request.form["desc"]: annotation["desc"] = request.form["desc"] if request.form["organism"]: annotation["organism"] = request.form["organism"] # TODO: handle annotation if 'file' not in request.files: raise ValueError('No file part') return redirect(request.url) file = request.files['file'] # if user does not select file, browser also # submit a empty part without filename if file.filename == '': raise ValueError('No selected file') return redirect(request.url) if file: filename = secure_filename(file.filename) file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename)) return imported_model(filename, annotation)
def get_corpus_nuggets(corpus_id): corpus = get_corpus(corpus_id) nuggets = {} for nugget in corpus.nuggets(): nuggets[nugget] = (corpus.get_nugget_desc(nugget), corpus.get_nugget_type(nugget)) data = {} data["nuggets"] = nuggets return jsonify(data), 200
def update_corpus_nugget(corpus_id, nugget_id): json_data = request.get_json() corpus = get_corpus(corpus_id) corpus.set_nugget_desc(nugget_id, json_data["desc"]) response = json.dumps({'success': True}), 200, { 'ContentType': 'application/json' } return response
def corpus_view(corpus_id): """View corpus.""" if app.neo4j_driver is None: return render_template("neo4j_connection_failure.html", uri=app.config["NEO4J_URI"], user=app.config["NEO4J_USER"]) if app.mongo.db is None: return render_template("mongo_connection_failure.html", uri=app.config["MONGO_URI"]) try: corpus = get_corpus(corpus_id) except: return render_template("neo4j_connection_failure.html", uri=app.config["NEO4J_URI"], user=app.config["NEO4J_USER"]) if corpus is not None: n_nuggets = len(corpus.nuggets()) genes = {} for g in corpus.protoforms(): genes[g] = [] modifications = {} for m in corpus.modifications(): modifications[m] = [] bindings = {} for b in corpus.bindings(): bindings[b] = [] raw_defs = app.mongo.db.kami_new_definitions.find( {"corpus_id": corpus_id}) n_defs = len(list(raw_defs)) model_id = None if "model_id" in request.args: model_id = request.args["model_id"] model_json = app.mongo.db.kami_models.find({"id": model_id}) if not model_json: model_id = None return render_template("corpus.html", kb_id=corpus_id, kb=corpus, n_nuggets=n_nuggets, n_definitons=n_defs, genes=json.dumps(genes), bindings=json.dumps(bindings), modifications=json.dumps(modifications), instantaited=False, model_id=model_id, readonly=app.config["READ_ONLY"]) else: return render_template("corpus_not_found.html", corpus_id=corpus_id)
def get_gene_data(corpus_id): """Get HGNC symbols and synonyms of genes.""" json_data = request.get_json() data = {"items": {}} corpus = get_corpus(corpus_id) for up in json_data["uniprots"]: gene_id = corpus.get_protoform_by_uniprot(up[0]) data["items"][up[0]] = [ corpus.get_hgnc_symbol(gene_id), corpus.get_synonyms(gene_id) ] return jsonify(data), 200
def add_interaction(corpus_id, add_agents=True, anatomize=True, apply_semantics=True): """Handle interaction addition.""" corpus = get_corpus(corpus_id) if request.method == 'GET': return render_template("add_interaction.html", corpus=corpus, readonly=app.config["READ_ONLY"]) elif request.method == 'POST': if app.config["READ_ONLY"]: return render_template("403.html") else: corpus = get_corpus(corpus_id) interaction = parse_interaction(request.form) corpus.add_interaction(interaction) update_revision_history(corpus) update_last_modified(corpus_id) return redirect(url_for('corpus.corpus_view', corpus_id=corpus._id))
def get_ag_node_by_type(corpus_id, element_type): """Add action graph nodes by type.""" data = {"elements": []} corpus = get_corpus(corpus_id) ag_nodes = corpus.nodes_of_type(element_type) for n in ag_nodes: element = {"id": n} element["attrs"] = { k: list(v) for k, v in corpus.get_ag_node_data(n).items() } data["elements"].append(element) return jsonify(data), 200
def get_genes(corpus_id): """Handle get genes request.""" corpus = get_corpus(corpus_id) response = json.dumps({'success': False}), 404, { 'ContentType': 'application/json' } if corpus is not None: gene_nodes = corpus.protoforms() data = {"genes": []} for g in gene_nodes: uniprotid, hgnc, syn, _ = corpus.get_protoform_data(g) data["genes"].append([uniprotid, hgnc, syn]) response = jsonify(data), 200 return response
def get_definitions(corpus_id): raw_defs = app.mongo.db.kami_new_definitions.find({"corpus_id": corpus_id}) corpus = get_corpus(corpus_id) definitions = {} for d in raw_defs: node_attrs = corpus.action_graph.get_node( corpus.get_protoform_by_uniprot(d["protoform"])) definitions[d["protoform"]] = {} definitions[d["protoform"]]["attrs"] = attrs_to_json(node_attrs) definitions[d["protoform"]]["variants"] = [ [k, v["desc"], v["wild_type"]] for k, v in d["products"].items() ] return jsonify(definitions), 200
def delete_corpus(corpus_id): """Handle removal of the corpus.""" corpus = get_corpus(corpus_id) if corpus is not None: # connect to db h = Neo4jHierarchy(driver=app.neo4j_driver) # remove nuggets for n in corpus.nuggets(): h.remove_graph(n) # remove the ag h.remove_graph(corpus._action_graph_id) # drop from mongo db app.mongo.db.kami_corpora.remove({"id": corpus_id}) return jsonify({"success": True}), 200 else: return render_template("corpus_not_found.html", corpus_id=corpus_id)
def raw_nugget_json(corpus_id, nugget_id): corpus = get_corpus(corpus_id) data = {} data["nuggetJson"] = corpus.get_nugget(nugget_id).to_d3_json() data["nuggetType"] = corpus.get_nugget_type(nugget_id) data["metaTyping"] = { k: corpus.get_action_graph_typing()[v] for k, v in corpus.get_nugget_typing(nugget_id).items() } data["agTyping"] = corpus.get_nugget_typing(nugget_id) data["templateRelation"] = {} for k, v in corpus.get_nugget_template_rel(nugget_id).items(): for vv in v: data["templateRelation"][vv] = k return jsonify(data), 200
def import_json_interactions(corpus_id): """Handle import of json interactions.""" if request.method == "GET": corpus = get_corpus(corpus_id) return render_template('import_interactions.html', corpus=corpus) else: if 'file' not in request.files: raise ValueError('No file part') return redirect(request.url) file = request.files['file'] # if user does not select file, browser also # submit a empty part without filename if file.filename == '': raise ValueError('No selected file') return redirect(request.url) if file: filename = secure_filename(file.filename) file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename)) return imported_interactions(filename, corpus_id)
def edit_meta_data(corpus_id): if request.method == "GET": corpus = get_corpus(corpus_id) return render_template("edit_meta_data.html", corpus=corpus) else: if app.config["READ_ONLY"]: return render_template("403.html") else: json_data = request.form corpus_json = app.mongo.db.kami_corpora.find_one({"id": corpus_id}) for k in json_data.keys(): corpus_json["meta_data"][k] = json_data[k] app.mongo.db.kami_corpora.update_one({"_id": corpus_json["_id"]}, {"$set": corpus_json}, upsert=False) return redirect(url_for('corpus.corpus_view', corpus_id=corpus_id))
def add_nugget_from_session(corpus_id, add_agents=True, anatomize=True, apply_semantics=True): """Add nugget stored in session to the corpus.""" json_data = request.get_json() corpus = get_corpus(corpus_id) if "nugget" not in session: return render_template("session_expired.html") # Apply the update of description if "nugget_desc" in json_data["updatedNuggetInfo"]: session["nugget_desc"] = json_data["updatedNuggetInfo"]["nugget_desc"][ 0] # Apply the update of meta-data update for k, v in json_data["updatedNuggetMetaData"].items(): session["nugget"].graph.set_node_attrs(k, v, update=False) # Apply the update of reference nodes for k, v in json_data["updatedReferenceElements"].items(): if v is not None: session["nugget"].reference_typing[k] = v corpus.add_nugget(session["nugget"], session["nugget_type"], session["template_rels"], desc=session["nugget_desc"], add_agents=add_agents, anatomize=anatomize, apply_semantics=apply_semantics) if "nugget" in session.keys(): session.pop("nugget", None) if "nugget_type" in session.keys(): session.pop("nugget_type", None) data = {"redirect": url_for('corpus.corpus_view', corpus_id=corpus_id)} return jsonify(data), 200
def instantiate_ag(corpus_id, model_id): """Return instantiated action graph.""" corpus = get_corpus(corpus_id) model = get_model(corpus, model_id) ag_rule, ag_instance = model.action_graph_instantiation_rule() rule = {} rule["cloned_nodes"] = {} for lhs_node, p_nodes in ag_rule.cloned_nodes().items(): rule["cloned_nodes"][lhs_node] = list(p_nodes) rule["removed_edges"] = list(ag_rule.removed_edges()) rule["added_node_attrs"] = {} for n, attrs in ag_rule.added_node_attrs().items(): rule["added_node_attrs"][n] = attrs_to_json(attrs) rule["removed_nodes"] = list(ag_rule.removed_nodes()) rule["removed_node_attrs"] = {} for n, attrs in ag_rule.removed_node_attrs().items(): rule["removed_node_attrs"][n] = attrs_to_json(attrs) rule["instance"] = ag_instance rule["p_lhs"] = ag_rule.p_lhs rule["p_rhs"] = ag_rule.p_rhs response = {"rule": rule, "instance": ag_instance} return jsonify(response), 200
def update_action_graph_edge_attrs(corpus_id): """Handle update of node attrs.""" json_data = request.get_json() source = json_data["source"] target = json_data["target"] edge_attrs = json_data["attrs"] corpus = get_corpus(corpus_id) response = json.dumps({'success': False}), 404, { 'ContentType': 'application/json' } if corpus is not None: if (source, target) in corpus.action_graph.edges(): try: corpus.action_graph.set_edge_attrs_from_json( source, target, edge_attrs) response = json.dumps({'success': True}), 200, { 'ContentType': 'application/json' } update_last_modified(corpus_id) except: pass return response
def get_corpus_action_graph(corpus_id, attrs=True): """Handle the raw json action graph representation.""" corpus = get_corpus(corpus_id) corpus_json = app.mongo.db.kami_corpora.find_one({"id": corpus_id}) return get_action_graph(corpus, corpus_json, attrs)
def remove_nugget_from_corpus(corpus_id, nugget_id): corpus = get_corpus(corpus_id) corpus.remove_nugget(nugget_id) return jsonify({"success": True}), 200
def get_corpus_gene_adjacency(corpus_id): """Generate a nugget table.""" corpus = get_corpus(corpus_id) data = get_gene_adjacency(corpus) return jsonify(data), 200
def corpus_nugget_json(corpus_id, nugget_id): corpus = get_corpus(corpus_id) return get_nugget(corpus, nugget_id)
def merge_corpus_ag_nodes(corpus_id): merge_ag_nodes(get_corpus(corpus_id), request.get_json()) return jsonify({"success": True}), 200
def get_ag_node_by_id(corpus_id, element_id): """Get action graph node by id.""" corpus = get_corpus(corpus_id) data = {k: list(v) for k, v in corpus.get_ag_node_data(element_id).items()} return jsonify(data), 200
def add_variant(corpus_id, gene_node_id): """Handle addition of protein variants.""" if request.method == "GET": try: corpus = get_corpus(corpus_id) graph = corpus.action_graph.to_d3_json( nodes=corpus.subcomponent_nodes(gene_node_id)) ag_typing = corpus.get_action_graph_typing() meta_typing = {n["id"]: ag_typing[n["id"]] for n in graph["nodes"]} try: canonical_sequence = corpus.get_canonical_sequence( gene_node_id) except: canonical_sequence = None return render_template("add_variant.html", corpus=corpus, graph_repr=json.dumps(graph), meta_typing_repr=json.dumps(meta_typing), canonical_sequence=canonical_sequence, gene_id=gene_node_id, readonly=app.config["READ_ONLY"]) except: return jsonify({"success": False}), 200 else: if app.config["READ_ONLY"]: return render_template("403.html") else: try: json_data = request.get_json() variant_name = json_data["variant_name"] desc = json_data["desc"] wt = json_data["wt"] raw_removed_components = json_data["removedComponents"] raw_selected_aa = json_data["selectedAA"] # Create a variant record corpus = get_corpus(corpus_id) gene_uniprot = corpus.get_uniprot(gene_node_id) components = { "regions": [], "sites": [], "residues": [], "states": [] } # TODO: think about removal of states for [c_id, c, c_type] in raw_removed_components: # attrs = {k: v["data"] for k, v in c.items()} if c_type == "region": # start, end = corpus.get_fragment_location(c_id) # if start is not None: # attrs["start"] = start # if end is not None: # attrs["end"] = end components["regions"].append(c_id) elif c_type == "site": # start, end = corpus.get_fragment_location(c_id) # if start is not None: # attrs["start"] = start # if end is not None: # attrs["end"] = end components["sites"].append(c_id) elif c_type == "residue": # loc = corpus.get_residue_location(c_id) # if loc is not None: # attrs["loc"] = loc components["residues"].append(c_id) residues = {} for [c_id, c, aa] in raw_selected_aa: # attrs = {k: v["data"] for k, v in c.items()} # loc = corpus.get_residue_location(c_id) # if loc is not None: # attrs["loc"] = loc # attrs["aa"] = aa residues[c_id] = aa product = { "desc": desc, "wild_type": wt, "removed_components": components, "residues": residues } update_protein_definition(corpus_id, gene_uniprot, variant_name, product) data = { "redirect": url_for('corpus.corpus_view', corpus_id=corpus_id) } return jsonify(data), 200 except: return jsonify({"success": False}), 200
def get_reference_candidates(corpus_id, element_type): """Fetch candidates for the reference node.""" json_data = request.get_json() reference_genes = json_data["genes"] original_ref_el = json_data["originalRefElement"] data = {"candidates": {}} corpus = get_corpus(corpus_id) def format_gene_data(attrs): uniprot = list(attrs["uniprotid"])[0] synonyms = [] if "hgnc_symbol" in attrs: synonyms.append(list(attrs["hgnc_symbol"])[0]) return "{} ({})".format(uniprot, ", ".join(synonyms)) def format_fragment_data(node_attrs, edge_attrs): data = [] if "name" in node_attrs: data += list(node_attrs["name"]) if "interproid" in node_attrs: data += list(node_attrs["interproid"]) if "start" in edge_attrs and "end" in edge_attrs: data.append("interval {}-{}".format( list(edge_attrs["start"])[0], list(edge_attrs["end"])[0])) if "order" in edge_attrs: data.append("order {}".format(list(edge_attrs["order"])[0])) return ", ".join(data) for gene in reference_genes: if element_type == "mod": candidates = corpus.get_attached_mod(gene, False, True) for c in candidates: if c != original_ref_el: enzymes = corpus.get_enzymes_of_mod(c) substrates = corpus.get_substrates_of_mod(c) node_attrs = corpus.action_graph.get_node(c) data["candidates"][c] = ( "Enzymes: {}, substrates: {}".format( " / ".join( format_gene_data( corpus.action_graph.get_node(p)) for p in enzymes), " / ".join( format_gene_data( corpus.action_graph.get_node(p)) for p in substrates)), attrs_to_json(node_attrs)) elif element_type == "bnd": candidates = corpus.get_attached_bnd(gene, False) for c in candidates: if c != original_ref_el: node_attrs = corpus.action_graph.get_node(c) partners = corpus.get_protoforms_of_bnd(c) data["candidates"][c] = ("Bindind partners: " + " / ".join( format_gene_data(corpus.action_graph.get_node(p)) for p in partners), attrs_to_json(node_attrs)) else: candidates = corpus.ag_predecessors_of_type(gene, element_type) for c in candidates: if c != original_ref_el: node_attrs = corpus.action_graph.get_node(c) edge_attrs = corpus.action_graph.get_edge(c, gene) data["candidates"][c] = (format_fragment_data( node_attrs, edge_attrs), attrs_to_json(node_attrs)) return jsonify(data), 200