intellif-aihub 0.1.5__py3-none-any.whl → 0.1.6__py3-none-any.whl
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.
Potentially problematic release.
This version of intellif-aihub might be problematic. Click here for more details.
- aihub/__init__.py +1 -1
- aihub/client.py +35 -12
- aihub/models/data_warehouse.py +95 -0
- aihub/models/dataset_management.py +99 -61
- aihub/models/document_center.py +26 -18
- aihub/models/eval.py +20 -11
- aihub/models/labelfree.py +12 -38
- aihub/models/model_center.py +141 -0
- aihub/models/model_training_platform.py +183 -149
- aihub/models/quota_schedule_management.py +201 -150
- aihub/models/tag_resource_management.py +30 -24
- aihub/models/task_center.py +39 -36
- aihub/models/user_system.py +159 -125
- aihub/models/workflow_center.py +461 -0
- aihub/services/artifact.py +22 -15
- aihub/services/data_warehouse.py +97 -0
- aihub/services/dataset_management.py +142 -23
- aihub/services/document_center.py +24 -5
- aihub/services/eval.py +14 -7
- aihub/services/labelfree.py +11 -0
- aihub/services/model_center.py +183 -0
- aihub/services/model_training_platform.py +99 -29
- aihub/services/quota_schedule_management.py +104 -7
- aihub/services/tag_resource_management.py +33 -2
- aihub/services/task_center.py +23 -9
- aihub/services/user_system.py +237 -2
- aihub/services/workflow_center.py +522 -0
- aihub/utils/download.py +19 -3
- {intellif_aihub-0.1.5.dist-info → intellif_aihub-0.1.6.dist-info}/METADATA +3 -3
- intellif_aihub-0.1.6.dist-info/RECORD +42 -0
- intellif_aihub-0.1.5.dist-info/RECORD +0 -36
- {intellif_aihub-0.1.5.dist-info → intellif_aihub-0.1.6.dist-info}/WHEEL +0 -0
- {intellif_aihub-0.1.5.dist-info → intellif_aihub-0.1.6.dist-info}/licenses/LICENSE +0 -0
- {intellif_aihub-0.1.5.dist-info → intellif_aihub-0.1.6.dist-info}/top_level.txt +0 -0
|
@@ -1,3 +1,16 @@
|
|
|
1
|
+
# !/usr/bin/env python
|
|
2
|
+
# -*- coding:utf-8 -*-
|
|
3
|
+
"""模型训练平台服务模块
|
|
4
|
+
|
|
5
|
+
对接 **model‑training‑platform** 后端,以 **训练任务** 为核心提供常用业务能力,包括:
|
|
6
|
+
|
|
7
|
+
- **创建训练任务**
|
|
8
|
+
- **分页查询 / 获取训练详情**
|
|
9
|
+
- **停止训练任务**
|
|
10
|
+
- **查询训练 Pod 及其 Logs / Events / Spec**
|
|
11
|
+
- **查询训练相关用户、容器等辅助信息**
|
|
12
|
+
"""
|
|
13
|
+
|
|
1
14
|
from __future__ import annotations
|
|
2
15
|
|
|
3
16
|
import httpx
|
|
@@ -26,6 +39,7 @@ _BASE = "/model-training-platform/api/v1"
|
|
|
26
39
|
|
|
27
40
|
|
|
28
41
|
class ModelTrainingPlatformService:
|
|
42
|
+
"""训练任务业务封装"""
|
|
29
43
|
|
|
30
44
|
def __init__(self, http: httpx.Client):
|
|
31
45
|
self._training = _Training(http)
|
|
@@ -42,59 +56,115 @@ class ModelTrainingPlatformService:
|
|
|
42
56
|
return self._training.create(payload)
|
|
43
57
|
|
|
44
58
|
def list_trainings(self, payload: ListTrainingsRequest) -> ListTrainingsResponse:
|
|
59
|
+
"""分页查询训练任务
|
|
60
|
+
|
|
61
|
+
Args:
|
|
62
|
+
payload: 分页与过滤条件,详见 ``ListTrainingsRequest``
|
|
63
|
+
|
|
64
|
+
Returns:
|
|
65
|
+
ListTrainingsResponse: 训练任务分页结果
|
|
66
|
+
"""
|
|
45
67
|
return self._training.list(payload)
|
|
46
68
|
|
|
47
69
|
def get_training(self, training_id: int) -> Training:
|
|
48
70
|
"""获取训练任务详情
|
|
49
71
|
|
|
50
72
|
Args:
|
|
51
|
-
training_id
|
|
52
|
-
Returns:
|
|
53
|
-
Training
|
|
73
|
+
training_id: 训练任务 ID
|
|
54
74
|
|
|
75
|
+
Returns:
|
|
76
|
+
Training: 训练任务完整信息
|
|
55
77
|
"""
|
|
56
78
|
return self._training.get(training_id)
|
|
57
79
|
|
|
58
80
|
def stop_training(self, training_id: int) -> None:
|
|
59
|
-
"""
|
|
81
|
+
"""停止训练任务
|
|
60
82
|
|
|
61
83
|
Args:
|
|
62
|
-
training_id
|
|
63
|
-
|
|
64
|
-
Returns:
|
|
65
|
-
|
|
84
|
+
training_id: 训练任务 ID
|
|
66
85
|
"""
|
|
67
86
|
self._training.stop(training_id)
|
|
68
87
|
|
|
69
|
-
def list_training_pods(
|
|
70
|
-
|
|
71
|
-
|
|
88
|
+
def list_training_pods(self, training_id: int, payload: ListTrainingPodsRequest) -> ListTrainingPodsResponse:
|
|
89
|
+
"""查询训练任务的 Pod 列表
|
|
90
|
+
|
|
91
|
+
Args:
|
|
92
|
+
training_id: 训练任务 ID
|
|
93
|
+
payload: 分页参数,详见 ``ListTrainingPodsRequest``
|
|
94
|
+
|
|
95
|
+
Returns:
|
|
96
|
+
ListTrainingPodsResponse: Pod 分页结果
|
|
97
|
+
"""
|
|
72
98
|
return self._training.list_training_pods(training_id, payload)
|
|
73
99
|
|
|
74
100
|
def get_training_pod(self, training_id: int, pod_id: int) -> Pod:
|
|
101
|
+
"""获取单个 Pod 详情
|
|
102
|
+
|
|
103
|
+
Args:
|
|
104
|
+
training_id: 训练任务 ID
|
|
105
|
+
pod_id: Pod ID
|
|
106
|
+
|
|
107
|
+
Returns:
|
|
108
|
+
Pod: Pod 详细信息
|
|
109
|
+
"""
|
|
75
110
|
return self._training.get_training_pod(training_id, pod_id)
|
|
76
111
|
|
|
77
|
-
def get_pod_logs_new(
|
|
78
|
-
|
|
79
|
-
|
|
112
|
+
def get_pod_logs_new(self, training_id: int, pod_id: int) -> GetTrainingPodLogsNewResponse:
|
|
113
|
+
"""获取 Pod 日志
|
|
114
|
+
|
|
115
|
+
Args:
|
|
116
|
+
training_id: 训练任务 ID
|
|
117
|
+
pod_id: Pod ID
|
|
118
|
+
|
|
119
|
+
Returns:
|
|
120
|
+
GetTrainingPodLogsNewResponse: 日志文件信息(名称 / URL 列表)
|
|
121
|
+
"""
|
|
80
122
|
return self._training.get_training_logs_new(training_id, pod_id)
|
|
81
123
|
|
|
82
124
|
def get_pod_spec(self, training_id: int, pod_id: int) -> GetTrainingPodSpecResponse:
|
|
125
|
+
"""获取 Pod Spec
|
|
126
|
+
|
|
127
|
+
Args:
|
|
128
|
+
training_id: 训练任务 ID
|
|
129
|
+
pod_id: Pod ID
|
|
130
|
+
|
|
131
|
+
Returns:
|
|
132
|
+
GetTrainingPodSpecResponse: Pod Spec 字符串
|
|
133
|
+
"""
|
|
83
134
|
return self._training.get_training_spec(training_id, pod_id)
|
|
84
135
|
|
|
85
|
-
def get_pod_events(
|
|
86
|
-
|
|
87
|
-
|
|
136
|
+
def get_pod_events(self, training_id: int, pod_id: int) -> GetTrainingPodEventsResponse:
|
|
137
|
+
"""获取 Pod Events
|
|
138
|
+
|
|
139
|
+
Args:
|
|
140
|
+
training_id: 训练任务 ID
|
|
141
|
+
pod_id: Pod ID
|
|
142
|
+
|
|
143
|
+
Returns:
|
|
144
|
+
GetTrainingPodEventsResponse: 事件文本
|
|
145
|
+
"""
|
|
88
146
|
return self._training.get_training_events(training_id, pod_id)
|
|
89
147
|
|
|
90
|
-
def list_training_users(
|
|
91
|
-
|
|
92
|
-
|
|
148
|
+
def list_training_users(self, payload: ListTrainingUsersRequest) -> ListTrainingUsersResponse:
|
|
149
|
+
"""查询训练任务的用户列表
|
|
150
|
+
|
|
151
|
+
Args:
|
|
152
|
+
payload: 分页参数 ``ListTrainingUsersRequest``
|
|
153
|
+
|
|
154
|
+
Returns:
|
|
155
|
+
ListTrainingUsersResponse: 用户分页结果
|
|
156
|
+
"""
|
|
93
157
|
return self._training.list_training_users(payload)
|
|
94
158
|
|
|
95
|
-
def list_training_containers(
|
|
96
|
-
|
|
97
|
-
|
|
159
|
+
def list_training_containers(self, payload: ListTrainingContainersRequest) -> ListTrainingContainersResponse:
|
|
160
|
+
"""查询训练容器信息
|
|
161
|
+
|
|
162
|
+
Args:
|
|
163
|
+
payload: 分页参数 ``ListTrainingContainersRequest``
|
|
164
|
+
|
|
165
|
+
Returns:
|
|
166
|
+
ListTrainingContainersResponse: 训练容器列表
|
|
167
|
+
"""
|
|
98
168
|
return self._training.list_training_containers(payload)
|
|
99
169
|
|
|
100
170
|
@property
|
|
@@ -141,7 +211,7 @@ class _Training:
|
|
|
141
211
|
raise APIError(f"backend code {wrapper.code}: {wrapper.msg}")
|
|
142
212
|
|
|
143
213
|
def list_training_pods(
|
|
144
|
-
|
|
214
|
+
self, training_id: int, payload: ListTrainingPodsRequest
|
|
145
215
|
) -> ListTrainingPodsResponse:
|
|
146
216
|
resp = self._http.get(
|
|
147
217
|
f"{_BASE}/trainings/{training_id}/pods",
|
|
@@ -160,7 +230,7 @@ class _Training:
|
|
|
160
230
|
return wrapper.data
|
|
161
231
|
|
|
162
232
|
def get_training_logs_new(
|
|
163
|
-
|
|
233
|
+
self, training_id: int, pod_id: int
|
|
164
234
|
) -> GetTrainingPodLogsNewResponse:
|
|
165
235
|
resp = self._http.get(f"{_BASE}/trainings/{training_id}/pods/{pod_id}/logs/new")
|
|
166
236
|
wrapper = APIWrapper[GetTrainingPodLogsNewResponse].model_validate(resp.json())
|
|
@@ -169,7 +239,7 @@ class _Training:
|
|
|
169
239
|
return wrapper.data
|
|
170
240
|
|
|
171
241
|
def get_training_spec(
|
|
172
|
-
|
|
242
|
+
self, training_id: int, pod_id: int
|
|
173
243
|
) -> GetTrainingPodSpecResponse:
|
|
174
244
|
resp = self._http.get(f"{_BASE}/trainings/{training_id}/pods/{pod_id}/spec")
|
|
175
245
|
wrapper = APIWrapper[GetTrainingPodSpecResponse].model_validate(resp.json())
|
|
@@ -178,7 +248,7 @@ class _Training:
|
|
|
178
248
|
return wrapper.data
|
|
179
249
|
|
|
180
250
|
def get_training_events(
|
|
181
|
-
|
|
251
|
+
self, training_id: int, pod_id: int
|
|
182
252
|
) -> GetTrainingPodEventsResponse:
|
|
183
253
|
resp = self._http.get(f"{_BASE}/trainings/{training_id}/pods/{pod_id}/events")
|
|
184
254
|
wrapper = APIWrapper[GetTrainingPodEventsResponse].model_validate(resp.json())
|
|
@@ -187,7 +257,7 @@ class _Training:
|
|
|
187
257
|
return wrapper.data
|
|
188
258
|
|
|
189
259
|
def list_training_users(
|
|
190
|
-
|
|
260
|
+
self, payload: ListTrainingUsersRequest
|
|
191
261
|
) -> ListTrainingUsersResponse:
|
|
192
262
|
resp = self._http.get(
|
|
193
263
|
f"{_BASE}/training-users", params=payload.model_dump(by_alias=True)
|
|
@@ -198,7 +268,7 @@ class _Training:
|
|
|
198
268
|
return wrapper.data
|
|
199
269
|
|
|
200
270
|
def list_training_containers(
|
|
201
|
-
|
|
271
|
+
self, payload: ListTrainingContainersRequest
|
|
202
272
|
) -> ListTrainingContainersResponse:
|
|
203
273
|
resp = self._http.get(
|
|
204
274
|
f"{_BASE}/training-containers", params=payload.model_dump(by_alias=True)
|
|
@@ -1,13 +1,43 @@
|
|
|
1
|
+
# !/usr/bin/env python
|
|
2
|
+
# -*- coding:utf-8 -*-
|
|
3
|
+
"""配额调度服务模块
|
|
4
|
+
|
|
5
|
+
封装 **quota‑schedule‑management** 后端接口,围绕 **配额调度任务** 提供常用能力:
|
|
6
|
+
|
|
7
|
+
- **创建 / 查询 / 停止调度任务**
|
|
8
|
+
- **Pod 维度信息**(列表 / Logs / Spec / Events)
|
|
9
|
+
- **GPU 资源概览、活跃用户、容器信息** 等辅助查询
|
|
10
|
+
- **Pre‑Stop** 机制:进程内检测平台下发的优雅终止信号
|
|
11
|
+
"""
|
|
12
|
+
|
|
1
13
|
from __future__ import annotations
|
|
2
14
|
|
|
3
15
|
import os
|
|
4
16
|
from pathlib import Path
|
|
17
|
+
from typing import List
|
|
5
18
|
|
|
6
19
|
import httpx
|
|
7
20
|
|
|
8
21
|
from ..exceptions import APIError
|
|
9
22
|
from ..models.common import APIWrapper
|
|
10
|
-
from ..models.quota_schedule_management import
|
|
23
|
+
from ..models.quota_schedule_management import (
|
|
24
|
+
CreateTaskRequest,
|
|
25
|
+
CreateTaskResponse,
|
|
26
|
+
ListTasksRequest,
|
|
27
|
+
ListTasksResponse,
|
|
28
|
+
Task,
|
|
29
|
+
ListTaskPodsRequest,
|
|
30
|
+
ListTaskPodsResponse,
|
|
31
|
+
Pod,
|
|
32
|
+
PodLogInfo,
|
|
33
|
+
GetTaskPodLogsNewResponse,
|
|
34
|
+
GetTaskPodSpecResponse,
|
|
35
|
+
GetTaskPodEventsResponse,
|
|
36
|
+
ListTaskUsersRequest,
|
|
37
|
+
ListTaskUsersResponse,
|
|
38
|
+
GetMetricsOverviewRequest,
|
|
39
|
+
GetMetricsOverviewResponse,
|
|
40
|
+
)
|
|
11
41
|
|
|
12
42
|
_ENV_KEY = "PRE_STOP_SENTINEL_FILE"
|
|
13
43
|
_DEFAULT_SENTINEL = "/tmp/pre_stop_sentinel_file"
|
|
@@ -16,6 +46,14 @@ _BASE = "/quota-schedule-management/api/v1"
|
|
|
16
46
|
|
|
17
47
|
|
|
18
48
|
def is_pre_stopped() -> bool:
|
|
49
|
+
"""判断当前进程是否已收到 *pre‑stop* 信号
|
|
50
|
+
|
|
51
|
+
该信号由调度平台通过创建哨兵文件的方式下发。文件路径可通过环境变量 ``PRE_STOP_SENTINEL_FILE`` 覆盖,
|
|
52
|
+
默认为``/tmp/pre_stop_sentinel_file``。
|
|
53
|
+
|
|
54
|
+
Returns:
|
|
55
|
+
bool: 若哨兵文件存在,返回 ``True``,表示应尽快停止任务。
|
|
56
|
+
"""
|
|
19
57
|
return _SENTINEL_PATH.exists()
|
|
20
58
|
|
|
21
59
|
|
|
@@ -26,6 +64,7 @@ class PreStopService:
|
|
|
26
64
|
|
|
27
65
|
|
|
28
66
|
class QuotaScheduleManagementService:
|
|
67
|
+
"""配额调度任务业务封装"""
|
|
29
68
|
|
|
30
69
|
def __init__(self, http: httpx.Client):
|
|
31
70
|
self._task = _Task(http)
|
|
@@ -34,7 +73,7 @@ class QuotaScheduleManagementService:
|
|
|
34
73
|
"""创建调度任务
|
|
35
74
|
|
|
36
75
|
Args:
|
|
37
|
-
payload:
|
|
76
|
+
payload: 创建任务的各项参数,详见 ``CreateTaskRequest``
|
|
38
77
|
|
|
39
78
|
Returns:
|
|
40
79
|
int: 后端生成的任务 ID
|
|
@@ -45,10 +84,10 @@ class QuotaScheduleManagementService:
|
|
|
45
84
|
"""分页查询任务列表
|
|
46
85
|
|
|
47
86
|
Args:
|
|
48
|
-
payload:
|
|
87
|
+
payload: 分页 / 过滤参数,详见 ``ListTasksRequest``
|
|
49
88
|
|
|
50
89
|
Returns:
|
|
51
|
-
ListTasksResponse:
|
|
90
|
+
ListTasksResponse: 任务分页结果
|
|
52
91
|
"""
|
|
53
92
|
return self._task.list(payload)
|
|
54
93
|
|
|
@@ -68,31 +107,89 @@ class QuotaScheduleManagementService:
|
|
|
68
107
|
|
|
69
108
|
Args:
|
|
70
109
|
task_id: 任务 ID
|
|
71
|
-
|
|
72
|
-
Returns:
|
|
73
|
-
None
|
|
74
110
|
"""
|
|
75
111
|
self._task.stop(task_id)
|
|
76
112
|
|
|
77
113
|
def list_task_pods(self, task_id: int, payload: ListTaskPodsRequest) -> ListTaskPodsResponse:
|
|
114
|
+
"""分页查询任务的 Pod 列表
|
|
115
|
+
|
|
116
|
+
Args:
|
|
117
|
+
task_id: 调度任务 ID
|
|
118
|
+
payload: 分页参数,见 :class:`ListTaskPodsRequest`
|
|
119
|
+
|
|
120
|
+
Returns:
|
|
121
|
+
ListTaskPodsResponse: Pod 列表及分页信息
|
|
122
|
+
"""
|
|
78
123
|
return self._task.list_pods(task_id, payload)
|
|
79
124
|
|
|
80
125
|
def get_task_pod(self, task_id: int, pod_id: int) -> Pod:
|
|
126
|
+
"""获取单个 Pod 详情
|
|
127
|
+
|
|
128
|
+
Args:
|
|
129
|
+
task_id: 调度任务 ID
|
|
130
|
+
pod_id: Pod ID(数据库主键)
|
|
131
|
+
|
|
132
|
+
Returns:
|
|
133
|
+
Pod: Pod 详细信息
|
|
134
|
+
"""
|
|
81
135
|
return self._task.get_pod(task_id, pod_id)
|
|
82
136
|
|
|
83
137
|
def get_pod_logs_new(self, task_id: int, pod_id: int) -> List[PodLogInfo]:
|
|
138
|
+
"""获取新版日志
|
|
139
|
+
|
|
140
|
+
Args:
|
|
141
|
+
task_id: 调度任务 ID
|
|
142
|
+
pod_id: Pod ID
|
|
143
|
+
|
|
144
|
+
Returns:
|
|
145
|
+
list[PodLogInfo]: 每条日志文件的名称与下载地址
|
|
146
|
+
"""
|
|
84
147
|
return self._task.get_logs_new(task_id, pod_id).logs
|
|
85
148
|
|
|
86
149
|
def get_pod_spec(self, task_id: int, pod_id: int) -> str:
|
|
150
|
+
"""获取 Pod 运行时 Spec(YAML)
|
|
151
|
+
|
|
152
|
+
Args:
|
|
153
|
+
task_id: 调度任务 ID
|
|
154
|
+
pod_id: Pod ID
|
|
155
|
+
|
|
156
|
+
Returns:
|
|
157
|
+
str: Pod 描述 YAML 字符串
|
|
158
|
+
"""
|
|
87
159
|
return self._task.get_spec(task_id, pod_id).spec
|
|
88
160
|
|
|
89
161
|
def get_pod_events(self, task_id: int, pod_id: int) -> str:
|
|
162
|
+
"""获取 Pod 事件
|
|
163
|
+
|
|
164
|
+
Args:
|
|
165
|
+
task_id: 调度任务 ID
|
|
166
|
+
pod_id: Pod ID
|
|
167
|
+
|
|
168
|
+
Returns:
|
|
169
|
+
str: 事件文本(kubectl describe events)
|
|
170
|
+
"""
|
|
90
171
|
return self._task.get_events(task_id, pod_id).events
|
|
91
172
|
|
|
92
173
|
def list_task_users(self, payload: ListTaskUsersRequest) -> ListTaskUsersResponse:
|
|
174
|
+
"""查询任务的用户列表
|
|
175
|
+
|
|
176
|
+
Args:
|
|
177
|
+
payload: 分页参数,见 :class:`ListTaskUsersRequest`
|
|
178
|
+
|
|
179
|
+
Returns:
|
|
180
|
+
ListTaskUsersResponse: 用户列表及分页信息
|
|
181
|
+
"""
|
|
93
182
|
return self._task.list_users(payload)
|
|
94
183
|
|
|
95
184
|
def get_metrics_overview(self, payload: GetMetricsOverviewRequest) -> GetMetricsOverviewResponse:
|
|
185
|
+
"""获取虚拟集群维度的 GPU 使用概览
|
|
186
|
+
|
|
187
|
+
Args:
|
|
188
|
+
payload: 分页参数,见 :class:`GetMetricsOverviewRequest`
|
|
189
|
+
|
|
190
|
+
Returns:
|
|
191
|
+
GetMetricsOverviewResponse: 各虚拟集群资源统计
|
|
192
|
+
"""
|
|
96
193
|
return self._task.get_metrics_overview(payload)
|
|
97
194
|
|
|
98
195
|
@property
|
|
@@ -1,25 +1,56 @@
|
|
|
1
1
|
# !/usr/bin/env python
|
|
2
|
-
# -*-coding:utf-8 -*-
|
|
2
|
+
# -*- coding:utf-8 -*-
|
|
3
|
+
"""标签资源管理服务模块
|
|
4
|
+
|
|
5
|
+
封装 **tag‑resource‑management** 相关接口,提供两组下拉选项:
|
|
6
|
+
|
|
7
|
+
- **选择项目(Project)下拉列表**
|
|
8
|
+
- **选择虚拟集群(Virtual‑Cluster)下拉列表**
|
|
9
|
+
"""
|
|
10
|
+
|
|
3
11
|
from __future__ import annotations
|
|
4
12
|
|
|
13
|
+
from typing import List
|
|
14
|
+
|
|
5
15
|
import httpx
|
|
6
16
|
|
|
7
17
|
from ..exceptions import APIError
|
|
8
18
|
from ..models.common import APIWrapper
|
|
9
|
-
from ..models.tag_resource_management import
|
|
19
|
+
from ..models.tag_resource_management import (
|
|
20
|
+
Project,
|
|
21
|
+
ProjectListData,
|
|
22
|
+
SelectVirtualClustersRequest,
|
|
23
|
+
SelectVirtualClustersResponse,
|
|
24
|
+
VirtualClusterBrief,
|
|
25
|
+
)
|
|
10
26
|
|
|
11
27
|
_BASE = "/tag-resource-management/api/v1"
|
|
12
28
|
|
|
13
29
|
|
|
14
30
|
class TagResourceManagementService:
|
|
31
|
+
"""标签资源管理服务"""
|
|
32
|
+
|
|
15
33
|
def __init__(self, http: httpx.Client):
|
|
16
34
|
self._project = _Project(http)
|
|
17
35
|
self._virtual_cluster = _VirtualCluster(http)
|
|
18
36
|
|
|
19
37
|
def select_projects(self) -> List[Project]:
|
|
38
|
+
"""获取全部项目下拉选项
|
|
39
|
+
|
|
40
|
+
Returns:
|
|
41
|
+
list[Project]: 项目列表,每项仅包含 `id` / `name`
|
|
42
|
+
"""
|
|
20
43
|
return self._project.select_projects()
|
|
21
44
|
|
|
22
45
|
def select_virtual_clusters(self, payload: SelectVirtualClustersRequest) -> List[VirtualClusterBrief]:
|
|
46
|
+
"""获取虚拟集群下拉选项
|
|
47
|
+
|
|
48
|
+
Args:
|
|
49
|
+
payload: 查询参数,包含用户 ID / 模块类型等过滤条件,详见 :class:`SelectVirtualClustersRequest`
|
|
50
|
+
|
|
51
|
+
Returns:
|
|
52
|
+
list[VirtualClusterBrief]: 过滤后的虚拟集群简要列表
|
|
53
|
+
"""
|
|
23
54
|
return self._virtual_cluster.select(payload).data
|
|
24
55
|
|
|
25
56
|
@property
|
aihub/services/task_center.py
CHANGED
|
@@ -1,3 +1,13 @@
|
|
|
1
|
+
# !/usr/bin/env python
|
|
2
|
+
# -*- coding:utf-8 -*-
|
|
3
|
+
"""任务中心服务模块
|
|
4
|
+
|
|
5
|
+
封装 **task‑center** 常用能力:
|
|
6
|
+
|
|
7
|
+
- **创建 / 查询任务**
|
|
8
|
+
- **一键创建标注任务**(高阶封装)
|
|
9
|
+
"""
|
|
10
|
+
|
|
1
11
|
from __future__ import annotations
|
|
2
12
|
|
|
3
13
|
import datetime
|
|
@@ -28,31 +38,37 @@ def date_str_to_timestamp(date_str: str) -> int:
|
|
|
28
38
|
|
|
29
39
|
|
|
30
40
|
class TaskCenterService:
|
|
41
|
+
"""任务中心服务"""
|
|
31
42
|
|
|
32
43
|
def __init__(self, http: httpx.Client):
|
|
33
44
|
self._TaskCenter = _TaskCenter(http)
|
|
34
45
|
self._http = http
|
|
35
46
|
|
|
36
47
|
def create(self, payload: CreateTaskReq) -> int:
|
|
48
|
+
"""创建任务
|
|
49
|
+
|
|
50
|
+
Args:
|
|
51
|
+
payload: 任务创建请求体,详见 :class:`CreateTaskReq`
|
|
52
|
+
|
|
53
|
+
Returns:
|
|
54
|
+
int: 后端生成的任务 ID
|
|
55
|
+
"""
|
|
37
56
|
return self._TaskCenter.create(payload)
|
|
38
57
|
|
|
39
58
|
def get(self, task_id: int) -> LabelTaskDetail:
|
|
40
|
-
"""
|
|
59
|
+
"""根据任务 ID 获取详情
|
|
41
60
|
|
|
42
61
|
Args:
|
|
43
|
-
task_id
|
|
44
|
-
|
|
62
|
+
task_id: 任务 ID
|
|
45
63
|
|
|
46
64
|
Returns:
|
|
47
|
-
LabelTaskDetail:
|
|
48
|
-
|
|
65
|
+
LabelTaskDetail: 任务完整信息
|
|
49
66
|
"""
|
|
50
|
-
|
|
51
67
|
return self._TaskCenter.get(task_id)
|
|
52
68
|
|
|
53
69
|
# 如果想要访问子对象,也保留属性
|
|
54
70
|
@property
|
|
55
|
-
def
|
|
71
|
+
def task_center(self) -> _TaskCenter:
|
|
56
72
|
return self._TaskCenter
|
|
57
73
|
|
|
58
74
|
def create_label_task(
|
|
@@ -160,7 +176,6 @@ class _TaskCenter:
|
|
|
160
176
|
self._http = http
|
|
161
177
|
|
|
162
178
|
def create(self, payload: CreateTaskReq) -> int:
|
|
163
|
-
"""创建任务"""
|
|
164
179
|
logger.debug(f"create task: {payload}")
|
|
165
180
|
resp = self._http.post(
|
|
166
181
|
f"{_BASE}/tasks",
|
|
@@ -176,7 +191,6 @@ class _TaskCenter:
|
|
|
176
191
|
return wrapper.data.id
|
|
177
192
|
|
|
178
193
|
def get(self, task_id: int) -> LabelTaskDetail:
|
|
179
|
-
"""获取任务"""
|
|
180
194
|
logger.debug(f"get task: {task_id}")
|
|
181
195
|
resp = self._http.get(
|
|
182
196
|
f"{_BASE}/tasks/{task_id}",
|