跳转到主要内容

这是本节的多页打印视图。 .

返回本页常规视图.

HugeGraph Client

Java 和 Go Client 位于 HugeGraph Toolchain 仓库,Python Client 位于 HugeGraph-AI 仓库。三者的安装方式和 API 不完全相同,请进入对应页面查看。

1 - HugeGraph-Java-Client

1 HugeGraph-Client 概述

HugeGraph Java Client 将 Java API 转换为 HugeGraph Server 的 REST 请求,支持管理 Schema 和图数据、执行 Gremlin 及调用 Traverser API。详细接口见 Client API,本文给出 Java 项目的接入示例。

其他语言可使用 Go Client 或 HugeGraph-AI 仓库中的 Python Client。

2 环境要求

  • JDK 11(当前 CI 使用版本;源码目标版本为 Java 8)
  • Maven 3.6+

3 使用流程

使用 HugeGraph-Client 的基本步骤如下:

  • 新建Eclipse/ IDEA Maven 项目;
  • 在 pom 文件中添加 HugeGraph-Client 依赖;
  • 创建类,调用 HugeGraph-Client 接口;

详细使用过程见下节完整示例。

4 完整示例

4.1 新建 Maven 工程

可以选择 Eclipse 或者 Intellij Idea 创建工程:

4.2 添加 hugegraph-client 依赖

添加 hugegraph-client 依赖

1
2<dependencies>
3    <dependency>
4        <groupId>org.apache.hugegraph</groupId>
5        <artifactId>hugegraph-client</artifactId>
6        <!-- 以下完整示例可使用已发布的 1.7.0 -->
7        <version>1.7.0</version>
8    </dependency>
9</dependencies>

以下完整示例使用的 Schema、Graph、Gremlin 和资源关闭接口在已发布的 Client 1.7.0 中可用,也与 Toolchain master 兼容。 上面的依赖可直接用于示例工程。

如果需要API 参考中的 master 新接口(例如能力探测),请使用 Toolchain master 的 Client 1.8.0, 将 POM 中的版本改为 1.8.0。该版本未发布到 Maven 仓库时,先在 Toolchain 源码根目录运行以下命令, 将 Client 及其父 POM 安装到本地 Maven 仓库。源码构建仍需从配置的 Maven 仓库获取依赖。

1mvn install -pl hugegraph-client -am -DskipTests -Dmaven.javadoc.skip=true -ntp

Client 与 Server 的版本不必相同;升级前核对服务端 API 兼容范围及所需功能。

4.3 Example

