From 3008d35eb298b4ddc0b85a3e0114e4bc0c87fe45 Mon Sep 17 00:00:00 2001 From: LV-426 Date: Sun, 28 Sep 2014 18:24:14 +0300 Subject: Early Rhizi API prototype: - load_node_by_id_attr() - response_wrap() --- src-py/rhizi_api.py | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 src-py/rhizi_api.py (limited to 'src-py/rhizi_api.py') diff --git a/src-py/rhizi_api.py b/src-py/rhizi_api.py new file mode 100644 index 00000000..246768aa --- /dev/null +++ b/src-py/rhizi_api.py @@ -0,0 +1,43 @@ +""" +Rhizi web API +""" +import os +import db_controller as dbc +import json +from flask import jsonify + +from flask import Flask +from flask import request + +webapp = Flask(__name__) +webapp.debug = True + +# injected: DB controller +db_ctl = None + +def __response_wrap(data=None, error=None): + """ + wrap response data/errors as dict - this should always be used when returning + data to allow easy return of list objects, assist in error case distinction, etc. + """ + return dict(data=data, error=error) + +@webapp.route("/load/node-single", methods=['POST']) +def load_node_by_id_attr(): + """ + @return: a list containing a single node whose id attribute matches 'id' or + an empty list if the requested node is not found + @raise exception: on error + """ + node_id = request.form['id'] + op = dbc.DBO_load_node_set_by_id_attribute([node_id]) + try: + n = db_ctl.exec_op(op) + ret = __response_wrap(n) + return jsonify(ret) + except Exception as e: + return jsonify('unable to load node with id: {0}'.format(node_id)) + +@webapp.route("/add/node-single") +def add_node(n): + pass -- cgit v1.3.1 From 78149303d695475be310acf245323c058e84ca6d Mon Sep 17 00:00:00 2001 From: LV-426 Date: Sun, 28 Sep 2014 18:30:52 +0300 Subject: __response_wrap on errror --- src-py/rhizi_api.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src-py/rhizi_api.py') diff --git a/src-py/rhizi_api.py b/src-py/rhizi_api.py index 246768aa..7fb988e7 100644 --- a/src-py/rhizi_api.py +++ b/src-py/rhizi_api.py @@ -33,11 +33,12 @@ def load_node_by_id_attr(): op = dbc.DBO_load_node_set_by_id_attribute([node_id]) try: n = db_ctl.exec_op(op) - ret = __response_wrap(n) + ret = __response_wrap(data=n) return jsonify(ret) except Exception as e: - return jsonify('unable to load node with id: {0}'.format(node_id)) + return jsonify(__response_wrap(error='unable to load node with id: {0}'.format(node_id))) -@webapp.route("/add/node-single") +@webapp.route("/add/node-single", methods=['POST']) def add_node(n): + pass -- cgit v1.3.1 From 56f72b17743b5f065be241202214b5578971e8da Mon Sep 17 00:00:00 2001 From: LV-426 Date: Sun, 28 Sep 2014 18:34:40 +0300 Subject: __sanitize_input stub --- src-py/rhizi_api.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'src-py/rhizi_api.py') diff --git a/src-py/rhizi_api.py b/src-py/rhizi_api.py index 7fb988e7..3bd11ea4 100644 --- a/src-py/rhizi_api.py +++ b/src-py/rhizi_api.py @@ -15,6 +15,9 @@ webapp.debug = True # injected: DB controller db_ctl = None +def __sanitize_input(): + pass + def __response_wrap(data=None, error=None): """ wrap response data/errors as dict - this should always be used when returning @@ -30,6 +33,9 @@ def load_node_by_id_attr(): @raise exception: on error """ node_id = request.form['id'] + + __sanitize_input(node_id) + op = dbc.DBO_load_node_set_by_id_attribute([node_id]) try: n = db_ctl.exec_op(op) @@ -40,5 +46,9 @@ def load_node_by_id_attr(): @webapp.route("/add/node-single", methods=['POST']) def add_node(n): - + pass + +@webapp.route("/add/node-set", methods=['POST']) +def add_node_set(n_set): + op = dbc.DBO_add_node_set() pass -- cgit v1.3.1 From 0c7aa6f772c2a1352a2b643885baa9085886bfec Mon Sep 17 00:00:00 2001 From: LV-426 Date: Mon, 29 Sep 2014 17:19:12 +0300 Subject: extend Flask class to allow customization of HTTP OPTIONS method response --- src-py/rhizi_api.py | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) (limited to 'src-py/rhizi_api.py') diff --git a/src-py/rhizi_api.py b/src-py/rhizi_api.py index 3bd11ea4..c8a323df 100644 --- a/src-py/rhizi_api.py +++ b/src-py/rhizi_api.py @@ -8,8 +8,22 @@ from flask import jsonify from flask import Flask from flask import request +from flask import make_response -webapp = Flask(__name__) + +class FlaskExt(Flask): + """ + Flask server customization + """ + + def make_default_options_response(self): + # sup = super(Flask, self) + ret = Flask.make_default_options_response(self) + ret.headers['Access-Control-Allow-Origin'] = '*' + ret.headers['Access-Control-Allow-Headers'] = "Origin, Content-Type, Accept, Authorization" + return ret + +webapp = FlaskExt(__name__) webapp.debug = True # injected: DB controller -- cgit v1.3.1 From 734c6f39e94600b90b417bd894503e00231d85af Mon Sep 17 00:00:00 2001 From: LV-426 Date: Mon, 29 Sep 2014 17:28:49 +0300 Subject: more response handling with __common_resp_handle() --- src-py/rhizi_api.py | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'src-py/rhizi_api.py') diff --git a/src-py/rhizi_api.py b/src-py/rhizi_api.py index c8a323df..eb76212e 100644 --- a/src-py/rhizi_api.py +++ b/src-py/rhizi_api.py @@ -39,6 +39,17 @@ def __response_wrap(data=None, error=None): """ return dict(data=data, error=error) +def __common_resp_handle(data=None, error=None): + """ + provide common response handling + """ + ret_data = __response_wrap(data, error) + resp = jsonify(ret_data) + + # more response processing + + return resp + @webapp.route("/load/node-single", methods=['POST']) def load_node_by_id_attr(): """ -- cgit v1.3.1 From 783aad986c91bf936fb128818b171439b160596c Mon Sep 17 00:00:00 2001 From: LV-426 Date: Mon, 29 Sep 2014 17:29:44 +0300 Subject: load_node_by_id_attr -> load_node_single_by_id_attr (unimplemented currently), load_node_set_by_id_attr --- src-py/rhizi_api.py | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) (limited to 'src-py/rhizi_api.py') diff --git a/src-py/rhizi_api.py b/src-py/rhizi_api.py index eb76212e..5a1a4845 100644 --- a/src-py/rhizi_api.py +++ b/src-py/rhizi_api.py @@ -51,23 +51,30 @@ def __common_resp_handle(data=None, error=None): return resp @webapp.route("/load/node-single", methods=['POST']) -def load_node_by_id_attr(): +def load_node_single_by_id_attr(): + assert False + +@webapp.route("/load/node-set", methods=['POST']) +def load_node_set_by_id_attr(): """ + @param id_set: list of node ids to match id attribute against @return: a list containing a single node whose id attribute matches 'id' or an empty list if the requested node is not found @raise exception: on error """ - node_id = request.form['id'] - - __sanitize_input(node_id) - - op = dbc.DBO_load_node_set_by_id_attribute([node_id]) + id_set = request.get_json()['id_set'] + __sanitize_input(id_set) + + return __load_node_set_by_id_attr_common(id_set) + +def __load_node_set_by_id_attr_common(id_set): + op = dbc.DBO_load_node_set_by_id_attribute(id_set) try: - n = db_ctl.exec_op(op) - ret = __response_wrap(data=n) - return jsonify(ret) + n_set = db_ctl.exec_op(op) + return __common_resp_handle(data=n_set) except Exception as e: - return jsonify(__response_wrap(error='unable to load node with id: {0}'.format(node_id))) + log.exception(e) + return __common_resp_handle(error='unable to load node with ids: {0}'.format(id_set)) @webapp.route("/add/node-single", methods=['POST']) def add_node(n): -- cgit v1.3.1 From 84a41242f0256db723842fec9521c0f8d2f79103 Mon Sep 17 00:00:00 2001 From: LV-426 Date: Mon, 29 Sep 2014 19:47:33 +0300 Subject: deffer support for single object API operations --- src-py/rhizi_api.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src-py/rhizi_api.py') diff --git a/src-py/rhizi_api.py b/src-py/rhizi_api.py index 5a1a4845..3a31ab11 100644 --- a/src-py/rhizi_api.py +++ b/src-py/rhizi_api.py @@ -52,6 +52,7 @@ def __common_resp_handle(data=None, error=None): @webapp.route("/load/node-single", methods=['POST']) def load_node_single_by_id_attr(): + # pending decision regarding support for single object operations assert False @webapp.route("/load/node-set", methods=['POST']) @@ -77,8 +78,9 @@ def __load_node_set_by_id_attr_common(id_set): return __common_resp_handle(error='unable to load node with ids: {0}'.format(id_set)) @webapp.route("/add/node-single", methods=['POST']) -def add_node(n): - pass +def add_node(): + # pending decision regarding support for single object operations + assert False @webapp.route("/add/node-set", methods=['POST']) def add_node_set(n_set): -- cgit v1.3.1 From 1a4607c092168bfc1333ad6048a62a58a116d908 Mon Sep 17 00:00:00 2001 From: LV-426 Date: Mon, 29 Sep 2014 19:50:13 +0300 Subject: add_node_set --- src-py/rhizi_api.py | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) (limited to 'src-py/rhizi_api.py') diff --git a/src-py/rhizi_api.py b/src-py/rhizi_api.py index 3a31ab11..7e001275 100644 --- a/src-py/rhizi_api.py +++ b/src-py/rhizi_api.py @@ -83,6 +83,17 @@ def add_node(): assert False @webapp.route("/add/node-set", methods=['POST']) -def add_node_set(n_set): - op = dbc.DBO_add_node_set() - pass +def add_node_set(): + """ + @param node_map: node type to node map, eg. { 'Skill': { 'name': 'kung-fu' } } + """ + node_map = request.get_json()['node_map'] + __sanitize_input(node_map) + + op = dbc.DBO_add_node_set(node_map) + try: + n_set = db_ctl.exec_op(op) + return __common_resp_handle(n_set) + except Exception as e: + return __common_resp_handle('exception raised: add_node_set') + -- cgit v1.3.1 From 410163f4c55208d2edf527e677eae532bf59e0aa Mon Sep 17 00:00:00 2001 From: LV-426 Date: Mon, 29 Sep 2014 19:51:40 +0300 Subject: misc --- src-py/rhizi_api.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src-py/rhizi_api.py') diff --git a/src-py/rhizi_api.py b/src-py/rhizi_api.py index 7e001275..0adf6bc3 100644 --- a/src-py/rhizi_api.py +++ b/src-py/rhizi_api.py @@ -4,12 +4,14 @@ Rhizi web API import os import db_controller as dbc import json +import logging from flask import jsonify from flask import Flask from flask import request from flask import make_response +log = logging.getLogger('rhizi') class FlaskExt(Flask): """ @@ -29,7 +31,7 @@ webapp.debug = True # injected: DB controller db_ctl = None -def __sanitize_input(): +def __sanitize_input(*args, **kw_args): pass def __response_wrap(data=None, error=None): -- cgit v1.3.1 From d04ec3ff09ca4b305f8b882f59af4e3aa713d8c0 Mon Sep 17 00:00:00 2001 From: LV-426 Date: Wed, 15 Oct 2014 18:50:23 +0200 Subject: topo_diff_commit, attr_diff_commit API stubs --- src-py/rhizi_api.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'src-py/rhizi_api.py') diff --git a/src-py/rhizi_api.py b/src-py/rhizi_api.py index 0adf6bc3..2744e355 100644 --- a/src-py/rhizi_api.py +++ b/src-py/rhizi_api.py @@ -83,6 +83,19 @@ def __load_node_set_by_id_attr_common(id_set): def add_node(): # pending decision regarding support for single object operations assert False +@webapp.route("/graph/topo-diff-commit", methods=['POST']) +def topo_diff_commit(): + """ + commit a graph topology diff + """ + pass + +@webapp.route("/graph/attr-diff-commit", methods=['POST']) +def attr_diff_commit(): + """ + commit a graph attribute diff + """ + pass @webapp.route("/add/node-set", methods=['POST']) def add_node_set(): -- cgit v1.3.1 From 671e9d2efe7f3ad6b6a67ba737da8758e24fbb73 Mon Sep 17 00:00:00 2001 From: LV-426 Date: Tue, 21 Oct 2014 21:39:39 +0200 Subject: load_link_set_by_link_ptr_set: introducing a deserialize_param_set() step --- src-py/rhizi_api.py | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'src-py/rhizi_api.py') diff --git a/src-py/rhizi_api.py b/src-py/rhizi_api.py index 2744e355..07778896 100644 --- a/src-py/rhizi_api.py +++ b/src-py/rhizi_api.py @@ -83,6 +83,32 @@ def __load_node_set_by_id_attr_common(id_set): def add_node(): # pending decision regarding support for single object operations assert False +@webapp.route("/load/link-set/by_link_ptr_set", methods=['POST']) +def load_link_set_by_link_ptr_set(): + + def deserialize_param_set(param_json): + l_ptr_set_raw = param_json['link_ptr_set'] + + __sanitize_input(l_ptr_set_raw) + + l_ptr_set = [] + for lptr_dict in l_ptr_set_raw: + src_id = lptr_dict.get('src_id') + dst_id = lptr_dict.get('dst_id') + l_ptr_set += [Link.Link_Ptr(src_id=src_id, dst_id=dst_id) ] + + return l_ptr_set + + l_ptr_set = deserialize_param_set(request.get_json()) + + op = dbc.DBO_load_link_set.init_from_link_ptr_set(l_ptr_set) + try: + l_set = db_ctl.exec_op(op) + return __common_resp_handle(data=l_set) + except Exception as e: + log.exception(e) + return __common_resp_handle(error='unable to load link set') + @webapp.route("/graph/topo-diff-commit", methods=['POST']) def topo_diff_commit(): """ -- cgit v1.3.1 From 1e314f66a75a0cd32b933771fe1031891af68d2c Mon Sep 17 00:00:00 2001 From: LV-426 Date: Mon, 27 Oct 2014 12:35:13 +0200 Subject: REST api impl: '/graph/topo-diff-commit' --- src-py/rhizi_api.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'src-py/rhizi_api.py') diff --git a/src-py/rhizi_api.py b/src-py/rhizi_api.py index 07778896..77f753e6 100644 --- a/src-py/rhizi_api.py +++ b/src-py/rhizi_api.py @@ -114,7 +114,13 @@ def topo_diff_commit(): """ commit a graph topology diff """ - pass + topo_diff_dict = request.get_json()['topo_diff'] + __sanitize_input(topo_diff_dict) + + topo_diff = Topo_Diff.from_dict(topo_diff_dict) + + op = dbc.DBO_topo_diff_commit(topo_diff) + return __common_exec(op) @webapp.route("/graph/attr-diff-commit", methods=['POST']) def attr_diff_commit(): -- cgit v1.3.1 From d311fcc30a3da95a5a8e4b15f99721a1aae0229c Mon Sep 17 00:00:00 2001 From: LV-426 Date: Mon, 27 Oct 2014 12:35:40 +0200 Subject: REST api impl: '/graph/attr-diff-commit' --- src-py/rhizi_api.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src-py/rhizi_api.py') diff --git a/src-py/rhizi_api.py b/src-py/rhizi_api.py index 77f753e6..5fce4542 100644 --- a/src-py/rhizi_api.py +++ b/src-py/rhizi_api.py @@ -127,7 +127,11 @@ def attr_diff_commit(): """ commit a graph attribute diff """ - pass + attr_diff = request.get_json()['attr_diff'] + __sanitize_input(attr_diff) + + op = dbc.DBO_attr_diff_commit(attr_diff) + return __common_exec(op) @webapp.route("/add/node-set", methods=['POST']) def add_node_set(): -- cgit v1.3.1 From de25fac01980581f98c1ea1f0740e4088aa0c0be Mon Sep 17 00:00:00 2001 From: LV-426 Date: Mon, 27 Oct 2014 12:40:55 +0200 Subject: rm single obj api calls --- src-py/rhizi_api.py | 8 -------- 1 file changed, 8 deletions(-) (limited to 'src-py/rhizi_api.py') diff --git a/src-py/rhizi_api.py b/src-py/rhizi_api.py index 5fce4542..c22df635 100644 --- a/src-py/rhizi_api.py +++ b/src-py/rhizi_api.py @@ -52,10 +52,6 @@ def __common_resp_handle(data=None, error=None): return resp -@webapp.route("/load/node-single", methods=['POST']) -def load_node_single_by_id_attr(): - # pending decision regarding support for single object operations - assert False @webapp.route("/load/node-set", methods=['POST']) def load_node_set_by_id_attr(): @@ -79,10 +75,6 @@ def __load_node_set_by_id_attr_common(id_set): log.exception(e) return __common_resp_handle(error='unable to load node with ids: {0}'.format(id_set)) -@webapp.route("/add/node-single", methods=['POST']) -def add_node(): - # pending decision regarding support for single object operations - assert False @webapp.route("/load/link-set/by_link_ptr_set", methods=['POST']) def load_link_set_by_link_ptr_set(): -- cgit v1.3.1 From 69d70685cfdea0ea6b6083d36f6fefd0be0741fe Mon Sep 17 00:00:00 2001 From: LV-426 Date: Mon, 27 Oct 2014 12:44:49 +0200 Subject: misc --- src-py/db_controller.py | 18 +++++++++--------- src-py/rhizi_api.py | 24 ++++++++++++++++++++---- 2 files changed, 29 insertions(+), 13 deletions(-) (limited to 'src-py/rhizi_api.py') diff --git a/src-py/db_controller.py b/src-py/db_controller.py index aa1e8450..f9656212 100644 --- a/src-py/db_controller.py +++ b/src-py/db_controller.py @@ -1,20 +1,19 @@ #!/usr/bin/python -import os import json -import re import logging +import os +import re import traceback +import urllib2 +from db_driver import DB_Driver_REST, DB_Driver_Base from model.graph import Attr_Diff from model.graph import Topo_Diff - -import urllib2 - -import neo4j_util as db_util -from neo4j_util import cfmt from neo4j_util import DB_result_set -from neo4j_util import Neo4JException +from neo4j_util import cfmt +import neo4j_util as db_util +from model.model import Link log = logging.getLogger('rhizi') @@ -183,7 +182,7 @@ class DBO_attr_diff_commit(DB_op): ret = {} for _, _, r_set in self: for row in r_set: - n_id, n = [v for v in row] # we expect a [n_id, n] array + n_id, n = [v for v in row] # we expect a [n_id, n] array ret[n_id] = n return ret @@ -234,6 +233,7 @@ class DBO_load_node_set_by_DB_id(DB_op): """ load a set of nodes whose DB id is in id_set + @param id_set: DB node id set @return: loaded node set or an empty set if no match was found """ super(DBO_load_node_set_by_DB_id, self).__init__() diff --git a/src-py/rhizi_api.py b/src-py/rhizi_api.py index c22df635..7a6a44e9 100644 --- a/src-py/rhizi_api.py +++ b/src-py/rhizi_api.py @@ -48,26 +48,42 @@ def __common_resp_handle(data=None, error=None): ret_data = __response_wrap(data, error) resp = jsonify(ret_data) + resp.headers['Access-Control-Allow-Origin'] = '*' + # more response processing return resp +def __common_exec(op, on_success=__common_resp_handle): + try: + op_ret = db_ctl.exec_op(op) + return on_success(op_ret) + except Exception as e: + return __common_resp_handle('exception raised: add_node_set') -@webapp.route("/load/node-set", methods=['POST']) +@webapp.route("/load/node-set-by-id", methods=['POST']) def load_node_set_by_id_attr(): """ + load node-set by ID attribute + @param id_set: list of node ids to match id attribute against - @return: a list containing a single node whose id attribute matches 'id' or + @return: a list of nodes whose id attribute matches 'id' or an empty list if the requested node is not found @raise exception: on error """ - id_set = request.get_json()['id_set'] + req_json = request.get_json() + id_set = req_json['id_set'] + __sanitize_input(id_set) return __load_node_set_by_id_attr_common(id_set) def __load_node_set_by_id_attr_common(id_set): - op = dbc.DBO_load_node_set_by_id_attribute(id_set) + """ + @param f_k: optional attribute filter key + @param f_vset: possible key values to match against + """ + op = dbc.DBO_match_node_set_by_id_attribute(id_set=id_set) try: n_set = db_ctl.exec_op(op) return __common_resp_handle(data=n_set) -- cgit v1.3.1 From 8e6eeb0db8616b79211f0c03472074bc36885658 Mon Sep 17 00:00:00 2001 From: LV-426 Date: Sun, 9 Nov 2014 12:18:05 +0200 Subject: common request handling --- src-py/rhizi_api.py | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) (limited to 'src-py/rhizi_api.py') diff --git a/src-py/rhizi_api.py b/src-py/rhizi_api.py index 7a6a44e9..53edf8f5 100644 --- a/src-py/rhizi_api.py +++ b/src-py/rhizi_api.py @@ -59,7 +59,9 @@ def __common_exec(op, on_success=__common_resp_handle): op_ret = db_ctl.exec_op(op) return on_success(op_ret) except Exception as e: - return __common_resp_handle('exception raised: add_node_set') + log.error(e.message) + log.error(traceback.print_exc()) + return __common_resp_handle('error occurred') @webapp.route("/load/node-set-by-id", methods=['POST']) def load_node_set_by_id_attr(): @@ -110,12 +112,7 @@ def load_link_set_by_link_ptr_set(): l_ptr_set = deserialize_param_set(request.get_json()) op = dbc.DBO_load_link_set.init_from_link_ptr_set(l_ptr_set) - try: - l_set = db_ctl.exec_op(op) - return __common_resp_handle(data=l_set) - except Exception as e: - log.exception(e) - return __common_resp_handle(error='unable to load link set') + return __common_exec(op) @webapp.route("/graph/topo-diff-commit", methods=['POST']) def topo_diff_commit(): @@ -150,9 +147,5 @@ def add_node_set(): __sanitize_input(node_map) op = dbc.DBO_add_node_set(node_map) - try: - n_set = db_ctl.exec_op(op) - return __common_resp_handle(n_set) - except Exception as e: - return __common_resp_handle('exception raised: add_node_set') + return __common_exec(op) -- cgit v1.3.1 From 2f460418e342c378e575a5693b38ae4b3c8ff254 Mon Sep 17 00:00:00 2001 From: LV-426 Date: Sun, 9 Nov 2014 12:18:47 +0200 Subject: match_node_set_by_attr_filter_map --- src-py/rhizi_api.py | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'src-py/rhizi_api.py') diff --git a/src-py/rhizi_api.py b/src-py/rhizi_api.py index 53edf8f5..b88a1ff2 100644 --- a/src-py/rhizi_api.py +++ b/src-py/rhizi_api.py @@ -93,6 +93,16 @@ def __load_node_set_by_id_attr_common(id_set): log.exception(e) return __common_resp_handle(error='unable to load node with ids: {0}'.format(id_set)) +@webapp.route("/match/node-set", methods=['POST']) +def match_node_set_by_attr_filter_map(attr_filter_map): + """ + @param attr_filter_map + + @return: a set of node DB id's + """ + op = dbc.DBO_match_node_id_set(attr_filter_map) + return __common_exec(op) + @webapp.route("/load/link-set/by_link_ptr_set", methods=['POST']) def load_link_set_by_link_ptr_set(): -- cgit v1.3.1 From 71c9e8dfd4c58942bcfa8f1cdd89d769ca769660 Mon Sep 17 00:00:00 2001 From: LV-426 Date: Sun, 9 Nov 2014 12:19:29 +0200 Subject: /graph/clone REST path --- src-py/rhizi_api.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'src-py/rhizi_api.py') diff --git a/src-py/rhizi_api.py b/src-py/rhizi_api.py index b88a1ff2..21c7d2a6 100644 --- a/src-py/rhizi_api.py +++ b/src-py/rhizi_api.py @@ -124,8 +124,11 @@ def load_link_set_by_link_ptr_set(): op = dbc.DBO_load_link_set.init_from_link_ptr_set(l_ptr_set) return __common_exec(op) -@webapp.route("/graph/topo-diff-commit", methods=['POST']) -def topo_diff_commit(): +@webapp.route("/graph/clone", methods=['POST']) +def rz_clone(): + op = dbc.DBO_rz_clone() + return __common_exec(op) + """ commit a graph topology diff """ -- cgit v1.3.1 From 2aff3e7698d08194c05c658c11158943395911d7 Mon Sep 17 00:00:00 2001 From: LV-426 Date: Sun, 9 Nov 2014 12:20:15 +0200 Subject: /graph/diff-commit-topo REST path --- src-py/rhizi_api.py | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'src-py/rhizi_api.py') diff --git a/src-py/rhizi_api.py b/src-py/rhizi_api.py index 21c7d2a6..36463531 100644 --- a/src-py/rhizi_api.py +++ b/src-py/rhizi_api.py @@ -137,6 +137,17 @@ def rz_clone(): topo_diff = Topo_Diff.from_dict(topo_diff_dict) +@webapp.route("/graph/diff-commit-topo", methods=['POST']) +def diff_commit_topo(): + """ + commit a graph topology diff + """ + def sanitize_input(req): + topo_diff_dict = request.get_json()['topo_diff'] + topo_diff = Topo_Diff.from_dict(topo_diff_dict) + return topo_diff; + + topo_diff = sanitize_input(request) op = dbc.DBO_topo_diff_commit(topo_diff) return __common_exec(op) -- cgit v1.3.1 From 30677e0342e796e7699bd2958aced711659e5ecc Mon Sep 17 00:00:00 2001 From: LV-426 Date: Sun, 9 Nov 2014 12:20:43 +0200 Subject: /graph/diff-commit-attr REST path --- src-py/rhizi_api.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src-py/rhizi_api.py') diff --git a/src-py/rhizi_api.py b/src-py/rhizi_api.py index 36463531..461f3e49 100644 --- a/src-py/rhizi_api.py +++ b/src-py/rhizi_api.py @@ -151,8 +151,8 @@ def diff_commit_topo(): op = dbc.DBO_topo_diff_commit(topo_diff) return __common_exec(op) -@webapp.route("/graph/attr-diff-commit", methods=['POST']) -def attr_diff_commit(): +@webapp.route("/graph/diff-commit-attr", methods=['POST']) +def diff_commit_attr(): """ commit a graph attribute diff """ -- cgit v1.3.1 From 92fdd5d1d8eb09eae6122ab803a24bf9cdc7dd10 Mon Sep 17 00:00:00 2001 From: LV-426 Date: Sun, 9 Nov 2014 12:21:03 +0200 Subject: /graph/diff-commit-set REST path --- src-py/rhizi_api.py | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'src-py/rhizi_api.py') diff --git a/src-py/rhizi_api.py b/src-py/rhizi_api.py index 461f3e49..cbaa82ec 100644 --- a/src-py/rhizi_api.py +++ b/src-py/rhizi_api.py @@ -129,13 +129,20 @@ def rz_clone(): op = dbc.DBO_rz_clone() return __common_exec(op) +@webapp.route("/graph/diff-commit-set", methods=['POST']) +def diff_commit_set(): """ - commit a graph topology diff + commit a diff set """ - topo_diff_dict = request.get_json()['topo_diff'] - __sanitize_input(topo_diff_dict) + def sanitize_input(req): + diff_set_dict = request.get_json()['diff_set'] + topo_diff_dict = diff_set_dict['__diff_set_topo'][0] + topo_diff = Topo_Diff.from_dict(topo_diff_dict) + return topo_diff; - topo_diff = Topo_Diff.from_dict(topo_diff_dict) + topo_diff = sanitize_input(request) + op = dbc.DBO_topo_diff_commit(topo_diff) + return __common_exec(op) @webapp.route("/graph/diff-commit-topo", methods=['POST']) def diff_commit_topo(): -- cgit v1.3.1 From 500d95dc5d6fde2a3f583538492f346c245a641e Mon Sep 17 00:00:00 2001 From: LV-426 Date: Sun, 9 Nov 2014 12:21:34 +0200 Subject: /graph/diff-commit-vis REST path stub --- src-py/rhizi_api.py | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src-py/rhizi_api.py') diff --git a/src-py/rhizi_api.py b/src-py/rhizi_api.py index cbaa82ec..e624b7ba 100644 --- a/src-py/rhizi_api.py +++ b/src-py/rhizi_api.py @@ -169,6 +169,10 @@ def diff_commit_attr(): op = dbc.DBO_attr_diff_commit(attr_diff) return __common_exec(op) +@webapp.route("/graph/diff-commit-vis", methods=['POST']) +def diff_commit_vis(): + pass + @webapp.route("/add/node-set", methods=['POST']) def add_node_set(): """ -- cgit v1.3.1 From 0f6443adf711b9f540b83e74f8a3d0767f01a38e Mon Sep 17 00:00:00 2001 From: LV-426 Date: Sun, 9 Nov 2014 12:22:03 +0200 Subject: mv to __src,__dst meta attr use --- src-py/rhizi_api.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src-py/rhizi_api.py') diff --git a/src-py/rhizi_api.py b/src-py/rhizi_api.py index e624b7ba..8c9df6e2 100644 --- a/src-py/rhizi_api.py +++ b/src-py/rhizi_api.py @@ -113,8 +113,8 @@ def load_link_set_by_link_ptr_set(): l_ptr_set = [] for lptr_dict in l_ptr_set_raw: - src_id = lptr_dict.get('src_id') - dst_id = lptr_dict.get('dst_id') + src_id = lptr_dict.get('__src') + dst_id = lptr_dict.get('__dst') l_ptr_set += [Link.Link_Ptr(src_id=src_id, dst_id=dst_id) ] return l_ptr_set -- cgit v1.3.1 From bfedd0aaba765d86053225fb4221c2ae80e451c0 Mon Sep 17 00:00:00 2001 From: LV-426 Date: Sun, 9 Nov 2014 12:22:38 +0200 Subject: deprecate /add/node-set --- src-py/rhizi_api.py | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src-py/rhizi_api.py') diff --git a/src-py/rhizi_api.py b/src-py/rhizi_api.py index 8c9df6e2..3e96d860 100644 --- a/src-py/rhizi_api.py +++ b/src-py/rhizi_api.py @@ -176,6 +176,8 @@ def diff_commit_vis(): @webapp.route("/add/node-set", methods=['POST']) def add_node_set(): """ + @deprecated: use topo_attr_commit + @param node_map: node type to node map, eg. { 'Skill': { 'name': 'kung-fu' } } """ node_map = request.get_json()['node_map'] -- cgit v1.3.1 From 427fbc64eeda746ad2c3e06cd34db296a00dbb78 Mon Sep 17 00:00:00 2001 From: LV-426 Date: Mon, 24 Nov 2014 17:34:48 +0200 Subject: monitor__server_info --- src-py/rhizi_api.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'src-py/rhizi_api.py') diff --git a/src-py/rhizi_api.py b/src-py/rhizi_api.py index 3e96d860..6bc77cb6 100644 --- a/src-py/rhizi_api.py +++ b/src-py/rhizi_api.py @@ -5,12 +5,18 @@ import os import db_controller as dbc import json import logging +import traceback from flask import jsonify from flask import Flask from flask import request from flask import make_response +from model.graph import Topo_Diff +from model.graph import Attr_Diff +from model.model import Link +from datetime import datetime + log = logging.getLogger('rhizi') class FlaskExt(Flask): @@ -186,3 +192,16 @@ def add_node_set(): op = dbc.DBO_add_node_set(node_map) return __common_exec(op) +@webapp.route("/monitor/server-info", methods=['GET']) +def monitor__server_info(): + """ + server monitor stub + """ + dt = datetime.now() + return "" + \ + "

