gremlinpython 4.0.0b2__py3-none-any.whl → 4.0.0.dev1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- gremlin_python/__init__.py +1 -1
- gremlin_python/driver/aiohttp/transport.py +257 -85
- gremlin_python/driver/auth.py +46 -21
- gremlin_python/driver/client.py +89 -61
- gremlin_python/driver/connection.py +123 -19
- gremlin_python/driver/driver_remote_connection.py +16 -39
- gremlin_python/driver/{transport.py → exceptions.py} +10 -24
- gremlin_python/driver/http_request.py +65 -0
- gremlin_python/driver/request.py +3 -2
- gremlin_python/driver/resultset.py +11 -5
- gremlin_python/driver/serializer.py +50 -130
- gremlin_python/driver/transaction.py +178 -0
- gremlin_python/driver/useragent.py +1 -1
- gremlin_python/process/graph_traversal.py +210 -93
- gremlin_python/process/traversal.py +114 -51
- gremlin_python/structure/graph.py +450 -5
- gremlin_python/structure/io/graphbinaryV4.py +177 -37
- {gremlinpython-4.0.0b2.dist-info → gremlinpython-4.0.0.dev1.dist-info}/METADATA +7 -5
- gremlinpython-4.0.0.dev1.dist-info/RECORD +33 -0
- {gremlinpython-4.0.0b2.dist-info → gremlinpython-4.0.0.dev1.dist-info}/WHEEL +1 -1
- gremlin_python/driver/protocol.py +0 -175
- gremlin_python/structure/io/graphsonV4.py +0 -599
- gremlinpython-4.0.0b2.dist-info/RECORD +0 -33
- {gremlinpython-4.0.0b2.dist-info → gremlinpython-4.0.0.dev1.dist-info}/licenses/LICENSE +0 -0
- {gremlinpython-4.0.0b2.dist-info → gremlinpython-4.0.0.dev1.dist-info}/licenses/NOTICE +0 -0
- {gremlinpython-4.0.0b2.dist-info → gremlinpython-4.0.0.dev1.dist-info}/top_level.txt +0 -0
|
@@ -16,10 +16,13 @@
|
|
|
16
16
|
# specific language governing permissions and limitations
|
|
17
17
|
# under the License.
|
|
18
18
|
#
|
|
19
|
+
import queue
|
|
19
20
|
from concurrent.futures import Future
|
|
20
21
|
|
|
21
22
|
__author__ = 'David M. Brown (davebshow@gmail.com)'
|
|
22
23
|
|
|
24
|
+
_EXHAUSTED = object()
|
|
25
|
+
|
|
23
26
|
|
|
24
27
|
class ResultSet:
|
|
25
28
|
|
|
@@ -45,7 +48,7 @@ class ResultSet:
|
|
|
45
48
|
|
|
46
49
|
def __next__(self):
|
|
47
50
|
result = self.one()
|
|
48
|
-
if
|
|
51
|
+
if result is _EXHAUSTED:
|
|
49
52
|
raise StopIteration
|
|
50
53
|
return result
|
|
51
54
|
|
|
@@ -62,11 +65,14 @@ class ResultSet:
|
|
|
62
65
|
|
|
63
66
|
def one(self):
|
|
64
67
|
while not self.done.done():
|
|
65
|
-
|
|
66
|
-
return self.stream.
|
|
68
|
+
try:
|
|
69
|
+
return self.stream.get(timeout=0.1)
|
|
70
|
+
except queue.Empty:
|
|
71
|
+
pass
|
|
67
72
|
if not self.stream.empty():
|
|
68
73
|
return self.stream.get_nowait()
|
|
69
|
-
|
|
74
|
+
self.done.result()
|
|
75
|
+
return _EXHAUSTED
|
|
70
76
|
|
|
71
77
|
def all(self):
|
|
72
78
|
future = Future()
|
|
@@ -79,7 +85,7 @@ class ResultSet:
|
|
|
79
85
|
else:
|
|
80
86
|
results = []
|
|
81
87
|
while not self.stream.empty():
|
|
82
|
-
results
|
|
88
|
+
results.append(self.stream.get_nowait())
|
|
83
89
|
future.set_result(results)
|
|
84
90
|
|
|
85
91
|
self.done.add_done_callback(cb)
|
|
@@ -17,81 +17,13 @@
|
|
|
17
17
|
# under the License.
|
|
18
18
|
#
|
|
19
19
|
|
|
20
|
-
import
|
|
21
|
-
import logging
|
|
22
|
-
import struct
|
|
23
|
-
import io
|
|
24
|
-
|
|
20
|
+
from gremlin_python.driver.connection import GremlinServerError
|
|
25
21
|
from gremlin_python.process.traversal import Traverser
|
|
26
|
-
|
|
27
|
-
try:
|
|
28
|
-
import ujson as json
|
|
29
|
-
if int(json.__version__[0]) < 2:
|
|
30
|
-
logging.warning("Detected ujson version below 2.0.0. This is not recommended as precision may be lost.")
|
|
31
|
-
except ImportError:
|
|
32
|
-
import json
|
|
33
|
-
|
|
34
|
-
from gremlin_python.structure.io import graphbinaryV4, graphsonV4
|
|
22
|
+
from gremlin_python.structure.io import graphbinaryV4
|
|
35
23
|
from gremlin_python.structure.io.util import Marker
|
|
36
24
|
|
|
37
25
|
__author__ = 'David M. Brown (davebshow@gmail.com), Lyndon Bauto (lyndonb@bitquilltech.com)'
|
|
38
26
|
|
|
39
|
-
"""
|
|
40
|
-
GraphSONV4
|
|
41
|
-
"""
|
|
42
|
-
|
|
43
|
-
class GraphSONSerializersV4(object):
|
|
44
|
-
"""
|
|
45
|
-
Message serializer for GraphSON. Allow users to pass custom reader,
|
|
46
|
-
writer, and version kwargs for custom serialization. Otherwise,
|
|
47
|
-
use current GraphSON version as default.
|
|
48
|
-
"""
|
|
49
|
-
|
|
50
|
-
# KEEP TRACK OF CURRENT DEFAULTS
|
|
51
|
-
DEFAULT_READER_CLASS = graphsonV4.GraphSONReader
|
|
52
|
-
DEFAULT_WRITER_CLASS = graphsonV4.GraphSONWriter
|
|
53
|
-
DEFAULT_VERSION = b"application/vnd.gremlin-v4.0+json"
|
|
54
|
-
|
|
55
|
-
def __init__(self, reader=None, writer=None, version=None):
|
|
56
|
-
if not version:
|
|
57
|
-
version = self.DEFAULT_VERSION
|
|
58
|
-
self._version = version
|
|
59
|
-
if not reader:
|
|
60
|
-
reader = self.DEFAULT_READER_CLASS()
|
|
61
|
-
self._graphson_reader = reader
|
|
62
|
-
if not writer:
|
|
63
|
-
writer = self.DEFAULT_WRITER_CLASS()
|
|
64
|
-
self._graphson_writer = writer
|
|
65
|
-
|
|
66
|
-
@property
|
|
67
|
-
def version(self):
|
|
68
|
-
"""Read only property"""
|
|
69
|
-
return self._version
|
|
70
|
-
|
|
71
|
-
def serialize_message(self, request_message):
|
|
72
|
-
message = self.build_message(request_message.fields, request_message.gremlin)
|
|
73
|
-
return message
|
|
74
|
-
|
|
75
|
-
def build_message(self, fields, gremlin):
|
|
76
|
-
message = {
|
|
77
|
-
'gremlin': gremlin # gremlin wil always be a gremlin lang string script
|
|
78
|
-
}
|
|
79
|
-
for k, v in fields.items():
|
|
80
|
-
message[k] = self._graphson_writer.to_dict(v)
|
|
81
|
-
return self.finalize_message(message)
|
|
82
|
-
|
|
83
|
-
def finalize_message(self, message):
|
|
84
|
-
message = json.dumps(message)
|
|
85
|
-
return message
|
|
86
|
-
|
|
87
|
-
def deserialize_message(self, message, is_first_chunk=False):
|
|
88
|
-
if is_first_chunk:
|
|
89
|
-
msg = json.loads(message if isinstance(message, str) else message.decode('utf-8'))
|
|
90
|
-
return self._graphson_reader.to_object(msg)
|
|
91
|
-
else:
|
|
92
|
-
# graphSON does not stream, all results are aggregated inside the first chunk
|
|
93
|
-
return ""
|
|
94
|
-
|
|
95
27
|
"""
|
|
96
28
|
GraphBinaryV4
|
|
97
29
|
"""
|
|
@@ -100,23 +32,27 @@ class GraphBinarySerializersV4(object):
|
|
|
100
32
|
DEFAULT_WRITER_CLASS = graphbinaryV4.GraphBinaryWriter
|
|
101
33
|
DEFAULT_VERSION = b"application/vnd.graphbinary-v4.0"
|
|
102
34
|
|
|
103
|
-
max_int64 = 0xFFFFFFFFFFFFFFFF
|
|
104
|
-
header_struct = struct.Struct('>b32sBQQ')
|
|
105
|
-
header_pack = header_struct.pack
|
|
106
35
|
int_pack = graphbinaryV4.int32_pack
|
|
107
|
-
int32_unpack = struct.Struct(">i").unpack
|
|
108
36
|
|
|
109
|
-
def __init__(self, reader=None, writer=None, version=None):
|
|
37
|
+
def __init__(self, reader=None, writer=None, version=None, pdt_registry=None):
|
|
110
38
|
if not version:
|
|
111
39
|
version = self.DEFAULT_VERSION
|
|
112
40
|
self._version = version
|
|
113
41
|
if not reader:
|
|
114
|
-
reader = self.DEFAULT_READER_CLASS()
|
|
42
|
+
reader = self.DEFAULT_READER_CLASS(pdt_registry=pdt_registry)
|
|
115
43
|
self._graphbinary_reader = reader
|
|
116
44
|
if not writer:
|
|
117
45
|
writer = self.DEFAULT_WRITER_CLASS()
|
|
118
46
|
self._graphbinary_writer = writer
|
|
119
|
-
|
|
47
|
+
|
|
48
|
+
def configure_pdt_registry(self, pdt_registry):
|
|
49
|
+
if self._graphbinary_reader.pdt_registry is None:
|
|
50
|
+
self._graphbinary_reader.pdt_registry = pdt_registry
|
|
51
|
+
else:
|
|
52
|
+
self._graphbinary_reader.pdt_registry._composite_adapters_by_name.update(pdt_registry._composite_adapters_by_name)
|
|
53
|
+
self._graphbinary_reader.pdt_registry._composite_adapters_by_class.update(pdt_registry._composite_adapters_by_class)
|
|
54
|
+
self._graphbinary_reader.pdt_registry._primitive_adapters_by_name.update(pdt_registry._primitive_adapters_by_name)
|
|
55
|
+
self._graphbinary_reader.pdt_registry._primitive_adapters_by_class.update(pdt_registry._primitive_adapters_by_class)
|
|
120
56
|
|
|
121
57
|
@property
|
|
122
58
|
def version(self):
|
|
@@ -153,58 +89,42 @@ class GraphBinarySerializersV4(object):
|
|
|
153
89
|
|
|
154
90
|
return bytes(ba)
|
|
155
91
|
|
|
156
|
-
def
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
'data': result}
|
|
174
|
-
}
|
|
175
|
-
status_code = self.int32_unpack(b.read(4))[0] # status code
|
|
176
|
-
status_msg = self._graphbinary_reader.to_object(b, graphbinaryV4.DataType.string, nullable=True)
|
|
177
|
-
status_ex = self._graphbinary_reader.to_object(b, graphbinaryV4.DataType.string, nullable=True)
|
|
178
|
-
# meta_attrs = self._graphbinary_reader.to_object(b, graphbinaryV4.DataType.map, nullable=False)
|
|
179
|
-
|
|
180
|
-
b.close()
|
|
181
|
-
|
|
182
|
-
msg = {'status': {'code': status_code,
|
|
183
|
-
'message': status_msg,
|
|
184
|
-
'exception': status_ex},
|
|
185
|
-
'result': {'meta': {},
|
|
186
|
-
'data': result}}
|
|
187
|
-
|
|
188
|
-
return msg
|
|
189
|
-
|
|
190
|
-
def read_payload(self, buffer):
|
|
191
|
-
results = []
|
|
192
|
-
readable = True
|
|
193
|
-
while buffer.readable(): # find method or way to access readable bytes without using buffer.getvalue()
|
|
194
|
-
if buffer.tell() == len(buffer.getvalue()):
|
|
195
|
-
readable = False
|
|
92
|
+
def deserialize_response_stream(self, stream):
|
|
93
|
+
"""
|
|
94
|
+
Yield each result item from a GraphBinary response stream as it is read
|
|
95
|
+
off the wire, then raise ``GremlinServerError`` if the trailing status
|
|
96
|
+
is not a success code. ``Connection._receive`` dispatches through this
|
|
97
|
+
method so custom response serializers can replace GraphBinary parsing.
|
|
98
|
+
"""
|
|
99
|
+
reader = self._graphbinary_reader
|
|
100
|
+
|
|
101
|
+
# Response header: version byte + flags byte
|
|
102
|
+
stream.read(1)
|
|
103
|
+
flags = stream.read(1)[0]
|
|
104
|
+
bulked = flags == 0x01
|
|
105
|
+
|
|
106
|
+
while True:
|
|
107
|
+
obj = reader.to_object(stream)
|
|
108
|
+
if obj == Marker.end_of_stream():
|
|
196
109
|
break
|
|
197
|
-
if
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
self._bulked = False # no more data expected, reset bulked flag
|
|
201
|
-
break
|
|
202
|
-
bulk = self._graphbinary_reader.to_object(buffer)
|
|
203
|
-
results.append(Traverser(item, bulk))
|
|
110
|
+
if bulked:
|
|
111
|
+
bulk = reader.to_object(stream)
|
|
112
|
+
yield Traverser(obj, bulk)
|
|
204
113
|
else:
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
114
|
+
yield obj
|
|
115
|
+
|
|
116
|
+
# Trailer: status code, message, exception
|
|
117
|
+
status_code = graphbinaryV4.int32_unpack(stream.read(4))
|
|
118
|
+
msg_is_null = stream.read(1)[0] == 0x01
|
|
119
|
+
status_message = '' if msg_is_null else reader.to_object(
|
|
120
|
+
stream, graphbinaryV4.DataType.string, False)
|
|
121
|
+
exc_is_null = stream.read(1)[0] == 0x01
|
|
122
|
+
status_exception = '' if exc_is_null else reader.to_object(
|
|
123
|
+
stream, graphbinaryV4.DataType.string, False)
|
|
124
|
+
|
|
125
|
+
if status_code not in (200, 204):
|
|
126
|
+
raise GremlinServerError({
|
|
127
|
+
'code': status_code,
|
|
128
|
+
'message': status_message,
|
|
129
|
+
'exception': status_exception
|
|
130
|
+
})
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Licensed to the Apache Software Foundation (ASF) under one
|
|
3
|
+
# or more contributor license agreements. See the NOTICE file
|
|
4
|
+
# distributed with this work for additional information
|
|
5
|
+
# regarding copyright ownership. The ASF licenses this file
|
|
6
|
+
# to you under the Apache License, Version 2.0 (the
|
|
7
|
+
# "License"); you may not use this file except in compliance
|
|
8
|
+
# with the License. You may obtain a copy of the License at
|
|
9
|
+
#
|
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
+
#
|
|
12
|
+
# Unless required by applicable law or agreed to in writing,
|
|
13
|
+
# software distributed under the License is distributed on an
|
|
14
|
+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
15
|
+
# KIND, either express or implied. See the License for the
|
|
16
|
+
# specific language governing permissions and limitations
|
|
17
|
+
# under the License.
|
|
18
|
+
#
|
|
19
|
+
import logging
|
|
20
|
+
|
|
21
|
+
from gremlin_python.driver.remote_connection import RemoteConnection, RemoteTraversal
|
|
22
|
+
|
|
23
|
+
log = logging.getLogger("gremlinpython")
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class Transaction:
|
|
27
|
+
"""Controls an explicit remote transaction. A thin wrapper around a Client
|
|
28
|
+
that adds transaction lifecycle (begin/commit/rollback/close) and attaches
|
|
29
|
+
a transactionId to every request.
|
|
30
|
+
|
|
31
|
+
Created via Client.transact() or g.tx(). The traversal source (g alias)
|
|
32
|
+
is inherited from the Client and cannot be changed.
|
|
33
|
+
|
|
34
|
+
Transactions are short-lived and single-use. After commit or rollback,
|
|
35
|
+
the transaction ID is invalid and the object cannot be reused.
|
|
36
|
+
|
|
37
|
+
This class is NOT thread-safe.
|
|
38
|
+
"""
|
|
39
|
+
|
|
40
|
+
def __init__(self, client):
|
|
41
|
+
self._client = client
|
|
42
|
+
self._transaction_id = None
|
|
43
|
+
self._is_open = False
|
|
44
|
+
self._failed = False
|
|
45
|
+
|
|
46
|
+
def begin(self):
|
|
47
|
+
"""Starts the transaction and returns a transaction-bound GraphTraversalSource.
|
|
48
|
+
|
|
49
|
+
The returned GTS can be used to submit traversals within this transaction.
|
|
50
|
+
Users of the driver-level API (client.transact()) may ignore the return
|
|
51
|
+
value and use submit() directly instead.
|
|
52
|
+
|
|
53
|
+
begin() is idempotent: calling it while a transaction is already open does not
|
|
54
|
+
send a second begin to the server and does not raise - it reuses the existing
|
|
55
|
+
transaction ID and returns a source bound to the same transaction. A transaction
|
|
56
|
+
is single-use, so calling begin() after it has been closed raises.
|
|
57
|
+
"""
|
|
58
|
+
if self._failed:
|
|
59
|
+
raise Exception("Transaction is closed and cannot be reused; begin a new transaction")
|
|
60
|
+
|
|
61
|
+
# idempotent: if a transaction is already open, reuse the existing transactionId without
|
|
62
|
+
# sending a second begin to the server, and return a source bound to the same transaction
|
|
63
|
+
if not self._is_open:
|
|
64
|
+
try:
|
|
65
|
+
result = self._client.submit("g.tx().begin()")
|
|
66
|
+
results = result.all().result()
|
|
67
|
+
except Exception:
|
|
68
|
+
self._failed = True
|
|
69
|
+
raise
|
|
70
|
+
|
|
71
|
+
if not results:
|
|
72
|
+
self._failed = True
|
|
73
|
+
raise Exception("Server did not return transaction ID")
|
|
74
|
+
|
|
75
|
+
result_map = results[0]
|
|
76
|
+
if isinstance(result_map, dict):
|
|
77
|
+
self._transaction_id = result_map.get('transactionId')
|
|
78
|
+
else:
|
|
79
|
+
self._failed = True
|
|
80
|
+
raise Exception("Server did not return transaction ID in expected format")
|
|
81
|
+
|
|
82
|
+
if not self._transaction_id:
|
|
83
|
+
self._failed = True
|
|
84
|
+
raise Exception("Server returned empty transaction ID")
|
|
85
|
+
|
|
86
|
+
self._is_open = True
|
|
87
|
+
self._client.track_transaction(self)
|
|
88
|
+
|
|
89
|
+
# Return a GraphTraversalSource bound to this transaction via
|
|
90
|
+
# TransactionRemoteConnection. Inline imports avoid circular dependencies
|
|
91
|
+
# between driver/ and process/ packages.
|
|
92
|
+
from gremlin_python.process.graph_traversal import GraphTraversalSource
|
|
93
|
+
from gremlin_python.process.traversal import TraversalStrategies, GremlinLang
|
|
94
|
+
from gremlin_python.driver.remote_connection import RemoteStrategy
|
|
95
|
+
|
|
96
|
+
tx_connection = TransactionRemoteConnection(self)
|
|
97
|
+
strategies = TraversalStrategies()
|
|
98
|
+
strategies.add_strategies([RemoteStrategy(tx_connection)])
|
|
99
|
+
return GraphTraversalSource(None, strategies, GremlinLang())
|
|
100
|
+
|
|
101
|
+
def submit(self, gremlin, parameters=None, request_options=None):
|
|
102
|
+
"""Submits a gremlin-lang string within this transaction.
|
|
103
|
+
|
|
104
|
+
The transactionId is automatically attached. Has the same signature
|
|
105
|
+
as Client.submit() so both can be used interchangeably.
|
|
106
|
+
"""
|
|
107
|
+
if not self._is_open:
|
|
108
|
+
raise Exception("Transaction is not open")
|
|
109
|
+
opts = {'transactionId': self._transaction_id}
|
|
110
|
+
if request_options:
|
|
111
|
+
opts.update(request_options)
|
|
112
|
+
return self._client.submit(gremlin, parameters=parameters, request_options=opts)
|
|
113
|
+
|
|
114
|
+
def commit(self):
|
|
115
|
+
"""Commits the transaction."""
|
|
116
|
+
self._close_transaction("g.tx().commit()")
|
|
117
|
+
|
|
118
|
+
def rollback(self):
|
|
119
|
+
"""Rolls back the transaction."""
|
|
120
|
+
self._close_transaction("g.tx().rollback()")
|
|
121
|
+
|
|
122
|
+
def _close_transaction(self, script):
|
|
123
|
+
if not self._is_open:
|
|
124
|
+
raise Exception("Transaction is not open")
|
|
125
|
+
self._client.submit(script, request_options={'transactionId': self._transaction_id}).all().result()
|
|
126
|
+
self._is_open = False
|
|
127
|
+
self._failed = True # Terminal state: transaction cannot be reused
|
|
128
|
+
self._client.untrack_transaction(self)
|
|
129
|
+
|
|
130
|
+
@property
|
|
131
|
+
def is_open(self):
|
|
132
|
+
return self._is_open
|
|
133
|
+
|
|
134
|
+
@property
|
|
135
|
+
def transaction_id(self):
|
|
136
|
+
return self._transaction_id
|
|
137
|
+
|
|
138
|
+
def close(self):
|
|
139
|
+
if self._is_open:
|
|
140
|
+
self.rollback()
|
|
141
|
+
|
|
142
|
+
def __enter__(self):
|
|
143
|
+
return self
|
|
144
|
+
|
|
145
|
+
def __exit__(self, exc_type, exc_val, exc_tb):
|
|
146
|
+
if self._is_open:
|
|
147
|
+
self.rollback()
|
|
148
|
+
return False
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
class TransactionRemoteConnection(RemoteConnection):
|
|
152
|
+
"""A RemoteConnection that attaches transactionId to all requests submitted
|
|
153
|
+
through the traversal API (g.tx().begin() -> gtx.addV()...).
|
|
154
|
+
|
|
155
|
+
This bridges the traversal machinery (which calls RemoteConnection.submit)
|
|
156
|
+
to the Transaction (which injects the transactionId).
|
|
157
|
+
"""
|
|
158
|
+
|
|
159
|
+
def __init__(self, transaction):
|
|
160
|
+
super().__init__(
|
|
161
|
+
transaction._client._url,
|
|
162
|
+
transaction._client._traversal_source)
|
|
163
|
+
self._transaction = transaction
|
|
164
|
+
|
|
165
|
+
def submit(self, gremlin_lang):
|
|
166
|
+
if not self._transaction.is_open:
|
|
167
|
+
raise Exception("Transaction is not open")
|
|
168
|
+
|
|
169
|
+
from gremlin_python.driver.driver_remote_connection import DriverRemoteConnection
|
|
170
|
+
request_options = DriverRemoteConnection.extract_request_options(gremlin_lang)
|
|
171
|
+
request_options['transactionId'] = self._transaction.transaction_id
|
|
172
|
+
|
|
173
|
+
result_set = self._transaction._client.submit(
|
|
174
|
+
gremlin_lang.get_gremlin(), request_options=request_options)
|
|
175
|
+
return RemoteTraversal(result_set)
|
|
176
|
+
|
|
177
|
+
def is_closed(self):
|
|
178
|
+
return not self._transaction.is_open
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
#
|
|
19
19
|
import platform
|
|
20
20
|
|
|
21
|
-
gremlin_version = "4.0.0-beta.
|
|
21
|
+
gremlin_version = "4.0.0-beta.3" # DO NOT MODIFY - Configured automatically by Maven Replacer Plugin
|
|
22
22
|
|
|
23
23
|
def _generate_user_agent():
|
|
24
24
|
application_name = "NotAvailable"
|