4.3.1 SingleExample
  1import java.io.IOException;
  2import java.util.Iterator;
  3import java.util.List;
  4
  5import org.apache.hugegraph.driver.GraphManager;
  6import org.apache.hugegraph.driver.GremlinManager;
  7import org.apache.hugegraph.driver.HugeClient;
  8import org.apache.hugegraph.driver.SchemaManager;
  9import org.apache.hugegraph.structure.constant.T;
 10import org.apache.hugegraph.structure.graph.Edge;
 11import org.apache.hugegraph.structure.graph.Path;
 12import org.apache.hugegraph.structure.graph.Vertex;
 13import org.apache.hugegraph.structure.gremlin.Result;
 14import org.apache.hugegraph.structure.gremlin.ResultSet;
 15
 16public class SingleExample {
 17
 18    public static void main(String[] args) throws IOException {
 19        // If connect failed will throw a exception.
 20        HugeClient hugeClient = HugeClient.builder("http://localhost:8080",
 21                                                   "DEFAULT",
 22                                                   "hugegraph")
 23                                          .configUser("username", "password")
 24                                          // 这是示例,生产环境需要使用安全的凭证
 25                                          .build();
 26
 27        SchemaManager schema = hugeClient.schema();
 28
 29        schema.propertyKey("name").asText().ifNotExist().create();
 30        schema.propertyKey("age").asInt().ifNotExist().create();
 31        schema.propertyKey("city").asText().ifNotExist().create();
 32        schema.propertyKey("weight").asDouble().ifNotExist().create();
 33        schema.propertyKey("lang").asText().ifNotExist().create();
 34        schema.propertyKey("date").asDate().ifNotExist().create();
 35        schema.propertyKey("price").asInt().ifNotExist().create();
 36
 37        schema.vertexLabel("person")
 38              .properties("name", "age", "city")
 39              .primaryKeys("name")
 40              .ifNotExist()
 41              .create();
 42
 43        schema.vertexLabel("software")
 44              .properties("name", "lang", "price")
 45              .primaryKeys("name")
 46              .ifNotExist()
 47              .create();
 48
 49        schema.indexLabel("personByCity")
 50              .onV("person")
 51              .by("city")
 52              .secondary()
 53              .ifNotExist()
 54              .create();
 55
 56        schema.indexLabel("personByAgeAndCity")
 57              .onV("person")
 58              .by("age", "city")
 59              .secondary()
 60              .ifNotExist()
 61              .create();
 62
 63        schema.indexLabel("softwareByPrice")
 64              .onV("software")
 65              .by("price")
 66              .range()
 67              .ifNotExist()
 68              .create();
 69
 70        schema.edgeLabel("knows")
 71              .sourceLabel("person")
 72              .targetLabel("person")
 73              .properties("date", "weight")
 74              .ifNotExist()
 75              .create();
 76
 77        schema.edgeLabel("created")
 78              .sourceLabel("person").targetLabel("software")
 79              .properties("date", "weight")
 80              .ifNotExist()
 81              .create();
 82
 83        schema.indexLabel("createdByDate")
 84              .onE("created")
 85              .by("date")
 86              .secondary()
 87              .ifNotExist()
 88              .create();
 89
 90        schema.indexLabel("createdByWeight")
 91              .onE("created")
 92              .by("weight")
 93              .range()
 94              .ifNotExist()
 95              .create();
 96
 97        schema.indexLabel("knowsByWeight")
 98              .onE("knows")
 99              .by("weight")
100              .range()
101              .ifNotExist()
102              .create();
103
104        GraphManager graph = hugeClient.graph();
105        Vertex marko = graph.addVertex(T.LABEL, "person", "name", "marko",
106                                       "age", 29, "city", "Beijing");
107        Vertex vadas = graph.addVertex(T.LABEL, "person", "name", "vadas",
108                                       "age", 27, "city", "Hongkong");
109        Vertex lop = graph.addVertex(T.LABEL, "software", "name", "lop",
110                                     "lang", "java", "price", 328);
111        Vertex josh = graph.addVertex(T.LABEL, "person", "name", "josh",
112                                      "age", 32, "city", "Beijing");
113        Vertex ripple = graph.addVertex(T.LABEL, "software", "name", "ripple",
114                                        "lang", "java", "price", 199);
115        Vertex peter = graph.addVertex(T.LABEL, "person", "name", "peter",
116                                       "age", 35, "city", "Shanghai");
117
118        marko.addEdge("knows", vadas, "date", "2016-01-10", "weight", 0.5);
119        marko.addEdge("knows", josh, "date", "2013-02-20", "weight", 1.0);
120        marko.addEdge("created", lop, "date", "2017-12-10", "weight", 0.4);
121        josh.addEdge("created", lop, "date", "2009-11-11", "weight", 0.4);
122        josh.addEdge("created", ripple, "date", "2017-12-10", "weight", 1.0);
123        peter.addEdge("created", lop, "date", "2017-03-24", "weight", 0.2);
124
125        GremlinManager gremlin = hugeClient.gremlin();
126        System.out.println("==== Path ====");
127        ResultSet resultSet = gremlin.gremlin("g.V().outE().path()").execute();
128        Iterator<Result> results = resultSet.iterator();
129        results.forEachRemaining(result -> {
130            System.out.println(result.getObject().getClass());
131            Object object = result.getObject();
132            if (object instanceof Vertex) {
133                System.out.println(((Vertex) object).id());
134            } else if (object instanceof Edge) {
135                System.out.println(((Edge) object).id());
136            } else if (object instanceof Path) {
137                List<Object> elements = ((Path) object).objects();
138                elements.forEach(element -> {
139                    System.out.println(element.getClass());
140                    System.out.println(element);
141                });
142            } else {
143                System.out.println(object);
144            }
145        });
146
147        hugeClient.close();
148    }
149}
4.3.2 BatchExample
  1import java.util.ArrayList;
  2import java.util.List;
  3
  4import org.apache.hugegraph.driver.GraphManager;
  5import org.apache.hugegraph.driver.HugeClient;
  6import org.apache.hugegraph.driver.SchemaManager;
  7import org.apache.hugegraph.structure.graph.Edge;
  8import org.apache.hugegraph.structure.graph.Vertex;
  9
 10public class BatchExample {
 11
 12    public static void main(String[] args) {
 13        // If connect failed will throw a exception.
 14        HugeClient hugeClient = HugeClient.builder("http://localhost:8080",
 15                                                "DEFAULT",
 16                                                "hugegraph")
 17                                          .configUser("username", "password")
 18                                          // 这是示例,生产环境需要使用安全的凭证
 19                                          .build();
 20
 21        SchemaManager schema = hugeClient.schema();
 22
 23        schema.propertyKey("name").asText().ifNotExist().create();
 24        schema.propertyKey("age").asInt().ifNotExist().create();
 25        schema.propertyKey("lang").asText().ifNotExist().create();
 26        schema.propertyKey("date").asDate().ifNotExist().create();
 27        schema.propertyKey("price").asInt().ifNotExist().create();
 28
 29        schema.vertexLabel("person")
 30              .properties("name", "age")
 31              .primaryKeys("name")
 32              .ifNotExist()
 33              .create();
 34
 35        schema.vertexLabel("person")
 36              .properties("price")
 37              .nullableKeys("price")
 38              .append();
 39
 40        schema.vertexLabel("software")
 41              .properties("name", "lang", "price")
 42              .primaryKeys("name")
 43              .ifNotExist()
 44              .create();
 45
 46        schema.indexLabel("softwareByPrice")
 47              .onV("software").by("price")
 48              .range()
 49              .ifNotExist()
 50              .create();
 51
 52        schema.edgeLabel("knows")
 53              .link("person", "person")
 54              .properties("date")
 55              .ifNotExist()
 56              .create();
 57
 58        schema.edgeLabel("created")
 59              .link("person", "software")
 60              .properties("date")
 61              .ifNotExist()
 62              .create();
 63
 64        schema.indexLabel("createdByDate")
 65              .onE("created").by("date")
 66              .secondary()
 67              .ifNotExist()
 68              .create();
 69
 70        // get schema object by name
 71        System.out.println(schema.getPropertyKey("name"));
 72        System.out.println(schema.getVertexLabel("person"));
 73        System.out.println(schema.getEdgeLabel("knows"));
 74        System.out.println(schema.getIndexLabel("createdByDate"));
 75
 76        // list all schema objects
 77        System.out.println(schema.getPropertyKeys());
 78        System.out.println(schema.getVertexLabels());
 79        System.out.println(schema.getEdgeLabels());
 80        System.out.println(schema.getIndexLabels());
 81
 82        GraphManager graph = hugeClient.graph();
 83
 84        Vertex marko = new Vertex("person").property("name", "marko")
 85                                           .property("age", 29);
 86        Vertex vadas = new Vertex("person").property("name", "vadas")
 87                                           .property("age", 27);
 88        Vertex lop = new Vertex("software").property("name", "lop")
 89                                           .property("lang", "java")
 90                                           .property("price", 328);
 91        Vertex josh = new Vertex("person").property("name", "josh")
 92                                          .property("age", 32);
 93        Vertex ripple = new Vertex("software").property("name", "ripple")
 94                                              .property("lang", "java")
 95                                              .property("price", 199);
 96        Vertex peter = new Vertex("person").property("name", "peter")
 97                                           .property("age", 35);
 98
 99        Edge markoKnowsVadas = new Edge("knows").source(marko).target(vadas)
100                                                .property("date", "2016-01-10");
101        Edge markoKnowsJosh = new Edge("knows").source(marko).target(josh)
102                                               .property("date", "2013-02-20");
103        Edge markoCreateLop = new Edge("created").source(marko).target(lop)
104                                                 .property("date",
105                                                           "2017-12-10");
106        Edge joshCreateRipple = new Edge("created").source(josh).target(ripple)
107                                                   .property("date",
108                                                             "2017-12-10");
109        Edge joshCreateLop = new Edge("created").source(josh).target(lop)
110                                                .property("date", "2009-11-11");
111        Edge peterCreateLop = new Edge("created").source(peter).target(lop)
112                                                 .property("date",
113                                                           "2017-03-24");
114
115        List<Vertex> vertices = new ArrayList<>();
116        vertices.add(marko);
117        vertices.add(vadas);
118        vertices.add(lop);
119        vertices.add(josh);
120        vertices.add(ripple);
121        vertices.add(peter);
122
123        List<Edge> edges = new ArrayList<>();
124        edges.add(markoKnowsVadas);
125        edges.add(markoKnowsJosh);
126        edges.add(markoCreateLop);
127        edges.add(joshCreateRipple);
128        edges.add(joshCreateLop);
129        edges.add(peterCreateLop);
130
131        vertices = graph.addVertices(vertices);
132        vertices.forEach(vertex -> System.out.println(vertex));
133
134        edges = graph.addEdges(edges, false);
135        edges.forEach(edge -> System.out.println(edge));
136
137        hugeClient.close();
138    }
139}

