From 4d1c821cae29fffca56b414a0141172618a281cb Mon Sep 17 00:00:00 2001 From: Tirumarai Selvan A Date: Thu, 24 Jan 2019 13:00:15 +0530 Subject: [PATCH 1/7] rename Request -> WebhookRequest --- server/src-lib/Hasura/Events/Lib.hs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/server/src-lib/Hasura/Events/Lib.hs b/server/src-lib/Hasura/Events/Lib.hs index d546a611a335f..6e6ce227fe895 100644 --- a/server/src-lib/Hasura/Events/Lib.hs +++ b/server/src-lib/Hasura/Events/Lib.hs @@ -88,13 +88,13 @@ instance ToJSON Event where $(deriveFromJSON (aesonDrop 1 snakeCase){omitNothingFields=True} ''Event) -data Request - = Request +data WebhookRequest + = WebhookRequest { _rqPayload :: Value , _rqHeaders :: Maybe [HeaderConf] , _rqVersion :: T.Text } -$(deriveToJSON (aesonDrop 3 snakeCase){omitNothingFields=True} ''Request) +$(deriveToJSON (aesonDrop 3 snakeCase){omitNothingFields=True} ''WebhookRequest) data WebhookResponse = WebhookResponse @@ -117,7 +117,7 @@ data Invocation = Invocation { iEventId :: EventId , iStatus :: Int - , iRequest :: Request + , iRequest :: WebhookRequest , iResponse :: Response } @@ -338,8 +338,8 @@ tryWebhook logenv pool e = do where decodeBS = TE.decodeUtf8With TE.lenientDecode - mkWebhookReq :: Value -> [HeaderConf] -> Request - mkWebhookReq payload headers = Request payload (mkMaybe headers) invocationVersion + mkWebhookReq :: Value -> [HeaderConf] -> WebhookRequest + mkWebhookReq payload headers = WebhookRequest payload (mkMaybe headers) invocationVersion mkResp :: Int -> TBS.TByteString -> [HeaderConf] -> Response mkResp status payload headers = From 5bbc3e97f3f4ab1d2564192a32f44c730814c9fb Mon Sep 17 00:00:00 2001 From: Tirumarai Selvan A Date: Thu, 24 Jan 2019 14:15:18 +0530 Subject: [PATCH 2/7] add session_variables from current_settings --- server/src-rsr/trigger.sql.j2 | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/server/src-rsr/trigger.sql.j2 b/server/src-rsr/trigger.sql.j2 index 2135499eecac2..8fd23154e25ab 100644 --- a/server/src-rsr/trigger.sql.j2 +++ b/server/src-rsr/trigger.sql.j2 @@ -7,8 +7,20 @@ CREATE OR REPLACE function hdb_views.{{QUALIFIED_TRIGGER_NAME}}() RETURNS trigge _new record; _data json; payload json; + session_variables json; + server_version_num int; BEGIN id := gen_random_uuid(); + server_version_num := current_setting('server_version_num'); + IF server_version_num >= 90600 THEN + session_variables := current_setting('hasura.user', 't'); + ELSE + BEGIN + session_variables := current_setting('hasura.user'); + EXCEPTION WHEN OTHERS THEN + session_variables := NULL; + END; + END IF; IF TG_OP = 'UPDATE' THEN _old := {{OLD_ROW}}; _new := {{NEW_ROW}}; @@ -23,7 +35,8 @@ CREATE OR REPLACE function hdb_views.{{QUALIFIED_TRIGGER_NAME}}() RETURNS trigge ); payload := json_build_object( 'op', TG_OP, - 'data', _data + 'data', _data, + 'session_variables', session_variables )::text; IF (TG_OP <> 'UPDATE') OR (_old <> _new) THEN INSERT INTO From b1373041d20e72ce984eb25f2eefc4437a4a9c2b Mon Sep 17 00:00:00 2001 From: Tirumarai Selvan A Date: Thu, 24 Jan 2019 15:06:33 +0530 Subject: [PATCH 3/7] v1q should take optional headers --- server/tests-py/context.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/server/tests-py/context.py b/server/tests-py/context.py index 309668d02ad3f..225d0597a0d48 100644 --- a/server/tests-py/context.py +++ b/server/tests-py/context.py @@ -137,8 +137,7 @@ def anyq(self, u, q, h): ) return resp.status_code, resp.json() - def v1q(self, q): - h = dict() + def v1q(self, q, h = {}): if self.hge_key is not None: h['X-Hasura-Access-Key'] = self.hge_key resp = self.http.post( From 6db6ad4245bcd33543c1c2dd03d4d1ff6bf0260f Mon Sep 17 00:00:00 2001 From: Tirumarai Selvan A Date: Thu, 24 Jan 2019 15:07:43 +0530 Subject: [PATCH 4/7] refactor check_event to take optional variables --- server/tests-py/test_events.py | 77 +++++++++++++++++----------------- server/tests-py/validate.py | 7 +++- 2 files changed, 45 insertions(+), 39 deletions(-) diff --git a/server/tests-py/test_events.py b/server/tests-py/test_events.py index 302750a69c15d..c4b197551db96 100755 --- a/server/tests-py/test_events.py +++ b/server/tests-py/test_events.py @@ -21,7 +21,7 @@ def select_last_event_fromdb(hge_ctx): return st_code, resp -def insert(hge_ctx, table, row, returning=[]): +def insert(hge_ctx, table, row, returning=[], headers = {}): q = { "type": "insert", "args": { @@ -30,11 +30,11 @@ def insert(hge_ctx, table, row, returning=[]): "returning": returning } } - st_code, resp = hge_ctx.v1q(q) + st_code, resp = hge_ctx.v1q(q, h = headers) return st_code, resp -def update(hge_ctx, table, where_exp, set_exp): +def update(hge_ctx, table, where_exp, set_exp, headers = {}): q = { "type": "update", "args": { @@ -43,11 +43,11 @@ def update(hge_ctx, table, where_exp, set_exp): "$set": set_exp } } - st_code, resp = hge_ctx.v1q(q) + st_code, resp = hge_ctx.v1q(q, h = headers) return st_code, resp -def delete(hge_ctx, table, where_exp): +def delete(hge_ctx, table, where_exp, headers = {}): q = { "type": "delete", "args": { @@ -55,7 +55,7 @@ def delete(hge_ctx, table, where_exp): "where": where_exp } } - st_code, resp = hge_ctx.v1q(q) + st_code, resp = hge_ctx.v1q(q, h = headers) return st_code, resp class TestCreateAndDelete(DefaultTestQueries): @@ -89,10 +89,9 @@ def test_basic(self, hge_ctx): "old": None, "new": init_row } - headers = {} st_code, resp = insert(hge_ctx, table, init_row) assert st_code == 200, resp - check_event(hge_ctx, "t1_all", table, "INSERT", exp_ev_data, headers, "/") + check_event(hge_ctx, "t1_all", table, "INSERT", exp_ev_data) where_exp = {"c1": 1} set_exp = {"c2": "world"} @@ -102,7 +101,7 @@ def test_basic(self, hge_ctx): } st_code, resp = update(hge_ctx, table, where_exp, set_exp) assert st_code == 200, resp - check_event(hge_ctx, "t1_all", table, "UPDATE", exp_ev_data, headers, "/") + check_event(hge_ctx, "t1_all", table, "UPDATE", exp_ev_data) exp_ev_data = { "old": {"c1": 1, "c2": "world"}, @@ -110,7 +109,7 @@ def test_basic(self, hge_ctx): } st_code, resp = delete(hge_ctx, table, where_exp) assert st_code == 200, resp - check_event(hge_ctx, "t1_all", table, "DELETE", exp_ev_data, headers, "/") + check_event(hge_ctx, "t1_all", table, "DELETE", exp_ev_data) class TestRetryConf(object): @@ -132,7 +131,6 @@ def test_basic(self, hge_ctx): "old": None, "new": init_row } - headers = {} st_code, resp = insert(hge_ctx, table, init_row) assert st_code == 200, resp time.sleep(15) @@ -162,7 +160,7 @@ def test_basic(self, hge_ctx): headers = {"X-Header-From-Value": "MyValue", "X-Header-From-Env": "MyEnvValue"} st_code, resp = insert(hge_ctx, table, init_row) assert st_code == 200, resp - check_event(hge_ctx, "t1_all", table, "INSERT", exp_ev_data, headers, "/") + check_event(hge_ctx, "t1_all", table, "INSERT", exp_ev_data, headers = headers) class TestUpdateEvtQuery(object): @@ -186,11 +184,10 @@ def test_update_basic(self, hge_ctx): "old": None, "new": {"c1": 1, "c2": "hello"} } - headers = {} st_code, resp = insert(hge_ctx, table, init_row) assert st_code == 200, resp with pytest.raises(queue.Empty): - check_event(hge_ctx, "t1_cols", table, "INSERT", exp_ev_data, headers, "/new") + check_event(hge_ctx, "t1_cols", table, "INSERT", exp_ev_data, webhook_path = "/new") where_exp = {"c1": 1} set_exp = {"c2": "world"} @@ -198,7 +195,7 @@ def test_update_basic(self, hge_ctx): st_code, resp = update(hge_ctx, table, where_exp, set_exp) assert st_code == 200, resp with pytest.raises(queue.Empty): - check_event(hge_ctx, "t1_cols", table, "UPDATE", exp_ev_data, headers, "/new") + check_event(hge_ctx, "t1_cols", table, "UPDATE", exp_ev_data, webhook_path = "/new") where_exp = {"c1": 1} set_exp = {"c1": 2} @@ -208,7 +205,7 @@ def test_update_basic(self, hge_ctx): } st_code, resp = update(hge_ctx, table, where_exp, set_exp) assert st_code == 200, resp - check_event(hge_ctx, "t1_cols", table, "UPDATE", exp_ev_data, headers, "/new") + check_event(hge_ctx, "t1_cols", table, "UPDATE", exp_ev_data, webhook_path ="/new") where_exp = {"c1": 2} exp_ev_data = { @@ -217,7 +214,7 @@ def test_update_basic(self, hge_ctx): } st_code, resp = delete(hge_ctx, table, where_exp) assert st_code == 200, resp - check_event(hge_ctx, "t1_cols", table, "DELETE", exp_ev_data, headers, "/new") + check_event(hge_ctx, "t1_cols", table, "DELETE", exp_ev_data, webhook_path = "/new") class TestDeleteEvtQuery(object): @@ -241,11 +238,10 @@ def test_delete_basic(self, hge_ctx): "old": None, "new": init_row } - headers = {} st_code, resp = insert(hge_ctx, table, init_row) assert st_code == 200, resp with pytest.raises(queue.Empty): - check_event(hge_ctx, "t1_all", table, "INSERT", exp_ev_data, headers, "/") + check_event(hge_ctx, "t1_all", table, "INSERT", exp_ev_data) where_exp = {"c1": 1} set_exp = {"c2": "world"} @@ -256,7 +252,7 @@ def test_delete_basic(self, hge_ctx): st_code, resp = update(hge_ctx, table, where_exp, set_exp) assert st_code == 200, resp with pytest.raises(queue.Empty): - check_event(hge_ctx, "t1_all", table, "UPDATE", exp_ev_data, headers, "/") + check_event(hge_ctx, "t1_all", table, "UPDATE", exp_ev_data) exp_ev_data = { "old": {"c1": 1, "c2": "world"}, @@ -265,7 +261,7 @@ def test_delete_basic(self, hge_ctx): st_code, resp = delete(hge_ctx, table, where_exp) assert st_code == 200, resp with pytest.raises(queue.Empty): - check_event(hge_ctx, "t1_all", table, "DELETE", exp_ev_data, headers, "/") + check_event(hge_ctx, "t1_all", table, "DELETE", exp_ev_data) class TestEvtSelCols: @@ -287,10 +283,9 @@ def test_selected_cols(self, hge_ctx): "old": None, "new": {"c1": 1, "c2": "hello"} } - headers = {} st_code, resp = insert(hge_ctx, table, init_row) assert st_code == 200, resp - check_event(hge_ctx, "t1_cols", table, "INSERT", exp_ev_data, headers, "/") + check_event(hge_ctx, "t1_cols", table, "INSERT", exp_ev_data) where_exp = {"c1": 1} set_exp = {"c2": "world"} @@ -298,7 +293,7 @@ def test_selected_cols(self, hge_ctx): st_code, resp = update(hge_ctx, table, where_exp, set_exp) assert st_code == 200, resp with pytest.raises(queue.Empty): - check_event(hge_ctx, "t1_cols", table, "UPDATE", exp_ev_data, headers, "/") + check_event(hge_ctx, "t1_cols", table, "UPDATE", exp_ev_data) where_exp = {"c1": 1} set_exp = {"c1": 2} @@ -308,7 +303,7 @@ def test_selected_cols(self, hge_ctx): } st_code, resp = update(hge_ctx, table, where_exp, set_exp) assert st_code == 200, resp - check_event(hge_ctx, "t1_cols", table, "UPDATE", exp_ev_data, headers, "/") + check_event(hge_ctx, "t1_cols", table, "UPDATE", exp_ev_data) where_exp = {"c1": 2} exp_ev_data = { @@ -317,7 +312,7 @@ def test_selected_cols(self, hge_ctx): } st_code, resp = delete(hge_ctx, table, where_exp) assert st_code == 200, resp - check_event(hge_ctx, "t1_cols", table, "DELETE", exp_ev_data, headers, "/") + check_event(hge_ctx, "t1_cols", table, "DELETE", exp_ev_data) def test_selected_cols_dep(self, hge_ctx): st_code, resp = hge_ctx.v1q({ @@ -357,10 +352,9 @@ def test_insert_only(self, hge_ctx): "old": None, "new": init_row } - headers = {} st_code, resp = insert(hge_ctx, table, init_row) assert st_code == 200, resp - check_event(hge_ctx, "t1_insert", table, "INSERT", exp_ev_data, headers, "/") + check_event(hge_ctx, "t1_insert", table, "INSERT", exp_ev_data) where_exp = {"c1": 1} set_exp = {"c2": "world"} @@ -371,7 +365,7 @@ def test_insert_only(self, hge_ctx): st_code, resp = update(hge_ctx, table, where_exp, set_exp) assert st_code == 200, resp with pytest.raises(queue.Empty): - check_event(hge_ctx, "t1_insert", table, "UPDATE", exp_ev_data, headers, "/") + check_event(hge_ctx, "t1_insert", table, "UPDATE", exp_ev_data) exp_ev_data = { "old": {"c1": 1, "c2": "world"}, @@ -380,7 +374,7 @@ def test_insert_only(self, hge_ctx): st_code, resp = delete(hge_ctx, table, where_exp) assert st_code == 200, resp with pytest.raises(queue.Empty): - check_event(hge_ctx, "t1_insert", table, "DELETE", exp_ev_data, headers, "/") + check_event(hge_ctx, "t1_insert", table, "DELETE", exp_ev_data) class TestEvtSelPayload: @@ -402,10 +396,9 @@ def test_selected_payload(self, hge_ctx): "old": None, "new": {"c1": 1, "c2": "hello"} } - headers = {} st_code, resp = insert(hge_ctx, table, init_row) assert st_code == 200, resp - check_event(hge_ctx, "t1_payload", table, "INSERT", exp_ev_data, headers, "/") + check_event(hge_ctx, "t1_payload", table, "INSERT", exp_ev_data) where_exp = {"c1": 1} set_exp = {"c2": "world"} @@ -415,7 +408,7 @@ def test_selected_payload(self, hge_ctx): } st_code, resp = update(hge_ctx, table, where_exp, set_exp) assert st_code == 200, resp - check_event(hge_ctx, "t1_payload", table, "UPDATE", exp_ev_data, headers, "/") + check_event(hge_ctx, "t1_payload", table, "UPDATE", exp_ev_data) where_exp = {"c1": 1} set_exp = {"c1": 2} @@ -425,7 +418,7 @@ def test_selected_payload(self, hge_ctx): } st_code, resp = update(hge_ctx, table, where_exp, set_exp) assert st_code == 200, resp - check_event(hge_ctx, "t1_payload", table, "UPDATE", exp_ev_data, headers, "/") + check_event(hge_ctx, "t1_payload", table, "UPDATE", exp_ev_data) where_exp = {"c1": 2} exp_ev_data = { @@ -434,7 +427,7 @@ def test_selected_payload(self, hge_ctx): } st_code, resp = delete(hge_ctx, table, where_exp) assert st_code == 200, resp - check_event(hge_ctx, "t1_payload", table, "DELETE", exp_ev_data, headers, "/") + check_event(hge_ctx, "t1_payload", table, "DELETE", exp_ev_data) def test_selected_payload_dep(self, hge_ctx): st_code, resp = hge_ctx.v1q({ @@ -474,10 +467,9 @@ def test_basic(self, hge_ctx): "old": None, "new": init_row } - headers = {} st_code, resp = insert(hge_ctx, table, init_row) assert st_code == 200, resp - check_event(hge_ctx, "t1_all", table, "INSERT", exp_ev_data, headers, "/") + check_event(hge_ctx, "t1_all", table, "INSERT", exp_ev_data) where_exp = {"c1": 1} set_exp = {"c2": "world"} @@ -487,7 +479,16 @@ def test_basic(self, hge_ctx): } st_code, resp = update(hge_ctx, table, where_exp, set_exp) assert st_code == 200, resp - check_event(hge_ctx, "t1_all", table, "UPDATE", exp_ev_data, headers, "/") + check_event(hge_ctx, "t1_all", table, "UPDATE", exp_ev_data) + + exp_ev_data = { + "old": {"c1": 1, "c2": "world"}, + "new": None + } + st_code, resp = delete(hge_ctx, table, where_exp) + assert st_code == 200, resp + check_event(hge_ctx, "t1_all", table, "DELETE", exp_ev_data) + exp_ev_data = { "old": {"c1": 1, "c2": "world"}, diff --git a/server/tests-py/validate.py b/server/tests-py/validate.py index 31d0128626228..4a0042326e46a 100644 --- a/server/tests-py/validate.py +++ b/server/tests-py/validate.py @@ -40,13 +40,18 @@ def validate_event_webhook(ev_webhook_path, webhook_path): assert ev_webhook_path == webhook_path -def check_event(hge_ctx, trig_name, table, operation, exp_ev_data, headers, webhook_path): +def check_event(hge_ctx, trig_name, table, operation, exp_ev_data, + headers = {}, + webhook_path = '/', + session_variables = {'x-hasura-role': 'admin'} +): ev_full = hge_ctx.get_event(3) validate_event_webhook(ev_full['path'], webhook_path) validate_event_headers(ev_full['headers'], headers) validate_event_payload(ev_full['body'], trig_name, table) ev = ev_full['body']['event'] assert ev['op'] == operation, ev + assert ev['session_variables'] == session_variables, ev assert ev['data'] == exp_ev_data, ev From e2f6e99fe5bcbdd0534a0d4e5cdccb0ab75dfea9 Mon Sep 17 00:00:00 2001 From: Tirumarai Selvan A Date: Thu, 24 Jan 2019 15:07:58 +0530 Subject: [PATCH 5/7] add tests for session variables in event trigger --- server/tests-py/test_events.py | 37 +++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/server/tests-py/test_events.py b/server/tests-py/test_events.py index c4b197551db96..940c7b55fb0e2 100755 --- a/server/tests-py/test_events.py +++ b/server/tests-py/test_events.py @@ -489,6 +489,41 @@ def test_basic(self, hge_ctx): assert st_code == 200, resp check_event(hge_ctx, "t1_all", table, "DELETE", exp_ev_data) +class TestSessionVariables(object): + + @pytest.fixture(autouse=True) + def transact(self, request, hge_ctx): + print("In setup method") + st_code, resp = hge_ctx.v1q_f('queries/event_triggers/basic/setup.yaml') + assert st_code == 200, resp + yield + st_code, resp = hge_ctx.v1q_f('queries/event_triggers/basic/teardown.yaml') + assert st_code == 200, resp + + def test_basic(self, hge_ctx): + table = {"schema": "hge_tests", "name": "test_t1"} + + init_row = {"c1": 1, "c2": "hello"} + exp_ev_data = { + "old": None, + "new": init_row + } + session_variables = { 'x-hasura-role': 'admin', 'x-hasura-allowed-roles': "['admin','user']", 'x-hasura-user-id': '1'} + st_code, resp = insert(hge_ctx, table, init_row, headers = session_variables) + assert st_code == 200, resp + check_event(hge_ctx, "t1_all", table, "INSERT", exp_ev_data, session_variables = session_variables) + + where_exp = {"c1": 1} + set_exp = {"c2": "world"} + exp_ev_data = { + "old": init_row, + "new": {"c1": 1, "c2": "world"} + } + session_variables = { 'x-hasura-role': 'admin', 'x-hasura-random': 'some_random_info', 'X-Random-Header': 'not_session_variable'} + st_code, resp = update(hge_ctx, table, where_exp, set_exp, headers = session_variables) + assert st_code == 200, resp + session_variables.pop('X-Random-Header') + check_event(hge_ctx, "t1_all", table, "UPDATE", exp_ev_data, session_variables = session_variables) exp_ev_data = { "old": {"c1": 1, "c2": "world"}, @@ -496,4 +531,4 @@ def test_basic(self, hge_ctx): } st_code, resp = delete(hge_ctx, table, where_exp) assert st_code == 200, resp - check_event(hge_ctx, "t1_all", table, "DELETE", exp_ev_data, headers, "/") + check_event(hge_ctx, "t1_all", table, "DELETE", exp_ev_data) From c7f7481df7a19f6ca52ddcebafdf748bfa8b3e65 Mon Sep 17 00:00:00 2001 From: Tirumarai Selvan A Date: Thu, 24 Jan 2019 15:24:01 +0530 Subject: [PATCH 6/7] add session-variables to event trigger payload docs --- docs/graphql/manual/event-triggers/payload.rst | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/docs/graphql/manual/event-triggers/payload.rst b/docs/graphql/manual/event-triggers/payload.rst index 1baebca1c3cb8..b1db137a0d108 100644 --- a/docs/graphql/manual/event-triggers/payload.rst +++ b/docs/graphql/manual/event-triggers/payload.rst @@ -23,10 +23,11 @@ JSON payload { "event": { + "session_variables": , "op": "", "data": { - "old": , - "new": + "old": , + "new": } }, "created_at": "", @@ -48,6 +49,9 @@ JSON payload * - Key - Type - Description + * - session-variables + - Object_ or NULL + - Key-value pairs of session variables (i.e. "x-hasura-\*" variables) and their values. NULL if no session variables found. * - op-name - OpName_ - Name of the operation. Can only be "INSERT", "UPDATE" or "DELETE" @@ -104,6 +108,11 @@ JSON payload "name": "users" }, "event": { + "session_variables": { + "x-hasura-role": "admin", + "x-hasura-allowed-roles": "['user', 'boo', 'admin']", + "x-hasura-user-id": "1" + }, "op": "INSERT", "data": { "old": null, From 9cbe0b7f5a082ac0ce9694ce02173e9f4c79f2fb Mon Sep 17 00:00:00 2001 From: Tirumarai Selvan A Date: Thu, 24 Jan 2019 19:00:07 +0530 Subject: [PATCH 7/7] create new copy of headers before mutating --- server/tests-py/context.py | 3 ++- server/tests-py/test_events.py | 6 +++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/server/tests-py/context.py b/server/tests-py/context.py index 225d0597a0d48..f91f364091202 100644 --- a/server/tests-py/context.py +++ b/server/tests-py/context.py @@ -137,7 +137,8 @@ def anyq(self, u, q, h): ) return resp.status_code, resp.json() - def v1q(self, q, h = {}): + def v1q(self, q, headers = {}): + h = headers.copy() if self.hge_key is not None: h['X-Hasura-Access-Key'] = self.hge_key resp = self.http.post( diff --git a/server/tests-py/test_events.py b/server/tests-py/test_events.py index 940c7b55fb0e2..c08925b7ac5c5 100755 --- a/server/tests-py/test_events.py +++ b/server/tests-py/test_events.py @@ -30,7 +30,7 @@ def insert(hge_ctx, table, row, returning=[], headers = {}): "returning": returning } } - st_code, resp = hge_ctx.v1q(q, h = headers) + st_code, resp = hge_ctx.v1q(q, headers = headers) return st_code, resp @@ -43,7 +43,7 @@ def update(hge_ctx, table, where_exp, set_exp, headers = {}): "$set": set_exp } } - st_code, resp = hge_ctx.v1q(q, h = headers) + st_code, resp = hge_ctx.v1q(q, headers = headers) return st_code, resp @@ -55,7 +55,7 @@ def delete(hge_ctx, table, where_exp, headers = {}): "where": where_exp } } - st_code, resp = hge_ctx.v1q(q, h = headers) + st_code, resp = hge_ctx.v1q(q, headers = headers) return st_code, resp class TestCreateAndDelete(DefaultTestQueries):