Rhizi Server v0.1

" + \ + "date: " + dt.strftime("%Y-%m-%d") + "
" + \ + "time: " + dt.strftime("%H:%M:%S") + "
" + \ + "

" + + -- cgit v1.3.1 From 23bb05b2f506743bf9c0008f8a7d9dd68bfa326e Mon Sep 17 00:00:00 2001 From: LV-426 Date: Sun, 30 Nov 2014 12:36:10 +0200 Subject: applicative REST API init - provides logic<>web-framework decoupling --- src-py/rhizi_api.py | 12 ------------ src-py/rhizi_server.py | 27 +++++++++++++++++++++++++++ 2 files changed, 27 insertions(+), 12 deletions(-) (limited to 'src-py/rhizi_api.py') diff --git a/src-py/rhizi_api.py b/src-py/rhizi_api.py index 6bc77cb6..7391c90f 100644 --- a/src-py/rhizi_api.py +++ b/src-py/rhizi_api.py @@ -31,8 +31,6 @@ class FlaskExt(Flask): ret.headers['Access-Control-Allow-Headers'] = "Origin, Content-Type, Accept, Authorization" return ret -webapp = FlaskExt(__name__) -webapp.debug = True # injected: DB controller db_ctl = None @@ -69,7 +67,6 @@ def __common_exec(op, on_success=__common_resp_handle): log.error(traceback.print_exc()) return __common_resp_handle('error occurred') -@webapp.route("/load/node-set-by-id", methods=['POST']) def load_node_set_by_id_attr(): """ load node-set by ID attribute @@ -99,7 +96,6 @@ def __load_node_set_by_id_attr_common(id_set): log.exception(e) return __common_resp_handle(error='unable to load node with ids: {0}'.format(id_set)) -@webapp.route("/match/node-set", methods=['POST']) def match_node_set_by_attr_filter_map(attr_filter_map): """ @param attr_filter_map @@ -109,7 +105,6 @@ def match_node_set_by_attr_filter_map(attr_filter_map): op = dbc.DBO_match_node_id_set(attr_filter_map) return __common_exec(op) -@webapp.route("/load/link-set/by_link_ptr_set", methods=['POST']) def load_link_set_by_link_ptr_set(): def deserialize_param_set(param_json): @@ -130,12 +125,10 @@ def load_link_set_by_link_ptr_set(): op = dbc.DBO_load_link_set.init_from_link_ptr_set(l_ptr_set) return __common_exec(op) -@webapp.route("/graph/clone", methods=['POST']) def rz_clone(): op = dbc.DBO_rz_clone() return __common_exec(op) -@webapp.route("/graph/diff-commit-set", methods=['POST']) def diff_commit_set(): """ commit a diff set @@ -150,7 +143,6 @@ def diff_commit_set(): op = dbc.DBO_topo_diff_commit(topo_diff) return __common_exec(op) -@webapp.route("/graph/diff-commit-topo", methods=['POST']) def diff_commit_topo(): """ commit a graph topology diff @@ -164,7 +156,6 @@ def diff_commit_topo(): op = dbc.DBO_topo_diff_commit(topo_diff) return __common_exec(op) -@webapp.route("/graph/diff-commit-attr", methods=['POST']) def diff_commit_attr(): """ commit a graph attribute diff @@ -175,11 +166,9 @@ def diff_commit_attr(): op = dbc.DBO_attr_diff_commit(attr_diff) return __common_exec(op) -@webapp.route("/graph/diff-commit-vis", methods=['POST']) def diff_commit_vis(): pass -@webapp.route("/add/node-set", methods=['POST']) def add_node_set(): """ @deprecated: use topo_attr_commit @@ -192,7 +181,6 @@ def add_node_set(): op = dbc.DBO_add_node_set(node_map) return __common_exec(op) -@webapp.route("/monitor/server-info", methods=['GET']) def monitor__server_info(): """ server monitor stub diff --git a/src-py/rhizi_server.py b/src-py/rhizi_server.py index f085e863..cef57f36 100644 --- a/src-py/rhizi_server.py +++ b/src-py/rhizi_server.py @@ -54,6 +54,33 @@ def init_logging(): class RhiziServer(object): pass +def init_rest_api(flask_webapp): + """ + map REST API calls + """ + rest_entry_set = [ + rest_entry('/add/node-set' , rhizi_api.add_node_set), + rest_entry('/graph/clone', rhizi_api.rz_clone), + rest_entry('/graph/diff-commit-set', rhizi_api.diff_commit_set), + rest_entry('/graph/diff-commit-topo', rhizi_api.diff_commit_topo), + rest_entry('/graph/diff-commit-attr', rhizi_api.diff_commit_attr), + rest_entry('/graph/diff-commit-vis', rhizi_api.diff_commit_vis), + rest_entry('/index', rhizi_api.index), + rest_entry('/load/node-set-by-id', rhizi_api.load_node_set_by_id_attr), + rest_entry('/load/link-set/by_link_ptr_set', rhizi_api.load_link_set_by_link_ptr_set), + rest_entry('/login', rhizi_api.login, {'methods': ['GET', 'POST']}), + rest_entry('/logout', rhizi_api.logout), + rest_entry('/match/node-set', rhizi_api.match_node_set_by_attr_filter_map), + rest_entry('/monitor/server-info', rhizi_api.monitor__server_info), + ] + + for re in rest_entry_set: + rest_path, f, flask_args = re + route_decorator = flask_webapp.route(rest_path, **flask_args) + flask_webapp.f = route_decorator(f) + + if '/login' != rest_path: + if __name__ == "__main__": p = argparse.ArgumentParser(description='rhizi-server') -- cgit v1.3.1 From 4730452ec0f922a8bb26690e5262efa3bb56f4eb Mon Sep 17 00:00:00 2001 From: LV-426 Date: Tue, 2 Dec 2014 02:07:23 +0200 Subject: REST /login,/logout paths --- src-py/rhizi_api.py | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) (limited to 'src-py/rhizi_api.py') diff --git a/src-py/rhizi_api.py b/src-py/rhizi_api.py index 7391c90f..8df36b56 100644 --- a/src-py/rhizi_api.py +++ b/src-py/rhizi_api.py @@ -192,4 +192,34 @@ def monitor__server_info(): "time: " + dt.strftime("%H:%M:%S") + "
" + \ "