4.4 运行 Example

运行 Example 之前需要启动 Server, 启动过程见HugeGraph-Server 快速上手

4.5 详细 API 说明

示例说明见HugeGraph-Client 基本 API 介绍

2 - HugeGraph Python 客户端快速上手

hugegraph-python-client 是 HugeGraph 的 Python SDK,可管理 Schema、读写图数据并执行 Gremlin 查询。HugeGraph-LLM 和 HugeGraph-ML 也使用这个客户端。

该模块位于 hugegraph-ai 仓库的 hugegraph-python-client/ 目录下,导入名为 pyhugegraph。

环境要求

  • 客户端与 HugeGraph-AI workspace 均要求 Python 3.10 或更高版本,CI 在 3.10 和 3.11 上运行客户端测试。
  • HugeGraph Server 1.5.0 或更高版本。客户端会拒绝连接更低版本的 Server,此类场景请改用 v1.3.x 客户端。
  • uv(推荐)或 pip

运行时依赖为 decorator、requests、setuptools、urllib3 和 rich。

安装

发布到 PyPI 的发行包名是 hugegraph-python:

1uv pip install hugegraph-python
2# 也可以使用 pip install hugegraph-python

上述命令不固定版本号,默认安装最新发布版;发行信息见 PyPI 发布页。源码目录名是 hugegraph-python-client,发行包名为 hugegraph-python;需要主线代码时,请从 HugeGraph-AI workspace 安装。

