semantica-graph-sdk 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- semantica_graph_sdk-0.1.0/PKG-INFO +164 -0
- semantica_graph_sdk-0.1.0/README.md +153 -0
- semantica_graph_sdk-0.1.0/pyproject.toml +28 -0
- semantica_graph_sdk-0.1.0/semantica_graph_sdk/__init__.py +110 -0
- semantica_graph_sdk-0.1.0/semantica_graph_sdk/_bootstrap.py +71 -0
- semantica_graph_sdk-0.1.0/semantica_graph_sdk/_version.py +1 -0
- semantica_graph_sdk-0.1.0/semantica_graph_sdk/async_client.py +371 -0
- semantica_graph_sdk-0.1.0/semantica_graph_sdk/client.py +403 -0
- semantica_graph_sdk-0.1.0/semantica_graph_sdk/envelope.py +39 -0
- semantica_graph_sdk-0.1.0/semantica_graph_sdk/errors.py +80 -0
- semantica_graph_sdk-0.1.0/semantica_graph_sdk/headers.py +57 -0
- semantica_graph_sdk-0.1.0/semantica_graph_sdk/models/__init__.py +3 -0
- semantica_graph_sdk-0.1.0/semantica_graph_sdk/models/graph.py +1194 -0
- semantica_graph_sdk-0.1.0/semantica_graph_sdk/trace.py +20 -0
- semantica_graph_sdk-0.1.0/semantica_graph_sdk/transport.py +227 -0
- semantica_graph_sdk-0.1.0/semantica_graph_sdk/transport_async.py +166 -0
- semantica_graph_sdk-0.1.0/semantica_graph_sdk.egg-info/PKG-INFO +164 -0
- semantica_graph_sdk-0.1.0/semantica_graph_sdk.egg-info/SOURCES.txt +42 -0
- semantica_graph_sdk-0.1.0/semantica_graph_sdk.egg-info/dependency_links.txt +1 -0
- semantica_graph_sdk-0.1.0/semantica_graph_sdk.egg-info/requires.txt +5 -0
- semantica_graph_sdk-0.1.0/semantica_graph_sdk.egg-info/top_level.txt +1 -0
- semantica_graph_sdk-0.1.0/setup.cfg +4 -0
- semantica_graph_sdk-0.1.0/tests/test_async.py +118 -0
- semantica_graph_sdk-0.1.0/tests/test_bootstrap.py +57 -0
- semantica_graph_sdk-0.1.0/tests/test_client.py +252 -0
- semantica_graph_sdk-0.1.0/tests/test_envelope.py +38 -0
- semantica_graph_sdk-0.1.0/tests/test_errors.py +48 -0
- semantica_graph_sdk-0.1.0/tests/test_headers.py +36 -0
- semantica_graph_sdk-0.1.0/tests/test_models.py +278 -0
- semantica_graph_sdk-0.1.0/tests/test_sdk_binding.py +105 -0
- semantica_graph_sdk-0.1.0/tests/test_trace.py +19 -0
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: semantica-graph-sdk
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Semantica Graph Engine 独立承载服务应用集成 SDK(图谱 CRUD / 建图合并 / 查询分析 / RDF 导出与 SPARQL / 异步任务)
|
|
5
|
+
Requires-Python: >=3.12
|
|
6
|
+
Description-Content-Type: text/markdown
|
|
7
|
+
Requires-Dist: httpx<1.0,>=0.27
|
|
8
|
+
Requires-Dist: ikc-sdk-lib==0.7.0
|
|
9
|
+
Provides-Extra: dev
|
|
10
|
+
Requires-Dist: pytest>=8.0; extra == "dev"
|
|
11
|
+
|
|
12
|
+
# semantica-graph-sdk
|
|
13
|
+
|
|
14
|
+
Semantica Graph Engine **独立承载服务**(图引擎作为独立进程/容器对外提供)的应用集成 SDK。**v0.1.0**,
|
|
15
|
+
依赖 `httpx`(传输)与 `ikc-sdk-lib==0.7.0`(图谱资产 DTO 的形状单一来源:`EntityView`/`RelationView`/
|
|
16
|
+
`GraphPageResult`/`EngineJobView` 等),与主包 `graph-engine`(服务端)解耦、不 import 服务端模块。
|
|
17
|
+
|
|
18
|
+
DTO 经 sdk 模型校验后序列化:分页壳含 `totalPages`;作业对象 `status` 为引擎本地态,`taskStatus` 为
|
|
19
|
+
映射后的外部态(`SUCCEEDED`/`FAILED`…,未知态 fail-closed=FAILED);`JobData.finished` 按外部态终态判定。
|
|
20
|
+
|
|
21
|
+
设计文档:`docs/独立承载服务与SDK集成设计.md`(仓库根目录)。
|
|
22
|
+
|
|
23
|
+
## 安装
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
pip install semantica-graph-sdk
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
本地开发调试可 `pip install sdk/python`,测试依赖 `pytest`(`pip install "sdk/python[dev]"`)。
|
|
30
|
+
|
|
31
|
+
## 快速开始(同步)
|
|
32
|
+
|
|
33
|
+
```python
|
|
34
|
+
from semantica_graph_sdk import GraphEngineClient
|
|
35
|
+
|
|
36
|
+
client = GraphEngineClient(
|
|
37
|
+
base_url="http://127.0.0.1:18010", # 独立承载服务地址(本地 serve / Docker 入口 18180)
|
|
38
|
+
token="<TOKEN>", # 可选;服务端启用鉴权/网关注入时使用
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
# 1. 创建图谱(graphSchema 校验由服务端执行)
|
|
42
|
+
graph = client.graphs.create(
|
|
43
|
+
kbId="kb_demo",
|
|
44
|
+
name="产品知识图谱",
|
|
45
|
+
graphSchema={
|
|
46
|
+
"entityTypes": [{"type": "person"}, {"type": "org"}],
|
|
47
|
+
"relationTypes": [{"type": "works_at", "sourceTypes": ["person"], "targetTypes": ["org"]}],
|
|
48
|
+
},
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
# 2. 建图:记录建图(稳定 ID + 证据 + 置信度)或文本建图
|
|
52
|
+
client.graphs.build(
|
|
53
|
+
graph.graphId,
|
|
54
|
+
docId="doc_1",
|
|
55
|
+
entities=[{"name": "Alice", "type": "person"}, {"name": "Acme", "type": "org"}],
|
|
56
|
+
relations=[{"type": "works_at", "sourceEntityId": "ent_a", "targetEntityId": "ent_b"}],
|
|
57
|
+
)
|
|
58
|
+
built = client.graphs.build(graph.graphId, docId="doc_2", title="手册", text="「Alice」加入「Acme」")
|
|
59
|
+
print(built.entityCount, built.semantica.semantica)
|
|
60
|
+
|
|
61
|
+
# 3. 查询 / 分析 / 导出 / SPARQL / 语义检索
|
|
62
|
+
stat = client.graphs.stat(graph.graphId)
|
|
63
|
+
nodes = client.graphs.nodes(graph.graphId, entityType="person", pageSize=50)
|
|
64
|
+
edges = client.graphs.edges(graph.graphId, relationType="works_at")
|
|
65
|
+
neighbors = client.graphs.neighbors(graph.graphId, entityId=nodes.items[0].entityId, depth=1)
|
|
66
|
+
paths = client.graphs.paths(graph.graphId, sourceEntityId="ent_a", targetEntityId="ent_b", maxDepth=3)
|
|
67
|
+
analytics = client.graphs.analytics(graph.graphId)
|
|
68
|
+
export = client.graphs.export(graph.graphId, format="turtle")
|
|
69
|
+
sparql = client.graphs.sparql(graph.graphId, query="SELECT ?s ?p ?o WHERE { ?s ?p ?o } LIMIT 5")
|
|
70
|
+
search = client.graphs.search(graph.graphId, query="Alice 在哪工作", topK=5)
|
|
71
|
+
print(stat.schemaCoverage.overall, len(sparql.bindings), search.semantica)
|
|
72
|
+
|
|
73
|
+
# 4. 异步任务(async_=True 登记 job;Celery 未启用时可手动执行或轮询)
|
|
74
|
+
job = client.graphs.build(graph.graphId, text="「异步」", async_=True)
|
|
75
|
+
job = client.jobs.run(job.jobId) # 或 client.jobs.wait(job.jobId)
|
|
76
|
+
print(job.status, job.result)
|
|
77
|
+
|
|
78
|
+
client.close()
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## 异步客户端
|
|
82
|
+
|
|
83
|
+
```python
|
|
84
|
+
import asyncio
|
|
85
|
+
from semantica_graph_sdk import AsyncGraphEngineClient
|
|
86
|
+
|
|
87
|
+
async def main():
|
|
88
|
+
async with AsyncGraphEngineClient(base_url="http://127.0.0.1:18010") as client:
|
|
89
|
+
graph = await client.graphs.create(kbId="kb_async", name="异步示例")
|
|
90
|
+
stat = await client.graphs.stat(graph.graphId)
|
|
91
|
+
print(stat.nodeCount)
|
|
92
|
+
|
|
93
|
+
asyncio.run(main())
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
同步与异步客户端共享同一套模型与错误映射;`request`/`raw`/`fetch_openapi`/`health` 低层调用与重试语义一致。
|
|
97
|
+
|
|
98
|
+
## 环境变量引导
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
export SEMANTICA_GRAPH_BASE_URL=http://127.0.0.1:18010
|
|
102
|
+
export SEMANTICA_GRAPH_TOKEN=<token> # 可选
|
|
103
|
+
export SEMANTICA_GRAPH_USER_ID=u1 # 可选,身份头 X-User-Id,并作为 ownerId 默认值
|
|
104
|
+
export SEMANTICA_GRAPH_TENANT_ID=t1 # 可选,身份头 X-Tenant-Id,并作为 tenantId 默认值
|
|
105
|
+
export SEMANTICA_GRAPH_ROLES=km_admin,viewer # 可选,身份头 X-User-Roles
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
```python
|
|
109
|
+
from semantica_graph_sdk import client_from_env, async_client_from_env
|
|
110
|
+
|
|
111
|
+
client = client_from_env() # 等价:GraphEngineClient(base_url=os.environ["SEMANTICA_GRAPH_BASE_URL"], ...)
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
`CallerIdentity` 的 `tenant_id`/`user_id` 会在请求缺省时补齐 `tenantId`/`ownerId`
|
|
115
|
+
(图引擎的租户/归属是请求参数),显式入参始终优先。
|
|
116
|
+
|
|
117
|
+
## 领域方法总览
|
|
118
|
+
|
|
119
|
+
- `client.graphs`:`create / list / get / delete / build / merge / deprecate_doc / stat / nodes / edges /
|
|
120
|
+
neighbors / paths / analytics / export / sparql / search / index_status`
|
|
121
|
+
- `client.jobs`:`run / get / list / wait`
|
|
122
|
+
- 低层:`request(method, path, ...)` / `raw(...)`(不抛业务异常)/ `fetch_openapi()` / `health()`
|
|
123
|
+
|
|
124
|
+
## 异常层级
|
|
125
|
+
|
|
126
|
+
```
|
|
127
|
+
GraphEngineError
|
|
128
|
+
├── GraphEngineTransportError # 传输层(含 traceId)
|
|
129
|
+
│ ├── GraphEngineConnectionError
|
|
130
|
+
│ ├── GraphEngineTimeoutError
|
|
131
|
+
│ ├── GraphEngineProtocolError # 响应不符统一壳协议
|
|
132
|
+
│ └── GraphEngineHTTPStatusError # 非 2xx 且非统一壳
|
|
133
|
+
└── GraphEngineAPIError # 业务异常(errCode/errMsg/traceId)
|
|
134
|
+
├── GraphEngineValidationError # 200001 参数非法
|
|
135
|
+
├── GraphEngineNotFoundError # 200404 资源不存在
|
|
136
|
+
├── GraphEngineConflictError # 200409 冲突
|
|
137
|
+
├── GraphEngineSystemError # 200500 系统错误
|
|
138
|
+
└── GraphEngineBusinessError # 其他错误码兜底
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
## 联调冒烟
|
|
142
|
+
|
|
143
|
+
先启动独立承载服务:
|
|
144
|
+
|
|
145
|
+
```bash
|
|
146
|
+
graph-engine serve http # 默认 18010
|
|
147
|
+
# 或 docker compose up -d # 单镜像栈入口 18180(HTTP)/ 18151(gRPC)
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
```bash
|
|
151
|
+
# 同步全链路:健康检查 → 建图 → 查询/分析/导出/检索 → 异步任务 → 清理
|
|
152
|
+
python sdk/python/examples/quickstart.py
|
|
153
|
+
|
|
154
|
+
# 异步客户端示例
|
|
155
|
+
python sdk/python/examples/async_quickstart.py
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
## 自测
|
|
159
|
+
|
|
160
|
+
```bash
|
|
161
|
+
cd sdk/python && PYTHONPATH=. python -m pytest tests -q
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
> 测试基于 `httpx.MockTransport`,无需起真实服务。
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
# semantica-graph-sdk
|
|
2
|
+
|
|
3
|
+
Semantica Graph Engine **独立承载服务**(图引擎作为独立进程/容器对外提供)的应用集成 SDK。**v0.1.0**,
|
|
4
|
+
依赖 `httpx`(传输)与 `ikc-sdk-lib==0.7.0`(图谱资产 DTO 的形状单一来源:`EntityView`/`RelationView`/
|
|
5
|
+
`GraphPageResult`/`EngineJobView` 等),与主包 `graph-engine`(服务端)解耦、不 import 服务端模块。
|
|
6
|
+
|
|
7
|
+
DTO 经 sdk 模型校验后序列化:分页壳含 `totalPages`;作业对象 `status` 为引擎本地态,`taskStatus` 为
|
|
8
|
+
映射后的外部态(`SUCCEEDED`/`FAILED`…,未知态 fail-closed=FAILED);`JobData.finished` 按外部态终态判定。
|
|
9
|
+
|
|
10
|
+
设计文档:`docs/独立承载服务与SDK集成设计.md`(仓库根目录)。
|
|
11
|
+
|
|
12
|
+
## 安装
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
pip install semantica-graph-sdk
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
本地开发调试可 `pip install sdk/python`,测试依赖 `pytest`(`pip install "sdk/python[dev]"`)。
|
|
19
|
+
|
|
20
|
+
## 快速开始(同步)
|
|
21
|
+
|
|
22
|
+
```python
|
|
23
|
+
from semantica_graph_sdk import GraphEngineClient
|
|
24
|
+
|
|
25
|
+
client = GraphEngineClient(
|
|
26
|
+
base_url="http://127.0.0.1:18010", # 独立承载服务地址(本地 serve / Docker 入口 18180)
|
|
27
|
+
token="<TOKEN>", # 可选;服务端启用鉴权/网关注入时使用
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
# 1. 创建图谱(graphSchema 校验由服务端执行)
|
|
31
|
+
graph = client.graphs.create(
|
|
32
|
+
kbId="kb_demo",
|
|
33
|
+
name="产品知识图谱",
|
|
34
|
+
graphSchema={
|
|
35
|
+
"entityTypes": [{"type": "person"}, {"type": "org"}],
|
|
36
|
+
"relationTypes": [{"type": "works_at", "sourceTypes": ["person"], "targetTypes": ["org"]}],
|
|
37
|
+
},
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
# 2. 建图:记录建图(稳定 ID + 证据 + 置信度)或文本建图
|
|
41
|
+
client.graphs.build(
|
|
42
|
+
graph.graphId,
|
|
43
|
+
docId="doc_1",
|
|
44
|
+
entities=[{"name": "Alice", "type": "person"}, {"name": "Acme", "type": "org"}],
|
|
45
|
+
relations=[{"type": "works_at", "sourceEntityId": "ent_a", "targetEntityId": "ent_b"}],
|
|
46
|
+
)
|
|
47
|
+
built = client.graphs.build(graph.graphId, docId="doc_2", title="手册", text="「Alice」加入「Acme」")
|
|
48
|
+
print(built.entityCount, built.semantica.semantica)
|
|
49
|
+
|
|
50
|
+
# 3. 查询 / 分析 / 导出 / SPARQL / 语义检索
|
|
51
|
+
stat = client.graphs.stat(graph.graphId)
|
|
52
|
+
nodes = client.graphs.nodes(graph.graphId, entityType="person", pageSize=50)
|
|
53
|
+
edges = client.graphs.edges(graph.graphId, relationType="works_at")
|
|
54
|
+
neighbors = client.graphs.neighbors(graph.graphId, entityId=nodes.items[0].entityId, depth=1)
|
|
55
|
+
paths = client.graphs.paths(graph.graphId, sourceEntityId="ent_a", targetEntityId="ent_b", maxDepth=3)
|
|
56
|
+
analytics = client.graphs.analytics(graph.graphId)
|
|
57
|
+
export = client.graphs.export(graph.graphId, format="turtle")
|
|
58
|
+
sparql = client.graphs.sparql(graph.graphId, query="SELECT ?s ?p ?o WHERE { ?s ?p ?o } LIMIT 5")
|
|
59
|
+
search = client.graphs.search(graph.graphId, query="Alice 在哪工作", topK=5)
|
|
60
|
+
print(stat.schemaCoverage.overall, len(sparql.bindings), search.semantica)
|
|
61
|
+
|
|
62
|
+
# 4. 异步任务(async_=True 登记 job;Celery 未启用时可手动执行或轮询)
|
|
63
|
+
job = client.graphs.build(graph.graphId, text="「异步」", async_=True)
|
|
64
|
+
job = client.jobs.run(job.jobId) # 或 client.jobs.wait(job.jobId)
|
|
65
|
+
print(job.status, job.result)
|
|
66
|
+
|
|
67
|
+
client.close()
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## 异步客户端
|
|
71
|
+
|
|
72
|
+
```python
|
|
73
|
+
import asyncio
|
|
74
|
+
from semantica_graph_sdk import AsyncGraphEngineClient
|
|
75
|
+
|
|
76
|
+
async def main():
|
|
77
|
+
async with AsyncGraphEngineClient(base_url="http://127.0.0.1:18010") as client:
|
|
78
|
+
graph = await client.graphs.create(kbId="kb_async", name="异步示例")
|
|
79
|
+
stat = await client.graphs.stat(graph.graphId)
|
|
80
|
+
print(stat.nodeCount)
|
|
81
|
+
|
|
82
|
+
asyncio.run(main())
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
同步与异步客户端共享同一套模型与错误映射;`request`/`raw`/`fetch_openapi`/`health` 低层调用与重试语义一致。
|
|
86
|
+
|
|
87
|
+
## 环境变量引导
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
export SEMANTICA_GRAPH_BASE_URL=http://127.0.0.1:18010
|
|
91
|
+
export SEMANTICA_GRAPH_TOKEN=<token> # 可选
|
|
92
|
+
export SEMANTICA_GRAPH_USER_ID=u1 # 可选,身份头 X-User-Id,并作为 ownerId 默认值
|
|
93
|
+
export SEMANTICA_GRAPH_TENANT_ID=t1 # 可选,身份头 X-Tenant-Id,并作为 tenantId 默认值
|
|
94
|
+
export SEMANTICA_GRAPH_ROLES=km_admin,viewer # 可选,身份头 X-User-Roles
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
```python
|
|
98
|
+
from semantica_graph_sdk import client_from_env, async_client_from_env
|
|
99
|
+
|
|
100
|
+
client = client_from_env() # 等价:GraphEngineClient(base_url=os.environ["SEMANTICA_GRAPH_BASE_URL"], ...)
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
`CallerIdentity` 的 `tenant_id`/`user_id` 会在请求缺省时补齐 `tenantId`/`ownerId`
|
|
104
|
+
(图引擎的租户/归属是请求参数),显式入参始终优先。
|
|
105
|
+
|
|
106
|
+
## 领域方法总览
|
|
107
|
+
|
|
108
|
+
- `client.graphs`:`create / list / get / delete / build / merge / deprecate_doc / stat / nodes / edges /
|
|
109
|
+
neighbors / paths / analytics / export / sparql / search / index_status`
|
|
110
|
+
- `client.jobs`:`run / get / list / wait`
|
|
111
|
+
- 低层:`request(method, path, ...)` / `raw(...)`(不抛业务异常)/ `fetch_openapi()` / `health()`
|
|
112
|
+
|
|
113
|
+
## 异常层级
|
|
114
|
+
|
|
115
|
+
```
|
|
116
|
+
GraphEngineError
|
|
117
|
+
├── GraphEngineTransportError # 传输层(含 traceId)
|
|
118
|
+
│ ├── GraphEngineConnectionError
|
|
119
|
+
│ ├── GraphEngineTimeoutError
|
|
120
|
+
│ ├── GraphEngineProtocolError # 响应不符统一壳协议
|
|
121
|
+
│ └── GraphEngineHTTPStatusError # 非 2xx 且非统一壳
|
|
122
|
+
└── GraphEngineAPIError # 业务异常(errCode/errMsg/traceId)
|
|
123
|
+
├── GraphEngineValidationError # 200001 参数非法
|
|
124
|
+
├── GraphEngineNotFoundError # 200404 资源不存在
|
|
125
|
+
├── GraphEngineConflictError # 200409 冲突
|
|
126
|
+
├── GraphEngineSystemError # 200500 系统错误
|
|
127
|
+
└── GraphEngineBusinessError # 其他错误码兜底
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
## 联调冒烟
|
|
131
|
+
|
|
132
|
+
先启动独立承载服务:
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
graph-engine serve http # 默认 18010
|
|
136
|
+
# 或 docker compose up -d # 单镜像栈入口 18180(HTTP)/ 18151(gRPC)
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
# 同步全链路:健康检查 → 建图 → 查询/分析/导出/检索 → 异步任务 → 清理
|
|
141
|
+
python sdk/python/examples/quickstart.py
|
|
142
|
+
|
|
143
|
+
# 异步客户端示例
|
|
144
|
+
python sdk/python/examples/async_quickstart.py
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
## 自测
|
|
148
|
+
|
|
149
|
+
```bash
|
|
150
|
+
cd sdk/python && PYTHONPATH=. python -m pytest tests -q
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
> 测试基于 `httpx.MockTransport`,无需起真实服务。
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=68", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "semantica-graph-sdk"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "Semantica Graph Engine 独立承载服务应用集成 SDK(图谱 CRUD / 建图合并 / 查询分析 / RDF 导出与 SPARQL / 异步任务)"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.12"
|
|
11
|
+
dependencies = [
|
|
12
|
+
"httpx>=0.27,<1.0",
|
|
13
|
+
# 跨层共享模型/协议 SDK:图谱资产对象(G8)、traceId 纯函数(G2)、引擎作业视图(G3)
|
|
14
|
+
"ikc-sdk-lib==0.7.0",
|
|
15
|
+
]
|
|
16
|
+
|
|
17
|
+
[project.optional-dependencies]
|
|
18
|
+
dev = ["pytest>=8.0"]
|
|
19
|
+
|
|
20
|
+
[tool.setuptools]
|
|
21
|
+
package-dir = {"" = "."}
|
|
22
|
+
|
|
23
|
+
[tool.setuptools.packages.find]
|
|
24
|
+
where = ["."]
|
|
25
|
+
include = ["semantica_graph_sdk*"]
|
|
26
|
+
|
|
27
|
+
[tool.pytest.ini_options]
|
|
28
|
+
testpaths = ["tests"]
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import logging
|
|
4
|
+
|
|
5
|
+
from ._bootstrap import async_client_from_env, client_from_env
|
|
6
|
+
from ._version import __version__
|
|
7
|
+
from .async_client import AsyncGraphClient, AsyncGraphEngineClient, AsyncJobsClient
|
|
8
|
+
from .client import GraphClient, GraphEngineClient, JobsClient
|
|
9
|
+
from .envelope import Envelope
|
|
10
|
+
from .errors import (
|
|
11
|
+
GraphEngineAPIError,
|
|
12
|
+
GraphEngineBusinessError,
|
|
13
|
+
GraphEngineConflictError,
|
|
14
|
+
GraphEngineConnectionError,
|
|
15
|
+
GraphEngineError,
|
|
16
|
+
GraphEngineHTTPStatusError,
|
|
17
|
+
GraphEngineNotFoundError,
|
|
18
|
+
GraphEngineProtocolError,
|
|
19
|
+
GraphEngineSystemError,
|
|
20
|
+
GraphEngineTimeoutError,
|
|
21
|
+
GraphEngineTransportError,
|
|
22
|
+
GraphEngineValidationError,
|
|
23
|
+
exception_from_code,
|
|
24
|
+
)
|
|
25
|
+
from .headers import CallerIdentity, identity_defaults
|
|
26
|
+
from .models.graph import (
|
|
27
|
+
AnalyticsData,
|
|
28
|
+
BuildResult,
|
|
29
|
+
DeleteResult,
|
|
30
|
+
DeprecateResult,
|
|
31
|
+
Entity,
|
|
32
|
+
EntityListData,
|
|
33
|
+
ExportResult,
|
|
34
|
+
GraphListData,
|
|
35
|
+
GraphMeta,
|
|
36
|
+
GraphPath,
|
|
37
|
+
IndexStatusData,
|
|
38
|
+
JobData,
|
|
39
|
+
JobListData,
|
|
40
|
+
NeighborData,
|
|
41
|
+
PathListData,
|
|
42
|
+
Relation,
|
|
43
|
+
RelationListData,
|
|
44
|
+
SchemaCoverage,
|
|
45
|
+
SearchData,
|
|
46
|
+
SearchHit,
|
|
47
|
+
SemanticaMeta,
|
|
48
|
+
SparqlResult,
|
|
49
|
+
StatResult,
|
|
50
|
+
TypeCount,
|
|
51
|
+
)
|
|
52
|
+
from .trace import generate_trace_id
|
|
53
|
+
|
|
54
|
+
__all__ = [
|
|
55
|
+
"GraphEngineClient",
|
|
56
|
+
"AsyncGraphEngineClient",
|
|
57
|
+
"GraphClient",
|
|
58
|
+
"AsyncGraphClient",
|
|
59
|
+
"JobsClient",
|
|
60
|
+
"AsyncJobsClient",
|
|
61
|
+
"client_from_env",
|
|
62
|
+
"async_client_from_env",
|
|
63
|
+
"Envelope",
|
|
64
|
+
"CallerIdentity",
|
|
65
|
+
"identity_defaults",
|
|
66
|
+
"GraphMeta",
|
|
67
|
+
"GraphListData",
|
|
68
|
+
"DeleteResult",
|
|
69
|
+
"SemanticaMeta",
|
|
70
|
+
"BuildResult",
|
|
71
|
+
"DeprecateResult",
|
|
72
|
+
"TypeCount",
|
|
73
|
+
"SchemaCoverage",
|
|
74
|
+
"StatResult",
|
|
75
|
+
"Entity",
|
|
76
|
+
"EntityListData",
|
|
77
|
+
"Relation",
|
|
78
|
+
"RelationListData",
|
|
79
|
+
"NeighborData",
|
|
80
|
+
"GraphPath",
|
|
81
|
+
"PathListData",
|
|
82
|
+
"AnalyticsData",
|
|
83
|
+
"ExportResult",
|
|
84
|
+
"SparqlResult",
|
|
85
|
+
"SearchHit",
|
|
86
|
+
"SearchData",
|
|
87
|
+
"IndexStatusData",
|
|
88
|
+
"JobData",
|
|
89
|
+
"JobListData",
|
|
90
|
+
"generate_trace_id",
|
|
91
|
+
"GraphEngineError",
|
|
92
|
+
"GraphEngineTransportError",
|
|
93
|
+
"GraphEngineConnectionError",
|
|
94
|
+
"GraphEngineTimeoutError",
|
|
95
|
+
"GraphEngineProtocolError",
|
|
96
|
+
"GraphEngineHTTPStatusError",
|
|
97
|
+
"GraphEngineAPIError",
|
|
98
|
+
"GraphEngineValidationError",
|
|
99
|
+
"GraphEngineNotFoundError",
|
|
100
|
+
"GraphEngineConflictError",
|
|
101
|
+
"GraphEngineSystemError",
|
|
102
|
+
"GraphEngineBusinessError",
|
|
103
|
+
"exception_from_code",
|
|
104
|
+
"__version__",
|
|
105
|
+
]
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
def set_log_level(level: int | str) -> None:
|
|
109
|
+
"""设置 SDK 日志级别(默认 WARNING)。"""
|
|
110
|
+
logging.getLogger("semantica_graph_sdk").setLevel(level)
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
|
|
5
|
+
from .async_client import AsyncGraphEngineClient
|
|
6
|
+
from .client import GraphEngineClient
|
|
7
|
+
from .headers import CallerIdentity
|
|
8
|
+
|
|
9
|
+
DEFAULT_BASE_URL = "http://127.0.0.1:18010"
|
|
10
|
+
|
|
11
|
+
_ENV_BASE_URL = "SEMANTICA_GRAPH_BASE_URL"
|
|
12
|
+
_ENV_TOKEN = "SEMANTICA_GRAPH_TOKEN"
|
|
13
|
+
_ENV_USER_ID = "SEMANTICA_GRAPH_USER_ID"
|
|
14
|
+
_ENV_TENANT_ID = "SEMANTICA_GRAPH_TENANT_ID"
|
|
15
|
+
_ENV_ROLES = "SEMANTICA_GRAPH_ROLES"
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def _identity_from_env(
|
|
19
|
+
user_id: str | None,
|
|
20
|
+
tenant_id: str | None,
|
|
21
|
+
roles: str | None,
|
|
22
|
+
) -> CallerIdentity | None:
|
|
23
|
+
"""组装身份上下文;所有字段为空时返回 None(不附加身份头、不补齐归属)。"""
|
|
24
|
+
user_id = user_id or os.getenv(_ENV_USER_ID, "").strip()
|
|
25
|
+
tenant_id = tenant_id or os.getenv(_ENV_TENANT_ID, "").strip()
|
|
26
|
+
roles_value = roles or os.getenv(_ENV_ROLES, "").strip()
|
|
27
|
+
|
|
28
|
+
roles_list: list[str] | None = None
|
|
29
|
+
if roles_value:
|
|
30
|
+
roles_list = [item.strip() for item in roles_value.split(",") if item.strip()]
|
|
31
|
+
|
|
32
|
+
if not user_id and not tenant_id and not roles_list:
|
|
33
|
+
return None
|
|
34
|
+
return CallerIdentity(user_id=user_id or None, tenant_id=tenant_id or None, roles=roles_list)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def client_from_env(
|
|
38
|
+
*,
|
|
39
|
+
base_url: str | None = None,
|
|
40
|
+
token: str | None = None,
|
|
41
|
+
user_id: str | None = None,
|
|
42
|
+
tenant_id: str | None = None,
|
|
43
|
+
roles: str | None = None,
|
|
44
|
+
**kwargs,
|
|
45
|
+
) -> GraphEngineClient:
|
|
46
|
+
"""从环境变量 + 显式参数构造同步客户端;显式参数优先。
|
|
47
|
+
|
|
48
|
+
env:SEMANTICA_GRAPH_BASE_URL(默认 http://127.0.0.1:18010)/ SEMANTICA_GRAPH_TOKEN /
|
|
49
|
+
SEMANTICA_GRAPH_USER_ID / SEMANTICA_GRAPH_TENANT_ID / SEMANTICA_GRAPH_ROLES。
|
|
50
|
+
额外关键字参数(timeout/max_retries/http_client 等)原样透传。
|
|
51
|
+
"""
|
|
52
|
+
resolved_base_url = base_url or os.getenv(_ENV_BASE_URL, DEFAULT_BASE_URL)
|
|
53
|
+
resolved_token = token or os.getenv(_ENV_TOKEN, "").strip() or None
|
|
54
|
+
identity = _identity_from_env(user_id, tenant_id, roles)
|
|
55
|
+
return GraphEngineClient(base_url=resolved_base_url, token=resolved_token, identity=identity, **kwargs)
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def async_client_from_env(
|
|
59
|
+
*,
|
|
60
|
+
base_url: str | None = None,
|
|
61
|
+
token: str | None = None,
|
|
62
|
+
user_id: str | None = None,
|
|
63
|
+
tenant_id: str | None = None,
|
|
64
|
+
roles: str | None = None,
|
|
65
|
+
**kwargs,
|
|
66
|
+
) -> AsyncGraphEngineClient:
|
|
67
|
+
"""从环境变量 + 显式参数构造异步客户端;语义与 client_from_env 一致。"""
|
|
68
|
+
resolved_base_url = base_url or os.getenv(_ENV_BASE_URL, DEFAULT_BASE_URL)
|
|
69
|
+
resolved_token = token or os.getenv(_ENV_TOKEN, "").strip() or None
|
|
70
|
+
identity = _identity_from_env(user_id, tenant_id, roles)
|
|
71
|
+
return AsyncGraphEngineClient(base_url=resolved_base_url, token=resolved_token, identity=identity, **kwargs)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.1.0"
|