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.

@@ -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
@@ -5,8 +5,8 @@ import datetime
5
5
  import httpx
6
6
  from loguru import logger
7
7
 
8
- from .tag_management import TagManagementService
9
- from .user import UserService
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.user import UserSearchReq
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
- 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,
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 = UserService(self._http)
96
+ user_service = UserSystemService(self._http)
97
97
  task_receiver_id = user_service.search_one(
98
- payload=UserSearchReq(nickname=task_receiver_name)
98
+ payload=SearchUsersRequest(nickname=task_receiver_name)
99
99
  )
100
100
 
101
101
  # 获取项目ID
102
- tag_service = TagManagementService(self._http)
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.2
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