intellif-aihub 0.1.2__py3-none-any.whl → 0.1.4__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 +19 -11
- aihub/models/eval.py +17 -0
- aihub/models/labelfree.py +35 -13
- aihub/models/model_training_platform.py +234 -0
- aihub/models/quota_schedule_management.py +239 -0
- aihub/models/tag_resource_management.py +50 -0
- aihub/models/task_center.py +10 -10
- aihub/models/user_system.py +262 -0
- aihub/services/artifact.py +29 -8
- aihub/services/dataset_management.py +1 -1
- aihub/services/eval.py +68 -0
- aihub/services/labelfree.py +1 -1
- aihub/services/model_training_platform.py +209 -0
- aihub/services/quota_schedule_management.py +164 -0
- aihub/services/tag_resource_management.py +55 -0
- aihub/services/task_center.py +16 -16
- aihub/services/user_system.py +339 -0
- {intellif_aihub-0.1.2.dist-info → intellif_aihub-0.1.4.dist-info}/METADATA +2 -2
- intellif_aihub-0.1.4.dist-info/RECORD +36 -0
- aihub/models/tag_management.py +0 -21
- aihub/models/user.py +0 -46
- aihub/services/tag_management.py +0 -35
- aihub/services/user.py +0 -47
- intellif_aihub-0.1.2.dist-info/RECORD +0 -32
- {intellif_aihub-0.1.2.dist-info → intellif_aihub-0.1.4.dist-info}/WHEEL +0 -0
- {intellif_aihub-0.1.2.dist-info → intellif_aihub-0.1.4.dist-info}/licenses/LICENSE +0 -0
- {intellif_aihub-0.1.2.dist-info → intellif_aihub-0.1.4.dist-info}/top_level.txt +0 -0
|
@@ -3,9 +3,16 @@ from __future__ import annotations
|
|
|
3
3
|
import os
|
|
4
4
|
from pathlib import Path
|
|
5
5
|
|
|
6
|
+
import httpx
|
|
7
|
+
|
|
8
|
+
from ..exceptions import APIError
|
|
9
|
+
from ..models.common import APIWrapper
|
|
10
|
+
from ..models.quota_schedule_management import *
|
|
11
|
+
|
|
6
12
|
_ENV_KEY = "PRE_STOP_SENTINEL_FILE"
|
|
7
13
|
_DEFAULT_SENTINEL = "/tmp/pre_stop_sentinel_file"
|
|
8
14
|
_SENTINEL_PATH = Path(os.getenv(_ENV_KEY, _DEFAULT_SENTINEL))
|
|
15
|
+
_BASE = "/quota-schedule-management/api/v1"
|
|
9
16
|
|
|
10
17
|
|
|
11
18
|
def is_pre_stopped() -> bool:
|
|
@@ -16,3 +23,160 @@ class PreStopService:
|
|
|
16
23
|
@staticmethod
|
|
17
24
|
def is_pre_stopped() -> bool:
|
|
18
25
|
return is_pre_stopped()
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class QuotaScheduleManagementService:
|
|
29
|
+
|
|
30
|
+
def __init__(self, http: httpx.Client):
|
|
31
|
+
self._task = _Task(http)
|
|
32
|
+
|
|
33
|
+
def create_task(self, payload: CreateTaskRequest) -> int:
|
|
34
|
+
"""创建调度任务
|
|
35
|
+
|
|
36
|
+
Args:
|
|
37
|
+
payload: 创建任务的各项参数
|
|
38
|
+
|
|
39
|
+
Returns:
|
|
40
|
+
int: 后端生成的任务 ID
|
|
41
|
+
"""
|
|
42
|
+
return self._task.create(payload)
|
|
43
|
+
|
|
44
|
+
def list_tasks(self, payload: ListTasksRequest) -> ListTasksResponse:
|
|
45
|
+
"""分页查询任务列表
|
|
46
|
+
|
|
47
|
+
Args:
|
|
48
|
+
payload: 查询条件(分页 / 过滤)
|
|
49
|
+
|
|
50
|
+
Returns:
|
|
51
|
+
ListTasksResponse: 列表及分页信息
|
|
52
|
+
"""
|
|
53
|
+
return self._task.list(payload)
|
|
54
|
+
|
|
55
|
+
def get_task(self, task_id: int) -> Task:
|
|
56
|
+
"""获取任务详情
|
|
57
|
+
|
|
58
|
+
Args:
|
|
59
|
+
task_id: 任务 ID
|
|
60
|
+
|
|
61
|
+
Returns:
|
|
62
|
+
Task: 任务完整信息
|
|
63
|
+
"""
|
|
64
|
+
return self._task.get(task_id)
|
|
65
|
+
|
|
66
|
+
def stop_task(self, task_id: int) -> None:
|
|
67
|
+
"""停止任务
|
|
68
|
+
|
|
69
|
+
Args:
|
|
70
|
+
task_id: 任务 ID
|
|
71
|
+
|
|
72
|
+
Returns:
|
|
73
|
+
None
|
|
74
|
+
"""
|
|
75
|
+
self._task.stop(task_id)
|
|
76
|
+
|
|
77
|
+
def list_task_pods(self, task_id: int, payload: ListTaskPodsRequest) -> ListTaskPodsResponse:
|
|
78
|
+
return self._task.list_pods(task_id, payload)
|
|
79
|
+
|
|
80
|
+
def get_task_pod(self, task_id: int, pod_id: int) -> Pod:
|
|
81
|
+
return self._task.get_pod(task_id, pod_id)
|
|
82
|
+
|
|
83
|
+
def get_pod_logs_new(self, task_id: int, pod_id: int) -> List[PodLogInfo]:
|
|
84
|
+
return self._task.get_logs_new(task_id, pod_id).logs
|
|
85
|
+
|
|
86
|
+
def get_pod_spec(self, task_id: int, pod_id: int) -> str:
|
|
87
|
+
return self._task.get_spec(task_id, pod_id).spec
|
|
88
|
+
|
|
89
|
+
def get_pod_events(self, task_id: int, pod_id: int) -> str:
|
|
90
|
+
return self._task.get_events(task_id, pod_id).events
|
|
91
|
+
|
|
92
|
+
def list_task_users(self, payload: ListTaskUsersRequest) -> ListTaskUsersResponse:
|
|
93
|
+
return self._task.list_users(payload)
|
|
94
|
+
|
|
95
|
+
def get_metrics_overview(self, payload: GetMetricsOverviewRequest) -> GetMetricsOverviewResponse:
|
|
96
|
+
return self._task.get_metrics_overview(payload)
|
|
97
|
+
|
|
98
|
+
@property
|
|
99
|
+
def task(self) -> _Task:
|
|
100
|
+
return self._task
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
class _Task:
|
|
104
|
+
|
|
105
|
+
def __init__(self, http: httpx.Client):
|
|
106
|
+
self._http = http
|
|
107
|
+
|
|
108
|
+
def create(self, payload: CreateTaskRequest) -> int:
|
|
109
|
+
resp = self._http.post(f"{_BASE}/tasks", json=payload.model_dump(by_alias=True, exclude_none=True))
|
|
110
|
+
wrapper = APIWrapper[CreateTaskResponse].model_validate(resp.json())
|
|
111
|
+
if wrapper.code != 0:
|
|
112
|
+
raise APIError(f"backend code {wrapper.code}: {wrapper.msg}")
|
|
113
|
+
return wrapper.data.id
|
|
114
|
+
|
|
115
|
+
def list(self, payload: ListTasksRequest) -> ListTasksResponse:
|
|
116
|
+
resp = self._http.get(f"{_BASE}/tasks", params=payload.model_dump(by_alias=True, exclude_none=True))
|
|
117
|
+
wrapper = APIWrapper[ListTasksResponse].model_validate(resp.json())
|
|
118
|
+
if wrapper.code != 0:
|
|
119
|
+
raise APIError(f"backend code {wrapper.code}: {wrapper.msg}")
|
|
120
|
+
return wrapper.data
|
|
121
|
+
|
|
122
|
+
def get(self, task_id: int) -> Task:
|
|
123
|
+
resp = self._http.get(f"{_BASE}/tasks/{task_id}")
|
|
124
|
+
wrapper = APIWrapper[Task].model_validate(resp.json())
|
|
125
|
+
if wrapper.code != 0:
|
|
126
|
+
raise APIError(f"backend code {wrapper.code}: {wrapper.msg}")
|
|
127
|
+
return wrapper.data
|
|
128
|
+
|
|
129
|
+
def stop(self, task_id: int) -> None:
|
|
130
|
+
resp = self._http.post(f"{_BASE}/tasks/{task_id}/stop")
|
|
131
|
+
wrapper = APIWrapper[dict].model_validate(resp.json())
|
|
132
|
+
if wrapper.code != 0:
|
|
133
|
+
raise APIError(f"backend code {wrapper.code}: {wrapper.msg}")
|
|
134
|
+
|
|
135
|
+
def list_pods(self, task_id: int, payload: ListTaskPodsRequest) -> ListTaskPodsResponse:
|
|
136
|
+
resp = self._http.get(f"{_BASE}/tasks/{task_id}/pods", params=payload.model_dump(by_alias=True))
|
|
137
|
+
wrapper = APIWrapper[ListTaskPodsResponse].model_validate(resp.json())
|
|
138
|
+
if wrapper.code != 0:
|
|
139
|
+
raise APIError(f"backend code {wrapper.code}: {wrapper.msg}")
|
|
140
|
+
return wrapper.data
|
|
141
|
+
|
|
142
|
+
def get_pod(self, task_id: int, pod_id: int) -> Pod:
|
|
143
|
+
resp = self._http.get(f"{_BASE}/tasks/{task_id}/pods/{pod_id}")
|
|
144
|
+
wrapper = APIWrapper[Pod].model_validate(resp.json())
|
|
145
|
+
if wrapper.code != 0:
|
|
146
|
+
raise APIError(f"backend code {wrapper.code}: {wrapper.msg}")
|
|
147
|
+
return wrapper.data
|
|
148
|
+
|
|
149
|
+
def get_logs_new(self, task_id: int, pod_id: int) -> GetTaskPodLogsNewResponse:
|
|
150
|
+
resp = self._http.get(f"{_BASE}/tasks/{task_id}/pods/{pod_id}/logs/new")
|
|
151
|
+
wrapper = APIWrapper[GetTaskPodLogsNewResponse].model_validate(resp.json())
|
|
152
|
+
if wrapper.code != 0:
|
|
153
|
+
raise APIError(f"backend code {wrapper.code}: {wrapper.msg}")
|
|
154
|
+
return wrapper.data
|
|
155
|
+
|
|
156
|
+
def get_spec(self, task_id: int, pod_id: int) -> GetTaskPodSpecResponse:
|
|
157
|
+
resp = self._http.get(f"{_BASE}/tasks/{task_id}/pods/{pod_id}/spec")
|
|
158
|
+
wrapper = APIWrapper[GetTaskPodSpecResponse].model_validate(resp.json())
|
|
159
|
+
if wrapper.code != 0:
|
|
160
|
+
raise APIError(f"backend code {wrapper.code}: {wrapper.msg}")
|
|
161
|
+
return wrapper.data
|
|
162
|
+
|
|
163
|
+
def get_events(self, task_id: int, pod_id: int) -> GetTaskPodEventsResponse:
|
|
164
|
+
resp = self._http.get(f"{_BASE}/tasks/{task_id}/pods/{pod_id}/events")
|
|
165
|
+
wrapper = APIWrapper[GetTaskPodEventsResponse].model_validate(resp.json())
|
|
166
|
+
if wrapper.code != 0:
|
|
167
|
+
raise APIError(f"backend code {wrapper.code}: {wrapper.msg}")
|
|
168
|
+
return wrapper.data
|
|
169
|
+
|
|
170
|
+
def list_users(self, payload: ListTaskUsersRequest) -> ListTaskUsersResponse:
|
|
171
|
+
resp = self._http.get(f"{_BASE}/task-users", params=payload.model_dump(by_alias=True))
|
|
172
|
+
wrapper = APIWrapper[ListTaskUsersResponse].model_validate(resp.json())
|
|
173
|
+
if wrapper.code != 0:
|
|
174
|
+
raise APIError(f"backend code {wrapper.code}: {wrapper.msg}")
|
|
175
|
+
return wrapper.data
|
|
176
|
+
|
|
177
|
+
def get_metrics_overview(self, payload: GetMetricsOverviewRequest) -> GetMetricsOverviewResponse:
|
|
178
|
+
resp = self._http.get(f"{_BASE}/metrics/overview", params=payload.model_dump(by_alias=True))
|
|
179
|
+
wrapper = APIWrapper[GetMetricsOverviewResponse].model_validate(resp.json())
|
|
180
|
+
if wrapper.code != 0:
|
|
181
|
+
raise APIError(f"backend code {wrapper.code}: {wrapper.msg}")
|
|
182
|
+
return wrapper.data
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# !/usr/bin/env python
|
|
2
|
+
# -*-coding:utf-8 -*-
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import httpx
|
|
6
|
+
|
|
7
|
+
from ..exceptions import APIError
|
|
8
|
+
from ..models.common import APIWrapper
|
|
9
|
+
from ..models.tag_resource_management import *
|
|
10
|
+
|
|
11
|
+
_BASE = "/tag-resource-management/api/v1"
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class TagResourceManagementService:
|
|
15
|
+
def __init__(self, http: httpx.Client):
|
|
16
|
+
self._project = _Project(http)
|
|
17
|
+
self._virtual_cluster = _VirtualCluster(http)
|
|
18
|
+
|
|
19
|
+
def select_projects(self) -> List[Project]:
|
|
20
|
+
return self._project.select_projects()
|
|
21
|
+
|
|
22
|
+
def select_virtual_clusters(self, payload: SelectVirtualClustersRequest) -> List[VirtualClusterBrief]:
|
|
23
|
+
return self._virtual_cluster.select(payload).data
|
|
24
|
+
|
|
25
|
+
@property
|
|
26
|
+
def project(self) -> _Project:
|
|
27
|
+
return self._project
|
|
28
|
+
|
|
29
|
+
@property
|
|
30
|
+
def virtual_cluster(self) -> _VirtualCluster:
|
|
31
|
+
return self._virtual_cluster
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class _Project:
|
|
35
|
+
def __init__(self, http: httpx.Client):
|
|
36
|
+
self._http = http
|
|
37
|
+
|
|
38
|
+
def select_projects(self) -> List[Project]:
|
|
39
|
+
resp = self._http.get(f"{_BASE}/select-projects")
|
|
40
|
+
wrapper = APIWrapper[ProjectListData].model_validate(resp.json())
|
|
41
|
+
if wrapper.code != 0:
|
|
42
|
+
raise APIError(f"backend code {wrapper.code}: {wrapper.msg}")
|
|
43
|
+
return wrapper.data.data
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class _VirtualCluster:
|
|
47
|
+
def __init__(self, http: httpx.Client):
|
|
48
|
+
self._http = http
|
|
49
|
+
|
|
50
|
+
def select(self, payload: SelectVirtualClustersRequest) -> SelectVirtualClustersResponse:
|
|
51
|
+
resp = self._http.get(f"{_BASE}/select-clusters", params=payload.model_dump(by_alias=True, exclude_none=True))
|
|
52
|
+
wrapper = APIWrapper[SelectVirtualClustersResponse].model_validate(resp.json())
|
|
53
|
+
if wrapper.code != 0:
|
|
54
|
+
raise APIError(f"backend code {wrapper.code}: {wrapper.msg}")
|
|
55
|
+
return wrapper.data
|
aihub/services/task_center.py
CHANGED
|
@@ -5,8 +5,8 @@ import datetime
|
|
|
5
5
|
import httpx
|
|
6
6
|
from loguru import logger
|
|
7
7
|
|
|
8
|
-
from .
|
|
9
|
-
from .
|
|
8
|
+
from .tag_resource_management import TagResourceManagementService
|
|
9
|
+
from .user_system import UserSystemService
|
|
10
10
|
from ..exceptions import APIError
|
|
11
11
|
from ..models.common import APIWrapper
|
|
12
12
|
from ..models.task_center import (
|
|
@@ -17,7 +17,7 @@ from ..models.task_center import (
|
|
|
17
17
|
TaskCenterPriorityEnum,
|
|
18
18
|
LabelTaskDetail,
|
|
19
19
|
)
|
|
20
|
-
from ..models.
|
|
20
|
+
from ..models.user_system import SearchUsersRequest
|
|
21
21
|
|
|
22
22
|
_BASE = "/task-center/api/v1"
|
|
23
23
|
|
|
@@ -56,16 +56,16 @@ class TaskCenterService:
|
|
|
56
56
|
return self._TaskCenter
|
|
57
57
|
|
|
58
58
|
def create_label_task(
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
59
|
+
self,
|
|
60
|
+
name: str,
|
|
61
|
+
dataset_version_name: str,
|
|
62
|
+
feishu_doc_name: str,
|
|
63
|
+
task_receiver_name: str,
|
|
64
|
+
estimated_delivery_at: str,
|
|
65
|
+
project_name: str,
|
|
66
|
+
label_type: LabelProjectTypeEnum = LabelProjectTypeEnum.IMAGE_CLASSIFICATION,
|
|
67
|
+
description: str = "",
|
|
68
|
+
task_priority: TaskCenterPriorityEnum = TaskCenterPriorityEnum.low,
|
|
69
69
|
) -> int:
|
|
70
70
|
"""创建标注任务
|
|
71
71
|
|
|
@@ -93,13 +93,13 @@ task_priority="low", estimated_delivery_at= "2025-08-01")
|
|
|
93
93
|
任务ID
|
|
94
94
|
"""
|
|
95
95
|
# 获取接收者ID
|
|
96
|
-
user_service =
|
|
96
|
+
user_service = UserSystemService(self._http)
|
|
97
97
|
task_receiver_id = user_service.search_one(
|
|
98
|
-
payload=
|
|
98
|
+
payload=SearchUsersRequest(nickname=task_receiver_name)
|
|
99
99
|
)
|
|
100
100
|
|
|
101
101
|
# 获取项目ID
|
|
102
|
-
tag_service =
|
|
102
|
+
tag_service = TagResourceManagementService(self._http)
|
|
103
103
|
projects = tag_service.select_projects()
|
|
104
104
|
project_id = None
|
|
105
105
|
for project in projects:
|
|
@@ -0,0 +1,339 @@
|
|
|
1
|
+
# !/usr/bin/env python
|
|
2
|
+
# -*-coding:utf-8 -*-
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import httpx
|
|
6
|
+
|
|
7
|
+
from ..exceptions import APIError
|
|
8
|
+
from ..models.common import APIWrapper
|
|
9
|
+
from ..models.user_system import *
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class UserSystemService:
|
|
13
|
+
|
|
14
|
+
def __init__(self, http: httpx.Client):
|
|
15
|
+
self._auth = _Auth(http)
|
|
16
|
+
self._menu = _Menu(http)
|
|
17
|
+
self._role = _Role(http)
|
|
18
|
+
self._user = _User(http)
|
|
19
|
+
|
|
20
|
+
# ==================================================
|
|
21
|
+
# AUTH 一级方法
|
|
22
|
+
# ==================================================
|
|
23
|
+
def login(self, payload: LoginRequest) -> LoginResponse:
|
|
24
|
+
return self._auth.login(payload)
|
|
25
|
+
|
|
26
|
+
def signup(self, payload: SignupRequest) -> SignupResponse:
|
|
27
|
+
return self._auth.signup(payload)
|
|
28
|
+
|
|
29
|
+
# ==================================================
|
|
30
|
+
# MENU 一级方法
|
|
31
|
+
# ==================================================
|
|
32
|
+
def list_menus(self, need_roles: bool = False) -> ListMenusResponse:
|
|
33
|
+
return self._menu.list(need_roles)
|
|
34
|
+
|
|
35
|
+
def get_menu(self, menu_id: int) -> Menu:
|
|
36
|
+
return self._menu.get(menu_id)
|
|
37
|
+
|
|
38
|
+
def create_menu(self, payload: CreateMenuRequest) -> int:
|
|
39
|
+
return self._menu.create(payload)
|
|
40
|
+
|
|
41
|
+
def update_menu(self, menu_id: int, payload: UpdateMenuRequest) -> None:
|
|
42
|
+
self._menu.update(menu_id, payload)
|
|
43
|
+
|
|
44
|
+
def delete_menu(self, menu_id: int) -> None:
|
|
45
|
+
self._menu.delete(menu_id)
|
|
46
|
+
|
|
47
|
+
def get_menu_roles(self, menu_id: int) -> List[int]:
|
|
48
|
+
return self._menu.get_roles(menu_id)
|
|
49
|
+
|
|
50
|
+
def set_menu_roles(self, menu_id: int, role_ids: List[int]) -> None:
|
|
51
|
+
self._menu.set_roles(menu_id, role_ids)
|
|
52
|
+
|
|
53
|
+
# ==================================================
|
|
54
|
+
# ROLE 一级方法
|
|
55
|
+
# ==================================================
|
|
56
|
+
def list_roles(self, payload: ListRolesRequest) -> ListRolesResponse:
|
|
57
|
+
return self._role.list(payload)
|
|
58
|
+
|
|
59
|
+
def get_role(self, role_id: int) -> Role:
|
|
60
|
+
return self._role.get(role_id)
|
|
61
|
+
|
|
62
|
+
def create_role(self, payload: CreateRoleRequest) -> int:
|
|
63
|
+
return self._role.create(payload)
|
|
64
|
+
|
|
65
|
+
def update_role(self, role_id: int, payload: UpdateRoleRequest) -> None:
|
|
66
|
+
self._role.update(role_id, payload)
|
|
67
|
+
|
|
68
|
+
def delete_role(self, role_id: int) -> None:
|
|
69
|
+
self._role.delete(role_id)
|
|
70
|
+
|
|
71
|
+
def get_role_menus(self, role_id: int) -> List[int]:
|
|
72
|
+
return self._role.get_menus(role_id)
|
|
73
|
+
|
|
74
|
+
def set_role_menus(self, role_id: int, menu_ids: List[int]) -> None:
|
|
75
|
+
self._role.set_menus(role_id, menu_ids)
|
|
76
|
+
|
|
77
|
+
def search_roles(self, payload: SearchRolesRequest) -> SearchRolesResponse:
|
|
78
|
+
return self._role.search(payload)
|
|
79
|
+
|
|
80
|
+
# ==================================================
|
|
81
|
+
# USER 一级方法
|
|
82
|
+
# ==================================================
|
|
83
|
+
def list_users(self, payload: ListUsersRequest) -> ListUsersResponse:
|
|
84
|
+
return self._user.list(payload)
|
|
85
|
+
|
|
86
|
+
def get_user(self, user_id: int) -> User:
|
|
87
|
+
return self._user.get(user_id)
|
|
88
|
+
|
|
89
|
+
def create_user(self, payload: CreateUserRequest) -> int:
|
|
90
|
+
return self._user.create(payload)
|
|
91
|
+
|
|
92
|
+
def update_user(self, user_id: int, payload: UpdateUserRequest) -> None:
|
|
93
|
+
self._user.update(user_id, payload)
|
|
94
|
+
|
|
95
|
+
def delete_user(self, user_id: int) -> None:
|
|
96
|
+
self._user.delete(user_id)
|
|
97
|
+
|
|
98
|
+
def set_user_roles(self, user_id: int, payload: SetUserRolesRequest) -> None:
|
|
99
|
+
self._user.set_roles(user_id, payload)
|
|
100
|
+
|
|
101
|
+
def get_user_menus(self, user_id: int, parent_id: int | None = None, auth: str | None = None, ) -> List[TreeMenu]:
|
|
102
|
+
return self._user.get_menus(user_id, parent_id=parent_id, auth=auth)
|
|
103
|
+
|
|
104
|
+
def search_users(self, payload: SearchUsersRequest) -> SearchUsersResponse:
|
|
105
|
+
return self._user.search(payload)
|
|
106
|
+
|
|
107
|
+
def search_one(self, payload: SearchUsersRequest) -> int:
|
|
108
|
+
return self._user.search_one(payload)
|
|
109
|
+
|
|
110
|
+
@property
|
|
111
|
+
def auth(self) -> _Auth:
|
|
112
|
+
return self._auth
|
|
113
|
+
|
|
114
|
+
@property
|
|
115
|
+
def menu(self) -> _Menu:
|
|
116
|
+
return self._menu
|
|
117
|
+
|
|
118
|
+
@property
|
|
119
|
+
def role(self) -> _Role:
|
|
120
|
+
return self._role
|
|
121
|
+
|
|
122
|
+
@property
|
|
123
|
+
def user(self) -> _User:
|
|
124
|
+
return self._user
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
class _Auth:
|
|
128
|
+
_base = "/api/v1/auth"
|
|
129
|
+
|
|
130
|
+
def __init__(self, http: httpx.Client):
|
|
131
|
+
self._http = http
|
|
132
|
+
|
|
133
|
+
def login(self, req: LoginRequest) -> LoginResponse:
|
|
134
|
+
resp = self._http.post(
|
|
135
|
+
f"{self._base}/login",
|
|
136
|
+
json=req.model_dump(by_alias=True, exclude_none=True),
|
|
137
|
+
)
|
|
138
|
+
wrapper = APIWrapper[LoginResponse].model_validate(resp.json())
|
|
139
|
+
if wrapper.code != 0:
|
|
140
|
+
raise APIError(f"backend code {wrapper.code}: {wrapper.msg}")
|
|
141
|
+
return wrapper.data
|
|
142
|
+
|
|
143
|
+
def signup(self, req: SignupRequest) -> SignupResponse:
|
|
144
|
+
resp = self._http.post(
|
|
145
|
+
f"{self._base}/signup",
|
|
146
|
+
json=req.model_dump(by_alias=True, exclude_none=True),
|
|
147
|
+
)
|
|
148
|
+
wrapper = APIWrapper[SignupResponse].model_validate(resp.json())
|
|
149
|
+
if wrapper.code != 0:
|
|
150
|
+
raise APIError(f"backend code {wrapper.code}: {wrapper.msg}")
|
|
151
|
+
return wrapper.data
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
class _Menu:
|
|
155
|
+
_base = "/api/v1/menus"
|
|
156
|
+
|
|
157
|
+
def __init__(self, http: httpx.Client):
|
|
158
|
+
self._http = http
|
|
159
|
+
|
|
160
|
+
def list(self, need_roles: bool) -> ListMenusResponse:
|
|
161
|
+
resp = self._http.get(self._base, params={"need_roles": str(need_roles).lower()})
|
|
162
|
+
wrapper = APIWrapper[ListMenusResponse].model_validate(resp.json())
|
|
163
|
+
if wrapper.code != 0:
|
|
164
|
+
raise APIError(f"backend code {wrapper.code}: {wrapper.msg}")
|
|
165
|
+
return wrapper.data
|
|
166
|
+
|
|
167
|
+
def get(self, menu_id: int) -> Menu:
|
|
168
|
+
resp = self._http.get(f"{self._base}/{menu_id}")
|
|
169
|
+
wrapper = APIWrapper[Menu].model_validate(resp.json())
|
|
170
|
+
if wrapper.code != 0:
|
|
171
|
+
raise APIError(f"backend code {wrapper.code}: {wrapper.msg}")
|
|
172
|
+
return wrapper.data
|
|
173
|
+
|
|
174
|
+
def create(self, req: CreateMenuRequest) -> int:
|
|
175
|
+
resp = self._http.post(self._base, json=req.model_dump(by_alias=True, exclude_none=True))
|
|
176
|
+
wrapper = APIWrapper[CreateMenuResponse].model_validate(resp.json())
|
|
177
|
+
if wrapper.code != 0:
|
|
178
|
+
raise APIError(f"backend code {wrapper.code}: {wrapper.msg}")
|
|
179
|
+
return wrapper.data.id
|
|
180
|
+
|
|
181
|
+
def update(self, menu_id: int, req: UpdateMenuRequest) -> None:
|
|
182
|
+
resp = self._http.put(f"{self._base}/{menu_id}", json=req.model_dump(by_alias=True, exclude_none=True))
|
|
183
|
+
wrapper = APIWrapper[dict].model_validate(resp.json())
|
|
184
|
+
if wrapper.code != 0:
|
|
185
|
+
raise APIError(f"backend code {wrapper.code}: {wrapper.msg}")
|
|
186
|
+
|
|
187
|
+
def delete(self, menu_id: int) -> None:
|
|
188
|
+
resp = self._http.delete(f"{self._base}/{menu_id}")
|
|
189
|
+
wrapper = APIWrapper[dict].model_validate(resp.json())
|
|
190
|
+
if wrapper.code != 0:
|
|
191
|
+
raise APIError(f"backend code {wrapper.code}: {wrapper.msg}")
|
|
192
|
+
|
|
193
|
+
def get_roles(self, menu_id: int) -> List[int]:
|
|
194
|
+
resp = self._http.get(f"{self._base}/{menu_id}/roles")
|
|
195
|
+
wrapper = APIWrapper[GetMenuRolesResponse].model_validate(resp.json())
|
|
196
|
+
if wrapper.code != 0:
|
|
197
|
+
raise APIError(f"backend code {wrapper.code}: {wrapper.msg}")
|
|
198
|
+
return wrapper.data.role_ids
|
|
199
|
+
|
|
200
|
+
def set_roles(self, menu_id: int, role_ids: List[int]) -> None:
|
|
201
|
+
resp = self._http.put(f"{self._base}/{menu_id}/roles", json={"role_ids": role_ids})
|
|
202
|
+
wrapper = APIWrapper[dict].model_validate(resp.json())
|
|
203
|
+
if wrapper.code != 0:
|
|
204
|
+
raise APIError(f"backend code {wrapper.code}: {wrapper.msg}")
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
class _Role:
|
|
208
|
+
_base = "/api/v1/roles"
|
|
209
|
+
_search = "/api/v1/search-roles"
|
|
210
|
+
|
|
211
|
+
def __init__(self, http: httpx.Client):
|
|
212
|
+
self._http = http
|
|
213
|
+
|
|
214
|
+
def list(self, req: ListRolesRequest) -> ListRolesResponse:
|
|
215
|
+
resp = self._http.get(self._base, params=req.model_dump(by_alias=True, exclude_none=True))
|
|
216
|
+
wrapper = APIWrapper[ListRolesResponse].model_validate(resp.json())
|
|
217
|
+
if wrapper.code != 0:
|
|
218
|
+
raise APIError(f"backend code {wrapper.code}: {wrapper.msg}")
|
|
219
|
+
return wrapper.data
|
|
220
|
+
|
|
221
|
+
def get(self, role_id: int) -> Role:
|
|
222
|
+
resp = self._http.get(f"{self._base}/{role_id}")
|
|
223
|
+
wrapper = APIWrapper[Role].model_validate(resp.json())
|
|
224
|
+
if wrapper.code != 0:
|
|
225
|
+
raise APIError(f"backend code {wrapper.code}: {wrapper.msg}")
|
|
226
|
+
return wrapper.data
|
|
227
|
+
|
|
228
|
+
def create(self, req: CreateRoleRequest) -> int:
|
|
229
|
+
resp = self._http.post(self._base, json=req.model_dump(by_alias=True, exclude_none=True))
|
|
230
|
+
wrapper = APIWrapper[CreateRoleResponse].model_validate(resp.json())
|
|
231
|
+
if wrapper.code != 0:
|
|
232
|
+
raise APIError(f"backend code {wrapper.code}: {wrapper.msg}")
|
|
233
|
+
return wrapper.data.id
|
|
234
|
+
|
|
235
|
+
def update(self, role_id: int, req: UpdateRoleRequest) -> None:
|
|
236
|
+
resp = self._http.put(f"{self._base}/{role_id}", json=req.model_dump(by_alias=True, exclude_none=True))
|
|
237
|
+
wrapper = APIWrapper[dict].model_validate(resp.json())
|
|
238
|
+
if wrapper.code != 0:
|
|
239
|
+
raise APIError(f"backend code {wrapper.code}: {wrapper.msg}")
|
|
240
|
+
|
|
241
|
+
def delete(self, role_id: int) -> None:
|
|
242
|
+
resp = self._http.delete(f"{self._base}/{role_id}")
|
|
243
|
+
wrapper = APIWrapper[dict].model_validate(resp.json())
|
|
244
|
+
if wrapper.code != 0:
|
|
245
|
+
raise APIError(f"backend code {wrapper.code}: {wrapper.msg}")
|
|
246
|
+
|
|
247
|
+
def get_menus(self, role_id: int) -> List[int]:
|
|
248
|
+
resp = self._http.get(f"{self._base}/{role_id}/menus")
|
|
249
|
+
wrapper = APIWrapper[GetRoleMenusResponse].model_validate(resp.json())
|
|
250
|
+
if wrapper.code != 0:
|
|
251
|
+
raise APIError(f"backend code {wrapper.code}: {wrapper.msg}")
|
|
252
|
+
return wrapper.data.menu_ids
|
|
253
|
+
|
|
254
|
+
def set_menus(self, role_id: int, menu_ids: List[int]) -> None:
|
|
255
|
+
resp = self._http.put(f"{self._base}/{role_id}/menus", json={"menu_ids": menu_ids})
|
|
256
|
+
wrapper = APIWrapper[dict].model_validate(resp.json())
|
|
257
|
+
if wrapper.code != 0:
|
|
258
|
+
raise APIError(f"backend code {wrapper.code}: {wrapper.msg}")
|
|
259
|
+
|
|
260
|
+
def search(self, req: SearchRolesRequest) -> SearchRolesResponse:
|
|
261
|
+
resp = self._http.post(self._search, json=req.model_dump(by_alias=True, exclude_none=True))
|
|
262
|
+
wrapper = APIWrapper[SearchRolesResponse].model_validate(resp.json())
|
|
263
|
+
if wrapper.code != 0:
|
|
264
|
+
raise APIError(f"backend code {wrapper.code}: {wrapper.msg}")
|
|
265
|
+
return wrapper.data
|
|
266
|
+
|
|
267
|
+
|
|
268
|
+
class _User:
|
|
269
|
+
_base = "/api/v1/users"
|
|
270
|
+
_search = "/api/v1/search-users"
|
|
271
|
+
|
|
272
|
+
def __init__(self, http: httpx.Client):
|
|
273
|
+
self._http = http
|
|
274
|
+
|
|
275
|
+
def list(self, req: ListUsersRequest) -> ListUsersResponse:
|
|
276
|
+
resp = self._http.get(self._base, params=req.model_dump(by_alias=True, exclude_none=True))
|
|
277
|
+
wrapper = APIWrapper[ListUsersResponse].model_validate(resp.json())
|
|
278
|
+
if wrapper.code != 0:
|
|
279
|
+
raise APIError(f"backend code {wrapper.code}: {wrapper.msg}")
|
|
280
|
+
return wrapper.data
|
|
281
|
+
|
|
282
|
+
def get(self, user_id: int) -> User:
|
|
283
|
+
resp = self._http.get(f"{self._base}/{user_id}")
|
|
284
|
+
wrapper = APIWrapper[User].model_validate(resp.json())
|
|
285
|
+
if wrapper.code != 0:
|
|
286
|
+
raise APIError(f"backend code {wrapper.code}: {wrapper.msg}")
|
|
287
|
+
return wrapper.data
|
|
288
|
+
|
|
289
|
+
def create(self, req: CreateUserRequest) -> int:
|
|
290
|
+
resp = self._http.post(self._base, json=req.model_dump(by_alias=True, exclude_none=True))
|
|
291
|
+
wrapper = APIWrapper[CreateUserResponse].model_validate(resp.json())
|
|
292
|
+
if wrapper.code != 0:
|
|
293
|
+
raise APIError(f"backend code {wrapper.code}: {wrapper.msg}")
|
|
294
|
+
return wrapper.data.id
|
|
295
|
+
|
|
296
|
+
def update(self, user_id: int, req: UpdateUserRequest) -> None:
|
|
297
|
+
resp = self._http.put(f"{self._base}/{user_id}", json=req.model_dump(by_alias=True, exclude_none=True))
|
|
298
|
+
wrapper = APIWrapper[dict].model_validate(resp.json())
|
|
299
|
+
if wrapper.code != 0:
|
|
300
|
+
raise APIError(f"backend code {wrapper.code}: {wrapper.msg}")
|
|
301
|
+
|
|
302
|
+
def delete(self, user_id: int) -> None:
|
|
303
|
+
resp = self._http.delete(f"{self._base}/{user_id}")
|
|
304
|
+
wrapper = APIWrapper[dict].model_validate(resp.json())
|
|
305
|
+
if wrapper.code != 0:
|
|
306
|
+
raise APIError(f"backend code {wrapper.code}: {wrapper.msg}")
|
|
307
|
+
|
|
308
|
+
def set_roles(self, user_id: int, req: SetUserRolesRequest) -> None:
|
|
309
|
+
resp = self._http.put(f"{self._base}/{user_id}/roles", json=req.model_dump(by_alias=True, exclude_none=True))
|
|
310
|
+
wrapper = APIWrapper[dict].model_validate(resp.json())
|
|
311
|
+
if wrapper.code != 0:
|
|
312
|
+
raise APIError(f"backend code {wrapper.code}: {wrapper.msg}")
|
|
313
|
+
|
|
314
|
+
def get_menus(self, user_id: int, parent_id: int | None = None, auth: str | None = None) -> List[TreeMenu]:
|
|
315
|
+
params = {}
|
|
316
|
+
if parent_id is not None:
|
|
317
|
+
params["parent_id"] = parent_id
|
|
318
|
+
if auth:
|
|
319
|
+
params["auth"] = auth
|
|
320
|
+
|
|
321
|
+
resp = self._http.get(f"{self._base}/{user_id}/menus", params=params)
|
|
322
|
+
wrapper = APIWrapper[GetUserMenusResponse].model_validate(resp.json())
|
|
323
|
+
if wrapper.code != 0:
|
|
324
|
+
raise APIError(f"backend code {wrapper.code}: {wrapper.msg}")
|
|
325
|
+
return wrapper.data.menus
|
|
326
|
+
|
|
327
|
+
def search(self, req: SearchUsersRequest) -> SearchUsersResponse:
|
|
328
|
+
resp = self._http.post(self._search, json=req.model_dump(by_alias=True, exclude_none=True))
|
|
329
|
+
wrapper = APIWrapper[SearchUsersResponse].model_validate(resp.json())
|
|
330
|
+
if wrapper.code != 0:
|
|
331
|
+
raise APIError(f"backend code {wrapper.code}: {wrapper.msg}")
|
|
332
|
+
return wrapper.data
|
|
333
|
+
|
|
334
|
+
def search_one(self, req: SearchUsersRequest) -> int:
|
|
335
|
+
resp = self.search(req)
|
|
336
|
+
for user in resp.data:
|
|
337
|
+
if user.nickname == req.nickname:
|
|
338
|
+
return user.id
|
|
339
|
+
raise APIError("no user found")
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: intellif-aihub
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.4
|
|
4
4
|
Summary: Intellif AI-hub SDK.
|
|
5
5
|
Author-email: Platform Team <aihub@example.com>
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -13,7 +13,7 @@ License-File: LICENSE
|
|
|
13
13
|
Requires-Dist: httpx<0.28,>=0.27
|
|
14
14
|
Requires-Dist: pydantic<3.0,>=2.5.3
|
|
15
15
|
Requires-Dist: typing-extensions<5.0,>=4.13.2
|
|
16
|
-
Requires-Dist: pyarrow<16.0,>=15.0
|
|
16
|
+
Requires-Dist: pyarrow<16.0,>=15.0.2
|
|
17
17
|
Requires-Dist: tqdm<5.0,>=4.66
|
|
18
18
|
Requires-Dist: loguru>=0.7.3
|
|
19
19
|
Requires-Dist: minio>=7.2.7
|