如需使用仓库中的最新代码,请从 HugeGraph-AI 仓库根目录同步 workspace。hugegraph-python-client 是 workspace 成员,通过 python-client extra 暴露,因此仅执行 uv sync 不会安装它:

1git clone https://github.com/apache/hugegraph-ai.git
2cd hugegraph-ai
3uv sync --extra python-client
4source .venv/bin/activate

连接并写入数据

 1from pyhugegraph.client import PyHugeClient
 2
 3client = PyHugeClient(
 4    url="http://127.0.0.1:8080",
 5    graph="hugegraph",
 6    user="admin",
 7    pwd="admin",
 8    graphspace=None,
 9)
10
11schema = client.schema()
12schema.propertyKey("name").asText().ifNotExist().create()
13schema.propertyKey("birthDate").asText().ifNotExist().create()
14schema.vertexLabel("Person").properties("name", "birthDate") \
15      .usePrimaryKeyId().primaryKeys("name").ifNotExist().create()
16schema.vertexLabel("Movie").properties("name") \
17      .usePrimaryKeyId().primaryKeys("name").ifNotExist().create()
18schema.edgeLabel("ActedIn").sourceLabel("Person").targetLabel("Movie") \
19      .ifNotExist().create()
20
21graph = client.graph()
22person = graph.addVertex(
23    "Person", {"name": "Al Pacino", "birthDate": "1940-04-25"}
24)
25movie = graph.addVertex("Movie", {"name": "The Godfather"})
26edge = graph.addEdge("ActedIn", person.id, movie.id, {})
27
28print(graph.getVertexById(person.id))
29print(graph.getEdgeById(edge.id))
30graph.close()

客户端参数

PyHugeClient(url, graph, user, pwd, graphspace=None, timeout=None)

参数类型默认值说明
urlstr必填HugeGraph Server 的基础 URL。若未带协议头,客户端会自动补上 http://,因此 127.0.0.1:8080 也可以使用。
graphstr必填图名称,是第二个位置参数。
userstr必填用户名,以 HTTP Basic Auth 发送。
pwdstr必填密码,以 HTTP Basic Auth 发送。
graphspacestr 或 NoneNoneGraphSpace 名称,None 的解析规则见下文。
timeouttuple[float, float] 或 NoneNone(连接, 读取) 超时时间,单位为秒。None 会取 (0.5, 15.0)。

每个 HTTP 会话在收到 500、502、504 响应时会重试 3 次,退避因子为 0.1。

Server 版本与 GraphSpace

客户端在构造时解析 GraphSpace:

  • 传入非空的 graphspace 字符串时直接开启 GraphSpace 模式。
  • 否则客户端会请求 GET {url}/versions 并读取 versions.core。
  • Server 版本低于 1.5.0 时抛出 RuntimeError,提示升级 Server 或改用 v1.3.x 客户端。
  • Server 版本高于 1.5.0 时会把 graphspace 设为 DEFAULT 并开启 GraphSpace 模式,同时在日志中打印警告。版本恰好为 1.5.0 时保持关闭。
  • 若因网络原因探测失败,GraphSpace 模式保持关闭。

