5454 SPARQL_EXPLAIN_MODES , OPENCYPHER_EXPLAIN_MODES , GREMLIN_EXPLAIN_MODES , \
5555 OPENCYPHER_PLAN_CACHE_MODES , OPENCYPHER_DEFAULT_TIMEOUT , OPENCYPHER_STATUS_STATE_MODES , \
5656 normalize_service_name , NEPTUNE_DB_SERVICE_NAME , NEPTUNE_ANALYTICS_SERVICE_NAME , GRAPH_PG_INFO_METRICS , \
57- GREMLIN_PROTOCOL_FORMATS , DEFAULT_HTTP_PROTOCOL , DEFAULT_WS_PROTOCOL , \
58- GREMLIN_SERIALIZERS_WS , GREMLIN_SERIALIZERS_CLASS_TO_MIME_MAP , normalize_protocol_name , generate_snapshot_name )
57+ GREMLIN_PROTOCOL_FORMATS , DEFAULT_HTTP_PROTOCOL , DEFAULT_WS_PROTOCOL , GRAPHSONV4_UNTYPED , \
58+ GREMLIN_SERIALIZERS_WS , get_gremlin_serializer_mime , normalize_protocol_name , generate_snapshot_name )
5959from graph_notebook .network import SPARQLNetwork
6060from graph_notebook .network .gremlin .GremlinNetwork import parse_pattern_list_str , GremlinNetwork
6161from graph_notebook .visualization .rows_and_columns import sparql_get_rows_and_columns , opencypher_get_rows_and_columns
@@ -1091,6 +1091,9 @@ def gremlin(self, line, cell, local_ns: dict = None):
10911091 f'If not specified, defaults to the value of the gremlin.connection_protocol field '
10921092 f'in %%graph_notebook_config. Please note that this option has no effect on the '
10931093 f'Profile and Explain modes, which must use HTTP.' )
1094+ parser .add_argument ('-qp' , '--query-parameters' , type = str , default = '' ,
1095+ help = 'Parameter definitions to apply to the query. This option can accept a local variable '
1096+ 'name, or a string representation of the map.' )
10941097 parser .add_argument ('--explain-type' , type = str .lower , default = 'dynamic' ,
10951098 help = f'Explain mode to use when using the explain query mode. '
10961099 f'Accepted values: { GREMLIN_EXPLAIN_MODES } ' )
@@ -1160,6 +1163,21 @@ def gremlin(self, line, cell, local_ns: dict = None):
11601163 logger .debug (f'Arguments { args } ' )
11611164 results_df = None
11621165
1166+ query_params = None
1167+ if args .query_parameters :
1168+ if args .query_parameters in local_ns :
1169+ query_params_input = local_ns [args .query_parameters ]
1170+ else :
1171+ query_params_input = args .query_parameters
1172+ if isinstance (query_params_input , dict ):
1173+ query_params = json .dumps (query_params_input )
1174+ else :
1175+ try :
1176+ query_params_dict = json .loads (query_params_input .replace ("'" , '"' ))
1177+ query_params = json .dumps (query_params_dict )
1178+ except Exception as e :
1179+ print (f"Invalid query parameter input, ignoring." )
1180+
11631181 if args .no_scroll :
11641182 gremlin_layout = UNRESTRICTED_LAYOUT
11651183 gremlin_scrollY = True
@@ -1184,8 +1202,13 @@ def gremlin(self, line, cell, local_ns: dict = None):
11841202
11851203 if mode == QueryMode .EXPLAIN :
11861204 try :
1205+ explain_args = {}
1206+ if args .explain_type :
1207+ explain_args ['explain.mode' ] = args .explain_type
1208+ if self .client .is_analytics_domain () and query_params :
1209+ explain_args ['parameters' ] = query_params
11871210 res = self .client .gremlin_explain (cell ,
1188- args = { 'explain.mode' : args . explain_type } if args . explain_type else {} )
1211+ args = explain_args )
11891212 res .raise_for_status ()
11901213 except Exception as e :
11911214 if self .client .is_analytics_domain ():
@@ -1219,6 +1242,8 @@ def gremlin(self, line, cell, local_ns: dict = None):
12191242 "profile.serializer" : serializer ,
12201243 "profile.indexOps" : args .profile_indexOps ,
12211244 "profile.debug" : args .profile_debug }
1245+ if self .client .is_analytics_domain () and query_params :
1246+ profile_args ['parameters' ] = query_params
12221247 try :
12231248 profile_misc_args_dict = json .loads (args .profile_misc_args )
12241249 profile_args .update (profile_misc_args_dict )
@@ -1269,17 +1294,29 @@ def gremlin(self, line, cell, local_ns: dict = None):
12691294 try :
12701295 if connection_protocol == DEFAULT_HTTP_PROTOCOL :
12711296 using_http = True
1297+ headers = {}
12721298 message_serializer = self .graph_notebook_config .gremlin .message_serializer
1273- message_serializer_mime = GREMLIN_SERIALIZERS_CLASS_TO_MIME_MAP [message_serializer ]
1274- query_res_http = self .client .gremlin_http_query (cell , headers = {
1275- 'Accept' : message_serializer_mime })
1299+ message_serializer_mime = get_gremlin_serializer_mime (message_serializer , DEFAULT_HTTP_PROTOCOL )
1300+ if message_serializer_mime != GRAPHSONV4_UNTYPED :
1301+ headers ['Accept' ] = message_serializer_mime
1302+ passed_params = query_params if self .client .is_analytics_domain () else None
1303+ query_res_http = self .client .gremlin_http_query (cell ,
1304+ headers = headers ,
1305+ query_params = passed_params )
12761306 query_res_http .raise_for_status ()
12771307 try :
12781308 query_res_http_json = query_res_http .json ()
12791309 except JSONDecodeError :
12801310 query_res_fixed = repair_json (query_res_http .text )
12811311 query_res_http_json = json .loads (query_res_fixed )
1282- query_res = query_res_http_json ['result' ]['data' ]
1312+ if 'result' in query_res_http_json :
1313+ query_res = query_res_http_json ['result' ]['data' ]
1314+ else :
1315+ if 'reason' in query_res_http_json :
1316+ logger .debug ('Query failed with internal error, see response.' )
1317+ else :
1318+ logger .debug ('Received unexpected response format, outputting as single entry.' )
1319+ query_res = [query_res_http_json ]
12831320 else :
12841321 query_res = self .client .gremlin_query (cell , transport_args = transport_args )
12851322 except Exception as e :
@@ -1317,7 +1354,7 @@ def gremlin(self, line, cell, local_ns: dict = None):
13171354 ignore_groups = args .ignore_groups ,
13181355 using_http = using_http )
13191356
1320- if using_http and 'path()' in cell and query_res :
1357+ if using_http and 'path()' in cell and query_res and isinstance ( query_res , list ) :
13211358 first_path = query_res [0 ]
13221359 if isinstance (first_path , dict ) and first_path .keys () == {'labels' , 'objects' }:
13231360 query_res_to_path_type = []
@@ -2844,8 +2881,8 @@ def seed(self, line, local_ns: dict = None):
28442881
28452882 if self .client .is_analytics_domain ():
28462883 model_options = SEED_MODEL_OPTIONS_PG
2847- custom_language_options = SEED_LANGUAGE_OPTIONS_OC
2848- samples_pg_language_options = SEED_LANGUAGE_OPTIONS_OC
2884+ custom_language_options = SEED_LANGUAGE_OPTIONS_PG
2885+ samples_pg_language_options = SEED_LANGUAGE_OPTIONS_PG
28492886 else :
28502887 model_options = SEED_MODEL_OPTIONS
28512888 custom_language_options = SEED_LANGUAGE_OPTIONS
@@ -3121,7 +3158,11 @@ def process_gremlin_query_line(query_line, line_index, q):
31213158 logger .debug (f"Skipped blank query at line { line_index + 1 } in seed file { q ['name' ]} " )
31223159 return 0
31233160 try :
3124- self .client .gremlin_query (query_line )
3161+ if self .client .is_neptune_domain () and self .client .is_analytics_domain () and \
3162+ self .graph_notebook_config .gremlin .connection_protocol == DEFAULT_HTTP_PROTOCOL :
3163+ self .client .gremlin_http_query (query_line )
3164+ else :
3165+ self .client .gremlin_query (query_line )
31253166 return 0
31263167 except GremlinServerError as gremlinEx :
31273168 try :
0 commit comments