Vermeer Python 客户端
vermeer-python-client 是 Vermeer 的 Python SDK。Vermeer 是使用 Go 编写、以内存计算为主的图计算引擎。该 SDK 封装了 Vermeer master 的 REST API,可以在 Python 中列出图、提交加载和计算任务、读取任务状态。导入时使用的包名是 pyvermeer。
模块没有固定 Vermeer 服务端版本,它通过 HTTP 访问 Vermeer master,调用的接口见 API 概览。
环境要求
- 单独使用该模块需要 Python 3.9 或更高版本;HugeGraph-AI 仓库整体要求 Python 3.10 或更高版本
- 一个可通过 HTTP 访问的 Vermeer master。默认 HTTP 端口为
6688;Docker 部署需发布6688:6688,见 Vermeer 快速开始。 uv(推荐)或pip
运行时依赖:requests、urllib3、python-dateutil、decorator、rich 和 setuptools。
安装
打包元数据中的发行包名是 vermeer-python-client,其版本号独立于仓库版本号管理。该包尚未发布到 PyPI,请从源码安装。
在 HugeGraph-AI 仓库根目录,使用 vermeer extra 把它安装到共用的虚拟环境中:
vermeer-python-client 是以可编辑路径依赖的方式接入的,并不是 uv workspace member,因此在仓库根目录直接执行 uv sync 不会安装它,必须显式指定该 extra(或使用 --all-extras)。
单独安装该模块:
连接 Vermeer master
构造函数参数:
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
ip | str | 必填 | Vermeer master 的主机名或 IP 地址 |
port | int | 必填 | Vermeer master 的 REST 端口 |
token | str | 必填 | 原样作为 Authorization 请求头发送 |
timeout | (float, float) 或 None | None | 连接超时和读取超时,单位为秒 |
log_level | str | "INFO" | 应用到共享 VermeerClient 日志器的级别 |
连接前需要了解的行为:
- 当 master 不校验鉴权时,
token可以是空字符串,但不能是None,否则会话会抛出ValueError("Vermeer Token must be provided.")。 timeout是(连接超时, 读取超时)二元组。VermeerConfig自身的默认值是(0.5, 15.0),但客户端总是把自己的参数传下去,因此不传timeout时实际存入的是None,请求会一直等待。需要超时就显式传入该二元组。- 基础 URL 固定拼接为
http://{ip}:{port}/,即客户端只使用明文 HTTP。 - 每个请求都会设置
Content-Type: application/json,并把params序列化进请求体,GET请求也是如此。 - 底层会话在 HTTP 500、502、504 时最多重试 3 次,退避系数为
0.1。 log_level设置的是名为VermeerClient的共享日志器的级别。它的控制台 handler 固定为INFO,因此目前DEBUG级别的记录不会打印到控制台。
端到端示例
模块自带一个可运行的示例:vermeer-python-client/src/pyvermeer/demo/task_demo.py。下面的版本在其基础上增加了带超时和失败处理的任务状态轮询,等待加载成功后再读取图,并从环境变量读取 HugeGraph 密码:
加载任务以 loaded 表示成功;error 或 canceled 会中止示例,不再读取图。可按数据量调整 poll_timeout(此处为 300 秒)。轮询期限与 HTTP 连接、读取超时相互独立,已发出的请求及 SDK 重试可能使实际等待时间超过该期限。超时只停止客户端等待,不会取消服务端任务。
不要把真实的 HugeGraph 密码写死在脚本或配置文件中,请像上面这样从环境变量或凭据管理系统读取。
模块自带的 task_demo.py 使用 8688。运行前,请将其中 PyVermeerClient 的 port 改为 6688,与默认 master HTTP 端口保持一致。根据安装后所在的目录选择对应命令:
仓库根目录安装(在 hugegraph-ai/ 下运行):
独立安装(在 hugegraph-ai/vermeer-python-client/ 下运行):
API 概览
PyVermeerClient 以属性的方式暴露各个 API 组,目前注册了 graph 和 tasks 两个组。
client.graph
| 方法 | Vermeer 接口 | 返回值 |
|---|---|---|
get_graphs() | GET /graphs | GraphsResponse |
get_graph(graph_name) | GET /graphs/{graph_name} | GraphResponse |
client.tasks
| 方法 | Vermeer 接口 | 返回值 |
|---|---|---|
get_tasks() | GET /tasks | TasksResponse |
get_task(task_id) | GET /task/{task_id} | TaskResponse |
create_task(create_task) | POST /tasks/create | TaskCreateResponse |
pyvermeer/api/master.py 和 pyvermeer/api/worker.py 目前只有许可证头,也没有注册到客户端上。因此尽管 pyvermeer/structure/ 下已经有 MasterResponse 和 WorkersResponse,master 和 worker 信息暂时还无法通过客户端获取。
client.send_request(method, endpoint, params) 是这两个组共用的请求入口。对于还没有封装的 Vermeer 接口,可以直接调用它,返回值是解析后的 JSON 字典。
请求与响应对象
TaskCreateRequest(task_type, graph_name, params) 序列化为 {"task_type": ..., "graph": ..., "params": ...}。注意 graph_name 在报文中的字段名是 graph,与 Vermeer REST API 的请求体一致。
所有响应类型都继承 BaseResponse,提供 errcode、message 属性和 to_dict() 方法。errcode 为 0 表示成功,1 表示错误,-1 表示响应体中没有该字段。
GraphsResponse.graphs和GraphResponse.graph返回VermeerGraph对象,包含name、space_name、status、create_time、update_time、vertex_count、edge_count、workers、worker_group、use_out_edges、use_property、use_out_degree、use_undirected、on_disk和backend_option。TasksResponse.tasks、TaskResponse.task和TaskCreateResponse.task返回TaskInfo对象,包含id、state、create_user、create_type、create_time、start_time、update_time、graph_name、space_name、type、params和workers。- 时间字段由
python-dateutil解析为datetime对象,空字符串会解析为None。
任务参数
客户端不会校验 params,键和值都会原样传给 Vermeer,因此可用的参数名由引擎决定,而不是由 SDK 决定。加载参数以及各算法的参数请参考 Vermeer 快速开始。
使用流程与直接调用 REST API 相同:先创建 load 任务把图读入 Vermeer,等待任务完成,再针对已加载的图创建计算任务。
异常
pyvermeer.utils.exception 定义了四种异常,都由底层的 requests 或 JSON 解析失败包装而来:
| 异常 | 触发场景 |
|---|---|
ConnectError | requests.ConnectionError,无法连接 master |
TimeOutError | requests.Timeout,连接或读取超时 |
JsonDecodeError | 响应体不是合法的 JSON |
UnknownError | 请求过程中的其他失败 |
客户端不检查响应的 HTTP 状态码,请通过返回对象的 errcode 和 message 判断是成功还是 Vermeer 端返回了错误。
代码检查
在 HugeGraph-AI 仓库根目录执行格式化和静态检查:
源码位于 vermeer-python-client/src/pyvermeer/。该模块目前没有测试用例。