该模式决定请求前缀:开启时为 /graphspaces/<graphspace>/graphs/<graph>/...,关闭时为 /graphs/<graph>/...。

客户端提供的 Manager

每个访问器都会惰性创建对应的 Manager,并为其分配独立的 HTTP 会话。

访问器Manager覆盖范围
client.schema()SchemaManager属性、顶点标签、边标签、索引标签
client.graph()GraphManager顶点与边的增删改查、批量写入、分页
client.gremlin()GremlinManager执行 Gremlin
client.graphs()GraphsManager图列表、图信息、配置、清空数据
client.traverser()TraverserManager遍历与路径算法
client.variable()VariableManager图变量
client.task()TaskManager异步任务的查询、取消、删除
client.auth()AuthManager用户、用户组、资源、归属、权限
client.metrics()MetricsManagerServer 指标
client.version()VersionManagerServer 版本

pyhugegraph.api 中还提供了 RankManager、RebuildManager 和 ServicesManager,但 PyHugeClient 暂未提供对应的访问器,需要时可自行传入 session 构造。

常用操作

构建 Schema

Schema 构建器采用链式调用,最后调用 create(),也可以用 append()、eliminate() 和 remove() 修改已有定义。

 1schema = client.schema()
 2
 3# 属性类型:asText/asInt/asLong/asFloat/asDouble/asBool/asByte/asBlob/asDate/asObject
 4# 基数:valueSingle/valueList/valueSet
 5# 聚合:calcMax/calcMin/calcSum/calcOld
 6schema.propertyKey("age").asInt().valueSingle().ifNotExist().create()
 7
 8# 顶点标签 ID 策略:useAutomaticId/useCustomizeStringId/useCustomizeNumberId/usePrimaryKeyId
 9schema.vertexLabel("person").properties("name", "age", "city") \
10      .primaryKeys("name").nullableKeys("city").ifNotExist().create()
11
12# 边标签:link() 等价于 sourceLabel() 加 targetLabel()
13schema.edgeLabel("knows").link("person", "person").multiTimes() \
14      .properties("date", "city").sortKeys("date").nullableKeys("city") \
15      .ifNotExist().create()
16
17# 索引标签:先 onV/onE,再选择 secondary/range/search/shard/unique
18schema.indexLabel("personByCity").onV("person").by("city") \
19      .secondary().ifNotExist().create()

查询 Schema

 1schema = client.schema()
 2print(schema.getSchema())            # 完整 Schema,format 默认为 json
 3print(schema.getPropertyKeys())
 4print(schema.getVertexLabels())
 5print(schema.getEdgeLabels())
 6print(schema.getIndexLabels())
 7
 8# 查询单个定义
 9print(schema.getPropertyKey("name"))
10print(schema.getVertexLabel("person"))
11print(schema.getEdgeLabel("knows"))
12print(schema.getIndexLabel("personByCity"))
13
14# 边标签的连接关系,格式形如 Person--ActedIn-->Movie
15print(schema.getRelations())

读取、更新和删除图数据

图接口直接接收属性字典,不支持链式的属性构建器:

1graph = client.graph()
2graph.appendVertex(person.id, {"birthDate": "1940-04-25"})    # 追加属性
3graph.eliminateVertex(person.id, {"birthDate": "1940-04-25"}) # 删除属性
4graph.appendEdge(edge.id, {"city": "Beijing"})
5graph.eliminateEdge(edge.id, {"city": "Beijing"})
6graph.removeEdgeById(edge.id)
7graph.removeVertexById(person.id)
8graph.close()

addVertex 返回 VertexData,包含 id、label、type 和 properties。addEdge 返回 EdgeData,包含 id、label、type、outV、outVLabel、inV、inVLabel 和 properties。

传给客户端的顶点 ID 可以是字符串、整数或 uuid.UUID。布尔值会被拒绝,整数必须落在 Java signed long 范围内。

批量写入

addVertices 接收 (label, properties) 二元组,addEdges 接收 (label, out_id, in_id, out_label, in_label, properties) 六元组。两者返回的对象只携带生成的 ID。

1graph = client.graph()
2vertices = graph.addVertices([
3    ("person", {"name": "Alice", "age": 20}),
4    ("person", {"name": "Bob", "age": 23}),
5])
6edges = graph.addEdges([
7    ("knows", vertices[0].id, vertices[1].id, "person", "person", {"date": "2012-01-10"}),
8])

