diff --git a/.github/workflows/update-gaffer-version.yaml b/.github/workflows/update-gaffer-version.yaml index 197d4ba5..b198ef7b 100644 --- a/.github/workflows/update-gaffer-version.yaml +++ b/.github/workflows/update-gaffer-version.yaml @@ -26,12 +26,9 @@ jobs: - name: Update Gaffer Version run: | - oldVersion=`sed -n 's/^__version__.*"\(.*\)"$/\1/p' src/__init__.py` newVersion=${{ github.event.milestone.title }} - - sed -i'' "s#__version__ = \"$oldVersion\"#__version__ = \"$newVersion\"#g" src/__init__.py - sed -i'' "s#__version__ = \"$oldVersion\"#__version__ = \"$newVersion\"#g" src/*/__init__.py - sed -i'' "s#release = '$oldVersion'#release = '$newVersion'#g" docs/source/conf.py + + bash update-versions.sh "${newVersion}" - name: Update gafferpy run: | diff --git a/requirements.txt b/requirements.txt index 077c95d8..975a8e19 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1 +1,2 @@ -requests==2.31.0 \ No newline at end of file +requests==2.31.0 +gremlinpython==3.6.2 \ No newline at end of file diff --git a/setup.py b/setup.py index 56517d67..896937c5 100644 --- a/setup.py +++ b/setup.py @@ -22,13 +22,14 @@ "Topic :: Software Development :: Libraries :: Python Modules", ] python_requires = ">3.6" -install_requires = [] +install_requires = [ + "requests>=2.4.0", + "gremlinpython>=3.6.2" +] extras_require = { - "requests": ["requests>=2.4.0"], "dev": [ "tox", "pytest", - "requests>=2.4.0", "sphinx~=7.2.6", "sphinx-rtd-theme~=1.3.0" ] diff --git a/src/gafferpy/gaffer_connector.py b/src/gafferpy/gaffer_connector.py index 55a83cf7..3fa11a1f 100644 --- a/src/gafferpy/gaffer_connector.py +++ b/src/gafferpy/gaffer_connector.py @@ -24,7 +24,7 @@ from gafferpy.gaffer_core import ToJson from gafferpy.gaffer_config import IsOperationSupported from gafferpy.gaffer_operations import OperationChain - +from gremlin_python.structure.io.graphsonV3d0 import GraphSONReader CLIENT_CLASS_NAMES = { "urllib": UrllibClient, @@ -57,6 +57,7 @@ def __init__(self, host, verbose=False, headers={}, client_class=UrllibClient, * client_class = CLIENT_CLASS_NAMES[client_class] self.client = client_class(host, verbose, headers, **kwargs) + self.graphson_reader = GraphSONReader() def execute(self, operation, headers=None): """ @@ -100,6 +101,62 @@ def execute_operation_chain(self, operation_chain, headers=None): json_body ) + def execute_gremlin(self, query: str, to_objects=True): + """ + Execute a Gremlin Groovy query using the Gaffer endpoint. + + Args: + query: The Gremlin query. + to_objects: Should the result be converted to Python objects or left as raw GraphSON. + + Returns: + The result of the query. + """ + target = "/gremlin/execute" + request_headers = {'accept': 'application/x-ndjson', 'Content-Type': 'text/plain'} + + result = self.client.perform_request( + method="POST", + target=target, + body=str.encode(query), + headers=request_headers + ) + + # Convert to python using gremlin-python's graphSON reader + if to_objects: + return self.graphson_reader.to_object(result) + + # Return just raw result + return result + + def execute_cypher(self, query: str, to_objects=True): + """ + Execute an Open Cypher query using the Gaffer endpoint. + + Args: + query: The Open Cypher query. + to_objects: Should the result be converted to Python objects or left as raw GraphSON. + + Returns: + The result of the query. + """ + target = "/gremlin/cypher/execute" + request_headers = {'accept': 'application/x-ndjson', 'Content-Type': 'text/plain'} + + result = self.client.perform_request( + method="POST", + target=target, + body=str.encode(query), + headers=request_headers + ) + + # Convert to python using gremlin-python's graphSON reader + if to_objects: + return self.graphson_reader.to_object(result) + + # Return just raw result + return result + def execute_get(self, operation, headers=None, json_result=False): """ This method queries Gaffer with a GET request to a specified endpoint. diff --git a/update-versions.sh b/update-versions.sh new file mode 100755 index 00000000..453daca7 --- /dev/null +++ b/update-versions.sh @@ -0,0 +1,29 @@ +#!/bin/bash +# Copyright 2024 Crown Copyright +# +# Licensed under the Apache License, Version 2.0 (the 'License'); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an 'AS IS' BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +if [ -z "${1}" ]; then + echo "Missing version argument" + exit 1 +fi + +# Upadate all the init python files +while read -r FILE +do + sed -ri "s/(^__version__ = \")(.*)/\1${1}\"/" "${FILE}" +done < <(find . -type f -name "__init__.py") + +# Update the docs +sed -ri "s/(^release = \")(.*)/\1${1}\"/" docs/source/conf.py