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)