分页与条件查询

 1graph = client.graph()
 2
 3# 返回 (vertices, next_page),把 next_page 传回即可继续翻页
 4vertices, next_page = graph.getVertexByPage("person", limit=10)
 5vertices, next_page = graph.getVertexByPage("person", limit=10, page=next_page)
 6
 7# 服务端属性条件
 8older = graph.getVertexByCondition("person", properties={"age": "P.gt(29)"})
 9
10# 边分页查询,传入 vertex_id 时必须同时传 direction
11edges, next_page = graph.getEdgeByPage(label="knows", limit=10)
12edges, next_page = graph.getEdgeByPage(vertex_id=person.id, direction="OUT", limit=10)
13
14# 按 ID 批量查询
15graph.getVerticesById([v1.id, v2.id])
16graph.getEdgesById([e1.id, e2.id])

执行 Gremlin

1gremlin = client.gremlin()
2result = gremlin.exec("g.V().limit(5)")
3print(result)

exec 会根据图名称和解析出的 GraphSpace 自动绑定 graph 与 g 别名,并返回服务端响应中的 result 字段。响应缺少 requestId、status 或 result 时抛出 ResponseParseError。

图遍历

TraverserManager 封装了 Server 的 traverser 接口,方法名使用蛇形命名。

 1traverser = client.traverser()
 2
 3traverser.k_out(marko_id, 2)
 4traverser.k_neighbor(marko_id, 2)
 5traverser.same_neighbors(marko_id, josh_id)
 6traverser.jaccard_similarity(marko_id, josh_id)
 7traverser.shortest_path(marko_id, ripple_id, 3)
 8traverser.all_shortest_paths(marko_id, ripple_id, 3)
 9traverser.weighted_shortest_path(marko_id, ripple_id, "weight", 3)
10traverser.single_source_shortest_path(marko_id, 2)
11traverser.multi_node_shortest_path([marko_id, josh_id], max_depth=2)
12traverser.paths(marko_id, josh_id, 2)
13traverser.crosspoints(marko_id, josh_id, 2)
14traverser.rings(marko_id, 3)
15traverser.rays(marko_id, 2)
16traverser.vertices(marko_id)
17traverser.edges(edge_id)

基于 POST 的接口需要传入请求体:advanced_paths、customized_paths、template_paths、customized_crosspoints 和 fusiform_similarity。

图变量

1variable = client.variable()
2variable.set("owner", "mary")
3print(variable.get("owner"))
4print(variable.all())
5variable.remove("owner")

异步任务

1task = client.task()
2print(task.list_tasks(status="success", limit=10))
3print(task.get_task(task_id))
4task.cancel_task(task_id)
5task.delete_task(task_id)

Server 指标与图信息

 1metrics = client.metrics()
 2metrics.get_all_basic_metrics()
 3metrics.get_gauges_metrics()
 4metrics.get_counters_metrics()
 5metrics.get_histograms_metrics()
 6metrics.get_meters_metrics()
 7metrics.get_timers_metrics()
 8metrics.get_statistics_metrics()
 9metrics.get_system_metrics()
10metrics.get_backend_metrics()
11
12graphs = client.graphs()
13graphs.get_all_graphs()
14graphs.get_version()
15graphs.get_graph_info()
16graphs.get_graph_config()
17graphs.clear_graph_all_data()   # 删除全部顶点、边和 Schema
18
19print(client.version().version())

认证与授权

AuthManager 与 Server 的路由保持一致:用户、资源、归属和权限挂载在 /graphspaces/{graphspace}/auth/... 下,用户组仍在 Server 级别的 /auth/groups。在 HugeGraph 1.7.0 及以上版本必须能解析出 graphspace,否则这些调用会在发出请求前抛出 ValueError。

 1auth = client.auth()
 2
 3user = auth.create_user("test_user", "password")
 4auth.modify_user(user["id"], user_email="hugegraph@apache.org")
 5auth.get_user(user["id"])
 6auth.list_users(limit=10)
 7auth.delete_user(user["id"])
 8
 9group = auth.create_group("test_group", "read only")
10auth.modify_group(group["id"], group_description="updated")
11auth.list_groups()
12auth.delete_group(group["id"])
13
14target = auth.create_target("target1", "hugegraph", "127.0.0.1:8080", [])
15auth.update_target(target["id"], "target1", "hugegraph", "127.0.0.1:8080", [])
16auth.list_targets()
17auth.delete_target(target["id"])
18
19belong = auth.create_belong(user["id"], group["id"])
20auth.update_belong(belong["id"], "description")
21auth.list_belongs()
22auth.delete_belong(belong["id"])
23
24access = auth.grant_accesses(group["id"], target["id"], "READ")
25auth.modify_accesses(access["id"], "description")
26auth.list_accesses()
27auth.revoke_accesses(access["id"])

