This is an automated email from the ASF dual-hosted git repository.

andreac pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git


The following commit(s) were added to refs/heads/master by this push:
     new c97d963c1a Integrate Python driver examples into automated build 
process (master) (#3280)
c97d963c1a is described below

commit c97d963c1a4c4fc09f94b5e24174d9f1d81ca5c4
Author: kirill-stepanishin <[email protected]>
AuthorDate: Thu Nov 20 16:57:42 2025 -0800

    Integrate Python driver examples into automated build process (master) 
(#3280)
    
    This is a follow-up to https://github.com/apache/tinkerpop/pull/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
---
 CHANGELOG.asciidoc                                 |  1 +
 gremlin-examples/gremlin-python/basic_gremlin.py   | 14 +++--
 gremlin-examples/gremlin-python/connections.py     | 32 ++++++-----
 gremlin-python/docker-compose.yml                  |  7 ++-
 .../src/main/python/examples/basic_gremlin.py      | 21 ++++---
 .../src/main/python/examples/connections.py        | 66 +++++++++++-----------
 .../src/main/python/examples/modern_traversals.py  | 12 +++-
 7 files changed, 88 insertions(+), 65 deletions(-)

diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc
index 271a1d8614..8df83871d4 100644
--- a/CHANGELOG.asciidoc
+++ b/CHANGELOG.asciidoc
@@ -81,6 +81,7 @@ 
image::https://raw.githubusercontent.com/apache/tinkerpop/master/docs/static/ima
 * Removed `minSize` setting for Gremlin Driver connection pool since 
connections are now short-lived HTTP connections
 * Added `idleConnectionTimeout` setting for Gremlin Driver and automatic 
closing of idle connections
 * Enabled TCP Keep-Alive in GremlinServer.
+* Updated Python GLV examples to use HTTP and to run as part of the 
integration tests.
 
 == TinkerPop 3.8.0 (Grix Greven)
 
diff --git a/gremlin-examples/gremlin-python/basic_gremlin.py 
b/gremlin-examples/gremlin-python/basic_gremlin.py
index 256ed98441..c351270de8 100644
--- a/gremlin-examples/gremlin-python/basic_gremlin.py
+++ b/gremlin-examples/gremlin-python/basic_gremlin.py
@@ -23,15 +23,17 @@ from gremlin_python.process.anonymous_traversal import 
traversal
 from gremlin_python.process.strategies import *
 from gremlin_python.driver.driver_remote_connection import 
DriverRemoteConnection
 
+VERTEX_LABEL = 'person'
 
 def main():
-    rc = DriverRemoteConnection('ws://localhost:8182/gremlin', 'g')
+    server_url = 'ws://localhost:8182/gremlin'
+    rc = DriverRemoteConnection(server_url, 'g')
     g = traversal().with_remote(rc)
 
     # basic Gremlin: adding and retrieving data
-    v1 = g.add_v('person').property('name', 'marko').next()
-    v2 = g.add_v('person').property('name', 'stephen').next()
-    v3 = g.add_v('person').property('name', 'vadas').next()
+    v1 = g.add_v(VERTEX_LABEL).property('name', 'marko').next()
+    v2 = g.add_v(VERTEX_LABEL).property('name', 'stephen').next()
+    v3 = g.add_v(VERTEX_LABEL).property('name', 'vadas').next()
 
     # be sure to use a terminating step like next() or iterate() so that the 
traversal "executes"
     # iterate() does not return any data and is used to just generate 
side-effects (i.e. write data to the database)
@@ -39,11 +41,11 @@ def main():
     g.V(v1).add_e('knows').to(v3).property('weight', 0.75).iterate()
 
     # retrieve the data from the "marko" vertex
-    marko = g.V().has('person', 'name', 'marko').values('name').next()
+    marko = g.V().has(VERTEX_LABEL, 'name', 'marko').values('name').next()
     print("name: " + marko)
 
     # find the "marko" vertex and then traverse to the people he "knows" and 
return their data
-    people_marko_knows = g.V().has('person', 'name', 
'marko').out('knows').values('name').to_list()
+    people_marko_knows = g.V().has(VERTEX_LABEL, 'name', 
'marko').out('knows').values('name').to_list()
     for person in people_marko_knows:
         print("marko knows " + person)
 
diff --git a/gremlin-examples/gremlin-python/connections.py 
b/gremlin-examples/gremlin-python/connections.py
index f268e6c27d..9997a181eb 100644
--- a/gremlin-examples/gremlin-python/connections.py
+++ b/gremlin-examples/gremlin-python/connections.py
@@ -24,6 +24,7 @@ from gremlin_python.process.strategies import *
 from gremlin_python.driver.driver_remote_connection import 
DriverRemoteConnection
 from gremlin_python.driver.serializer import GraphBinarySerializersV1
 
+VERTEX_LABEL = 'connection'
 
 def main():
     with_remote()
@@ -40,15 +41,13 @@ def with_remote():
     #
     # which starts it in "console" mode with an empty in-memory TinkerGraph 
ready to go bound to a
     # variable named "g" as referenced in the following line.
-    rc = DriverRemoteConnection('ws://localhost:8182/gremlin', 'g')
+    server_url = 'ws://localhost:8182/gremlin'
+    rc = DriverRemoteConnection(server_url, 'g')
     g = traversal().with_remote(rc)
 
-    # drop existing vertices
-    g.V().drop().iterate()
-
     # simple query to verify connection
-    v = g.add_v().iterate()
-    count = g.V().count().next()
+    v = g.add_v(VERTEX_LABEL).iterate()
+    count = g.V().has_label(VERTEX_LABEL).count().next()
     print("Vertex count: " + str(count))
 
     # cleanup
@@ -57,11 +56,12 @@ def with_remote():
 
 # connecting with plain text authentication
 def with_auth():
-    rc = DriverRemoteConnection('ws://localhost:8182/gremlin', 'g', 
username='stephen', password='password')
+    server_url = 'ws://localhost:8182/gremlin'
+    rc = DriverRemoteConnection(server_url, 'g', username='stephen', 
password='password')
     g = traversal().with_remote(rc)
 
-    v = g.add_v().iterate()
-    count = g.V().count().next()
+    v = g.add_v(VERTEX_LABEL).iterate()
+    count = g.V().has_label(VERTEX_LABEL).count().next()
     print("Vertex count: " + str(count))
 
     rc.close()
@@ -69,11 +69,12 @@ def with_auth():
 
 # connecting with Kerberos SASL authentication
 def with_kerberos():
-    rc = DriverRemoteConnection('ws://localhost:8182/gremlin', 'g', 
kerberized_service='[email protected]')
+    server_url = 'ws://localhost:8182/gremlin'
+    rc = DriverRemoteConnection(server_url, 'g', 
kerberized_service='[email protected]')
     g = traversal().with_remote(rc)
 
-    v = g.add_v().iterate()
-    count = g.V().count().next()
+    v = g.add_v(VERTEX_LABEL).iterate()
+    count = g.V().has_label(VERTEX_LABEL).count().next()
     print("Vertex count: " + str(count))
 
     rc.close()
@@ -81,8 +82,9 @@ def with_kerberos():
 
 # connecting with customized configurations
 def with_configs():
+    server_url = 'ws://localhost:8182/gremlin'
     rc = DriverRemoteConnection(
-        'ws://localhost:8182/gremlin', 'g',
+        server_url, 'g',
         username="", password="", kerberized_service='',
         message_serializer=GraphBinarySerializersV1(), graphson_reader=None,
         graphson_writer=None, headers=None, session=None,
@@ -90,8 +92,8 @@ def with_configs():
     )
     g = traversal().with_remote(rc)
 
-    v = g.add_v().iterate()
-    count = g.V().count().next()
+    v = g.add_v(VERTEX_LABEL).iterate()
+    count = g.V().has_label(VERTEX_LABEL).count().next()
     print("Vertex count: " + str(count))
 
     rc.close()
diff --git a/gremlin-python/docker-compose.yml 
b/gremlin-python/docker-compose.yml
index bdc7f6332b..a1baa4809b 100644
--- a/gremlin-python/docker-compose.yml
+++ b/gremlin-python/docker-compose.yml
@@ -64,7 +64,12 @@ services:
       && radish -f dots -e -t -b ./radish ./gremlin-test 
--user-data='serializer=application/vnd.graphbinary-v4.0' 
--user-data='parameterize=true'
       && radish -f dots -e -t -b ./radish ./gremlin-test 
--user-data='serializer=application/vnd.graphbinary-v4.0'
       && radish -f dots -e -t -b ./radish ./gremlin-test 
--user-data='serializer=application/vnd.gremlin-v4.0+json' 
--user-data='parameterize=true'
-      && radish -f dots -e -t -b ./radish ./gremlin-test 
--user-data='serializer=application/vnd.gremlin-v4.0+json';
+      && radish -f dots -e -t -b ./radish ./gremlin-test 
--user-data='serializer=application/vnd.gremlin-v4.0+json'
+      && echo 'Running examples...'
+      && python3 examples/basic_gremlin.py
+      && python3 examples/connections.py
+      && python3 examples/modern_traversals.py
+      && echo 'All examples completed successfully';
       EXIT_CODE=$$?; chown -R `stat -c "%u:%g" .` .; exit $$EXIT_CODE"
     depends_on:
       gremlin-server-test-python:
diff --git a/gremlin-python/src/main/python/examples/basic_gremlin.py 
b/gremlin-python/src/main/python/examples/basic_gremlin.py
index 256ed98441..873fd0a731 100644
--- a/gremlin-python/src/main/python/examples/basic_gremlin.py
+++ b/gremlin-python/src/main/python/examples/basic_gremlin.py
@@ -16,34 +16,39 @@
 # under the License.
 
 import sys
+import os
 
 sys.path.append("..")
 
 from gremlin_python.process.anonymous_traversal import traversal
+from gremlin_python.process.graph_traversal import __
 from gremlin_python.process.strategies import *
 from gremlin_python.driver.driver_remote_connection import 
DriverRemoteConnection
 
+VERTEX_LABEL = os.getenv('VERTEX_LABEL', 'person')
 
 def main():
-    rc = DriverRemoteConnection('ws://localhost:8182/gremlin', 'g')
+    # if there is a port placeholder in the env var then we are running with 
docker so set appropriate port
+    server_url = os.getenv('GREMLIN_SERVER_URL', 
'http://localhost:8182/gremlin').format(45940)
+    rc = DriverRemoteConnection(server_url, 'g')
     g = traversal().with_remote(rc)
 
     # basic Gremlin: adding and retrieving data
-    v1 = g.add_v('person').property('name', 'marko').next()
-    v2 = g.add_v('person').property('name', 'stephen').next()
-    v3 = g.add_v('person').property('name', 'vadas').next()
+    v1 = g.add_v(VERTEX_LABEL).property('name', 'marko').next()
+    v2 = g.add_v(VERTEX_LABEL).property('name', 'stephen').next()
+    v3 = g.add_v(VERTEX_LABEL).property('name', 'vadas').next()
 
     # be sure to use a terminating step like next() or iterate() so that the 
traversal "executes"
     # iterate() does not return any data and is used to just generate 
side-effects (i.e. write data to the database)
-    g.V(v1).add_e('knows').to(v2).property('weight', 0.75).iterate()
-    g.V(v1).add_e('knows').to(v3).property('weight', 0.75).iterate()
+    g.V(v1).add_e('knows').to(__.V(v2)).property('weight', 0.75).iterate()
+    g.V(v1).add_e('knows').to(__.V(v3)).property('weight', 0.75).iterate()
 
     # retrieve the data from the "marko" vertex
-    marko = g.V().has('person', 'name', 'marko').values('name').next()
+    marko = g.V().has(VERTEX_LABEL, 'name', 'marko').values('name').next()
     print("name: " + marko)
 
     # find the "marko" vertex and then traverse to the people he "knows" and 
return their data
-    people_marko_knows = g.V().has('person', 'name', 
'marko').out('knows').values('name').to_list()
+    people_marko_knows = g.V().has(VERTEX_LABEL, 'name', 
'marko').out('knows').values('name').to_list()
     for person in people_marko_knows:
         print("marko knows " + person)
 
diff --git a/gremlin-python/src/main/python/examples/connections.py 
b/gremlin-python/src/main/python/examples/connections.py
index f268e6c27d..f396a8d797 100644
--- a/gremlin-python/src/main/python/examples/connections.py
+++ b/gremlin-python/src/main/python/examples/connections.py
@@ -14,21 +14,23 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
-
+import ssl
 import sys
+import os
 
 sys.path.append("..")
 
 from gremlin_python.process.anonymous_traversal import traversal
-from gremlin_python.process.strategies import *
 from gremlin_python.driver.driver_remote_connection import 
DriverRemoteConnection
-from gremlin_python.driver.serializer import GraphBinarySerializersV1
+from gremlin_python.driver.aiohttp.transport import AiohttpHTTPTransport
+from gremlin_python.driver.auth import basic
+from gremlin_python.driver.serializer import GraphBinarySerializersV4
 
+VERTEX_LABEL = os.getenv('VERTEX_LABEL', 'connection')
 
 def main():
     with_remote()
     with_auth()
-    with_kerberos()
     with_configs()
 
 
@@ -40,15 +42,14 @@ def with_remote():
     #
     # which starts it in "console" mode with an empty in-memory TinkerGraph 
ready to go bound to a
     # variable named "g" as referenced in the following line.
-    rc = DriverRemoteConnection('ws://localhost:8182/gremlin', 'g')
+    # if there is a port placeholder in the env var then we are running with 
docker so set appropriate port
+    server_url = os.getenv('GREMLIN_SERVER_URL', 
'http://localhost:8182/gremlin').format(45940)
+    rc = DriverRemoteConnection(server_url, 'g')
     g = traversal().with_remote(rc)
 
-    # drop existing vertices
-    g.V().drop().iterate()
-
     # simple query to verify connection
-    v = g.add_v().iterate()
-    count = g.V().count().next()
+    v = g.add_v(VERTEX_LABEL).iterate()
+    count = g.V().has_label(VERTEX_LABEL).count().next()
     print("Vertex count: " + str(count))
 
     # cleanup
@@ -57,45 +58,42 @@ def with_remote():
 
 # connecting with plain text authentication
 def with_auth():
-    rc = DriverRemoteConnection('ws://localhost:8182/gremlin', 'g', 
username='stephen', password='password')
+    # if there is a port placeholder in the env var then we are running with 
docker so set appropriate port
+    server_url = os.getenv('GREMLIN_SERVER_BASIC_AUTH_URL', 
'http://localhost:8182/gremlin').format(45941)
+    
+    # disable SSL certificate verification for CI environments
+    if ':45941' in server_url:
+        ssl_opts = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
+        ssl_opts.check_hostname = False
+        ssl_opts.verify_mode = ssl.CERT_NONE
+        rc = DriverRemoteConnection(server_url, 'g', auth=basic('stephen', 
'password'),
+                                    transport_factory=lambda: 
AiohttpHTTPTransport(ssl_options=ssl_opts))
+    else:
+        rc = DriverRemoteConnection(server_url, 'g', auth=basic('stephen', 
'password'))
+    
     g = traversal().with_remote(rc)
 
-    v = g.add_v().iterate()
-    count = g.V().count().next()
+    v = g.add_v(VERTEX_LABEL).iterate()
+    count = g.V().has_label(VERTEX_LABEL).count().next()
     print("Vertex count: " + str(count))
 
     rc.close()
 
-
-# connecting with Kerberos SASL authentication
-def with_kerberos():
-    rc = DriverRemoteConnection('ws://localhost:8182/gremlin', 'g', 
kerberized_service='[email protected]')
-    g = traversal().with_remote(rc)
-
-    v = g.add_v().iterate()
-    count = g.V().count().next()
-    print("Vertex count: " + str(count))
-
-    rc.close()
-
-
 # connecting with customized configurations
 def with_configs():
+    server_url = os.getenv('GREMLIN_SERVER_URL', 
'http://localhost:8182/gremlin').format(45940)
     rc = DriverRemoteConnection(
-        'ws://localhost:8182/gremlin', 'g',
-        username="", password="", kerberized_service='',
-        message_serializer=GraphBinarySerializersV1(), graphson_reader=None,
-        graphson_writer=None, headers=None, session=None,
-        enable_user_agent_on_connect=True
+        server_url, 'g',
+        request_serializer=GraphBinarySerializersV4(),
+        headers=None,
     )
     g = traversal().with_remote(rc)
 
-    v = g.add_v().iterate()
-    count = g.V().count().next()
+    v = g.add_v(VERTEX_LABEL).iterate()
+    count = g.V().has_label(VERTEX_LABEL).count().next()
     print("Vertex count: " + str(count))
 
     rc.close()
 
-
 if __name__ == "__main__":
     main()
diff --git a/gremlin-python/src/main/python/examples/modern_traversals.py 
b/gremlin-python/src/main/python/examples/modern_traversals.py
index ae757b10b4..9feb66d775 100644
--- a/gremlin-python/src/main/python/examples/modern_traversals.py
+++ b/gremlin-python/src/main/python/examples/modern_traversals.py
@@ -16,6 +16,7 @@
 # under the License.
 
 import sys
+import os
 
 sys.path.append("..")
 
@@ -31,7 +32,16 @@ def main():
     # This example requires the Modern toy graph to be preloaded upon 
launching the Gremlin server.
     # For details, see 
https://tinkerpop.apache.org/docs/current/reference/#gremlin-server-docker-image
 and use
     # conf/gremlin-server-modern.yaml.
-    rc = DriverRemoteConnection('ws://localhost:8182/gremlin', 'g')
+    # if there is a port placeholder in the env var then we are running with 
docker so set appropriate port
+    server_url = os.getenv('GREMLIN_SERVER_URL', 
'http://localhost:8182/gremlin').format(45940)
+    
+    # CI uses port 45940 with gmodern binding, local uses 8182 with g binding
+    if ':45940' in server_url:
+        graph_binding = 'gmodern'  # CI environment
+    else:
+        graph_binding = 'g'        # Local environment
+    
+    rc = DriverRemoteConnection(server_url, graph_binding)
     g = traversal().with_remote(rc)
 
     e1 = g.V(1).both_e().to_list()  # (1)

Reply via email to