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

jin 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 48875c9  feat: initialize hugegraph python client (#5)
48875c9 is described below

commit 48875c9b4755240c5779ac8294c29711b0ee86ef
Author: Simon Cheung <[email protected]>
AuthorDate: Wed Oct 18 12:12:39 2023 +0800

    feat: initialize hugegraph python client (#5)
---
 LICENSE                                            | 201 +++++++++++++++
 hugegraph-python/README.md                         |  62 +++++
 hugegraph-python/example/__init__.py               |  16 ++
 hugegraph-python/example/client_test.py            |  23 ++
 hugegraph-python/example/hugegraph_test.py         |  48 ++++
 hugegraph-python/example/test.py                   |  68 +++++
 hugegraph-python/requirements.txt                  |   4 +
 hugegraph-python/src/__init__.py                   |  16 ++
 hugegraph-python/src/api/__init__.py               |  16 ++
 hugegraph-python/src/api/common.py                 |  67 +++++
 hugegraph-python/src/api/graph.py                  | 276 +++++++++++++++++++++
 hugegraph-python/src/api/graphs.py                 |  71 ++++++
 hugegraph-python/src/api/gremlin.py                |  48 ++++
 hugegraph-python/src/api/schema.py                 | 166 +++++++++++++
 hugegraph-python/src/api/schema_manage/__init__.py |  16 ++
 .../src/api/schema_manage/edge_label.py            | 150 +++++++++++
 .../src/api/schema_manage/index_label.py           | 103 ++++++++
 .../src/api/schema_manage/property_key.py          | 168 +++++++++++++
 .../src/api/schema_manage/vertex_label.py          | 156 ++++++++++++
 hugegraph-python/src/client.py                     |  57 +++++
 hugegraph-python/src/structure/__init__.py         |  16 ++
 hugegraph-python/src/structure/edge_data.py        |  64 +++++
 hugegraph-python/src/structure/edge_label_data.py  |  78 ++++++
 hugegraph-python/src/structure/graph_instance.py   |  54 ++++
 hugegraph-python/src/structure/index_label_data.py |  56 +++++
 .../src/structure/property_key_data.py             |  51 ++++
 hugegraph-python/src/structure/respon_data.py      |  39 +++
 hugegraph-python/src/structure/vertex_data.py      |  44 ++++
 .../src/structure/vertex_label_data.py             |  62 +++++
 hugegraph-python/src/utils/__init__.py             |  16 ++
 hugegraph-python/src/utils/constants.py            |  21 ++
 hugegraph-python/src/utils/exceptions.py           |  62 +++++
 hugegraph-python/src/utils/huge_decorator.py       |  45 ++++
 hugegraph-python/src/utils/huge_requests.py        |  32 +++
 hugegraph-python/src/utils/util.py                 |  43 ++++
 35 files changed, 2415 insertions(+)

diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..8dada3e
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,201 @@
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "{}"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright {yyyy} {name of copyright owner}
+
+   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.
diff --git a/hugegraph-python/README.md b/hugegraph-python/README.md
new file mode 100644
index 0000000..4210647
--- /dev/null
+++ b/hugegraph-python/README.md
@@ -0,0 +1,62 @@
+# hugegraph-python
+A Python SDK for Apache HugeGraph
+
+# Installation
+
+```shell
+pip3 install hugegraph-python
+```
+
+## Install from source
+release soon
+
+# Examples
+
+```python
+from src.client import PyHugeClient
+
+client = PyHugeClient("127.0.0.1", "8080", user="admin", pwd="admin", 
graph="hugegraph")
+
+"""system"""
+print(client.get_graphinfo())
+print(client.get_all_graphs())
+print(client.get_version())
+print(client.get_graph_config())
+
+"""schema"""
+schema = client.schema()
+schema.propertyKey("name").asText().ifNotExist().create()
+schema.propertyKey("birthDate").asText().ifNotExist().create()
+schema.vertexLabel("Person").properties("name", 
"birthDate").usePrimaryKeyId().primaryKeys(
+  "name").ifNotExist().create()
+schema.vertexLabel("Movie").properties("name").usePrimaryKeyId().primaryKeys("name").ifNotExist().create()
+schema.edgeLabel("ActedIn").sourceLabel("Person").targetLabel("Movie").ifNotExist().create()
+
+print(schema.getVertexLabels())
+print(schema.getEdgeLabels())
+print(schema.getRelations())
+
+"""graph"""
+g = client.graph()
+g.addVertex("Person", {"name": "Al Pacino", "birthDate": "1940-04-25"})
+g.addVertex("Person", {"name": "Robert De Niro", "birthDate": "1943-08-17"})
+g.addVertex("Movie", {"name": "The Godfather"})
+g.addVertex("Movie", {"name": "The Godfather Part II"})
+g.addVertex("Movie", {"name": "The Godfather Coda The Death of Michael 
Corleone"})
+
+g.addEdge("ActedIn", "12:Al Pacino", "13:The Godfather", {})
+g.addEdge("ActedIn", "12:Al Pacino", "13:The Godfather Part II", {})
+g.addEdge("ActedIn", "12:Al Pacino", "13:The Godfather Coda The Death of 
Michael Corleone", {})
+g.addEdge("ActedIn", "12:Robert De Niro", "13:The Godfather Part II", {})
+
+res = g.getVertexById("12:Al Pacino").label
+# g.removeVertexById("12:Al Pacino")
+print(res)
+g.close()
+
+"""gremlin"""
+g = client.gremlin()
+res = g.exec("g.V().limit(10)")
+print(res)
+
+```
\ No newline at end of file
diff --git a/hugegraph-python/example/__init__.py 
b/hugegraph-python/example/__init__.py
new file mode 100644
index 0000000..e0533d9
--- /dev/null
+++ b/hugegraph-python/example/__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/example/client_test.py 
b/hugegraph-python/example/client_test.py
new file mode 100644
index 0000000..c3d9808
--- /dev/null
+++ b/hugegraph-python/example/client_test.py
@@ -0,0 +1,23 @@
+import unittest
+from typing import Any
+from unittest.mock import MagicMock, patch
+
+from example.test_hugegraph import HugeGraph
+
+class HugeGraphTest(unittest.TestCase):
+    def setUp(self) -> None:
+        self.username = "test_user"
+        self.password = "test_password"
+        self.address = "test_address"
+        self.graph = "test_hugegraph"
+        self.port = 1234
+        self.session_pool_size = 10
+
+    @patch("src.client.PyHugeGraph")
+    def test_init(self, mock_graph: Any) -> None:
+        mock_graph.return_value = MagicMock()
+        client = HugeGraph(self.username, self.password, self.address, 
self.port, self.graph)
+
+        result = client.exec("g.V().limit(10)")
+        self.assertIsInstance(result, MagicMock)
+
diff --git a/hugegraph-python/example/hugegraph_test.py 
b/hugegraph-python/example/hugegraph_test.py
new file mode 100644
index 0000000..e41908a
--- /dev/null
+++ b/hugegraph-python/example/hugegraph_test.py
@@ -0,0 +1,48 @@
+# 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.
+
+class HugeGraph:
+    """HugeGraph wrapper for graph operations"""
+
+    def __init__(
+        self,
+        username: str = "default",
+        password: str = "default",
+        address: str = "127.0.0.1",
+        port: int = 8081,
+        graph: str = "hugegraph"
+    ) -> None:
+        """Create a new HugeGraph wrapper instance."""
+        try:
+            from src.client import PyHugeClient
+        except ImportError:
+            raise ValueError(
+                "Please install HugeGraph Python client first: "
+                "`pip3 install hugegraph-python-client`"
+            )
+
+        self.username = username
+        self.password = password
+        self.address = address
+        self.port = port
+        self.graph = graph
+        self.client = PyHugeClient(address, port, user=username, pwd=password, 
graph=graph)
+        self.schema = ""
+
+    def exec(self, query) -> str:
+        """Returns the schema of the HugeGraph database"""
+        return self.client.gremlin().exec(query)
diff --git a/hugegraph-python/example/test.py b/hugegraph-python/example/test.py
new file mode 100644
index 0000000..056ccae
--- /dev/null
+++ b/hugegraph-python/example/test.py
@@ -0,0 +1,68 @@
+# 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 src.client import PyHugeClient
+
+if __name__ == '__main__':
+    client = PyHugeClient("127.0.0.1", "8080", user="admin", pwd="admin", 
graph="test")
+
+    """schema"""
+    schema = client.schema()
+    schema.propertyKey("name").asText().ifNotExist().create()
+    schema.propertyKey("birthDate").asText().ifNotExist().create()
+    schema.vertexLabel("Person").properties("name", 
"birthDate").usePrimaryKeyId().primaryKeys(
+        "name").ifNotExist().create()
+    
schema.vertexLabel("Movie").properties("name").usePrimaryKeyId().primaryKeys("name").ifNotExist().create()
+    
schema.edgeLabel("ActedIn").sourceLabel("Person").targetLabel("Movie").ifNotExist().create()
+
+    print(schema.getVertexLabels())
+    print(schema.getEdgeLabels())
+    print(schema.getRelations())
+
+    """graph"""
+    g = client.graph()
+    # add Vertex
+    p1 = g.addVertex("Person", {"name": "Al Pacino", "birthDate": 
"1940-04-25"})
+    p2 = g.addVertex("Person", {"name": "Robert De Niro", "birthDate": 
"1943-08-17"})
+    m1 = g.addVertex("Movie", {"name": "The Godfather"})
+    m2 = g.addVertex("Movie", {"name": "The Godfather Part II"})
+    m3 = g.addVertex("Movie", {"name": "The Godfather Coda The Death of 
Michael Corleone"})
+
+    # add Edge
+    g.addEdge("ActedIn", p1.id, m1.id, {})
+    g.addEdge("ActedIn", p1.id, m2.id, {})
+    g.addEdge("ActedIn", p1.id, m3.id, {})
+    g.addEdge("ActedIn", p2.id, m2.id, {})
+
+    # update property
+    g.eliminateVertex("vertex_id", {"property_key": "property_value"})
+
+
+    print(g.getVertexById(p1.id).label)
+    # g.removeVertexById("12:Al Pacino")
+    g.close()
+
+    """gremlin"""
+    g = client.gremlin()
+    print("gremlin.exec: ", g.exec("g.V().limit(10)"))
+
+    """graphs"""
+    g = client.graphs()
+    print("get_graph_info: ", g.get_graph_info())
+    print("get_all_graphs: ", g.get_all_graphs())
+    print("get_version: ", g.get_version())
+    print("get_graph_config: ", g.get_graph_config())
diff --git a/hugegraph-python/requirements.txt 
b/hugegraph-python/requirements.txt
new file mode 100644
index 0000000..d9f0102
--- /dev/null
+++ b/hugegraph-python/requirements.txt
@@ -0,0 +1,4 @@
+decorator==5.1.1
+Requests==2.31.0
+setuptools==67.6.1
+urllib3==2.0.3
diff --git a/hugegraph-python/src/__init__.py b/hugegraph-python/src/__init__.py
new file mode 100644
index 0000000..e0533d9
--- /dev/null
+++ b/hugegraph-python/src/__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/src/api/__init__.py 
b/hugegraph-python/src/api/__init__.py
new file mode 100644
index 0000000..e0533d9
--- /dev/null
+++ b/hugegraph-python/src/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/src/api/common.py 
b/hugegraph-python/src/api/common.py
new file mode 100644
index 0000000..42b6c0a
--- /dev/null
+++ b/hugegraph-python/src/api/common.py
@@ -0,0 +1,67 @@
+# 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 src.utils.constants import Constants
+
+
+class ParameterHolder:
+    def __init__(self):
+        self._dic = {}
+
+    def set(self, key, value):
+        self._dic[key] = value
+
+    def get_value(self, key):
+        if key not in self._dic:
+            return None
+        else:
+            return self._dic[key]
+
+    def get_dic(self):
+        return self._dic
+
+    def get_keys(self):
+        return self._dic.keys()
+
+
+class HugeParamsBase:
+    def __init__(self, graph_instance):
+        self._graph_instance = graph_instance
+        self._ip = graph_instance.ip
+        self._port = graph_instance.port
+        self._user = graph_instance.user_name
+        self._pwd = graph_instance.passwd
+        self._host = "http://{}:{}".format(graph_instance.ip, 
graph_instance.port)
+        self._auth = (graph_instance.user_name, graph_instance.passwd)
+        self._graph_name = graph_instance.graph_name
+        self._parameter_holder = None
+        self._headers = {
+            'Content-Type': Constants.HEADER_CONTENT_TYPE
+        }
+        self._timeout = graph_instance.timeout
+
+    def add_parameter(self, key, value):
+        self._parameter_holder.set(key, value)
+        return
+
+    def get_parameter_holder(self):
+        return self._parameter_holder
+
+    def create_parameter_holder(self):
+        self._parameter_holder = ParameterHolder()
+
+    def clean_parameter_holder(self):
+        self._parameter_holder = None
diff --git a/hugegraph-python/src/api/graph.py 
b/hugegraph-python/src/api/graph.py
new file mode 100644
index 0000000..1ddb594
--- /dev/null
+++ b/hugegraph-python/src/api/graph.py
@@ -0,0 +1,276 @@
+# 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 src.utils.huge_requests import HugeSession
+from src.api.common import HugeParamsBase
+from src.structure.vertex_data import VertexData
+from src.structure.edge_data import EdgeData
+from src.utils.exceptions import NotFoundError, CreateError, RemoveError, 
UpdateError
+from src.utils.util import create_exception, check_if_authorized, 
check_if_success
+
+
+class GraphManager(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 addVertex(self, label, properties, id=None):
+        data = dict()
+        if id is not None:
+            data['id'] = id
+        data['label'] = label
+        data["properties"] = properties
+        url = f'{self._host}/graphs/{self._graph_name}/graph/vertices'
+        response = self.session.post(url, data=json.dumps(data), 
auth=self._auth,
+                                     headers=self._headers, 
timeout=self._timeout)
+        if check_if_success(response, CreateError("create vertex failed: 
{}".format(response.content))):
+            res = VertexData(json.loads(response.content))
+            return res
+
+    def addVertices(self, input_data):
+        url = f'{self._host}/graphs/{self._graph_name}/graph/vertices/batch'
+
+        data = []
+        for item in input_data:
+            data.append({'label': item[0], 'properties': item[1]})
+        response = self.session.post(url, data=json.dumps(data), 
auth=self._auth,
+                                     headers=self._headers, 
timeout=self._timeout)
+        if check_if_success(response, CreateError("create vertexes failed: 
{}".format(response.content))):
+            res = []
+            for item in json.loads(response.content):
+                res.append(VertexData({"id": item}))
+            return res
+
+    def appendVertex(self, vertex_id, properties):
+        url = 
f'{self._host}/graphs/{self._graph_name}/graph/vertices/"{vertex_id}"?action=append'
+
+        data = {
+            "properties": properties
+        }
+        response = self.session.put(url, data=json.dumps(data), 
auth=self._auth,
+                                    headers=self._headers, 
timeout=self._timeout)
+        if check_if_success(response, UpdateError("append vertex failed: 
{}".format(response.content))):
+            res = VertexData(json.loads(response.content))
+            return res
+
+    def eliminateVertex(self, vertex_id, properties):
+        url = 
f'{self._host}/graphs/{self._graph_name}/graph/vertices/"{vertex_id}"?action=eliminate'
+
+        data = {
+            "properties": properties
+        }
+        response = self.session.put(url, data=json.dumps(data), 
auth=self._auth, headers=self._headers,
+                                    timeout=self._timeout)
+        if check_if_success(response, UpdateError("eliminate vertex failed: 
{}".format(response.content))):
+            res = VertexData(json.loads(response.content))
+            return res
+
+    def getVertexById(self, vertex_id):
+        url = 
f'{self._host}/graphs/{self._graph_name}/graph/vertices/"{vertex_id}"'
+
+        response = self.session.get(url, auth=self._auth, 
headers=self._headers, timeout=self._timeout)
+        if check_if_success(response, NotFoundError("Vertex not found: 
{}".format(response.content))):
+            res = VertexData(json.loads(response.content))
+            return res
+
+    def getVertexByPage(self, label, limit, page, properties=None):
+        url = f'{self._host}/graphs/{self._graph_name}/graph/vertices?'
+
+        para = ""
+        para = para + "&label=" + label
+        if properties:
+            para = para + "&properties=" + json.dumps(properties)
+        if page:
+            para += '&page={}'.format(page)
+        else:
+            para += '&page'
+        para = para + "&limit=" + str(limit)
+        url = url + para[1:]
+        response = self.session.get(url, auth=self._auth, 
headers=self._headers, timeout=self._timeout)
+        if check_if_success(response, NotFoundError("Vertex not found: 
{}".format(response.content))):
+            res = []
+            for item in json.loads(response.content)["vertices"]:
+                res.append(VertexData(item))
+            next_page = json.loads(response.content)["page"]
+            return res, next_page
+
+    def getVertexByCondition(self, label="", limit=0, page='', 
properties=None):
+        url = f'{self._host}/graphs/{self._graph_name}/graph/vertices?'
+
+        para = ""
+        if label:
+            para = para + "&label=" + label
+        if properties:
+            para = para + "&properties=" + json.dumps(properties)
+        if limit > 0:
+            para = para + "&limit=" + str(limit)
+        if page:
+            para += '&page={}'.format(page)
+        else:
+            para += '&page'
+        url = url + para[1:]
+        response = self.session.get(url, auth=self._auth, 
headers=self._headers, timeout=self._timeout)
+        if check_if_success(response, NotFoundError("Vertex not found: 
{}".format(response.content))):
+            res = []
+            for item in json.loads(response.content)["vertices"]:
+                res.append(VertexData(item))
+            return res
+
+    def removeVertexById(self, vertex_id):
+        url = 
f'{self._host}/graphs/{self._graph_name}/graph/vertices/"{vertex_id}"'
+        response = self.session.delete(url, auth=self._auth, 
headers=self._headers, timeout=self._timeout)
+        if check_if_success(response, RemoveError("remove vertex failed: 
{}".format(response.content))):
+            return response.content
+
+    def addEdge(self, edge_label, out_id, in_id, properties):
+        url = f'{self._host}/graphs/{self._graph_name}/graph/edges'
+
+        data = {
+            "label": edge_label,
+            "outV": out_id,
+            "inV": in_id,
+            "properties": properties
+        }
+        response = self.session.post(url, data=json.dumps(data), 
auth=self._auth,
+                                     headers=self._headers, 
timeout=self._timeout)
+        if check_if_success(response, CreateError("created edge failed: 
{}".format(response.content))):
+            res = EdgeData(json.loads(response.content))
+            return res
+
+    def addEdges(self, input_data):
+        url = f'{self._host}/graphs/{self._graph_name}/graph/edges/batch'
+
+        data = []
+        for item in input_data:
+            data.append({'label': item[0], 'outV': item[1], 'inV': item[2], 
'outVLabel': item[3],
+                         'inVLabel': item[4], 'properties': item[5]})
+        response = self.session.post(url, data=json.dumps(data), 
auth=self._auth,
+                                     headers=self._headers, 
timeout=self._timeout)
+        if check_if_success(response, CreateError("created edges failed:  
{}".format(response.content))):
+            res = []
+            for item in json.loads(response.content):
+                res.append(EdgeData({"id": item}))
+            return res
+
+    def appendEdge(self, edge_id, properties):
+        url = 
f'{self._host}/graphs/{self._graph_name}/graph/edges/{edge_id}?action=append'
+
+        data = {
+            "properties": properties
+        }
+        response = self.session.put(url, data=json.dumps(data), 
auth=self._auth,
+                                    headers=self._headers, 
timeout=self._timeout)
+        if check_if_success(response, UpdateError("append edge failed: 
{}".format(response.content))):
+            res = EdgeData(json.loads(response.content))
+            return res
+
+    def eliminateEdge(self, edge_id, properties):
+        url = 
f'{self._host}/graphs/{self._graph_name}/graph/edges/{edge_id}?action=eliminate'
+
+        data = {
+            "properties": properties
+        }
+        response = self.session.put(url, data=json.dumps(data), 
auth=self._auth,
+                                    headers=self._headers, 
timeout=self._timeout)
+        if check_if_success(response, UpdateError("eliminate edge failed: 
{}".format(response.content))):
+            res = EdgeData(json.loads(response.content))
+            return res
+
+    def getEdgeById(self, edge_id):
+        url = f'{self._host}/graphs/{self._graph_name}/graph/edges/{edge_id}'
+
+        response = self.session.get(url, auth=self._auth, 
headers=self._headers, timeout=self._timeout)
+        if check_if_success(response, NotFoundError("not found edge: 
{}".format(response.content))):
+            res = EdgeData(json.loads(response.content))
+            return res
+
+    def getEdgeByPage(self, label=None, vertex_id=None, direction=None, 
limit=0, page=None, properties=None):
+        url = f'{self._host}/graphs/{self._graph_name}/graph/edges?'
+
+        para = ""
+        if vertex_id:
+            if direction:
+                para = para + "&vertex_id=\"" + vertex_id + "\"&direction=" + 
direction
+            else:
+                raise NotFoundError("Direction can not be empty.")
+        if label:
+            para = para + "&label=" + label
+        if properties:
+            para = para + "&properties=" + json.dumps(properties)
+        if page is not None:
+            if page:
+                para += '&page={}'.format(page)
+            else:
+                para += '&page'
+        if limit > 0:
+            para = para + "&limit=" + str(limit)
+        url = url + para[1:]
+        response = self.session.get(url, auth=self._auth, 
headers=self._headers, timeout=self._timeout)
+        if check_if_success(response, NotFoundError("not found edges: 
{}".format(response.content))):
+            res = []
+            for item in json.loads(response.content)["edges"]:
+                res.append(EdgeData(item))
+            return res, json.loads(response.content)["page"]
+
+    def removeEdgeById(self, edge_id):
+        url = f'{self._host}/graphs/{self._graph_name}/graph/edges/{edge_id}'
+
+        response = self.session.delete(url, auth=self._auth, 
headers=self._headers, timeout=self._timeout)
+        if check_if_success(response, RemoveError("remove edge failed: 
{}".format(response.content))):
+            return response.content
+
+    def getVerticesById(self, vertex_ids):
+        if not vertex_ids:
+            return []
+        url = f'{self._host}/graphs/{self._graph_name}/traversers/vertices?'
+        for vertex_id in vertex_ids:
+            url += 'ids="{}"&'.format(vertex_id)
+        url = url.rstrip("&")
+        response = self.session.get(url, auth=self._auth, 
headers=self._headers, timeout=self._timeout)
+        if response.status_code == 200 and check_if_authorized(response):
+            res = []
+            for item in json.loads(response.content)["vertices"]:
+                res.append(VertexData(item))
+            return res
+        else:
+            create_exception(response.content)
+
+    def getEdgesById(self, edge_ids):
+        if not edge_ids:
+            return []
+        url = f'{self._host}/graphs/{self._graph_name}/traversers/edges?'
+        for vertex_id in edge_ids:
+            url += 'ids={}&'.format(vertex_id)
+        url = url.rstrip("&")
+        response = self.session.get(url, auth=self._auth, 
headers=self._headers, timeout=self._timeout)
+        if response.status_code == 200 and check_if_authorized(response):
+            res = []
+            for item in json.loads(response.content)["edges"]:
+                res.append(EdgeData(item))
+            return res
+        else:
+            create_exception(response.content)
diff --git a/hugegraph-python/src/api/graphs.py 
b/hugegraph-python/src/api/graphs.py
new file mode 100644
index 0000000..b22ec3a
--- /dev/null
+++ b/hugegraph-python/src/api/graphs.py
@@ -0,0 +1,71 @@
+# 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 expresponses or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+import json
+import re
+
+import requests
+
+from src.api.common import HugeParamsBase
+
+from src.utils.constants import Constants
+from src.utils.exceptions import NotFoundError
+from src.utils.huge_requests import HugeSession
+from src.utils.util import check_if_success
+
+
+class GraphsManager(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 get_all_graphs(self):
+        url = f'{self._host}/graphs'
+        response = self.session.get(url, auth=self._auth, 
headers=self._headers)
+        if check_if_success(response, NotFoundError(response.content)):
+            return str(response.content)
+
+    def get_version(self):
+        url = f'{self._host}/versions'
+        response = self.session.get(url, auth=self._auth, 
headers=self._headers)
+        if check_if_success(response, NotFoundError(response.content)):
+            return str(response.content)
+
+    def get_graph_info(self):
+        url = f'{self._host}/graphs/{self._graph_name}'
+        response = self.session.get(url, auth=self._auth, 
headers=self._headers)
+        if check_if_success(response, NotFoundError(response.content)):
+            return str(response.content)
+
+    def clear_graph_all_data(self):
+        url = 
f'{self._host}/graphs/{self._graph_name}/clear?confirm_message={Constants.CONFORM_MESSAGE}'
+        response = self.session.delete(url, auth=self._auth, 
headers=self._headers)
+        if check_if_success(response, NotFoundError(response.content)):
+            return str(response.content)
+
+    def get_graph_config(self):
+        url = self._host + "/graphs" + "/" + self._graph_name + "/conf"
+        response = self.session.get(url, auth=self._auth, 
headers=self._headers)
+        if check_if_success(response, NotFoundError(response.content)):
+            return str(response.content)
diff --git a/hugegraph-python/src/api/gremlin.py 
b/hugegraph-python/src/api/gremlin.py
new file mode 100644
index 0000000..38a7c30
--- /dev/null
+++ b/hugegraph-python/src/api/gremlin.py
@@ -0,0 +1,48 @@
+# 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
+
+import requests
+
+from src.api.common import HugeParamsBase
+from src.structure.respon_data import ResponseData
+from src.utils.exceptions import NotFoundError
+from src.utils.huge_requests import HugeSession
+from src.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("Gremlin can't get results: 
{}".format(response.content))
+        if check_if_success(response, error):
+            return ResponseData(json.loads(response.content)).result
diff --git a/hugegraph-python/src/api/schema.py 
b/hugegraph-python/src/api/schema.py
new file mode 100644
index 0000000..9001028
--- /dev/null
+++ b/hugegraph-python/src/api/schema.py
@@ -0,0 +1,166 @@
+# 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 src.api.common import HugeParamsBase
+from src.api.schema_manage.edge_label import EdgeLabel
+from src.api.schema_manage.index_label import IndexLabel
+from src.api.schema_manage.property_key import PropertyKey
+from src.api.schema_manage.vertex_label import VertexLabel
+from src.structure.edge_label_data import EdgeLabelData
+from src.structure.index_label_data import IndexLabelData
+from src.structure.property_key_data import PropertyKeyData
+from src.structure.vertex_label_data import VertexLabelData
+from src.utils.exceptions import NotFoundError
+from src.utils.huge_requests import HugeSession
+from src.utils.util import check_if_success
+
+
+class SchemaManager(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()
+
+    """
+    create schemas, including propertyKey/vertexLabel/edgeLabel/indexLabel
+    """
+
+    def propertyKey(self, property_name):
+        property_key = PropertyKey(self._graph_instance, self.session)
+        property_key.create_parameter_holder()
+        property_key.add_parameter("name", property_name)
+        property_key.add_parameter("not_exist", True)
+        return property_key
+
+    def vertexLabel(self, vertex_name):
+        vertex_label = VertexLabel(self._graph_instance, self.session)
+        vertex_label.create_parameter_holder()
+        vertex_label.add_parameter("name", vertex_name)
+        # vertex_label.add_parameter("id_strategy", "AUTOMATIC")
+        vertex_label.add_parameter("not_exist", True)
+        return vertex_label
+
+    def edgeLabel(self, name):
+        edge_label = EdgeLabel(self._graph_instance, self.session)
+        edge_label.create_parameter_holder()
+        edge_label.add_parameter("name", name)
+        edge_label.add_parameter("not_exist", True)
+        return edge_label
+
+    def indexLabel(self, name):
+        index_label = IndexLabel(self._graph_instance, self.session)
+        index_label.create_parameter_holder()
+        index_label.add_parameter("name", name)
+        return index_label
+
+    """
+    create schemas
+    """
+    def getSchema(self):
+        url = f'{self._host}/graphs/{self._graph_name}/schema'
+        response = self.session.get(url, auth=self._auth, 
headers=self._headers)
+        error = NotFoundError(f"schema not found: {response.content}")
+        if check_if_success(response, error):
+            schema = json.loads(response.content)
+            return schema
+
+    def getPropertyKey(self, property_name):
+        url = 
f'{self._host}/graphs/{self._graph_name}/schema/propertykeys/{property_name}'
+        response = self.session.get(url, auth=self._auth, 
headers=self._headers)
+        error = NotFoundError(f"PropertyKey not found: {response.content}")
+        if check_if_success(response, error):
+            property_keys_data = PropertyKeyData(json.loads(response.content))
+            return property_keys_data
+
+    def getPropertyKeys(self):
+        url = f'{self._host}/graphs/{self._graph_name}/schema/propertykeys'
+        response = self.session.get(url, auth=self._auth, 
headers=self._headers)
+        res = []
+        if check_if_success(response):
+            for item in json.loads(response.content)["propertykeys"]:
+                res.append(PropertyKeyData(item))
+            return res
+
+    def getVertexLabel(self, name):
+        url = 
f'{self._host}/graphs/{self._graph_name}/schema/vertexlabels/{name}'
+        response = self.session.get(url, auth=self._auth, 
headers=self._headers)
+        error = NotFoundError("VertexLabel not found: 
{}".format(response.content))
+        if check_if_success(response, error):
+            res = VertexLabelData(json.loads(response.content))
+            return res
+
+    def getVertexLabels(self):
+        url = f'{self._host}/graphs/{self._graph_name}/schema/vertexlabels'
+        response = self.session.get(url, auth=self._auth, 
headers=self._headers)
+        res = []
+        if check_if_success(response):
+            for item in json.loads(response.content)["vertexlabels"]:
+                res.append(VertexLabelData(item))
+            return res
+
+    def getEdgeLabel(self, label_name):
+        url = 
f'{self._host}/graphs/{self._graph_name}/schema/edgelabels/{label_name}'
+        response = self.session.get(url, auth=self._auth, 
headers=self._headers)
+        error = NotFoundError("EdgeLabel not found: 
{}".format(response.content))
+        if check_if_success(response, error):
+            res = EdgeLabelData(json.loads(response.content))
+            return res
+
+    def getEdgeLabels(self):
+        url = f'{self._host}/graphs/{self._graph_name}/schema/edgelabels'
+        response = self.session.get(url, auth=self._auth, 
headers=self._headers)
+        res = []
+        if check_if_success(response):
+            for item in json.loads(response.content)["edgelabels"]:
+                res.append(EdgeLabelData(item))
+            return res
+
+    def getRelations(self):
+        url = f'{self._host}/graphs/{self._graph_name}/schema/edgelabels'
+        response = self.session.get(url, auth=self._auth, 
headers=self._headers)
+        res = []
+        if check_if_success(response):
+            for item in json.loads(response.content)["edgelabels"]:
+                res.append(EdgeLabelData(item).relations())
+            return res
+
+    def getIndexLabel(self, name):
+        url = 
f'{self._host}/graphs/{self._graph_name}/schema/indexlabels/{name}'
+        response = self.session.get(url, auth=self._auth, 
headers=self._headers)
+        error = NotFoundError("EdgeLabel not found: 
{}".format(response.content))
+        if check_if_success(response, error):
+            res = IndexLabelData(json.loads(response.content))
+            return res
+
+    def getIndexLabels(self):
+        url = f'{self._host}/graphs/{self._graph_name}/schema/indexlabels'
+        response = self.session.get(url, auth=self._auth, 
headers=self._headers)
+        res = []
+        if check_if_success(response):
+            for item in json.loads(response.content)['indexlabels']:
+                res.append(IndexLabelData(item))
+            return res
diff --git a/hugegraph-python/src/api/schema_manage/__init__.py 
b/hugegraph-python/src/api/schema_manage/__init__.py
new file mode 100644
index 0000000..e0533d9
--- /dev/null
+++ b/hugegraph-python/src/api/schema_manage/__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/src/api/schema_manage/edge_label.py 
b/hugegraph-python/src/api/schema_manage/edge_label.py
new file mode 100644
index 0000000..31d81d9
--- /dev/null
+++ b/hugegraph-python/src/api/schema_manage/edge_label.py
@@ -0,0 +1,150 @@
+# 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 expresponses or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+import json
+
+from src.api.common import HugeParamsBase
+from src.utils.exceptions import CreateError, UpdateError, RemoveError
+from src.utils.huge_decorator import decorator_params, decorator_create
+from src.utils.util import check_if_success, check_if_authorized
+
+
+class EdgeLabel(HugeParamsBase):
+    def __init__(self, graph_instance, session):
+        super().__init__(graph_instance)
+        self.session = session
+
+    @decorator_params
+    def link(self, source_label, target_label):
+        self._parameter_holder.set("source_label", source_label)
+        self._parameter_holder.set("target_label", target_label)
+        return self
+
+    @decorator_params
+    def sourceLabel(self, source_label):
+        self._parameter_holder.set("source_label", source_label)
+        return self
+
+    @decorator_params
+    def targetLabel(self, target_label):
+        self._parameter_holder.set("target_label", target_label)
+        return self
+
+    @decorator_params
+    def userdata(self, *args):
+        if not self._parameter_holder.get_value("user_data"):
+            self._parameter_holder.set('user_data', dict())
+        user_data = self._parameter_holder.get_value("user_data")
+        i = 0
+        while i < len(args):
+            user_data[args[i]] = args[i + 1]
+            i += 2
+        return self
+
+    @decorator_params
+    def properties(self, *args):
+        self._parameter_holder.set("properties", list(args))
+        return self
+
+    @decorator_params
+    def singleTime(self):
+        self._parameter_holder.set("frequency", "SINGLE")
+        return self
+
+    @decorator_params
+    def multiTimes(self):
+        self._parameter_holder.set("frequency", "MULTIPLE")
+        return self
+
+    @decorator_params
+    def sortKeys(self, *args):
+        self._parameter_holder.set("sort_keys", list(args))
+        return self
+
+    @decorator_params
+    def nullableKeys(self, *args):
+        nullable_keys = set(args)
+        self._parameter_holder.set("nullable_keys", list(nullable_keys))
+        return self
+
+    @decorator_params
+    def ifNotExist(self):
+        url = 
f'{self._host}/graphs/{self._graph_name}/schema/edgelabels/{self._parameter_holder.get_value("name")}'
+
+        response = self.session.get(url, auth=self._auth, 
headers=self._headers)
+        if response.status_code == 200 and check_if_authorized(response):
+            self._parameter_holder.set("not_exist", False)
+        return self
+
+    @decorator_create
+    def create(self):
+        dic = self._parameter_holder.get_dic()
+        data = dict()
+        keys = ['name', 'source_label', 'target_label', 'nullable_keys', 
'properties',
+                'enable_label_index', 'sort_keys', 'user_data', 'frequency']
+        for key in keys:
+            if key in dic:
+                data[key] = dic[key]
+        url = f'{self._host}/graphs/{self._graph_name}/schema/edgelabels'
+        response = self.session.post(url, data=json.dumps(data), 
auth=self._auth, headers=self._headers)
+        self.clean_parameter_holder()
+        error = CreateError('CreateError: "create EdgeLabel failed", Detail:  
"{}"'
+                            .format(str(response.content)))
+        if check_if_success(response, error):
+            return 'create EdgeLabel success, Detail: 
"{}"'.format(str(response.content))
+
+    @decorator_params
+    def remove(self):
+        url = 
f'{self._host}/graphs/{self._graph_name}/schema/edgelabels/{self._parameter_holder.get_value("name")}'
+        response = self.session.delete(url, auth=self._auth, 
headers=self._headers)
+        self.clean_parameter_holder()
+        error = RemoveError('RemoveError: "remove EdgeLabel failed", Detail:  
"{}"'
+                            .format(str(response.content)))
+        if check_if_success(response, error):
+            return 'remove EdgeLabel success, Detail: 
"{}"'.format(str(response.content))
+
+    @decorator_params
+    def append(self):
+        dic = self._parameter_holder.get_dic()
+        data = dict()
+        keys = ['name', 'nullable_keys', 'properties', 'user_data']
+        for key in keys:
+            if key in dic:
+                data[key] = dic[key]
+
+        url = 
f'{self._host}/graphs/{self._graph_name}/schema/edgelabels/{data["name"]}?action=append'
+        response = self.session.put(url, data=json.dumps(data), 
auth=self._auth, headers=self._headers)
+        self.clean_parameter_holder()
+        error = UpdateError('UpdateError: "append EdgeLabel failed", Detail: 
"{}"'.format(str(response.content)))
+        if check_if_success(response, error):
+            return 'append EdgeLabel success, Detail: 
"{}"'.format(str(response.content))
+
+    @decorator_params
+    def eliminate(self):
+        name = self._parameter_holder.get_value("name")
+        user_data = self._parameter_holder.get_value("user_data") if \
+            self._parameter_holder.get_value("user_data") else {}
+        url = 
f'{self._host}/graphs/{self._graph_name}/schema/edgelabels/{name}?action=eliminate'
+        data = {
+            "name": name,
+            "user_data": user_data
+        }
+        response = self.session.put(url, data=json.dumps(data), 
auth=self._auth, headers=self._headers)
+        self.clean_parameter_holder()
+        error = UpdateError('UpdateError: "eliminate EdgeLabel failed", 
Detail: "{}"'.format(str(response.content)))
+        if check_if_success(response, error):
+            return 'eliminate EdgeLabel success, Detail: 
"{}"'.format(str(response.content))
diff --git a/hugegraph-python/src/api/schema_manage/index_label.py 
b/hugegraph-python/src/api/schema_manage/index_label.py
new file mode 100644
index 0000000..cc93a91
--- /dev/null
+++ b/hugegraph-python/src/api/schema_manage/index_label.py
@@ -0,0 +1,103 @@
+# 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 requests
+
+from src.api.common import HugeParamsBase
+from src.utils.huge_decorator import decorator_params, decorator_create
+from src.utils.exceptions import CreateError, RemoveError
+from src.utils.util import check_if_authorized, check_if_success
+
+
+class IndexLabel(HugeParamsBase):
+    def __init__(self, graph_instance, session):
+        super().__init__(graph_instance)
+        self.session = session
+
+    @decorator_params
+    def onV(self, vertex_label):
+        self._parameter_holder.set("base_value", vertex_label)
+        self._parameter_holder.set("base_type", "VERTEX_LABEL")
+        return self
+
+    @decorator_params
+    def onE(self, edge_label):
+        self._parameter_holder.set("base_value", edge_label)
+        self._parameter_holder.set("base_type", "EDGE_LABEL")
+        return self
+
+    @decorator_params
+    def by(self, *args):
+        if "fields" not in self._parameter_holder.get_keys():
+            self._parameter_holder.set("fields", set())
+        s = self._parameter_holder.get_value("fields")
+        for item in args:
+            s.add(item)
+        return self
+
+    @decorator_params
+    def secondary(self):
+        self._parameter_holder.set("index_type", "SECONDARY")
+        return self
+
+    @decorator_params
+    def range(self):
+        self._parameter_holder.set("index_type", "RANGE")
+        return self
+
+    @decorator_params
+    def Search(self):
+        self._parameter_holder.set("index_type", "SEARCH")
+        return self
+
+    @decorator_params
+    def ifNotExist(self):
+        url = 
f'{self._host}/graphs/{self._graph_name}/schema/indexlabels/{self._parameter_holder.get_value("name")}'
+        response = self.session.get(url, auth=self._auth, 
headers=self._headers)
+        if response.status_code == 200 and check_if_authorized(response):
+            self._parameter_holder.set("not_exist", False)
+        return self
+
+    @decorator_create
+    def create(self):
+        dic = self._parameter_holder.get_dic()
+        data = dict()
+        data["name"] = dic["name"]
+        data["base_type"] = dic["base_type"]
+        data["base_value"] = dic["base_value"]
+        data["index_type"] = dic["index_type"]
+        data["fields"] = list(dic["fields"])
+        url = f'{self._host}/graphs/{self._graph_name}/schema/indexlabels'
+        response = self.session.post(url, data=json.dumps(data), 
auth=self._auth, headers=self._headers)
+        self.clean_parameter_holder()
+        error = CreateError('CreateError: "create IndexLabel failed", '
+                            'Detail "{}"'.format(str(response.content)))
+        if check_if_success(response, error):
+            return 'create IndexLabel success, Deatil: 
"{}"'.format(str(response.content))
+
+    @decorator_params
+    def remove(self):
+        name = self._parameter_holder.get_value("name")
+        url = 
f'{self._host}/graphs/{self._graph_name}/schema/indexlabels/{name}'
+        response = self.session.delete(url, auth=self._auth, 
headers=self._headers)
+        self.clean_parameter_holder()
+        error = RemoveError('RemoveError: "remove IndexLabel failed", '
+                            'Detail "{}"'.format(str(response.content)))
+        if check_if_success(response, error):
+            return 'remove IndexLabel success, Deatil: 
"{}"'.format(str(response.content))
diff --git a/hugegraph-python/src/api/schema_manage/property_key.py 
b/hugegraph-python/src/api/schema_manage/property_key.py
new file mode 100644
index 0000000..6f9cce4
--- /dev/null
+++ b/hugegraph-python/src/api/schema_manage/property_key.py
@@ -0,0 +1,168 @@
+# 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 expresponses or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+import json
+
+import requests
+
+from src.api.common import HugeParamsBase
+from src.utils.exceptions import CreateError, UpdateError, RemoveError
+from src.utils.huge_decorator import decorator_params, decorator_create
+from src.utils.util import check_if_success, check_if_authorized
+
+
+class PropertyKey(HugeParamsBase):
+    def __init__(self, graph_instance, session):
+        super().__init__(graph_instance)
+        self.session = session
+
+    @decorator_params
+    def asInt(self):
+        self._parameter_holder.set("data_type", "INT")
+        return self
+
+    @decorator_params
+    def asText(self):
+        self._parameter_holder.set("data_type", "TEXT")
+        return self
+
+    @decorator_params
+    def asDouble(self):
+        self._parameter_holder.set("data_type", "DOUBLE")
+        return self
+
+    @decorator_params
+    def asDate(self):
+        self._parameter_holder.set("data_type", "DATE")
+        return self
+
+    @decorator_params
+    def valueSingle(self):
+        self._parameter_holder.set("cardinality", "SINGLE")
+        return self
+
+    @decorator_params
+    def valueList(self):
+        self._parameter_holder.set("cardinality", "LIST")
+        return self
+
+    @decorator_params
+    def valueSet(self):
+        self._parameter_holder.set("cardinality", "SET")
+        return self
+
+    @decorator_params
+    def calcMax(self):
+        self._parameter_holder.set("aggregate_type", "MAX")
+        return self
+
+    @decorator_params
+    def calcMin(self):
+        self._parameter_holder.set("aggregate_type", "MIN")
+        return self
+
+    @decorator_params
+    def calcSum(self):
+        self._parameter_holder.set("aggregate_type", "SUM")
+        return self
+
+    @decorator_params
+    def calcOld(self):
+        self._parameter_holder.set("aggregate_type", "OLD")
+        return self
+
+    @decorator_params
+    def userdata(self, *args):
+        user_data = self._parameter_holder.get_value("user_data")
+        if not user_data:
+            self._parameter_holder.set("user_data", dict())
+            user_data = self._parameter_holder.get_value("user_data")
+        i = 0
+        while i < len(args):
+            user_data[args[i]] = args[i + 1]
+            i += 2
+        return self
+
+    def ifNotExist(self):
+        url = 
f'{self._host}/graphs/{self._graph_name}/schema/propertykeys/{self._parameter_holder.get_value("name")}'
+        response = self.session.get(url, auth=self._auth, 
headers=self._headers)
+        if response.status_code == 200 and check_if_authorized(response):
+            self._parameter_holder.set("not_exist", False)
+        return self
+
+    @decorator_create
+    def create(self):
+        dic = self._parameter_holder.get_dic()
+        property_keys = {
+            "name": dic["name"]
+        }
+        if "data_type" in dic:
+            property_keys["data_type"] = dic["data_type"]
+        if "cardinality" in dic:
+            property_keys["cardinality"] = dic["cardinality"]
+        url = f'{self._host}/graphs/{self._graph_name}/schema/propertykeys'
+        response = self.session.post(url, data=json.dumps(property_keys), 
auth=self._auth, headers=self._headers)
+        self.clean_parameter_holder()
+        if check_if_success(response, CreateError(
+                'CreateError: "create PropertyKey failed", Detail: 
{}'.format(response.content))):
+            return 'create PropertyKey success, Detail: 
{}'.format(response.content)
+
+    @decorator_params
+    def append(self):
+        property_name = self._parameter_holder.get_value("name")
+        user_data = self._parameter_holder.get_value("user_data")
+        if not user_data:
+            user_data = dict()
+        data = {
+            "name": property_name,
+            "user_data": user_data
+        }
+
+        url = 
f'{self._host}/graphs/{self._graph_name}/schema/propertykeys/{property_name}/?action=append'
+        response = self.session.put(url, data=json.dumps(data), 
auth=self._auth, headers=self._headers)
+        self.clean_parameter_holder()
+        if check_if_success(response, UpdateError(
+                'UpdateError: "append PropertyKey failed", Detail: 
{}'.format(response.content))):
+            return 'append PropertyKey success, Detail: 
{}'.format(response.content)
+
+    @decorator_params
+    def eliminate(self):
+        property_name = self._parameter_holder.get_value("name")
+        user_data = self._parameter_holder.get_value("user_data")
+        if not user_data:
+            user_data = dict()
+        data = {
+            "name": property_name,
+            "user_data": user_data
+        }
+
+        url = 
f'{self._host}/graphs/{self._graph_name}/schema/propertykeys/{property_name}/?action=eliminate'
+        response = self.session.put(url, data=json.dumps(data), 
auth=self._auth, headers=self._headers)
+        self.clean_parameter_holder()
+        error = UpdateError(f'UpdateError: "eliminate PropertyKey failed", 
Detail: {str(response.content)}')
+        if check_if_success(response, error):
+            return 'eliminate PropertyKey success, Detail: 
{}'.format(str(response.content))
+
+    @decorator_params
+    def remove(self):
+        dic = self._parameter_holder.get_dic()
+        url = 
f'{self._host}/graphs/{self._graph_name}/schema/propertykeys/{dic["name"]}'
+        response = self.session.delete(url)
+        self.clean_parameter_holder()
+        if check_if_success(response, RemoveError(
+                'RemoveError: "delete PropertyKey failed", Detail: 
{}'.format(str(response.content)))):
+            return 'delete PropertyKey success, Detail: {}'.format(dic["name"])
diff --git a/hugegraph-python/src/api/schema_manage/vertex_label.py 
b/hugegraph-python/src/api/schema_manage/vertex_label.py
new file mode 100644
index 0000000..462fe13
--- /dev/null
+++ b/hugegraph-python/src/api/schema_manage/vertex_label.py
@@ -0,0 +1,156 @@
+# 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 requests
+
+from src.api.common import HugeParamsBase
+from src.utils.exceptions import CreateError, UpdateError, RemoveError
+from src.utils.huge_decorator import decorator_params, decorator_create
+from src.utils.util import check_if_success, check_if_authorized
+
+
+class VertexLabel(HugeParamsBase):
+    def __init__(self, graph_instance, session):
+        super().__init__(graph_instance)
+        self.session = session
+
+    @decorator_params
+    def useAutomaticId(self):
+        self._parameter_holder.set("id_strategy", "AUTOMATIC")
+        return self
+
+    @decorator_params
+    def useCustomizeStringId(self):
+        self._parameter_holder.set("id_strategy", "CUSTOMIZE_STRING")
+        return self
+
+    @decorator_params
+    def useCustomizeNumberId(self):
+        self._parameter_holder.set("id_strategy", "CUSTOMIZE_NUMBER")
+        return self
+
+    @decorator_params
+    def usePrimaryKeyId(self):
+        self._parameter_holder.set("id_strategy", "PRIMARY_KEY")
+        return self
+
+    @decorator_params
+    def properties(self, *args):
+        self._parameter_holder.set("properties", list(args))
+        return self
+
+    @decorator_params
+    def primaryKeys(self, *args):
+        self._parameter_holder.set("primary_keys", list(args))
+        return self
+
+    @decorator_params
+    def nullableKeys(self, *args):
+        self._parameter_holder.set("nullable_keys", list(args))
+        return self
+
+    @decorator_params
+    def enableLabelIndex(self, flag):
+        self._parameter_holder.set("enable_label_index", flag)
+        return self
+
+    @decorator_params
+    def userdata(self, *args):
+        if "user_data" not in self._parameter_holder.get_keys():
+            self._parameter_holder.set('user_data', dict())
+        user_data = self._parameter_holder.get_value('user_data')
+        i = 0
+        while i < len(args):
+            user_data[args[i]] = args[i + 1]
+            i += 2
+        return self
+
+    def ifNotExist(self):
+        url = 
f'{self._host}/graphs/{self._graph_name}/schema/vertexlabels/{self._parameter_holder.get_value("name")}'
+
+        response = self.session.get(url, auth=self._auth, 
headers=self._headers)
+        if response.status_code == 200 and check_if_authorized(response):
+            self._parameter_holder.set("not_exist", False)
+        return self
+
+    @decorator_create
+    def create(self):
+        dic = self._parameter_holder.get_dic()
+        key_list = ["name", "id_strategy", "primary_keys", "nullable_keys", 
"index_labels",
+                    "properties", "enable_label_index", "user_data"]
+        data = {}
+        for key in key_list:
+            if key in dic:
+                data[key] = dic[key]
+        url = f'{self._host}/graphs/{self._graph_name}/schema/vertexlabels'
+        response = self.session.post(url, data=json.dumps(data), 
auth=self._auth, headers=self._headers)
+        self.clean_parameter_holder()
+        error = CreateError('CreateError: "create VertexLabel failed", Detail: 
"{}"'
+                            .format(str(response.content)))
+        if check_if_success(response, error):
+            return 'create VertexLabel success, Detail: 
"{}"'.format(str(response.content))
+
+    @decorator_params
+    def append(self):
+        dic = self._parameter_holder.get_dic()
+        properties = dic['properties'] if "properties" in dic else []
+        nullable_keys = dic['nullable_keys'] if "nullable_keys" in dic else []
+        user_data = dic['user_data'] if 'user_data' in dic else {}
+        url = 
f'{self._host}/graphs/{self._graph_name}/schema/vertexlabels/{dic["name"]}?action=append'
+
+        data = {
+            "name": dic["name"],
+            "properties": properties,
+            "nullable_keys": nullable_keys,
+            "user_data": user_data
+        }
+        response = self.session.put(url, data=json.dumps(data), 
auth=self._auth, headers=self._headers)
+        self.clean_parameter_holder()
+        error = UpdateError('UpdateError: "append VertexLabel failed", Detail: 
"{}"'.
+                            format(str(response.content)))
+        if check_if_success(response, error):
+            return 'append VertexLabel success, Detail: 
"{}"'.format(str(response.content))
+
+    @decorator_params
+    def remove(self):
+        name = self._parameter_holder.get_value("name")
+        url = 
f'{self._host}/graphs/{self._graph_name}/schema/vertexlabels/{name}'
+        response = self.session.delete(url, auth=self._auth, 
headers=self._headers)
+        self.clean_parameter_holder()
+        error = RemoveError('RemoveError: "remove VertexLabel failed", Detail: 
"{}"'.
+                            format(str(response.content)))
+        if check_if_success(response, error):
+            return 'remove VertexLabel success, Detail: 
"{}"'.format(str(response.content))
+
+    @decorator_params
+    def eliminate(self):
+        name = self._parameter_holder.get_value("name")
+        url = 
f'{self._host}/graphs/{self._graph_name}/schema/vertexlabels/{name}/?action=eliminate'
+
+        dic = self._parameter_holder.get_dic()
+        user_data = dic['user_data'] if 'user_data' in dic else {}
+        data = {
+            "name": self._parameter_holder.get_value("name"),
+            "user_data": user_data,
+        }
+        response = self.session.put(url, data=json.dumps(data), 
auth=self._auth, headers=self._headers)
+        error = UpdateError('UpdateError: "eliminate VertexLabel failed", 
Detail: "{}"'.
+                            format(str(response.content)))
+        if check_if_success(response, error):
+            return 'eliminate VertexLabel success, Detail: 
"{}"'.format(str(response.content))
diff --git a/hugegraph-python/src/client.py b/hugegraph-python/src/client.py
new file mode 100644
index 0000000..b039725
--- /dev/null
+++ b/hugegraph-python/src/client.py
@@ -0,0 +1,57 @@
+# 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 src.api.common import HugeParamsBase
+from src.api.graph import GraphManager
+from src.api.graphs import GraphsManager
+from src.api.gremlin import GremlinManager
+from src.api.schema import SchemaManager
+from src.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
diff --git a/hugegraph-python/src/structure/__init__.py 
b/hugegraph-python/src/structure/__init__.py
new file mode 100644
index 0000000..e0533d9
--- /dev/null
+++ b/hugegraph-python/src/structure/__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/src/structure/edge_data.py 
b/hugegraph-python/src/structure/edge_data.py
new file mode 100644
index 0000000..1269e0a
--- /dev/null
+++ b/hugegraph-python/src/structure/edge_data.py
@@ -0,0 +1,64 @@
+# 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.
+
+
+class EdgeData:
+    def __init__(self, dic):
+        self.__id = dic["id"]
+        self.__label = dic["label"] if "label" in dic else None
+        self.__type = dic["type"] if "type" in dic else None
+        self.__outV = dic["outV"] if "outV" in dic else None
+        self.__outVLabel = dic["outVLabel"] if "outVLabel" in dic else None
+        self.__inV = dic["inV"] if "inV" in dic else None
+        self.__inVLabel = dic["inVLabel"] if "inVLabel" in dic else None
+        self.__properties = dic["properties"] if "properties" in dic else None
+
+    @property
+    def id(self):
+        return self.__id
+
+    @property
+    def label(self):
+        return self.__label
+
+    @property
+    def type(self):
+        return self.__type
+
+    @property
+    def outV(self):
+        return self.__outV
+
+    @property
+    def outVLabel(self):
+        return self.__outVLabel
+
+    @property
+    def inV(self):
+        return self.__inV
+
+    @property
+    def inVLabel(self):
+        return self.__inVLabel
+
+    @property
+    def properties(self):
+        return self.__properties
+
+    def __repr__(self):
+        res = "{}--{}-->{}".format(self.__outV, self.__label, self.__inV)
+        return res
diff --git a/hugegraph-python/src/structure/edge_label_data.py 
b/hugegraph-python/src/structure/edge_label_data.py
new file mode 100644
index 0000000..57cfc58
--- /dev/null
+++ b/hugegraph-python/src/structure/edge_label_data.py
@@ -0,0 +1,78 @@
+# 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.
+
+
+class EdgeLabelData:
+    def __init__(self, dic):
+        self.__id = dic["id"]
+        self.__name = dic["name"]
+        self.__source_label = dic["source_label"]
+        self.__target_label = dic["target_label"]
+        self.__frequency = dic["frequency"]
+        self.__sort_keys = dic["sort_keys"]
+        self.__nullable_keys = dic["nullable_keys"]
+        self.__index_labels = dic["index_labels"]
+        self.__properties = dic["properties"]
+        self.__enable_label_index = dic["enable_label_index"]
+        self.__user_data = dic["user_data"]
+
+    @property
+    def id(self):
+        return self.__id
+
+    @property
+    def name(self):
+        return self.__name
+
+    @property
+    def sourceLabel(self):
+        return self.__source_label
+
+    @property
+    def targetLabel(self):
+        return self.__target_label
+
+    @property
+    def frequency(self):
+        return self.__frequency
+
+    @property
+    def sortKeys(self):
+        return self.__sort_keys
+
+    @property
+    def properties(self):
+        return self.__properties
+
+    @property
+    def nullableKeys(self):
+        return self.__nullable_keys
+
+    @property
+    def userdata(self):
+        return self.__user_data
+
+    def relations(self):
+        res = "{}--{}-->{}".format(
+            self.__source_label, self.__name, self.__target_label)
+        return res
+
+    def __repr__(self):
+        res = "name: {}, properties: {}".format(
+            self.__name
+            , self.__properties)
+        return res
diff --git a/hugegraph-python/src/structure/graph_instance.py 
b/hugegraph-python/src/structure/graph_instance.py
new file mode 100644
index 0000000..34bed43
--- /dev/null
+++ b/hugegraph-python/src/structure/graph_instance.py
@@ -0,0 +1,54 @@
+# 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.
+
+
+class GraphInstance:
+    def __init__(self, ip, port, graph_name, user_name, passwd, timeout):
+        self.__ip = ip
+        self.__port = port
+        self.__graph_name = graph_name
+        self.__user_name = user_name
+        self.__passwd = passwd
+        self.__timeout = timeout
+
+    @property
+    def ip(self):
+        return self.__ip
+
+    @property
+    def port(self):
+        return self.__port
+
+    @property
+    def graph_name(self):
+        return self.__graph_name
+
+    @property
+    def user_name(self):
+        return self.__user_name
+
+    @property
+    def passwd(self):
+        return self.__passwd
+
+    @property
+    def timeout(self):
+        return self.__timeout
+
+    def __repr__(self):
+        res = f"ip:{self.ip}, port:{self.port}, graph_name:{self.graph_name}, 
user_name:{self.user_name}, passwd:{self.passwd}, timeout:{self.timeout}"
+        return res
diff --git a/hugegraph-python/src/structure/index_label_data.py 
b/hugegraph-python/src/structure/index_label_data.py
new file mode 100644
index 0000000..4f60233
--- /dev/null
+++ b/hugegraph-python/src/structure/index_label_data.py
@@ -0,0 +1,56 @@
+# 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.
+
+
+class IndexLabelData:
+    def __init__(self, dic):
+        self.__id = dic["id"] if "id" in dic else None
+        self.__base_type = dic["base_type"] if "base_type" in dic else None
+        self.__base_value = dic["base_value"] if "base_value" in dic else None
+        self.__name = dic["name"] if "name" in dic else None
+        self.__fields = dic["fields"] if "fields" in dic else None
+        self.__index_type = dic["index_type"] if "index_type" in dic else None
+
+    @property
+    def id(self):
+        return self.__id
+
+    @property
+    def baseType(self):
+        return self.__base_type
+
+    @property
+    def baseValue(self):
+        return self.__base_value
+
+    @property
+    def name(self):
+        return self.__name
+
+    @property
+    def fields(self):
+        return self.__fields
+
+    @property
+    def indexType(self):
+        return self.__index_type
+
+    def __repr__(self):
+        res = "index_name: {}, base_value: {}, base_type: {}, fields: [], 
index_type: {}"\
+            .format(self.__name, self.__base_value, self.__base_type, 
self.__fields,
+                    self.__index_type)
+        return res
diff --git a/hugegraph-python/src/structure/property_key_data.py 
b/hugegraph-python/src/structure/property_key_data.py
new file mode 100644
index 0000000..665d632
--- /dev/null
+++ b/hugegraph-python/src/structure/property_key_data.py
@@ -0,0 +1,51 @@
+# 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.
+
+
+class PropertyKeyData:
+    def __init__(self, dic):
+        self.__id = dic["id"]
+        self.__name = dic["name"]
+        self.__cardinality = dic["cardinality"]
+        self.__data_type = dic["data_type"]
+        self.__user_data = dic["user_data"]
+
+    @property
+    def id(self):
+        return self.__id
+
+    @property
+    def cardinality(self):
+        return self.__cardinality
+
+    @property
+    def name(self):
+        return self.__name
+
+    @property
+    def dataType(self):
+        return self.__data_type
+
+    @property
+    def userdata(self):
+        return self.__user_data
+
+    def __repr__(self):
+        res = "name: {}, cardinality: {}, data_type: {}".format(
+            self.__name, self.__cardinality, self.__data_type
+        )
+        return res
diff --git a/hugegraph-python/src/structure/respon_data.py 
b/hugegraph-python/src/structure/respon_data.py
new file mode 100644
index 0000000..cbbbc81
--- /dev/null
+++ b/hugegraph-python/src/structure/respon_data.py
@@ -0,0 +1,39 @@
+# 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.
+
+
+class ResponseData:
+    def __init__(self, dic):
+        self.__id = dic["requestId"]
+        self.__status = dic["status"]
+        self.__result = dic["result"]
+
+    @property
+    def id(self):
+        return self.__id
+
+    @property
+    def status(self):
+        return self.__status
+
+    @property
+    def result(self):
+        return self.__result
+
+    def __repr__(self):
+        res = "id: {}, status: {}, result: {}".format(self.__id, 
self.__status, self.__result)
+        return res
diff --git a/hugegraph-python/src/structure/vertex_data.py 
b/hugegraph-python/src/structure/vertex_data.py
new file mode 100644
index 0000000..eb358bc
--- /dev/null
+++ b/hugegraph-python/src/structure/vertex_data.py
@@ -0,0 +1,44 @@
+# 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.
+
+
+class VertexData:
+    def __init__(self, dic):
+        self.__id = dic["id"]
+        self.__label = dic["label"] if "label" in dic else None
+        self.__type = dic["type"] if "type" in dic else None
+        self.__properties = dic["properties"] if "properties" in dic else None
+
+    @property
+    def id(self):
+        return self.__id
+
+    @property
+    def label(self):
+        return self.__label
+
+    @property
+    def type(self):
+        return self.__type
+
+    @property
+    def properties(self):
+        return self.__properties
+
+    def __repr__(self):
+        res = "id: {}, label: {}, type: {}".format(self.__id, self.__label, 
self.__type)
+        return res
diff --git a/hugegraph-python/src/structure/vertex_label_data.py 
b/hugegraph-python/src/structure/vertex_label_data.py
new file mode 100644
index 0000000..fe2a8b5
--- /dev/null
+++ b/hugegraph-python/src/structure/vertex_label_data.py
@@ -0,0 +1,62 @@
+# 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.
+
+
+class VertexLabelData:
+    def __init__(self, dic):
+        self.__id = dic["id"]
+        self.__name = dic["name"]
+        self.__id_strategy = dic["id_strategy"]
+        self.__primary_keys = dic["primary_keys"]
+        self.__nullable_keys = dic["nullable_keys"]
+        self.__index_labels = dic["index_labels"]
+        self.__properties = dic["properties"]
+        self.__enable_label_index = dic["enable_label_index"]
+        self.__user_data = dic["user_data"]
+
+    @property
+    def id(self):
+        return self.__id
+
+    @property
+    def name(self):
+        return self.__name
+
+    @property
+    def primaryKeys(self):
+        return self.__primary_keys
+
+    @property
+    def idStrategy(self):
+        return self.__id_strategy
+
+    @property
+    def properties(self):
+        return self.__properties
+
+    @property
+    def nullableKeys(self):
+        return self.__nullable_keys
+
+    @property
+    def userdata(self):
+        return self.__user_data
+
+    def __repr__(self):
+        res = "name: {}, primary_keys: {}, properties: {}".format(
+            self.__name, self.__primary_keys, self.__properties)
+        return res
diff --git a/hugegraph-python/src/utils/__init__.py 
b/hugegraph-python/src/utils/__init__.py
new file mode 100644
index 0000000..e0533d9
--- /dev/null
+++ b/hugegraph-python/src/utils/__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/src/utils/constants.py 
b/hugegraph-python/src/utils/constants.py
new file mode 100644
index 0000000..27a5b84
--- /dev/null
+++ b/hugegraph-python/src/utils/constants.py
@@ -0,0 +1,21 @@
+# 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.
+
+
+class Constants(str):
+    CONFORM_MESSAGE = "I%27m+sure+to+delete+all+data"
+    HEADER_CONTENT_TYPE = "application/json"
diff --git a/hugegraph-python/src/utils/exceptions.py 
b/hugegraph-python/src/utils/exceptions.py
new file mode 100644
index 0000000..7cfb4aa
--- /dev/null
+++ b/hugegraph-python/src/utils/exceptions.py
@@ -0,0 +1,62 @@
+# 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.
+
+
+class NotAuthorizedError(Exception):
+    """
+        Not Authorized
+    """
+
+class InvalidParameter(Exception):
+    """
+        Parameter setting error
+    """
+
+class NotFoundError(Exception):
+    """
+        no content found
+    """
+
+
+class CreateError(Exception):
+    """
+        Failed to create vertex or edge
+    """
+
+
+class RemoveError(Exception):
+    """
+        Failed to delete vertex or edge
+    """
+
+
+class UpdateError(Exception):
+    """
+        Failed to modify node
+    """
+
+
+class DataFormatError(Exception):
+    """
+        Input data format error
+    """
+
+
+class ServiceUnavailableException(Exception):
+    """
+        The server is too busy to be available
+    """
diff --git a/hugegraph-python/src/utils/huge_decorator.py 
b/hugegraph-python/src/utils/huge_decorator.py
new file mode 100644
index 0000000..9077bb8
--- /dev/null
+++ b/hugegraph-python/src/utils/huge_decorator.py
@@ -0,0 +1,45 @@
+# 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 decorator import decorator
+
+from src.utils.exceptions import NotAuthorizedError
+
+
+@decorator
+def decorator_params(func, *args, **kwargs):
+    parameter_holder = args[0].get_parameter_holder()
+    if parameter_holder is None or "name" not in parameter_holder.get_keys():
+        print('Parameters required, please set necessary parameters.')
+        raise
+    return func(*args, **kwargs)
+
+
+@decorator
+def decorator_create(func, *args, **kwargs):
+    parameter_holder = args[0].get_parameter_holder()
+    if parameter_holder.get_value('not_exist') is False:
+        return 'Create failed, "{}" already 
exists.'.format(parameter_holder.get_value('name'))
+    return func(*args, **kwargs)
+
+
+@decorator
+def decorator_auth(func, *args, **kwargs):
+    response = args[0]
+    if response.status_code == 401:
+        raise NotAuthorizedError("NotAuthorized: {}".format(response.content))
+    return func(*args, **kwargs)
diff --git a/hugegraph-python/src/utils/huge_requests.py 
b/hugegraph-python/src/utils/huge_requests.py
new file mode 100644
index 0000000..744e8b5
--- /dev/null
+++ b/hugegraph-python/src/utils/huge_requests.py
@@ -0,0 +1,32 @@
+# 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 requests
+from requests.adapters import HTTPAdapter
+from urllib3.util.retry import Retry
+
+
+class HugeSession:
+    @staticmethod
+    def new_session():
+        session = requests.Session()
+        retry = Retry(connect=5, backoff_factor=1)
+        adapter = HTTPAdapter(max_retries=retry)
+        session.mount('http://', adapter)
+        session.mount('https://', adapter)
+        session.keep_alive = False
+        return session
diff --git a/hugegraph-python/src/utils/util.py 
b/hugegraph-python/src/utils/util.py
new file mode 100644
index 0000000..9b9424b
--- /dev/null
+++ b/hugegraph-python/src/utils/util.py
@@ -0,0 +1,43 @@
+# 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 src.utils.exceptions import ServiceUnavailableException, 
NotAuthorizedError, NotFoundError
+
+
+def create_exception(response_content):
+    data = json.loads(response_content)
+    if "ServiceUnavailableException" in data["exception"]:
+        raise ServiceUnavailableException('ServiceUnavailableException, 
"message": "{}", "cause": "{}"'.
+                                          format(data["message"], 
data["cause"]))
+    else:
+        raise Exception(response_content)
+
+
+def check_if_authorized(response):
+    if response.status_code == 401:
+        raise NotAuthorizedError("Please check your username and password. 
{}".format(response.content))
+    return True
+
+
+def check_if_success(response, error=None):
+    if (not str(response.status_code).startswith("20")) and 
check_if_authorized(response):
+        if error is None:
+            error = NotFoundError(response.content)
+        raise error
+    return True

Reply via email to