方法命名

Manager 中以驼峰命名的方法(例如 addVertex、getVertexById)会在构造时自动生成蛇形命名别名,graph.add_vertex(...) 与 graph.addVertex(...) 指向同一个方法。驼峰写法已在 debug 日志中标记为废弃,新代码建议使用蛇形命名。

错误处理

异常定义在 pyhugegraph.utils.exceptions 中:

异常触发条件
NotAuthorizedErrorServer 返回 401
NotFoundErrorServer 返回 404,或缺少必填参数
ServerError其他非 2xx 响应,异常信息中附带服务端消息
ResponseParseError成功响应无法解析为预期结构
ServiceUnavailableErrorServer 返回 ServiceUnavailableException
InvalidParameterError、CreateError、RemoveError、UpdateError、DataFormatError由各构建器和数据结构抛出

请求体与响应体写入日志时,会对密码、token 和 secret 等字段做脱敏处理。

1from pyhugegraph.utils.exceptions import NotFoundError
2
3try:
4    graph.getVertexById("no-such-id")
5except NotFoundError:
6    print("vertex missing")

接口参数会随 HugeGraph REST API 版本变化。遇到不兼容时,先核对当前 Server 的 REST API 文档与客户端测试用例。

开发检查

在 HugeGraph-AI 仓库根目录运行格式与静态检查:

1./style/code_format_and_analysis.sh

按照 CI 的方式运行测试:

1# 单元测试与契约测试,无需 Server
2uv run pytest hugegraph-python-client/src/tests -m "unit or contract"
3
4# 集成测试,需要可访问的 Server
5HUGEGRAPH_URL=http://127.0.0.1:8080 \
6HUGEGRAPH_GRAPH=hugegraph \
7HUGEGRAPH_USER=admin \
8HUGEGRAPH_PASSWORD=admin \
9uv run pytest hugegraph-python-client/src/tests -m "integration and hugegraph"

CI 的集成测试作业使用 hugegraph/hugegraph:1.7.0 镜像。需要非默认空间时,还可以设置 HUGEGRAPH_GRAPHSPACE。

源码与测试位于 hugegraph-python-client/src/pyhugegraph/ 和 hugegraph-python-client/src/tests/,可直接运行的示例在 hugegraph-python-client/src/pyhugegraph/example/hugegraph_example.py。

3 - HugeGraph Go 客户端快速入门

HugeGraph Go Client 是 Toolchain 仓库中的 Go SDK,目前提供版本查询、Schema(PropertyKey、VertexLabel、EdgeLabel)、顶点和 Gremlin API。边数据 API 尚未实现。

该模块仍在开发中。接口范围以 hugegraph-client-go/api/v1 下的源码为准。

环境要求

  • Go 1.19 或更高版本
  • 可访问的 HugeGraph Server,默认示例地址为 http://127.0.0.1:8080

安装

在 Go module 项目中执行:

1go get github.com/apache/hugegraph-toolchain/hugegraph-client-go

初始化客户端

NewCommonClient 要求 Host 是 IP 地址,Port 在 1 到 65535 之间;客户端始终使用明文 HTTP 连接。未启用认证时,用户名和密码留空;只有两者都设置时才会发送 Basic Auth。

GraphSpace 只在 Vertex API(此时请求路径为 /graphspaces/{space}/graphs/{graph}/...)和 Gremlin 默认 aliases 中生效(空值按 DEFAULT 处理)。Schema 相关入口和 Version() 始终请求 /graphs/{graph}/... 和 /versions,与 GraphSpace 无关。默认图空间填写 DEFAULT;将 GraphSpace 留空时,Vertex API 会回退到旧版 Server 使用的 /graphs/{graph} 路径。

 1package main
 2
 3import (
 4	"fmt"
 5	"log"
 6
 7	hugegraph "github.com/apache/hugegraph-toolchain/hugegraph-client-go"
 8)
 9
10func main() {
11	client, err := hugegraph.NewCommonClient(hugegraph.Config{
12		Host:       "127.0.0.1",
13		Port:       8080,
14		GraphSpace: "DEFAULT",
15		Graph:      "hugegraph",
16		Username:   "",
17		Password:   "",
18	})
19	if err != nil {
20		log.Fatal(err)
21	}
22
23	response, err := client.Version()
24	if err != nil {
25		log.Fatal(err)
26	}
27	defer response.Body.Close()
28
29	fmt.Println(response.Versions.Version)
30}

