Skip to content

Commit c97d963

Browse files
Integrate Python driver examples into automated build process (master) (#3280)
This is a follow-up to #3231 and includes the integration of Python driver examples into the automated build process, as well as the updates needed to make the examples work against the master code. Changes Made: - Added example execution to gremlin-python-integration-tests container in docker-compose.yml - Made server URLs configurable via environment variables - Added configurable vertex labels via VERTEX_LABEL environment variable - Update root-level examples to be consistent with dev-level examples Updates for master: - Updated protocol from WebSocket (ws://) to HTTP - Updated serializer from GraphBinarySerializersV1 to GraphBinarySerializersV4 - Fixed edge creation syntax using __.V() wrapper for TinkerPop 4 from()/to() compatibility - Migrated example authentication from parameters to auth functions
1 parent 2df5882 commit c97d963

File tree

7 files changed

+88
-65
lines changed

7 files changed

+88
-65
lines changed

CHANGELOG.asciidoc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ image::https://raw.githubusercontent.com/apache/tinkerpop/master/docs/static/ima
8181
* Removed `minSize` setting for Gremlin Driver connection pool since connections are now short-lived HTTP connections
8282
* Added `idleConnectionTimeout` setting for Gremlin Driver and automatic closing of idle connections
8383
* Enabled TCP Keep-Alive in GremlinServer.
84+
* Updated Python GLV examples to use HTTP and to run as part of the integration tests.
8485
8586
== TinkerPop 3.8.0 (Grix Greven)
8687

gremlin-examples/gremlin-python/basic_gremlin.py

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,27 +23,29 @@
2323
from gremlin_python.process.strategies import *
2424
from gremlin_python.driver.driver_remote_connection import DriverRemoteConnection
2525

26+
VERTEX_LABEL = 'person'
2627

2728
def main():
28-
rc = DriverRemoteConnection('ws://localhost:8182/gremlin', 'g')
29+
server_url = 'ws://localhost:8182/gremlin'
30+
rc = DriverRemoteConnection(server_url, 'g')
2931
g = traversal().with_remote(rc)
3032

3133
# basic Gremlin: adding and retrieving data
32-
v1 = g.add_v('person').property('name', 'marko').next()
33-
v2 = g.add_v('person').property('name', 'stephen').next()
34-
v3 = g.add_v('person').property('name', 'vadas').next()
34+
v1 = g.add_v(VERTEX_LABEL).property('name', 'marko').next()
35+
v2 = g.add_v(VERTEX_LABEL).property('name', 'stephen').next()
36+
v3 = g.add_v(VERTEX_LABEL).property('name', 'vadas').next()
3537

3638
# be sure to use a terminating step like next() or iterate() so that the traversal "executes"
3739
# iterate() does not return any data and is used to just generate side-effects (i.e. write data to the database)
3840
g.V(v1).add_e('knows').to(v2).property('weight', 0.75).iterate()
3941
g.V(v1).add_e('knows').to(v3).property('weight', 0.75).iterate()
4042

4143
# retrieve the data from the "marko" vertex
42-
marko = g.V().has('person', 'name', 'marko').values('name').next()
44+
marko = g.V().has(VERTEX_LABEL, 'name', 'marko').values('name').next()
4345
print("name: " + marko)
4446

4547
# find the "marko" vertex and then traverse to the people he "knows" and return their data
46-
people_marko_knows = g.V().has('person', 'name', 'marko').out('knows').values('name').to_list()
48+
people_marko_knows = g.V().has(VERTEX_LABEL, 'name', 'marko').out('knows').values('name').to_list()
4749
for person in people_marko_knows:
4850
print("marko knows " + person)
4951

gremlin-examples/gremlin-python/connections.py

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
from gremlin_python.driver.driver_remote_connection import DriverRemoteConnection
2525
from gremlin_python.driver.serializer import GraphBinarySerializersV1
2626

27+
VERTEX_LABEL = 'connection'
2728

2829
def main():
2930
with_remote()
@@ -40,15 +41,13 @@ def with_remote():
4041
#
4142
# which starts it in "console" mode with an empty in-memory TinkerGraph ready to go bound to a
4243
# variable named "g" as referenced in the following line.
43-
rc = DriverRemoteConnection('ws://localhost:8182/gremlin', 'g')
44+
server_url = 'ws://localhost:8182/gremlin'
45+
rc = DriverRemoteConnection(server_url, 'g')
4446
g = traversal().with_remote(rc)
4547

46-
# drop existing vertices
47-
g.V().drop().iterate()
48-
4948
# simple query to verify connection
50-
v = g.add_v().iterate()
51-
count = g.V().count().next()
49+
v = g.add_v(VERTEX_LABEL).iterate()
50+
count = g.V().has_label(VERTEX_LABEL).count().next()
5251
print("Vertex count: " + str(count))
5352

5453
# cleanup
@@ -57,41 +56,44 @@ def with_remote():
5756

5857
# connecting with plain text authentication
5958
def with_auth():
60-
rc = DriverRemoteConnection('ws://localhost:8182/gremlin', 'g', username='stephen', password='password')
59+
server_url = 'ws://localhost:8182/gremlin'
60+
rc = DriverRemoteConnection(server_url, 'g', username='stephen', password='password')
6161
g = traversal().with_remote(rc)
6262

63-
v = g.add_v().iterate()
64-
count = g.V().count().next()
63+
v = g.add_v(VERTEX_LABEL).iterate()
64+
count = g.V().has_label(VERTEX_LABEL).count().next()
6565
print("Vertex count: " + str(count))
6666

6767
rc.close()
6868

6969

7070
# connecting with Kerberos SASL authentication
7171
def with_kerberos():
72-
rc = DriverRemoteConnection('ws://localhost:8182/gremlin', 'g', kerberized_service='[email protected]')
72+
server_url = 'ws://localhost:8182/gremlin'
73+
rc = DriverRemoteConnection(server_url, 'g', kerberized_service='[email protected]')
7374
g = traversal().with_remote(rc)
7475

75-
v = g.add_v().iterate()
76-
count = g.V().count().next()
76+
v = g.add_v(VERTEX_LABEL).iterate()
77+
count = g.V().has_label(VERTEX_LABEL).count().next()
7778
print("Vertex count: " + str(count))
7879

7980
rc.close()
8081

8182

8283
# connecting with customized configurations
8384
def with_configs():
85+
server_url = 'ws://localhost:8182/gremlin'
8486
rc = DriverRemoteConnection(
85-
'ws://localhost:8182/gremlin', 'g',
87+
server_url, 'g',
8688
username="", password="", kerberized_service='',
8789
message_serializer=GraphBinarySerializersV1(), graphson_reader=None,
8890
graphson_writer=None, headers=None, session=None,
8991
enable_user_agent_on_connect=True
9092
)
9193
g = traversal().with_remote(rc)
9294

93-
v = g.add_v().iterate()
94-
count = g.V().count().next()
95+
v = g.add_v(VERTEX_LABEL).iterate()
96+
count = g.V().has_label(VERTEX_LABEL).count().next()
9597
print("Vertex count: " + str(count))
9698

9799
rc.close()

gremlin-python/docker-compose.yml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,12 @@ services:
6464
&& radish -f dots -e -t -b ./radish ./gremlin-test --user-data='serializer=application/vnd.graphbinary-v4.0' --user-data='parameterize=true'
6565
&& radish -f dots -e -t -b ./radish ./gremlin-test --user-data='serializer=application/vnd.graphbinary-v4.0'
6666
&& radish -f dots -e -t -b ./radish ./gremlin-test --user-data='serializer=application/vnd.gremlin-v4.0+json' --user-data='parameterize=true'
67-
&& radish -f dots -e -t -b ./radish ./gremlin-test --user-data='serializer=application/vnd.gremlin-v4.0+json';
67+
&& radish -f dots -e -t -b ./radish ./gremlin-test --user-data='serializer=application/vnd.gremlin-v4.0+json'
68+
&& echo 'Running examples...'
69+
&& python3 examples/basic_gremlin.py
70+
&& python3 examples/connections.py
71+
&& python3 examples/modern_traversals.py
72+
&& echo 'All examples completed successfully';
6873
EXIT_CODE=$$?; chown -R `stat -c "%u:%g" .` .; exit $$EXIT_CODE"
6974
depends_on:
7075
gremlin-server-test-python:

gremlin-python/src/main/python/examples/basic_gremlin.py

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,34 +16,39 @@
1616
# under the License.
1717

1818
import sys
19+
import os
1920

2021
sys.path.append("..")
2122

2223
from gremlin_python.process.anonymous_traversal import traversal
24+
from gremlin_python.process.graph_traversal import __
2325
from gremlin_python.process.strategies import *
2426
from gremlin_python.driver.driver_remote_connection import DriverRemoteConnection
2527

28+
VERTEX_LABEL = os.getenv('VERTEX_LABEL', 'person')
2629

2730
def main():
28-
rc = DriverRemoteConnection('ws://localhost:8182/gremlin', 'g')
31+
# if there is a port placeholder in the env var then we are running with docker so set appropriate port
32+
server_url = os.getenv('GREMLIN_SERVER_URL', 'http://localhost:8182/gremlin').format(45940)
33+
rc = DriverRemoteConnection(server_url, 'g')
2934
g = traversal().with_remote(rc)
3035

3136
# basic Gremlin: adding and retrieving data
32-
v1 = g.add_v('person').property('name', 'marko').next()
33-
v2 = g.add_v('person').property('name', 'stephen').next()
34-
v3 = g.add_v('person').property('name', 'vadas').next()
37+
v1 = g.add_v(VERTEX_LABEL).property('name', 'marko').next()
38+
v2 = g.add_v(VERTEX_LABEL).property('name', 'stephen').next()
39+
v3 = g.add_v(VERTEX_LABEL).property('name', 'vadas').next()
3540

3641
# be sure to use a terminating step like next() or iterate() so that the traversal "executes"
3742
# iterate() does not return any data and is used to just generate side-effects (i.e. write data to the database)
38-
g.V(v1).add_e('knows').to(v2).property('weight', 0.75).iterate()
39-
g.V(v1).add_e('knows').to(v3).property('weight', 0.75).iterate()
43+
g.V(v1).add_e('knows').to(__.V(v2)).property('weight', 0.75).iterate()
44+
g.V(v1).add_e('knows').to(__.V(v3)).property('weight', 0.75).iterate()
4045

4146
# retrieve the data from the "marko" vertex
42-
marko = g.V().has('person', 'name', 'marko').values('name').next()
47+
marko = g.V().has(VERTEX_LABEL, 'name', 'marko').values('name').next()
4348
print("name: " + marko)
4449

4550
# find the "marko" vertex and then traverse to the people he "knows" and return their data
46-
people_marko_knows = g.V().has('person', 'name', 'marko').out('knows').values('name').to_list()
51+
people_marko_knows = g.V().has(VERTEX_LABEL, 'name', 'marko').out('knows').values('name').to_list()
4752
for person in people_marko_knows:
4853
print("marko knows " + person)
4954

gremlin-python/src/main/python/examples/connections.py

Lines changed: 32 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -14,21 +14,23 @@
1414
# KIND, either express or implied. See the License for the
1515
# specific language governing permissions and limitations
1616
# under the License.
17-
17+
import ssl
1818
import sys
19+
import os
1920

2021
sys.path.append("..")
2122

2223
from gremlin_python.process.anonymous_traversal import traversal
23-
from gremlin_python.process.strategies import *
2424
from gremlin_python.driver.driver_remote_connection import DriverRemoteConnection
25-
from gremlin_python.driver.serializer import GraphBinarySerializersV1
25+
from gremlin_python.driver.aiohttp.transport import AiohttpHTTPTransport
26+
from gremlin_python.driver.auth import basic
27+
from gremlin_python.driver.serializer import GraphBinarySerializersV4
2628

29+
VERTEX_LABEL = os.getenv('VERTEX_LABEL', 'connection')
2730

2831
def main():
2932
with_remote()
3033
with_auth()
31-
with_kerberos()
3234
with_configs()
3335

3436

@@ -40,15 +42,14 @@ def with_remote():
4042
#
4143
# which starts it in "console" mode with an empty in-memory TinkerGraph ready to go bound to a
4244
# variable named "g" as referenced in the following line.
43-
rc = DriverRemoteConnection('ws://localhost:8182/gremlin', 'g')
45+
# if there is a port placeholder in the env var then we are running with docker so set appropriate port
46+
server_url = os.getenv('GREMLIN_SERVER_URL', 'http://localhost:8182/gremlin').format(45940)
47+
rc = DriverRemoteConnection(server_url, 'g')
4448
g = traversal().with_remote(rc)
4549

46-
# drop existing vertices
47-
g.V().drop().iterate()
48-
4950
# simple query to verify connection
50-
v = g.add_v().iterate()
51-
count = g.V().count().next()
51+
v = g.add_v(VERTEX_LABEL).iterate()
52+
count = g.V().has_label(VERTEX_LABEL).count().next()
5253
print("Vertex count: " + str(count))
5354

5455
# cleanup
@@ -57,45 +58,42 @@ def with_remote():
5758

5859
# connecting with plain text authentication
5960
def with_auth():
60-
rc = DriverRemoteConnection('ws://localhost:8182/gremlin', 'g', username='stephen', password='password')
61+
# if there is a port placeholder in the env var then we are running with docker so set appropriate port
62+
server_url = os.getenv('GREMLIN_SERVER_BASIC_AUTH_URL', 'http://localhost:8182/gremlin').format(45941)
63+
64+
# disable SSL certificate verification for CI environments
65+
if ':45941' in server_url:
66+
ssl_opts = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
67+
ssl_opts.check_hostname = False
68+
ssl_opts.verify_mode = ssl.CERT_NONE
69+
rc = DriverRemoteConnection(server_url, 'g', auth=basic('stephen', 'password'),
70+
transport_factory=lambda: AiohttpHTTPTransport(ssl_options=ssl_opts))
71+
else:
72+
rc = DriverRemoteConnection(server_url, 'g', auth=basic('stephen', 'password'))
73+
6174
g = traversal().with_remote(rc)
6275

63-
v = g.add_v().iterate()
64-
count = g.V().count().next()
76+
v = g.add_v(VERTEX_LABEL).iterate()
77+
count = g.V().has_label(VERTEX_LABEL).count().next()
6578
print("Vertex count: " + str(count))
6679

6780
rc.close()
6881

69-
70-
# connecting with Kerberos SASL authentication
71-
def with_kerberos():
72-
rc = DriverRemoteConnection('ws://localhost:8182/gremlin', 'g', kerberized_service='[email protected]')
73-
g = traversal().with_remote(rc)
74-
75-
v = g.add_v().iterate()
76-
count = g.V().count().next()
77-
print("Vertex count: " + str(count))
78-
79-
rc.close()
80-
81-
8282
# connecting with customized configurations
8383
def with_configs():
84+
server_url = os.getenv('GREMLIN_SERVER_URL', 'http://localhost:8182/gremlin').format(45940)
8485
rc = DriverRemoteConnection(
85-
'ws://localhost:8182/gremlin', 'g',
86-
username="", password="", kerberized_service='',
87-
message_serializer=GraphBinarySerializersV1(), graphson_reader=None,
88-
graphson_writer=None, headers=None, session=None,
89-
enable_user_agent_on_connect=True
86+
server_url, 'g',
87+
request_serializer=GraphBinarySerializersV4(),
88+
headers=None,
9089
)
9190
g = traversal().with_remote(rc)
9291

93-
v = g.add_v().iterate()
94-
count = g.V().count().next()
92+
v = g.add_v(VERTEX_LABEL).iterate()
93+
count = g.V().has_label(VERTEX_LABEL).count().next()
9594
print("Vertex count: " + str(count))
9695

9796
rc.close()
9897

99-
10098
if __name__ == "__main__":
10199
main()

gremlin-python/src/main/python/examples/modern_traversals.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
# under the License.
1717

1818
import sys
19+
import os
1920

2021
sys.path.append("..")
2122

@@ -31,7 +32,16 @@ def main():
3132
# This example requires the Modern toy graph to be preloaded upon launching the Gremlin server.
3233
# For details, see https://tinkerpop.apache.org/docs/current/reference/#gremlin-server-docker-image and use
3334
# conf/gremlin-server-modern.yaml.
34-
rc = DriverRemoteConnection('ws://localhost:8182/gremlin', 'g')
35+
# if there is a port placeholder in the env var then we are running with docker so set appropriate port
36+
server_url = os.getenv('GREMLIN_SERVER_URL', 'http://localhost:8182/gremlin').format(45940)
37+
38+
# CI uses port 45940 with gmodern binding, local uses 8182 with g binding
39+
if ':45940' in server_url:
40+
graph_binding = 'gmodern' # CI environment
41+
else:
42+
graph_binding = 'g' # Local environment
43+
44+
rc = DriverRemoteConnection(server_url, graph_binding)
3545
g = traversal().with_remote(rc)
3646

3747
e1 = g.V(1).both_e().to_list() # (1)

0 commit comments

Comments
 (0)