Skip to content

Commit f3fbef3

Browse files
Integrate Python driver examples into automated build process
- Add examples execution to gremlin-python-integration-tests container - Make server URLs configurable via environment variables - Add cleanup for mutating examples - Graph binding detection (gmodern in CI, g locally) - Handle SSL certificates and Kerberos failures - Build fails if any example fails to execute
1 parent 8acad04 commit f3fbef3

File tree

5 files changed

+67
-12
lines changed

5 files changed

+67
-12
lines changed

CHANGELOG.asciidoc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ image::https://raw.githubusercontent.com/apache/tinkerpop/master/docs/static/ima
2828
* Added properties to `Element` objects found in a `Path` for GraphSON v2 and v3 and GraphBinary.
2929
* Fixed edge properties for GraphBinary which were not deserializing properly.
3030
* Bump netty to 4.1.125.Final
31+
* Integrated Python driver examples into automated build process to ensure examples remain functional.
3132
3233
[[release-3-7-4]]
3334
=== TinkerPop 3.7.4 (Release Date: August 1, 2025)

gremlin-python/docker-compose.yml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,12 @@ services:
7575
&& python3 ./setup.py test
7676
&& python3 ./setup.py install
7777
&& radish -f dots -e -t -b ./radish ./gremlin-test --user-data='serializer=application/vnd.gremlin-v3.0+json'
78-
&& radish -f dots -e -t -b ./radish ./gremlin-test --user-data='serializer=application/vnd.graphbinary-v1.0';
78+
&& radish -f dots -e -t -b ./radish ./gremlin-test --user-data='serializer=application/vnd.graphbinary-v1.0'
79+
&& echo 'Running examples...'
80+
&& python3 examples/basic_gremlin.py
81+
&& python3 examples/connections.py
82+
&& python3 examples/modern_traversals.py
83+
&& echo 'All examples completed successfully';
7984
EXIT_CODE=$$?; chown -R `stat -c "%u:%g" .` .; exit $$EXIT_CODE"
8085
depends_on:
8186
gremlin-server-test-python:

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

Lines changed: 9 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

@@ -25,9 +26,13 @@
2526

2627

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

33+
# drop existing vertices
34+
g.V().drop().iterate()
35+
3136
# basic Gremlin: adding and retrieving data
3237
v1 = g.add_v('person').property('name', 'marko').next()
3338
v2 = g.add_v('person').property('name', 'stephen').next()
@@ -47,6 +52,9 @@ def main():
4752
for person in people_marko_knows:
4853
print("marko knows " + person)
4954

55+
# clean added data
56+
g.V().drop().iterate()
57+
5058
rc.close()
5159

5260

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

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

1818
import sys
19+
import os
20+
import ssl
1921

2022
sys.path.append("..")
2123

2224
from gremlin_python.process.anonymous_traversal import traversal
2325
from gremlin_python.process.strategies import *
2426
from gremlin_python.driver.driver_remote_connection import DriverRemoteConnection
2527
from gremlin_python.driver.serializer import GraphBinarySerializersV1
28+
from gremlin_python.driver.aiohttp.transport import AiohttpTransport
2629

2730

2831
def main():
@@ -40,7 +43,8 @@ def with_remote():
4043
#
4144
# which starts it in "console" mode with an empty in-memory TinkerGraph ready to go bound to a
4245
# variable named "g" as referenced in the following line.
43-
rc = DriverRemoteConnection('ws://localhost:8182/gremlin', 'g')
46+
server_url = os.getenv('GREMLIN_SERVER_URL', 'ws://localhost:8182/gremlin').format(45940)
47+
rc = DriverRemoteConnection(server_url, 'g')
4448
g = traversal().with_remote(rc)
4549

4650
# drop existing vertices
@@ -57,32 +61,57 @@ def with_remote():
5761

5862
# connecting with plain text authentication
5963
def with_auth():
60-
rc = DriverRemoteConnection('ws://localhost:8182/gremlin', 'g', username='stephen', password='password')
64+
server_url = os.getenv('GREMLIN_SERVER_BASIC_AUTH_URL', 'ws://localhost:8182/gremlin').format(45941)
65+
# turn off certificate verification for testing purposes only
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', username='stephen', password='password',
70+
transport_factory=lambda: AiohttpTransport(ssl_options=ssl_opts))
6171
g = traversal().with_remote(rc)
6272

73+
# drop existing vertices
74+
g.V().drop().iterate()
75+
6376
v = g.add_v().iterate()
6477
count = g.V().count().next()
6578
print("Vertex count: " + str(count))
6679

80+
# clean added data
81+
g.V().drop().iterate()
6782
rc.close()
6883

6984

7085
# connecting with Kerberos SASL authentication
7186
def with_kerberos():
72-
rc = DriverRemoteConnection('ws://localhost:8182/gremlin', 'g', kerberized_service='[email protected]')
73-
g = traversal().with_remote(rc)
87+
server_url = os.getenv('GREMLIN_SERVER_URL', 'ws://localhost:8182/gremlin').format(45942)
88+
kerberos_hostname = os.getenv('KRB_HOSTNAME', 'gremlin-server-test')
89+
kerberized_service = f'test-service@{kerberos_hostname}'
90+
91+
try:
92+
rc = DriverRemoteConnection(server_url, 'g', kerberized_service=kerberized_service)
93+
g = traversal().with_remote(rc)
7494

75-
v = g.add_v().iterate()
76-
count = g.V().count().next()
77-
print("Vertex count: " + str(count))
95+
# drop existing vertices
96+
g.V().drop().iterate()
7897

79-
rc.close()
98+
v = g.add_v().iterate()
99+
count = g.V().count().next()
100+
print("Vertex count: " + str(count))
101+
102+
# clean added data
103+
g.V().drop().iterate()
104+
rc.close()
105+
except Exception as e:
106+
print(f"Kerberos authentication failed (expected in test environment): {e}")
107+
# This is expected to fail in CI without proper Kerberos setup
80108

81109

82110
# connecting with customized configurations
83111
def with_configs():
112+
server_url = os.getenv('GREMLIN_SERVER_URL', 'ws://localhost:8182/gremlin').format(45940)
84113
rc = DriverRemoteConnection(
85-
'ws://localhost:8182/gremlin', 'g',
114+
server_url, 'g',
86115
username="", password="", kerberized_service='',
87116
message_serializer=GraphBinarySerializersV1(), graphson_reader=None,
88117
graphson_writer=None, headers=None, session=None,
@@ -94,6 +123,9 @@ def with_configs():
94123
count = g.V().count().next()
95124
print("Vertex count: " + str(count))
96125

126+
# clean added data
127+
g.V().drop().iterate()
128+
97129
rc.close()
98130

99131

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

Lines changed: 10 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,15 @@ 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+
server_url = os.getenv('GREMLIN_SERVER_URL', 'ws://localhost:8182/gremlin').format(45940)
36+
37+
# CI uses port 45940 with gmodern binding, local uses 8182 with g binding
38+
if ':45940' in server_url:
39+
graph_binding = 'gmodern' # CI environment
40+
else:
41+
graph_binding = 'g' # Local environment
42+
43+
rc = DriverRemoteConnection(server_url, graph_binding)
3544
g = traversal().with_remote(rc)
3645

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

0 commit comments

Comments
 (0)