Version() 返回的 Versions 包含 HugeGraph Server、Core、Gremlin 和 REST API 版本。若使用源码提供的 NewDefaultCommonClient(),默认连接 127.0.0.1:8080 下的 hugegraph 图,使用 admin/pa 认证,并挂载一个打印全部请求和响应体的 ColorLogger;生产代码通常应显式传入配置。

配置项

hugegraph.Config 包含以下字段:

字段类型说明
HoststringHugeGraph Server 的 IP 地址,不支持主机名
PortintHugeGraph Server 的 REST 端口,取值 1 到 65535
GraphSpacestring图空间,仅 Vertex API 和 Gremlin 默认 aliases 使用;不需要时填空字符串
GraphstringServer 上配置的图名
UsernamestringServer 用户名,未启用认证时填空字符串
PasswordstringServer 密码,未启用认证时填空字符串
Transporthttp.RoundTripper自定义 HTTP transport,为 nil 时使用 http.DefaultTransport
Loggerhgtransport.Logger请求/响应日志,为 nil 时不记录日志

hgtransport 包提供四种 logger:TextLogger(纯文本)、ColorLogger(终端彩色)、CurlLogger(可执行的 curl 命令)和 JSONLogger(JSON 行)。它们的字段相同:Output(io.Writer)、EnableRequestBody 和 EnableResponseBody。

 1import (
 2	"os"
 3
 4	hugegraph "github.com/apache/hugegraph-toolchain/hugegraph-client-go"
 5	"github.com/apache/hugegraph-toolchain/hugegraph-client-go/hgtransport"
 6)
 7
 8client, err := hugegraph.NewCommonClient(hugegraph.Config{
 9	Host:  "127.0.0.1",
10	Port:  8080,
11	Graph: "hugegraph",
12	Logger: &hgtransport.ColorLogger{
13		Output:             os.Stdout,
14		EnableRequestBody:  true,
15		EnableResponseBody: true,
16	},
17})

已实现的入口

CommonClient 当前公开以下入口:

入口用途
Version()查询服务端版本
Schema()查询完整 Schema
PropertykeyCreate、GetAll、GetByName、UpdateUserdata、DeleteByName
VertexLabelCreate、GetAll、GetByName、UpdateUserdata、DeleteByName
EdgeLabelCreate、GetAll、DeleteByName
VertexCreate、BatchCreate、UpdateProperties(通过 WithAction 指定 append 或 eliminate)
GremlinGet 和 Post。Post 默认 language 为 gremlin-groovy,根据 GraphSpace 和 Graph 自动填充 graph/g aliases,并在 Data 中返回解析后的结果;Get 只返回状态码,并把原始响应打印到 stdout。

每个操作都通过挂在操作本身上的 With... 函数式选项传参,例如 client.Gremlin.Post.WithGremlin(...) 或 client.Propertykey.GetByName.WithName(...)。

EdgeLabel.Create 的请求数据允许 Properties: nil 或空切片 []string{},用于创建无属性的边标签。

类型化 API 返回的 err 表示参数校验、传输、响应读取或 JSON 解码错误。 HTTP 4xx/5xx 仍可能返回 err == nil,例如创建顶点时指定不存在的 label 会返回 HTTP 400。 读取结果数据前,请检查 response.StatusCode 是否属于 2xx。调用 Gremlin.Post 时,还需检查 response.Data.Status.Code 是否为成功的 Gremlin 协议状态码(2xx)。

 1resp, err := client.Gremlin.Post(
 2	client.Gremlin.Post.WithGremlin("g.V().limit(3)"),
 3)
 4if err != nil {
 5	log.Fatal(err)
 6}
 7defer resp.Body.Close()
 8if resp.StatusCode < 200 || resp.StatusCode >= 300 {
 9	log.Fatalf("HugeGraph returned HTTP %d", resp.StatusCode)
10}
11if resp.Data.Status.Code < 200 || resp.Data.Status.Code >= 300 {
12	log.Fatalf("Gremlin returned status %d: %s", resp.Data.Status.Code, resp.Data.Status.Message)
13}
14fmt.Println(resp.Data.Result.Data)

Vertex 相关操作的入参是 internal/model 包中的 model.Vertex[any]。Go 不允许从其他 module 导入 internal 包,因此目前 Vertex API 只能在客户端 module 内部调用;其测试文件也已全部注释。

完整调用方式可参考各 API 目录中的测试,例如 version_test.go、gemlin_test.go 和 vertexlabel_test.go。