This is an automated email from the ASF dual-hosted git repository.
ming pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-hugegraph-ai.git
The following commit(s) were added to refs/heads/main by this push:
new 1466986 feat(client): add variables api and test (#24)
1466986 is described below
commit 14669867224d284348c205530386f3d049019d87
Author: Liu Xiao <[email protected]>
AuthorDate: Thu Oct 26 14:19:40 2023 +0800
feat(client): add variables api and test (#24)
* feat: add variables api
* revert example port
* update
* fix
* fix
* format
* add example
* fix
* fix
* clear data
* fix
---------
Co-authored-by: Simon Cheung <[email protected]>
---
.github/workflows/hugegraph-python-client.yml | 39 +++++++
.github/workflows/pylint.yml | 2 +-
.../example/{test.py => hugegraph_example.py} | 4 +-
hugegraph-python-client/requirements.txt | 2 +-
.../src/pyhugegraph/api/gremlin.py | 105 ++++++++++--------
.../src/pyhugegraph/api/variable.py | 90 +++++++++++++++
hugegraph-python-client/src/pyhugegraph/client.py | 122 +++++++++++----------
.../src/pyhugegraph/structure/gremlin_data.py | 73 ++++++++++++
hugegraph-python-client/src/tests/__init__.py | 16 +++
hugegraph-python-client/src/tests/api/__init__.py | 16 +++
.../src/tests/api/test_gremlin.py | 92 ++++++++++++++++
.../src/tests/api/test_variable.py | 82 ++++++++++++++
hugegraph-python-client/src/tests/client_utils.py | 101 +++++++++++++++++
13 files changed, 636 insertions(+), 108 deletions(-)
diff --git a/.github/workflows/hugegraph-python-client.yml
b/.github/workflows/hugegraph-python-client.yml
new file mode 100644
index 0000000..450ebf5
--- /dev/null
+++ b/.github/workflows/hugegraph-python-client.yml
@@ -0,0 +1,39 @@
+name: HG-Python-Client CI
+
+on:
+ push:
+ branches:
+ - 'release-*'
+ pull_request:
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ strategy:
+ matrix:
+ python-version: ["3.8", "3.9", "3.10", "3.11"]
+ steps:
+ - uses: actions/checkout@v3
+ - name: Set up Python ${{ matrix.python-version }}
+ uses: actions/setup-python@v4
+ with:
+ python-version: ${{ matrix.python-version }}
+ cache: 'pip'
+ - name: Install dependencies
+ run: |
+ python -m pip install --upgrade pip
+ pip install pytest
+ pip install -r ./hugegraph-python-client/requirements.txt
+ - name: Prepare HugeGraph Server Environment
+ run: |
+ docker run -d --name=graph -p 8080:8080 hugegraph/hugegraph
+ sleep 20
+ - name: Test example
+ run: |
+ export PYTHONPATH=$(pwd)/hugegraph-python-client/src
+ echo ${PYTHONPATH}
+ python hugegraph-python-client/example/hugegraph_example.py
+ - name: Test with pytest
+ run: |
+ pytest
+ working-directory: hugegraph-python-client
diff --git a/.github/workflows/pylint.yml b/.github/workflows/pylint.yml
index ccb4613..7467c4f 100644
--- a/.github/workflows/pylint.yml
+++ b/.github/workflows/pylint.yml
@@ -21,7 +21,7 @@ jobs:
- name: Install dependencies
run: |
python -m pip install --upgrade pip
- pip install pylint
+ pip install pylint pytest
pip install -r ./hugegraph-llm/requirements.txt
pip install -r ./hugegraph-python-client/requirements.txt
- name: Analysing the code with pylint
diff --git a/hugegraph-python-client/example/test.py
b/hugegraph-python-client/example/hugegraph_example.py
similarity index 96%
rename from hugegraph-python-client/example/test.py
rename to hugegraph-python-client/example/hugegraph_example.py
index 5162444..27d0246 100644
--- a/hugegraph-python-client/example/test.py
+++ b/hugegraph-python-client/example/hugegraph_example.py
@@ -18,7 +18,7 @@
from pyhugegraph.client import PyHugeClient
if __name__ == "__main__":
- client = PyHugeClient("127.0.0.1", "8080", user="admin", pwd="admin",
graph="test")
+ client = PyHugeClient("127.0.0.1", "8080", user="admin", pwd="admin",
graph="hugegraph")
"""schema"""
schema = client.schema()
@@ -52,7 +52,7 @@ if __name__ == "__main__":
g.addEdge("ActedIn", p2.id, m2.id, {})
# update property
- g.eliminateVertex("vertex_id", {"property_key": "property_value"})
+ # g.eliminateVertex("vertex_id", {"property_key": "property_value"})
print(g.getVertexById(p1.id).label)
# g.removeVertexById("12:Al Pacino")
diff --git a/hugegraph-python-client/requirements.txt
b/hugegraph-python-client/requirements.txt
index 6d154a0..469bab3 100644
--- a/hugegraph-python-client/requirements.txt
+++ b/hugegraph-python-client/requirements.txt
@@ -1,4 +1,4 @@
decorator==5.1.1
-Requests==2.31.0
+requests==2.31.0
setuptools==67.6.1
urllib3==2.0.7
diff --git a/hugegraph-python-client/src/pyhugegraph/api/gremlin.py
b/hugegraph-python-client/src/pyhugegraph/api/gremlin.py
index 97b63cb..fcffd98 100644
--- a/hugegraph-python-client/src/pyhugegraph/api/gremlin.py
+++ b/hugegraph-python-client/src/pyhugegraph/api/gremlin.py
@@ -1,47 +1,58 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you 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.
-import json
-import re
-
-from pyhugegraph.api.common import HugeParamsBase
-from pyhugegraph.structure.response_data import ResponseData
-from pyhugegraph.utils.exceptions import NotFoundError
-from pyhugegraph.utils.huge_requests import HugeSession
-from pyhugegraph.utils.util import check_if_success
-
-
-class GremlinManager(HugeParamsBase):
- def __init__(self, graph_instance):
- super().__init__(graph_instance)
- self.session = self.set_session(HugeSession.new_session())
-
- def set_session(self, session):
- self.session = session
- return session
-
- def close(self):
- if self.session:
- self.session.close()
-
- def exec(self, gremlin):
- gremlin = re.sub("^g", self._graph_name + ".traversal()", gremlin)
- url = f"{self._host}/gremlin?gremlin={gremlin}"
- response = self.session.get(url, auth=self._auth,
headers=self._headers)
- error = NotFoundError(f"Gremlin can't get results: {response.content}")
- if check_if_success(response, error):
- return ResponseData(json.loads(response.content)).result
- return ""
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you 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.
+
+import json
+
+from pyhugegraph.api.common import HugeParamsBase
+from pyhugegraph.structure.gremlin_data import GremlinData
+from pyhugegraph.structure.response_data import ResponseData
+from pyhugegraph.utils.exceptions import NotFoundError
+from pyhugegraph.utils.huge_requests import HugeSession
+from pyhugegraph.utils.util import check_if_success
+
+
+class GremlinManager(HugeParamsBase):
+ def __init__(self, graph_instance):
+ super().__init__(graph_instance)
+ self.session = self.set_session(HugeSession.new_session())
+
+ def set_session(self, session):
+ self.session = session
+ return session
+
+ def close(self):
+ if self.session:
+ self.session.close()
+
+ def exec(self, gremlin):
+ url = f"{self._host}/gremlin"
+ gremlin_data = GremlinData(gremlin)
+ gremlin_data.aliases = {
+ 'graph': self._graph_name,
+ 'g': '__g_' + self._graph_name
+ }
+ response = self.session.post(
+ url,
+ data=gremlin_data.to_json(),
+ auth=self._auth,
+ headers=self._headers,
+ timeout=self._timeout
+ )
+ error = NotFoundError(f"Gremlin can't get results: {response.content}")
+ if check_if_success(response, error):
+ return ResponseData(json.loads(response.content)).result
+ return ""
diff --git a/hugegraph-python-client/src/pyhugegraph/api/variable.py
b/hugegraph-python-client/src/pyhugegraph/api/variable.py
new file mode 100644
index 0000000..16abe61
--- /dev/null
+++ b/hugegraph-python-client/src/pyhugegraph/api/variable.py
@@ -0,0 +1,90 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you 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.
+
+import json
+
+from pyhugegraph.api.common import HugeParamsBase
+from pyhugegraph.utils.exceptions import NotFoundError
+from pyhugegraph.utils.huge_requests import HugeSession
+from pyhugegraph.utils.util import check_if_success
+
+
+class VariableManager(HugeParamsBase):
+
+ def __init__(self, graph_instance):
+ super().__init__(graph_instance)
+ self.session = self.set_session(HugeSession.new_session())
+
+ def set_session(self, session):
+ self.session = session
+ return session
+
+ def close(self):
+ if self.session:
+ self.session.close()
+
+ def set(self, key, value):
+ url = f'{self._host}/graphs/{self._graph_name}/variables/{key}'
+ data = {'data': value}
+
+ response = self.session.put(
+ url,
+ data=json.dumps(data),
+ auth=self._auth,
+ headers=self._headers,
+ timeout=self._timeout,
+ )
+ if check_if_success(response, NotFoundError(response.content)):
+ return response.json()
+ return {}
+
+ def get(self, key):
+ url = f'{self._host}/graphs/{self._graph_name}/variables/{key}'
+
+ response = self.session.get(
+ url,
+ auth=self._auth,
+ headers=self._headers,
+ timeout=self._timeout
+ )
+ if check_if_success(response, NotFoundError(response.content)):
+ return response.json()
+ return {}
+
+ def all(self):
+ url = f'{self._host}/graphs/{self._graph_name}/variables'
+
+ response = self.session.get(
+ url,
+ auth=self._auth,
+ headers=self._headers,
+ timeout=self._timeout
+ )
+ if check_if_success(response, NotFoundError(response.content)):
+ return response.json()
+ return {}
+
+ def remove(self, key):
+ url = f'{self._host}/graphs/{self._graph_name}/variables/{key}'
+
+ response = self.session.delete(
+ url,
+ auth=self._auth,
+ headers=self._headers,
+ timeout=self._timeout
+ )
+ check_if_success(response, NotFoundError(response.content))
diff --git a/hugegraph-python-client/src/pyhugegraph/client.py
b/hugegraph-python-client/src/pyhugegraph/client.py
index e12b73d..3972af0 100644
--- a/hugegraph-python-client/src/pyhugegraph/client.py
+++ b/hugegraph-python-client/src/pyhugegraph/client.py
@@ -1,57 +1,65 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you 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.
-
-from pyhugegraph.api.common import HugeParamsBase
-from pyhugegraph.api.graph import GraphManager
-from pyhugegraph.api.graphs import GraphsManager
-from pyhugegraph.api.gremlin import GremlinManager
-from pyhugegraph.api.schema import SchemaManager
-from pyhugegraph.structure.graph_instance import GraphInstance
-
-
-class PyHugeClient(HugeParamsBase):
- def __init__(self, ip, port, graph, user, pwd, timeout=10):
- self._graph_instance = GraphInstance(ip, port, graph, user, pwd,
timeout)
- super().__init__(self._graph_instance)
- self._schema = None
- self._graph = None
- self._graphs = None
- self._gremlin = None
-
- def schema(self):
- if self._schema:
- return self._schema
- self._schema = SchemaManager(self._graph_instance)
- return self._schema
-
- def gremlin(self):
- if self._gremlin:
- return self._gremlin
- self._gremlin = GremlinManager(self._graph_instance)
- return self._gremlin
-
- def graph(self):
- if self._graph:
- return self._graph
- self._graph = GraphManager(self._graph_instance)
- return self._graph
-
- def graphs(self):
- if self._graphs:
- return self._graphs
- self._graphs = GraphsManager(self._graph_instance)
- return self._graphs
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you 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.
+
+from pyhugegraph.api.common import HugeParamsBase
+from pyhugegraph.api.graph import GraphManager
+from pyhugegraph.api.graphs import GraphsManager
+from pyhugegraph.api.gremlin import GremlinManager
+from pyhugegraph.api.schema import SchemaManager
+from pyhugegraph.api.variable import VariableManager
+from pyhugegraph.structure.graph_instance import GraphInstance
+
+
+class PyHugeClient(HugeParamsBase):
+ def __init__(self, ip, port, graph, user, pwd, timeout=10):
+ self._graph_instance = GraphInstance(ip, port, graph, user, pwd,
timeout)
+ super().__init__(self._graph_instance)
+ self._schema = None
+ self._graph = None
+ self._graphs = None
+ self._gremlin = None
+ self._variable = None
+
+ def schema(self):
+ if self._schema:
+ return self._schema
+ self._schema = SchemaManager(self._graph_instance)
+ return self._schema
+
+ def gremlin(self):
+ if self._gremlin:
+ return self._gremlin
+ self._gremlin = GremlinManager(self._graph_instance)
+ return self._gremlin
+
+ def graph(self):
+ if self._graph:
+ return self._graph
+ self._graph = GraphManager(self._graph_instance)
+ return self._graph
+
+ def graphs(self):
+ if self._graphs:
+ return self._graphs
+ self._graphs = GraphsManager(self._graph_instance)
+ return self._graphs
+
+ def variable(self):
+ if self._variable:
+ return self._variable
+ self._variable = VariableManager(self._graph_instance)
+ return self._variable
diff --git a/hugegraph-python-client/src/pyhugegraph/structure/gremlin_data.py
b/hugegraph-python-client/src/pyhugegraph/structure/gremlin_data.py
new file mode 100644
index 0000000..9440b84
--- /dev/null
+++ b/hugegraph-python-client/src/pyhugegraph/structure/gremlin_data.py
@@ -0,0 +1,73 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you 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.
+
+import json
+
+
+class GremlinData:
+
+ def __init__(self, gremlin):
+ self.__gremlin = gremlin
+ self.__bindings = {}
+ self.__language = "gremlin-groovy"
+ self.__aliases = {}
+
+ @property
+ def gremlin(self):
+ return self.__gremlin
+
+ @gremlin.setter
+ def gremlin(self, _gremlin):
+ self.__gremlin = _gremlin
+
+ @property
+ def bindings(self):
+ return self.__bindings
+
+ @bindings.setter
+ def bindings(self, _bindings):
+ self.__bindings = _bindings
+
+ @property
+ def language(self):
+ return self.__language
+
+ @language.setter
+ def language(self, _language):
+ self.__language = _language
+
+ @property
+ def aliases(self):
+ return self.__aliases
+
+ @aliases.setter
+ def aliases(self, _aliases):
+ self.__aliases = _aliases
+
+ def __repr__(self):
+ res = f"gremlin: {self.__gremlin}, bindings: {self.__bindings}," \
+ f"language: {self.__language}, aliases: {self.__aliases}"
+ return res
+
+ def to_json(self):
+ return json.dumps(self, cls=GremlinDataEncoder)
+
+
+class GremlinDataEncoder(json.JSONEncoder):
+
+ def default(self, o):
+ return {k.split('__')[1]: v for k, v in vars(o).items()}
diff --git a/hugegraph-python-client/src/tests/__init__.py
b/hugegraph-python-client/src/tests/__init__.py
new file mode 100644
index 0000000..13a8339
--- /dev/null
+++ b/hugegraph-python-client/src/tests/__init__.py
@@ -0,0 +1,16 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you 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.
diff --git a/hugegraph-python-client/src/tests/api/__init__.py
b/hugegraph-python-client/src/tests/api/__init__.py
new file mode 100644
index 0000000..13a8339
--- /dev/null
+++ b/hugegraph-python-client/src/tests/api/__init__.py
@@ -0,0 +1,16 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you 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.
diff --git a/hugegraph-python-client/src/tests/api/test_gremlin.py
b/hugegraph-python-client/src/tests/api/test_gremlin.py
new file mode 100644
index 0000000..45d36ad
--- /dev/null
+++ b/hugegraph-python-client/src/tests/api/test_gremlin.py
@@ -0,0 +1,92 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you 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.
+
+import unittest
+
+import pytest
+
+from pyhugegraph.utils.exceptions import NotFoundError
+from tests.client_utils import ClientUtils
+
+
+class TestGremlin(unittest.TestCase):
+
+ client = None
+ gremlin = None
+
+ @classmethod
+ def setUpClass(cls):
+ cls.client = ClientUtils()
+ cls.client.clear_graph_all_data()
+ cls.gremlin = cls.client.gremlin
+ cls.client.init_property_key()
+ cls.client.init_vertex_label()
+ cls.client.init_edge_label()
+
+ @classmethod
+ def tearDownClass(cls):
+ cls.client.clear_graph_all_data()
+
+ def setUp(self):
+ self.client.init_vertices()
+ self.client.init_edges()
+
+ def tearDown(self):
+ pass
+
+ def test_query_all_vertices(self):
+ vertices = self.gremlin.exec('g.V()')
+ lst = vertices.get('data', [])
+ assert 6 == len(lst)
+
+ self.gremlin.exec('g.V().drop()')
+ vertices = self.gremlin.exec('g.V()')
+ lst = vertices.get('data', [])
+ assert 0 == len(lst)
+
+ def test_query_all_edges(self):
+ edges = self.gremlin.exec('g.E()')
+ lst = edges.get('data', [])
+ assert 6 == len(lst)
+
+ self.gremlin.exec('g.E().drop()')
+ edges = self.gremlin.exec('g.E()')
+ lst = edges.get('data', [])
+ assert 0 == len(lst)
+
+ def test_primitive_object(self):
+ result = self.gremlin.exec('1 + 2')
+ print(result)
+ result_set = result.get('data', [])
+ assert 1 == len(result_set)
+
+ data = result_set[0]
+ assert isinstance(data, int)
+ assert 3 == data
+
+ def test_empty_result_set(self):
+ result = self.gremlin.exec('g.V().limit(0)')
+ lst = result.get('data', [])
+ assert 0 == len(lst)
+
+ def test_invalid_gremlin(self):
+ with pytest.raises(NotFoundError):
+ assert self.gremlin.exec('g.V2()')
+
+ def test_security_operation(self):
+ with pytest.raises(NotFoundError):
+ assert self.gremlin.exec('System.exit(-1)')
diff --git a/hugegraph-python-client/src/tests/api/test_variable.py
b/hugegraph-python-client/src/tests/api/test_variable.py
new file mode 100644
index 0000000..cf73b99
--- /dev/null
+++ b/hugegraph-python-client/src/tests/api/test_variable.py
@@ -0,0 +1,82 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you 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.
+
+import unittest
+
+import pytest
+
+from pyhugegraph.utils.exceptions import NotFoundError
+from tests.client_utils import ClientUtils
+
+
+class TestVariable(unittest.TestCase):
+
+ client = None
+ variable = None
+
+ @classmethod
+ def setUpClass(cls):
+ cls.client = ClientUtils()
+ cls.variable = cls.client.variable
+
+ @classmethod
+ def tearDownClass(cls):
+ cls.client.clear_graph_all_data()
+
+ def setUp(self):
+ self.client.clear_graph_all_data()
+
+ def tearDown(self):
+ pass
+
+ def test_all(self):
+ assert 0 == len(self.variable.all())
+ self.variable.set('student', 'mary')
+ self.variable.set('price', 20.86)
+
+ dic = self.variable.all()
+ assert 2 == len(dic)
+ assert 'mary' == dic.get('student', None)
+ assert 20.86 == dic.get('price', None)
+
+ def test_remove(self):
+ self.variable.set('lang', 'java')
+ dic = self.variable.all()
+ assert 1 == len(dic)
+ assert 'java' == dic.get('lang', None)
+
+ self.variable.remove('lang')
+ dic = self.variable.all()
+ assert 0 == len(dic)
+ assert dic.get('lang', None) is None
+
+ def test_set_and_get(self):
+ self.variable.set('name', 'tom')
+ self.variable.set('age', 18)
+
+ assert 2 == len(self.variable.all())
+ name = self.variable.get('name').get('name', None)
+ assert 'tom' == name
+ age = self.variable.get('age').get('age', None)
+ assert 18 == age
+
+ def test_get_key_not_exist(self):
+ with pytest.raises(NotFoundError):
+ assert self.variable.get('id').get('id') is None
+
+ def test_remove_key_not_exist(self):
+ self.variable.remove('id')
diff --git a/hugegraph-python-client/src/tests/client_utils.py
b/hugegraph-python-client/src/tests/client_utils.py
new file mode 100644
index 0000000..166b526
--- /dev/null
+++ b/hugegraph-python-client/src/tests/client_utils.py
@@ -0,0 +1,101 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you 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.
+
+from pyhugegraph.client import PyHugeClient
+
+
+class ClientUtils:
+ IP = "127.0.0.1"
+ PORT = 8080
+ GRAPH = "hugegraph"
+ USERNAME = 'admin'
+ PASSWORD = 'admin'
+ TIMEOUT = 10
+
+ def __init__(self):
+ self.client = PyHugeClient(self.IP, self.PORT, user=self.USERNAME,
+ pwd=self.PASSWORD, graph=self.GRAPH)
+ assert self.client is not None
+
+ self.schema = self.client.schema()
+ self.gremlin = self.client.gremlin()
+ self.graph = self.client.graph()
+ self.graphs = self.client.graphs()
+ self.variable = self.client.variable()
+
+ def init_property_key(self):
+ schema = self.schema
+ schema.propertyKey("name").asText().ifNotExist().create()
+ schema.propertyKey("age").asInt().ifNotExist().create()
+ schema.propertyKey("city").asText().ifNotExist().create()
+ schema.propertyKey("lang").asText().ifNotExist().create()
+ schema.propertyKey("date").asDate().ifNotExist().create()
+ schema.propertyKey("price").asInt().ifNotExist().create()
+ schema.propertyKey("weight").asDouble().ifNotExist().create()
+
+ def init_vertex_label(self):
+ schema = self.schema
+ schema.vertexLabel("person").properties("name", "age",
"city").primaryKeys("name") \
+ .nullableKeys("city").ifNotExist().create()
+ schema.vertexLabel("software").properties("name", "lang",
"price").primaryKeys("name") \
+ .nullableKeys("price").ifNotExist().create()
+ schema.vertexLabel("book").useCustomizeStringId().properties("name",
"price") \
+ .nullableKeys("price").ifNotExist().create()
+
+ def init_edge_label(self):
+ schema = self.schema
+ schema.edgeLabel("knows").sourceLabel("person").targetLabel("person") \
+ .multiTimes().properties("date", "city").sortKeys("date") \
+ .nullableKeys("city").ifNotExist().create()
+
schema.edgeLabel("created").sourceLabel("person").targetLabel("software") \
+ .properties("date",
"city").nullableKeys("city").ifNotExist().create()
+
+ def init_vertices(self):
+ graph = self.graph
+ graph.addVertex("person", {"name": "marko", "age": 29, "city":
"Beijing"})
+ graph.addVertex("person", {"name": "vadas", "age": 27, "city":
"Hongkong"})
+ graph.addVertex("software", {"name": "lop", "lang": "java", "price":
328})
+ graph.addVertex("person", {"name": "josh", "age": 32, "city":
"Beijing"})
+ graph.addVertex("software", {"name": "ripple", "lang": "java",
"price": 199})
+ graph.addVertex("person", {"name": "peter", "age": 29, "city":
"Shanghai"})
+
+ def init_edges(self):
+ marko_id = self._get_vertex_id("person", {"name": "marko"})
+ vadas_id = self._get_vertex_id("person", {"name": "vadas"})
+ josh_id = self._get_vertex_id("person", {"name": "josh"})
+ peter_id = self._get_vertex_id("person", {"name": "peter"})
+ lop_id = self._get_vertex_id("software", {"name": "lop"})
+ ripple_id = self._get_vertex_id("software", {"name": "ripple"})
+
+ self.graph.addEdge("knows", marko_id, vadas_id, {"date": "2012-01-10"})
+ self.graph.addEdge("knows", marko_id, josh_id, {"date": "2013-01-10"})
+ self.graph.addEdge("created", marko_id, lop_id, {"date": "2014-01-10",
"city": "Shanghai"})
+ self.graph.addEdge("created", josh_id, ripple_id, {"date":
"2015-01-10", "city": "Beijing"})
+ self.graph.addEdge("created", josh_id, lop_id, {"date": "2016-01-10",
"city": "Beijing"})
+ self.graph.addEdge("created", peter_id, lop_id, {"date": "2017-01-10",
"city": "Hongkong"})
+
+ def _get_vertex_id(self, label, properties):
+ res = self._get_vertex(label, properties)
+ return res.id
+
+ def _get_vertex(self, label, properties):
+ lst = self.graph.getVertexByCondition(label=label, limit=1,
properties=properties)
+ assert 1 == len(lst), "Can't find vertex."
+ return lst[0]
+
+ def clear_graph_all_data(self):
+ self.graphs.clear_graph_all_data()