" +def index(): + return render_template('index.html') +def login(): + + def sanitize_input(req): + req_json = request.get_json() + u = req_json['username'] + p = req_json['password'] + return u, p + + if request.method == 'POST': + try: + u, p = sanitize_input(request) + crypt_util.validate_login(flask.current_app.rz_config, u, p) + except Exception as e: + log.warn('login: unauthorized: user: %s' % (u)) + abort(401) + + # login successful + session['username'] = u + log.debug('login: success: user: %s' % (u)) + return redirect('/index') + + if request.method == 'GET': + return render_template('login.html') + +def logout(): + # remove the username from the session if it's there + session.pop('username', None) + return redirect(url_for('login')) -- cgit v1.3.1 From 073da71b6318f1d69cd5f45f4f60da00bd437fa2 Mon Sep 17 00:00:00 2001 From: LV-426 Date: Wed, 3 Dec 2014 16:49:33 +0200 Subject: pass username to index template --- src-py/rhizi_api.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'src-py/rhizi_api.py') diff --git a/src-py/rhizi_api.py b/src-py/rhizi_api.py index 8df36b56..95822be2 100644 --- a/src-py/rhizi_api.py +++ b/src-py/rhizi_api.py @@ -193,7 +193,8 @@ def monitor__server_info(): "

" def index(): - return render_template('index.html') + username = escape(session['username']) + return render_template('index.html', username=username) def login(): @@ -208,18 +209,20 @@ def login(): u, p = sanitize_input(request) crypt_util.validate_login(flask.current_app.rz_config, u, p) except Exception as e: + # login failed log.warn('login: unauthorized: user: %s' % (u)) - abort(401) + return render_template('login.html', login_failed=True) # login successful session['username'] = u log.debug('login: success: user: %s' % (u)) - return redirect('/index') + return redirect(url_for('index')) if request.method == 'GET': return render_template('login.html') def logout(): # remove the username from the session if it's there - session.pop('username', None) + u = session.pop('username', None) + log.debug('logout: success: user: %s' % (u)) return redirect(url_for('login')) -- cgit v1.3.1 From f103eae07ae8a61845899879445d4bfadbb0e10d Mon Sep 17 00:00:00 2001 From: LV-426 Date: Sat, 6 Dec 2014 21:23:20 +0200 Subject: mv FlaskExt --- src-py/rhizi_api.py | 13 ------------- src-py/rhizi_server.py | 26 +++++++++++++++++++++++--- 2 files changed, 23 insertions(+), 16 deletions(-) (limited to 'src-py/rhizi_api.py') diff --git a/src-py/rhizi_api.py b/src-py/rhizi_api.py index 95822be2..2ba25ad8 100644 --- a/src-py/rhizi_api.py +++ b/src-py/rhizi_api.py @@ -19,19 +19,6 @@ from datetime import datetime log = logging.getLogger('rhizi') -class FlaskExt(Flask): - """ - Flask server customization - """ - - def make_default_options_response(self): - # sup = super(Flask, self) - ret = Flask.make_default_options_response(self) - ret.headers['Access-Control-Allow-Origin'] = '*' - ret.headers['Access-Control-Allow-Headers'] = "Origin, Content-Type, Accept, Authorization" - return ret - - # injected: DB controller db_ctl = None diff --git a/src-py/rhizi_server.py b/src-py/rhizi_server.py index 024e7246..58d4ee68 100644 --- a/src-py/rhizi_server.py +++ b/src-py/rhizi_server.py @@ -93,10 +93,30 @@ class Config(object): def secret_key(self): return self.SECRET_KEY -class RhiziServer(object): - pass +class FlaskExt(Flask): + """ + Flask server customization + """ + + def __init__(self, import_name, *args, **kwargs): + """ + reserved for future use + """ + super(FlaskExt, self).__init__(import_name, *args, **kwargs) -def init_logging(): + def before_request(self, *args, **kwargs): + # TODO impl + pass + + def make_default_options_response(self): + ret = Flask.make_default_options_response(self) + + ret.headers['Access-Control-Allow-Origin'] = 'http://rhizi.net' + ret.headers['Access-Control-Allow-Headers'] = "Accept, Authorization, Content-Type, Origin" + ret.headers['Access-Control-Allow-Credentials'] = 'true' + + # ret.headers['Access-Control-Allow-Methods'] = ', '.join(m_list) + return ret log = logging.getLogger('rhizi') log.setLevel(logging.DEBUG) -- cgit v1.3.1 From 06e57b020ae3c91ddb7d4faefce7b17f561170ab Mon Sep 17 00:00:00 2001 From: LV-426 Date: Sat, 6 Dec 2014 21:32:54 +0200 Subject: /index: safe template var filling --- src-py/rhizi_api.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'src-py/rhizi_api.py') diff --git a/src-py/rhizi_api.py b/src-py/rhizi_api.py index 2ba25ad8..829bb6c7 100644 --- a/src-py/rhizi_api.py +++ b/src-py/rhizi_api.py @@ -6,11 +6,19 @@ import db_controller as dbc import json import logging import traceback -from flask import jsonify +import crypt_util +import flask +from flask import jsonify from flask import Flask from flask import request from flask import make_response +from flask import session +from flask import redirect +from flask import escape +from flask import url_for +from flask import render_template +from flask import send_from_directory from model.graph import Topo_Diff from model.graph import Attr_Diff @@ -180,7 +188,7 @@ def monitor__server_info(): "

" def index(): - username = escape(session['username']) + username = escape(session.get('username')) return render_template('index.html', username=username) def login(): @@ -213,3 +221,4 @@ def logout(): u = session.pop('username', None) log.debug('logout: success: user: %s' % (u)) return redirect(url_for('login')) + -- cgit v1.3.1 From 56c56c9de79c72c2b82ed044445d2e86db75bd58 Mon Sep 17 00:00:00 2001 From: LV-426 Date: Mon, 8 Dec 2014 22:39:49 +0200 Subject: sanitize_input__X(): pre-DB data insertion boundary --- src-py/rhizi_api.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'src-py/rhizi_api.py') diff --git a/src-py/rhizi_api.py b/src-py/rhizi_api.py index 829bb6c7..461f1e03 100644 --- a/src-py/rhizi_api.py +++ b/src-py/rhizi_api.py @@ -33,6 +33,24 @@ db_ctl = None def __sanitize_input(*args, **kw_args): pass +def sanitize_input__node(n): + """ + provide a control point as to which node fields are persisted + """ + assert None != n['id'], 'invalid input: node: missing id' + +def sanitize_input__link(l): + """ + provide a control point as to which node fields are persisted + """ + pass + +def sanitize_input__topo_diff(topo_diff): + for n in topo_diff.node_set_add: + sanitize_input__node(n) + for l in topo_diff.link_set_add: + sanitize_input__link(l) + def __response_wrap(data=None, error=None): """ wrap response data/errors as dict - this should always be used when returning @@ -132,6 +150,8 @@ def diff_commit_set(): diff_set_dict = request.get_json()['diff_set'] topo_diff_dict = diff_set_dict['__diff_set_topo'][0] topo_diff = Topo_Diff.from_dict(topo_diff_dict) + + sanitize_input__topo_diff(topo_diff) return topo_diff; topo_diff = sanitize_input(request) @@ -145,6 +165,8 @@ def diff_commit_topo(): def sanitize_input(req): topo_diff_dict = request.get_json()['topo_diff'] topo_diff = Topo_Diff.from_dict(topo_diff_dict) + + sanitize_input__topo_diff(topo_diff) return topo_diff; topo_diff = sanitize_input(request) -- cgit v1.3.1 From 3ed7eae2d984493e1b295f853780556a0d4a93e4 Mon Sep 17 00:00:00 2001 From: LV-426 Date: Mon, 8 Dec 2014 22:40:56 +0200 Subject: rename diff_commit__X according to diff type --- src-py/rhizi_api.py | 8 ++++---- src-py/rhizi_server.py | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) (limited to 'src-py/rhizi_api.py') diff --git a/src-py/rhizi_api.py b/src-py/rhizi_api.py index 461f1e03..8d787a5c 100644 --- a/src-py/rhizi_api.py +++ b/src-py/rhizi_api.py @@ -142,7 +142,7 @@ def rz_clone(): op = dbc.DBO_rz_clone() return __common_exec(op) -def diff_commit_set(): +def diff_commit__set(): """ commit a diff set """ @@ -158,7 +158,7 @@ def diff_commit_set(): op = dbc.DBO_topo_diff_commit(topo_diff) return __common_exec(op) -def diff_commit_topo(): +def diff_commit__topo(): """ commit a graph topology diff """ @@ -173,7 +173,7 @@ def diff_commit_topo(): op = dbc.DBO_topo_diff_commit(topo_diff) return __common_exec(op) -def diff_commit_attr(): +def diff_commit__attr(): """ commit a graph attribute diff """ @@ -183,7 +183,7 @@ def diff_commit_attr(): op = dbc.DBO_attr_diff_commit(attr_diff) return __common_exec(op) -def diff_commit_vis(): +def diff_commit__vis(): pass def add_node_set(): diff --git a/src-py/rhizi_server.py b/src-py/rhizi_server.py index 621868cd..4f0c7b52 100644 --- a/src-py/rhizi_server.py +++ b/src-py/rhizi_server.py @@ -175,10 +175,10 @@ def init_rest_api(cfg, flask_webapp): rest_entry_set = [ rest_entry('/add/node-set' , rhizi_api.add_node_set), rest_entry('/graph/clone', rhizi_api.rz_clone), - rest_entry('/graph/diff-commit-set', rhizi_api.diff_commit_set), - rest_entry('/graph/diff-commit-topo', rhizi_api.diff_commit_topo), - rest_entry('/graph/diff-commit-attr', rhizi_api.diff_commit_attr), - rest_entry('/graph/diff-commit-vis', rhizi_api.diff_commit_vis), + rest_entry('/graph/diff-commit-set', rhizi_api.diff_commit__set), + rest_entry('/graph/diff-commit-topo', rhizi_api.diff_commit__topo), + rest_entry('/graph/diff-commit-attr', rhizi_api.diff_commit__attr), + rest_entry('/graph/diff-commit-vis', rhizi_api.diff_commit__vis), rest_entry('/index', rhizi_api.index, {'methods': ['GET']}), rest_entry('/load/node-set-by-id', rhizi_api.load_node_set_by_id_attr), rest_entry('/load/link-set/by_link_ptr_set', rhizi_api.load_link_set_by_link_ptr_set), -- cgit v1.3.1 From 0950293605eecff2de9cdadccf1def2d7d9b73bc Mon Sep 17 00:00:00 2001 From: LV-426 Date: Wed, 10 Dec 2014 15:16:06 +0200 Subject: distinguish __src (obj) vs. __src_id (str) --- src-py/db_controller.py | 4 ++-- src-py/model/model.py | 25 ++++++++++++++++--------- src-py/neo4j_util.py | 16 ++++++++-------- src-py/rhizi_api.py | 4 ++-- 4 files changed, 28 insertions(+), 21 deletions(-) (limited to 'src-py/rhizi_api.py') diff --git a/src-py/db_controller.py b/src-py/db_controller.py index 460686a5..2d4fe8ce 100644 --- a/src-py/db_controller.py +++ b/src-py/db_controller.py @@ -426,8 +426,8 @@ class DBO_rz_clone(DB_op): continue l = l_tuple[1] - l['__src'] = n['id'] - l['__dst'] = l_tuple[0] + l['__src_id'] = n['id'] + l['__dst_id'] = l_tuple[0] l['__label_set'] = [l_tuple[2]] # box single value returned by type() ret_l_set.append(l) diff --git a/src-py/model/model.py b/src-py/model/model.py index 701074ab..33cf9e6a 100644 --- a/src-py/model/model.py +++ b/src-py/model/model.py @@ -3,24 +3,31 @@ class Link(): documentation anchor - this class currently carries no implementation and only acts as a documentation anchor - link['__src'] - meta attribute for link source - link['__dst'] - meta attribute for link destination + link['__src'] - meta attribute for link source object + link['__dst'] - meta attribute for link destination object """ - + + def __init__(self, src=None, dst=None): + assert False, 'currently unused' + class Link_Ptr(dict): + """ + link['__src_id'] - meta attribute for link source id + link['__dst_id'] - meta attribute for link destination id + """ def __init__(self, src_id=None, dst_id=None): assert None != src_id or None != dst_id - - self['__src'] = src_id - self['__dst'] = dst_id - + + self['__src_id'] = src_id + self['__dst_id'] = dst_id + @property def src_id(self): - return self['__src'] + return self['__src_id'] @property def dst_id(self): - return self['__dst'] + return self['__dst_id'] @staticmethod def link_ptr(src_id=None, dst_id=None): diff --git a/src-py/neo4j_util.py b/src-py/neo4j_util.py index cc3d53d8..a203207f 100644 --- a/src-py/neo4j_util.py +++ b/src-py/neo4j_util.py @@ -199,16 +199,16 @@ def gen_query_create_from_link_map(link_map, input_to_DB_property_map=lambda _: for link in l_set: __type_check_link(link) - n_src = link['__src'] - n_dst = link['__dst'] + src_id = link['__src_id'] + dst_id = link['__dst_id'] # TODO: use object based link representation prop_dict = link.copy() - del prop_dict['__dst'] - del prop_dict['__src'] + del prop_dict['__dst_id'] + del prop_dict['__src_id'] - q_params = {'src': { 'id': n_src} , - 'dst': { 'id': n_dst} , + q_params = {'src': { 'id': src_id} , + 'dst': { 'id': dst_id} , 'link_attr' : input_to_DB_property_map(prop_dict)} ret.append((q, q_params)) @@ -239,8 +239,8 @@ def meta_attr_list_to_meta_attr_map(e_set, meta_attr='__label_set'): return ret def __type_check_link(link): - assert link.has_key('__src') - assert link.has_key('__dst') + assert link.has_key('__src_id') + assert link.has_key('__dst_id') def __type_check_link_or_node_map(x_map): for k, v in x_map.iteritems(): # do some type sanity checking diff --git a/src-py/rhizi_api.py b/src-py/rhizi_api.py index 8d787a5c..ef904a37 100644 --- a/src-py/rhizi_api.py +++ b/src-py/rhizi_api.py @@ -127,8 +127,8 @@ def load_link_set_by_link_ptr_set(): l_ptr_set = [] for lptr_dict in l_ptr_set_raw: - src_id = lptr_dict.get('__src') - dst_id = lptr_dict.get('__dst') + src_id = lptr_dict.get('__src_id') + dst_id = lptr_dict.get('__dst_id') l_ptr_set += [Link.Link_Ptr(src_id=src_id, dst_id=dst_id) ] return l_ptr_set -- cgit v1.3.1 From 22bcff47e68ca662360017f4829e35e02b4a33c6 Mon Sep 17 00:00:00 2001 From: LV-426 Date: Wed, 10 Dec 2014 15:20:57 +0200 Subject: sanitize_input__link --- src-py/rhizi_api.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src-py/rhizi_api.py') diff --git a/src-py/rhizi_api.py b/src-py/rhizi_api.py index ef904a37..0c1b68b5 100644 --- a/src-py/rhizi_api.py +++ b/src-py/rhizi_api.py @@ -43,7 +43,9 @@ def sanitize_input__link(l): """ provide a control point as to which node fields are persisted """ - pass + assert None != l['id'], 'invalid input: link: missing id' + assert None != l['__src_id'], 'invalid input: link: missing src id' + assert None != l['__dst_id'], 'invalid input: link: missing dst id' def sanitize_input__topo_diff(topo_diff): for n in topo_diff.node_set_add: -- cgit v1.3.1 From 43fc57a01028b374234042ab59fdbdd48157a88e Mon Sep 17 00:00:00 2001 From: LV-426 Date: Sun, 14 Dec 2014 22:45:27 +0200 Subject: Attr_Diff: __type_node, __type_link separation --- src-py/db_controller.py | 9 ++++++--- src-py/model/graph.py | 49 ++++++++++++++++++++++++++++++++++++++----------- src-py/rhizi_api.py | 9 +++++++-- 3 files changed, 51 insertions(+), 16 deletions(-) (limited to 'src-py/rhizi_api.py') diff --git a/src-py/db_controller.py b/src-py/db_controller.py index 2ca7b551..c17fd0cd 100644 --- a/src-py/db_controller.py +++ b/src-py/db_controller.py @@ -161,10 +161,10 @@ class DBO_attr_diff_commit(DB_op): def __init__(self, attr_diff): super(DBO_attr_diff_commit, self).__init__() - for id_attr, n_attr_diff in attr_diff.items(): + for id_attr, n_attr_diff in attr_diff.type__node.items(): # TODO parameterize multiple attr removal - r_attr_set = n_attr_diff['attr_remove'] - w_attr_set = n_attr_diff['attr_write'] + r_attr_set = n_attr_diff['__attr_remove'] + w_attr_set = n_attr_diff['__attr_write'] assert len(r_attr_set) > 0 or len(w_attr_set) > 0 @@ -184,6 +184,9 @@ class DBO_attr_diff_commit(DB_op): q = " ".join(q_arr) self.add_statement(q, q_param_set) + for id_attr, n_attr_diff in attr_diff.type__link.items(): + pass # TODO: handl link attr_diffs + def process_result_set(self): ret = {} for _, _, r_set in self: diff --git a/src-py/model/graph.py b/src-py/model/graph.py index 86a195d4..b40b805a 100644 --- a/src-py/model/graph.py +++ b/src-py/model/graph.py @@ -5,31 +5,58 @@ class Attr_Diff(dict): changed or removed Example: - attr_diff = {n_id: {'attr_write': {'attr_0': 0, - 'attr_1': 'a'}, - 'attr_remove': ['attr_2'] } + attr_diff = {'__type_node' : {n_id: {'__attr_write': {'attr_0': 0, + 'attr_1': 'a'}, + '__attr_remove': ['attr_2'] }} + '__type_link' : {l_id: ... } } """ def __init__(self): - pass + self['__type_node'] = {} + self['__type_link'] = {} def init_node_attr_diff(self, n_id): - ret = {'attr_write': {}, - 'attr_remove': []} - self[n_id] = ret + ret = {'__attr_write': {}, + '__attr_remove': []} + self['__type_node'][n_id] = ret + return ret + + @staticmethod + def from_json_dict(json_dict): + ret = Attr_Diff() + for obj_type in ret.keys(): + obj_ad_set = json_dict.get(obj_type) + if None != obj_ad_set: + for o_id, ad in obj_ad_set.items(): + if None != ad.get('__attr_write'): + for k, v in ad['__attr_write'].items(): + ret.add_node_attr_write(o_id, k, v) + if None != ad.get('__attr_remove'): + for k in ad['__attr_remove']: + ret.add_node_attr_rm(o_id, k) return ret + @property + def type__node(self): + return self['__type_node'] + + @property + def type__link(self): + return self['__type_link'] + def add_node_attr_write(self, n_id, attr_name, attr_val): - n_attr_diff = self.get(n_id) + + + n_attr_diff = self['__type_node'].get(n_id) if None == n_attr_diff: n_attr_diff = self.init_node_attr_diff(n_id) - n_attr_diff['attr_write'][attr_name] = attr_val + n_attr_diff['__attr_write'][attr_name] = attr_val def add_node_attr_rm(self, n_id, attr_name): - n_attr_diff = self.get(n_id) + n_attr_diff = self['__type_node'].get(n_id) if None == n_attr_diff: n_attr_diff = self.init_node_attr_diff(n_id) - n_attr_diff['attr_remove'].append(attr_name) + n_attr_diff['__attr_remove'].append(attr_name) class Topo_Diff(object): """ diff --git a/src-py/rhizi_api.py b/src-py/rhizi_api.py index 0c1b68b5..b89e8c18 100644 --- a/src-py/rhizi_api.py +++ b/src-py/rhizi_api.py @@ -179,9 +179,14 @@ def diff_commit__attr(): """ commit a graph attribute diff """ - attr_diff = request.get_json()['attr_diff'] - __sanitize_input(attr_diff) + def sanitize_input(req): + attr_diff_dict = request.get_json()['attr_diff'] + attr_diff = Attr_Diff.from_json_dict(attr_diff_dict) + + sanitize_input__attr_diff(attr_diff) + return attr_diff; + attr_diff = sanitize_input(request) op = dbc.DBO_attr_diff_commit(attr_diff) return __common_exec(op) -- cgit v1.3.1 From 292e45dd6590ada4a5155ec4cfe9446610eaf502 Mon Sep 17 00:00:00 2001 From: LV-426 Date: Sun, 14 Dec 2014 22:48:13 +0200 Subject: rename from_dict -> from_json_dict --- src-py/model/graph.py | 4 ++-- src-py/rhizi_api.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'src-py/rhizi_api.py') diff --git a/src-py/model/graph.py b/src-py/model/graph.py index b40b805a..ebe8b31e 100644 --- a/src-py/model/graph.py +++ b/src-py/model/graph.py @@ -83,7 +83,7 @@ class Topo_Diff(object): pass @staticmethod - def from_dict(topo_diff_dict): + def from_json_dict(json_dict): """ construct from dict - no node/link constructor set must be provided """ @@ -92,7 +92,7 @@ class Topo_Diff(object): # merge keys - this allows constructor argument omission (link_set_rm, # node_set_rm, etc.) such as when constructing from POST JSON data for k, _ in ret.__dict__.items(): - v = topo_diff_dict.get(k) + v = json_dict.get(k) if None != v: ret.__dict__[k] = v return ret diff --git a/src-py/rhizi_api.py b/src-py/rhizi_api.py index b89e8c18..228fcd66 100644 --- a/src-py/rhizi_api.py +++ b/src-py/rhizi_api.py @@ -151,7 +151,7 @@ def diff_commit__set(): def sanitize_input(req): diff_set_dict = request.get_json()['diff_set'] topo_diff_dict = diff_set_dict['__diff_set_topo'][0] - topo_diff = Topo_Diff.from_dict(topo_diff_dict) + topo_diff = Topo_Diff.from_json_dict(topo_diff_dict) sanitize_input__topo_diff(topo_diff) return topo_diff; @@ -166,7 +166,7 @@ def diff_commit__topo(): """ def sanitize_input(req): topo_diff_dict = request.get_json()['topo_diff'] - topo_diff = Topo_Diff.from_dict(topo_diff_dict) + topo_diff = Topo_Diff.from_json_dict(topo_diff_dict) sanitize_input__topo_diff(topo_diff) return topo_diff; -- cgit v1.3.1 From dc540c722c5146156fadd2d5db5c14dc96a996c6 Mon Sep 17 00:00:00 2001 From: LV-426 Date: Sun, 14 Dec 2014 23:12:38 +0200 Subject: sanitize_input__attr_diff stub --- src-py/rhizi_api.py | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src-py/rhizi_api.py') diff --git a/src-py/rhizi_api.py b/src-py/rhizi_api.py index 228fcd66..579d41e1 100644 --- a/src-py/rhizi_api.py +++ b/src-py/rhizi_api.py @@ -53,6 +53,9 @@ def sanitize_input__topo_diff(topo_diff): for l in topo_diff.link_set_add: sanitize_input__link(l) +def sanitize_input__attr_diff(attr_diff): + pass # TODO: impl + def __response_wrap(data=None, error=None): """ wrap response data/errors as dict - this should always be used when returning -- cgit v1.3.1