intellif-aihub 0.1.21__py3-none-any.whl → 0.1.23__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.

@@ -2,40 +2,47 @@
2
2
  # -*- coding:utf-8 -*-
3
3
  """模型中心服务模块
4
4
 
5
- 封装与 **Model‑Center** 后端交互的常用能力,主要涉及模型的增、删、改、查,以及模型元数据(类型 / 部署平台 / 量化等级)的查询功能:
6
-
7
- - **分页查询模型列表**
8
- - **获取单个模型详情**
9
- - **新建模型**
10
- - **编辑模型**
11
- - **删除模型**
12
- - **查询模型类型下拉**
13
- - **查询部署平台下拉**
14
- - **查询量化等级下拉**
5
+ 当前封装的能力:
6
+ - 分页查询模型列表
7
+ - 获取单个模型详情
8
+ - 新建模型
9
+ - 编辑模型
10
+ - 删除模型
11
+ - 上传模型
12
+ - 下载模型
13
+ - 查询模型 DB 信息
15
14
  """
16
15
 
17
16
  from __future__ import annotations
18
17
 
18
+ import io
19
+ import os
20
+ import time
21
+
19
22
  import httpx
23
+ import minio
24
+ from loguru import logger
20
25
 
21
26
  from ..exceptions import APIError
27
+ from ..models.artifact import StsResp
22
28
  from ..models.common import APIWrapper
23
29
  from ..models.model_center import (
24
30
  ListModelsRequest,
25
31
  ListModelsResponse,
26
- ListModelTypesRequest,
27
- ListModelTypesResponse,
28
- ListDeployPlatformsRequest,
29
- ListDeployPlatformsResponse,
30
- ListQuantLevelsRequest,
31
- ListQuantLevelsResponse,
32
+ ModelCardDetail,
32
33
  CreateModelRequest,
33
34
  CreateModelResponse,
34
35
  EditModelRequest,
35
- Model,
36
+ ModelDb,
36
37
  )
38
+ from ..utils.di import SimpleS3Client, DataUploader
39
+ from ..utils.s3 import parse_s3_path_strict, download_dir_from_s3_to_local
37
40
 
38
41
  _BASE = "/model-center/api/v1"
42
+ MODEL_STATUS_INIT = "init"
43
+ MODEL_STATUS_UPLOADING = "uploading"
44
+ MODEL_STATUS_READY = "ready"
45
+ MODEL_STATUS_FAILED = "failed"
39
46
 
40
47
 
41
48
  class ModelCenterService:
@@ -55,14 +62,14 @@ class ModelCenterService:
55
62
  """
56
63
  return self._model.list(payload)
57
64
 
58
- def get_model(self, model_id: int) -> Model:
65
+ def get_model(self, model_id: int) -> ModelCardDetail:
59
66
  """获取模型详情
60
67
 
61
68
  Args:
62
69
  model_id: 模型 ID
63
70
 
64
71
  Returns:
65
- Model: 模型完整信息
72
+ ModelCardDetail: 模型详情(含 README、模型树、基模型等)
66
73
  """
67
74
  return self._model.get(model_id)
68
75
 
@@ -77,13 +84,14 @@ class ModelCenterService:
77
84
  """
78
85
  return self._model.create(payload)
79
86
 
80
- def edit_model(self, payload: EditModelRequest) -> None:
87
+ def edit_model(self, model_id: int, payload: EditModelRequest) -> None:
81
88
  """编辑模型信息
82
89
 
83
90
  Args:
84
- payload: 编辑模型所需字段(需包含 id)
91
+ model_id: 模型ID
92
+ payload: 编辑模型信息
85
93
  """
86
- self._model.edit(payload)
94
+ self._model.edit(model_id, payload)
87
95
 
88
96
  def delete_model(self, model_id: int) -> None:
89
97
  """删除模型
@@ -93,29 +101,50 @@ class ModelCenterService:
93
101
  """
94
102
  self._model.delete(model_id)
95
103
 
96
- def list_model_types(self) -> ListModelTypesResponse:
97
- """查询模型类型列表
104
+ def get_model_db(self, *, id: int | None = None, name: str | None = None) -> ModelDb:
105
+ """通过 id 或 name 查询模型 DB 信息
106
+
107
+ Args:
108
+ id: 模型id
109
+ name: 模型名称
98
110
 
99
111
  Returns:
100
- ListModelTypesResponse: 模型类型集合
112
+ ModelDb: 模型在DB中的信息
101
113
  """
102
- return self._model.list_types(ListModelTypesRequest())
114
+ return self._model.get_model_db(id=id, name=name)
115
+
116
+ def upload(
117
+ self,
118
+ *,
119
+ local_dir: str,
120
+ model_id: int | None = None,
121
+ model_name: str | None = None,
122
+ timeout_seconds: int = 3600,
123
+ ) -> None:
124
+ """上传模型
103
125
 
104
- def list_deploy_platforms(self) -> ListDeployPlatformsResponse:
105
- """查询可用部署平台列表
106
-
107
- Returns:
108
- ListDeployPlatformsResponse: 部署平台集合
126
+ Args:
127
+ local_dir: 本地模型目录
128
+ model_id: 模型 id
129
+ model_name: 模型名称
130
+ timeout_seconds: 超时时间
109
131
  """
110
- return self._model.list_platforms(ListDeployPlatformsRequest())
132
+ return self._model.upload(
133
+ local_dir=local_dir,
134
+ model_id=model_id,
135
+ model_name=model_name,
136
+ timeout_seconds=timeout_seconds,
137
+ )
111
138
 
112
- def list_quant_levels(self) -> ListQuantLevelsResponse:
113
- """查询量化等级列表
139
+ def download(self, *, local_dir: str, model_id: int | None = None, model_name: str | None = None) -> None:
140
+ """下载模型
114
141
 
115
- Returns:
116
- ListQuantLevelsResponse: 量化等级集合
142
+ Args:
143
+ local_dir: 要下载到的本地目录
144
+ model_id: 模型id
145
+ model_name: 模型名称
117
146
  """
118
- return self._model.list_quant_levels(ListQuantLevelsRequest())
147
+ return self._model.download(local_dir=local_dir, model_id=model_id, model_name=model_name)
119
148
 
120
149
  @property
121
150
  def model(self) -> _Model:
@@ -134,23 +163,39 @@ class _Model:
134
163
  raise APIError(f"backend code {wrapper.code}: {wrapper.msg}")
135
164
  return wrapper.data
136
165
 
137
- def get(self, model_id: int) -> Model:
166
+ def get(self, model_id: int) -> ModelCardDetail:
138
167
  resp = self._http.get(f"{_BASE}/models/{model_id}")
139
- wrapper = APIWrapper[Model].model_validate(resp.json())
168
+ wrapper = APIWrapper[ModelCardDetail].model_validate(resp.json())
140
169
  if wrapper.code != 0:
141
170
  raise APIError(f"backend code {wrapper.code}: {wrapper.msg}")
142
171
  return wrapper.data
143
172
 
144
- def create(self, payload: CreateModelRequest) -> int:
145
- resp = self._http.post(f"{_BASE}/models", json=payload.model_dump(by_alias=True, exclude_none=True))
173
+ def create(self, form: CreateModelRequest) -> int:
174
+ files = {
175
+ "name": (None, form.name),
176
+ "is_public": (None, "true" if bool(form.is_public) else "false"),
177
+ }
178
+ if form.description is not None:
179
+ files["description"] = (None, form.description)
180
+ if form.tags is not None:
181
+ files["tags"] = (None, form.tags)
182
+
183
+ if form.readme_content:
184
+ md_text = (
185
+ form.readme_content
186
+ if (form.readme_content and form.readme_content.strip())
187
+ else f"# {form.name}\n\nAutogenerated at {int(time.time())}\n"
188
+ )
189
+ files["readme_file"] = ("README.md", io.BytesIO(md_text.encode("utf-8")), "text/markdown")
190
+
191
+ resp = self._http.post(f"{_BASE}/models", files=files)
146
192
  wrapper = APIWrapper[CreateModelResponse].model_validate(resp.json())
147
193
  if wrapper.code != 0:
148
194
  raise APIError(f"backend code {wrapper.code}: {wrapper.msg}")
149
195
  return wrapper.data.id
150
196
 
151
- def edit(self, payload: EditModelRequest) -> None:
152
- resp = self._http.put(f"{_BASE}/models/{payload.id}",
153
- json=payload.model_dump(by_alias=True, exclude_none=True))
197
+ def edit(self, model_id: int, payload: EditModelRequest) -> None:
198
+ resp = self._http.put(f"{_BASE}/models/{model_id}", json=payload.model_dump(by_alias=True, exclude_none=True))
154
199
  wrapper = APIWrapper[dict].model_validate(resp.json())
155
200
  if wrapper.code != 0:
156
201
  raise APIError(f"backend code {wrapper.code}: {wrapper.msg}")
@@ -161,23 +206,126 @@ class _Model:
161
206
  if wrapper.code != 0:
162
207
  raise APIError(f"backend code {wrapper.code}: {wrapper.msg}")
163
208
 
164
- def list_types(self, payload: ListModelTypesRequest) -> ListModelTypesResponse:
165
- resp = self._http.get(f"{_BASE}/model-types", params=payload.model_dump(by_alias=True))
166
- wrapper = APIWrapper[ListModelTypesResponse].model_validate(resp.json())
209
+ def get_model_db(self, *, id: int | None = None, name: str | None = None) -> ModelDb:
210
+ if id is None and (name is None or name == ""):
211
+ raise ValueError("id or name is required")
212
+
213
+ params = {"id": id} if id is not None else {"name": name}
214
+ resp = self._http.get(f"{_BASE}/models/db", params=params)
215
+ wrapper = APIWrapper[ModelDb].model_validate(resp.json())
167
216
  if wrapper.code != 0:
168
217
  raise APIError(f"backend code {wrapper.code}: {wrapper.msg}")
169
218
  return wrapper.data
170
219
 
171
- def list_platforms(self, payload: ListDeployPlatformsRequest) -> ListDeployPlatformsResponse:
172
- resp = self._http.get(f"{_BASE}/deploy-platforms", params=payload.model_dump(by_alias=True))
173
- wrapper = APIWrapper[ListDeployPlatformsResponse].model_validate(resp.json())
220
+ def _get_sts(self) -> StsResp:
221
+ resp = self._http.get(f"{_BASE}/models/get-sts")
222
+ wrapper = APIWrapper[StsResp].model_validate(resp.json())
174
223
  if wrapper.code != 0:
175
224
  raise APIError(f"backend code {wrapper.code}: {wrapper.msg}")
176
225
  return wrapper.data
177
226
 
178
- def list_quant_levels(self, payload: ListQuantLevelsRequest) -> ListQuantLevelsResponse:
179
- resp = self._http.get(f"{_BASE}/quant-levels", params=payload.model_dump(by_alias=True))
180
- wrapper = APIWrapper[ListQuantLevelsResponse].model_validate(resp.json())
227
+ def upload(
228
+ self,
229
+ *,
230
+ local_dir: str,
231
+ model_id: int | None = None,
232
+ model_name: str | None = None,
233
+ timeout_seconds: int = 3600,
234
+ ) -> None:
235
+ if (model_id is None) and (not model_name):
236
+ raise ValueError("id or name is required")
237
+ if not local_dir or not os.path.exists(local_dir):
238
+ raise ValueError(f"local_dir not exists: {local_dir}")
239
+
240
+ # 1. get db info
241
+ db_info = self.get_model_db(id=model_id, name=model_name)
242
+ resolved_id = db_info.id
243
+ s3_target = db_info.object_storage_path
244
+ s3_csv_path = db_info.csv_file_path
245
+ s3_status_path = db_info.task_status_s3_path
246
+
247
+ # 2. upload file to s3
248
+ sts = self._get_sts()
249
+ s3_client = SimpleS3Client(
250
+ sts.endpoint, sts.access_key_id, sts.secret_access_key, session_token=sts.session_token
251
+ )
252
+ uploader = DataUploader(
253
+ task_id=resolved_id,
254
+ local_path=local_dir,
255
+ s3_target=s3_target,
256
+ csv_path=s3_csv_path,
257
+ status_path=s3_status_path,
258
+ num_workers=40,
259
+ )
260
+ stats = uploader.run(s3_client)
261
+
262
+ # 3. invoke model center upload interface
263
+ payload = {
264
+ "model_id": resolved_id,
265
+ "object_cnt": stats.uploaded_count,
266
+ "data_size": stats.uploaded_size,
267
+ }
268
+ resp = self._http.post(f"{_BASE}/models/upload", json=payload)
269
+ wrapper = APIWrapper[dict].model_validate(resp.json())
181
270
  if wrapper.code != 0:
182
271
  raise APIError(f"backend code {wrapper.code}: {wrapper.msg}")
183
- return wrapper.data
272
+
273
+ logger.info(f"模型上传本地处理完成,model_id={resolved_id},等待服务端处理,3s 后开始轮询状态…")
274
+ time.sleep(3)
275
+
276
+ start_ts = time.time()
277
+ poll_interval = 10
278
+ while True:
279
+ db_cur = self.get_model_db(id=resolved_id)
280
+ status = (db_cur.status or "").lower()
281
+
282
+ if status == MODEL_STATUS_READY:
283
+ logger.info(f"模型处理成功:model_id={resolved_id}, status=ready")
284
+ return
285
+
286
+ if status == MODEL_STATUS_FAILED:
287
+ logger.error(f"模型处理失败:model_id={resolved_id}, status=failed")
288
+ raise APIError(f"模型处理失败:model_id={resolved_id}, status=failed")
289
+
290
+ elapsed = time.time() - start_ts
291
+ if elapsed > timeout_seconds:
292
+ logger.error(f"等待模型就绪超时:model_id={resolved_id}, waited={int(elapsed)}s")
293
+ raise TimeoutError(f"等待模型就绪超时:model_id={resolved_id}, waited={int(elapsed)}s")
294
+
295
+ logger.info(f"[Model Upload] id={resolved_id} 已等待 {int(elapsed)}s,当前 status={status},继续轮询…")
296
+ time.sleep(poll_interval)
297
+
298
+ def download(self, *, local_dir: str, model_id: int | None = None, model_name: str | None = None) -> None:
299
+ if (model_id is None) and (not model_name):
300
+ raise ValueError("id or name is required")
301
+ if not local_dir:
302
+ raise ValueError("local_dir is required")
303
+
304
+ db_info = self.get_model_db(id=model_id, name=model_name)
305
+
306
+ # 判断是否允许下载
307
+ status = (db_info.status or "").lower()
308
+ if status != "ready":
309
+ raise APIError(f"model is not ready for download (current status: {db_info.status})")
310
+ if not (db_info.parquet_index_path or "").strip():
311
+ raise APIError("parquet index path is required and cannot be empty")
312
+
313
+ s3_dir_path = db_info.object_storage_path
314
+ if not s3_dir_path or not s3_dir_path.startswith("s3://"):
315
+ raise APIError(f"invalid object_storage_path: {s3_dir_path}")
316
+
317
+ sts = self._get_sts()
318
+ s3_client = minio.Minio(
319
+ sts.endpoint,
320
+ access_key=sts.access_key_id,
321
+ secret_key=sts.secret_access_key,
322
+ session_token=sts.session_token,
323
+ secure=False,
324
+ )
325
+
326
+ bucket, object_name = parse_s3_path_strict(s3_dir_path)
327
+ if not bucket or not object_name:
328
+ raise APIError(f"invalid s3 path: {s3_dir_path}")
329
+
330
+ os.makedirs(local_dir, exist_ok=True)
331
+ download_dir_from_s3_to_local(s3_client, bucket, object_name, local_dir)
@@ -84,6 +84,7 @@ class TaskCenterService:
84
84
  label_type: LabelProjectTypeEnum = LabelProjectTypeEnum.IMAGE_CLASSIFICATION,
85
85
  description: str = "",
86
86
  task_priority: TaskCenterPriorityEnum = TaskCenterPriorityEnum.low,
87
+ auto_valid_interval: int = 3,
87
88
  ) -> int:
88
89
  """创建标注任务
89
90
 
@@ -107,6 +108,7 @@ task_priority="low", estimated_delivery_at= "2025-08-01")
107
108
  label_type (LabelProjectTypeEnum): 标注项目类型,默认为图像分类
108
109
  description (str): 任务描述,默认为空
109
110
  task_priority (TaskCenterPriorityEnum): 任务优先级,默认为低优先级
111
+ auto_valid_interval(str): 标注自动验收时间(默认三天)
110
112
  Returns:
111
113
  任务ID
112
114
  """
@@ -153,6 +155,7 @@ task_priority="low", estimated_delivery_at= "2025-08-01")
153
155
  dataset_version_id=dataset_version_id,
154
156
  doc_id=doc_id,
155
157
  doc_type="doc_center",
158
+ auto_valid_interval=auto_valid_interval,
156
159
  )
157
160
  estimated_delivery_at_timestamp = date_str_to_timestamp(estimated_delivery_at)
158
161
  task_req = CreateTaskReq(
@@ -290,9 +290,9 @@ class UserSystemService:
290
290
  def delete_user(self, user_id: int) -> None:
291
291
  """删除用户
292
292
 
293
- Args:
294
- user_id: 目标用户 ID
295
- """
293
+ Args:
294
+ user_id: 目标用户 ID
295
+ """
296
296
  self._user.delete(user_id)
297
297
 
298
298
  def set_user_roles(self, user_id: int, payload: SetUserRolesRequest) -> None:
@@ -304,7 +304,12 @@ class UserSystemService:
304
304
  """
305
305
  self._user.set_roles(user_id, payload)
306
306
 
307
- def get_user_menus(self, user_id: int, parent_id: int | None = None, auth: str | None = None, ) -> List[TreeMenu]:
307
+ def get_user_menus(
308
+ self,
309
+ user_id: int,
310
+ parent_id: int | None = None,
311
+ auth: str | None = None,
312
+ ) -> List[TreeMenu]:
308
313
  """查询用户可见菜单
309
314
 
310
315
  Args:
@@ -317,7 +322,7 @@ class UserSystemService:
317
322
  """
318
323
  return self._user.get_menus(user_id, parent_id=parent_id, auth=auth)
319
324
 
320
- def search_users(self, payload: SearchUsersRequest) -> SearchUsersResponse:
325
+ def search_users(self, payload: SearchUsersRequest) -> List[User]:
321
326
  """条件搜索用户
322
327
 
323
328
  Args:
@@ -326,13 +331,15 @@ class UserSystemService:
326
331
  Returns:
327
332
  SearchUsersResponse: 搜索结果
328
333
  """
329
- return self._user.search(payload)
334
+ resp = self._user.search(payload)
335
+ return resp.data
330
336
 
331
- def search_one(self, payload: SearchUsersRequest) -> int:
337
+ def search_one(self, nickname: str) -> int:
332
338
  """搜索单个用户并返回其 ID
333
339
 
334
340
  Args:
335
- payload: 搜索条件
341
+ nickname: 用户昵称
342
+
336
343
 
337
344
  Returns:
338
345
  int: 命中的用户 ID
@@ -340,7 +347,10 @@ class UserSystemService:
340
347
  Raises:
341
348
  APIError: 未找到用户时抛出
342
349
  """
343
- return self._user.search_one(payload)
350
+ req = SearchUsersRequest(
351
+ nickname=nickname,
352
+ )
353
+ return self._user.search_one(req)
344
354
 
345
355
  @property
346
356
  def auth(self) -> _Auth:
@@ -568,6 +578,13 @@ class _User:
568
578
 
569
579
  def search_one(self, req: SearchUsersRequest) -> int:
570
580
  resp = self.search(req)
581
+
582
+ if resp.data is None:
583
+ raise APIError(f"no user found")
584
+
585
+ if len(resp.data) > 1:
586
+ raise APIError("more than one user found")
587
+
571
588
  for user in resp.data:
572
589
  if user.nickname == req.nickname:
573
590
  return user.id
aihub/utils/s3.py CHANGED
@@ -36,9 +36,7 @@ def local_path_to_s3_key(work_dir: str, local_path: str) -> str:
36
36
  return s3_key
37
37
 
38
38
 
39
- def upload_dir_to_s3(
40
- s3_client: Minio, local_dir: str, bucket: str, object_prefix: str
41
- ) -> None:
39
+ def upload_dir_to_s3(s3_client: Minio, local_dir: str, bucket: str, object_prefix: str) -> None:
42
40
  logger.info(
43
41
  f"Uploading directory {local_dir} to S3 bucket {bucket} with prefix {object_prefix}"
44
42
  )
@@ -57,9 +55,7 @@ def upload_dir_to_s3(
57
55
  return
58
56
 
59
57
 
60
- def download_dir_from_s3(
61
- s3_client: Minio, bucket: str, object_prefix: str, local_dir: str
62
- ) -> None:
58
+ def download_dir_from_s3(s3_client: Minio, bucket: str, object_prefix: str, local_dir: str) -> None:
63
59
  logger.info(
64
60
  f"Downloading directory from S3 bucket {bucket} with prefix {object_prefix} to {local_dir}"
65
61
  )
@@ -75,3 +71,50 @@ def download_dir_from_s3(
75
71
  f"Downloaded directory from S3 bucket {bucket} with prefix {object_prefix} to {local_dir}"
76
72
  )
77
73
  return
74
+
75
+
76
+ def parse_s3_path_strict(s3_path: str) -> tuple[str, str]:
77
+ if not isinstance(s3_path, str) or not s3_path.startswith("s3://"):
78
+ raise ValueError(f"invalid s3 path: {s3_path}")
79
+ without_scheme = s3_path[5:]
80
+ parts = without_scheme.split("/", 1)
81
+ bucket = parts[0].strip()
82
+ if not bucket:
83
+ raise ValueError(f"invalid s3 path (empty bucket): {s3_path}")
84
+ key = parts[1] if len(parts) > 1 else ""
85
+ return bucket, key
86
+
87
+
88
+ def download_dir_from_s3_to_local(s3_client: Minio, bucket: str, object_prefix: str, local_dir: str) -> None:
89
+ logger.info(f"Downloading directory from S3 bucket {bucket} with prefix {object_prefix} to {local_dir}")
90
+
91
+ norm_prefix = object_prefix.replace("\\", "/").lstrip("/")
92
+ if norm_prefix and not norm_prefix.endswith("/"):
93
+ norm_prefix = norm_prefix + "/"
94
+
95
+ prefixes = [object_prefix]
96
+ norm_for_list = object_prefix.replace("\\", "/")
97
+ if norm_for_list != object_prefix:
98
+ prefixes.append(norm_for_list)
99
+
100
+ seen = set()
101
+ for pfx in prefixes:
102
+ for obj in s3_client.list_objects(bucket, pfx, recursive=True):
103
+ key = obj.object_name
104
+ if key in seen:
105
+ continue
106
+ seen.add(key)
107
+
108
+ norm_key = key.replace("\\", "/")
109
+ if norm_key.endswith("/"):
110
+ continue
111
+
112
+ if norm_prefix and not norm_key.startswith(norm_prefix):
113
+ continue
114
+
115
+ rel = norm_key[len(norm_prefix):] if norm_prefix else norm_key
116
+ dest_path = os.path.join(local_dir, *rel.split("/"))
117
+ os.makedirs(os.path.dirname(dest_path), exist_ok=True)
118
+ s3_client.fget_object(bucket, key, dest_path)
119
+
120
+ logger.info(f"Downloaded directory from S3 bucket {bucket} with prefix {object_prefix} to {local_dir}")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: intellif-aihub
3
- Version: 0.1.21
3
+ Version: 0.1.23
4
4
  Summary: Intellif AI-hub SDK.
5
5
  Author-email: Platform Team <aihub@example.com>
6
6
  License-Expression: Apache-2.0
@@ -18,6 +18,7 @@ Requires-Dist: tqdm<5.0,>=4.66
18
18
  Requires-Dist: loguru>=0.7.3
19
19
  Requires-Dist: minio>=7.2.7
20
20
  Requires-Dist: requests>=2.32.4
21
+ Requires-Dist: typer>=0.12.0
21
22
  Dynamic: license-file
22
23
 
23
24
  # Intellif AI-Hub SDK
@@ -1,43 +1,49 @@
1
- aihub/__init__.py,sha256=qEmNtjnOwhDYQ0cHPPtUkUaghzD2xl0thJEznl4giYw,23
1
+ aihub/__init__.py,sha256=0byemO6n6WCv41u9vBG2AIsOkVbxLvok7puvwy8EhfU,23
2
2
  aihub/client.py,sha256=Fu3jlEy21T4nJDV5EXTDujy1_B3Pf6CSTyPwkj3PPuE,5574
3
3
  aihub/exceptions.py,sha256=l2cMAvipTqQOio3o11fXsCCSCevbuK4PTsxofkobFjk,500
4
+ aihub/cli/__init__.py,sha256=I6NwAccz4OA13yBkQNVGqdY4by3a9S4Nwc_Nb9myXqM,27
5
+ aihub/cli/__main__.py,sha256=0O3_NGUh4DfaofAxxjmJnyTNSLljwWTclJHQTXrnCco,139
6
+ aihub/cli/config.py,sha256=GRn_SaQFHPK8BuIuyf3PHWmxvr-ZC4vLf8RUAZM5gqQ,3564
7
+ aihub/cli/main.py,sha256=ujEZZuwG2UsQRO5kS2A41EpfaA8G-B41wfUvtcN94ts,9924
8
+ aihub/cli/model_center.py,sha256=CbYP_vkIGIZ_K5k63S_VmSAoSKLyeF1vrKbEg5sXgnA,11974
4
9
  aihub/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
10
  aihub/models/artifact.py,sha256=F-r7DJY9A09yIQJqWol6gLRu6y7NGjRa6-BxkMEluxU,4655
6
11
  aihub/models/common.py,sha256=qmabc2LkAdQJXIcpT1P35zxd0Lc8yDYdD4ame1iF4Bs,241
7
12
  aihub/models/data_warehouse.py,sha256=zXvWwg7ySoFJMdqQ_1UMTNEKDMhu1hDHlWdBAXdizBk,3905
8
13
  aihub/models/dataset_management.py,sha256=4DuQ0zM7jv73SJiqvieHLtn2Y-T6FIFV9r7bgzyCtDo,10790
9
14
  aihub/models/document_center.py,sha256=od9bzx6krAS6ktIA-ChxeqGcch0v2wsS1flY2vuHXBc,1340
10
- aihub/models/eval.py,sha256=fcCoCFiDdZksJnbf7IsVPuwPwYMnGbSiVR8U4gN-3OM,3867
15
+ aihub/models/eval.py,sha256=eebUv31GJ_gf7-vCYCLknN6utsPZw9G3t6ikZb9gK0I,4865
11
16
  aihub/models/labelfree.py,sha256=YUnUv0tjYSFAFzYtmbnLOha8rnDe32sb50HkPOclAzU,2016
12
- aihub/models/model_center.py,sha256=DNMchrN0pYDcTMHApWNNVMrARF_i9Ng5xlAwHX5isYw,5935
17
+ aihub/models/model_center.py,sha256=q-ga1Khnb-WbA_gbLHbhwqGPuQ2qjpC4ailaaNpoccU,5491
13
18
  aihub/models/model_training_platform.py,sha256=2zir5i-XvuxKKVYr4wuNYUC7nwMzetdtCRoysZ1W_Tc,11725
14
19
  aihub/models/quota_schedule_management.py,sha256=LdXwKkpJd0jUFSHtTHUlFLlH-NUSmgywWtxwFg57CNk,12368
15
20
  aihub/models/tag_resource_management.py,sha256=-FgiKyDIG7bZagzVRf-8rXWuqH9GyciDadxz5W2f3I8,2195
16
- aihub/models/task_center.py,sha256=rGCvrkDjHLLBQ46DtDA7UAJ4eBQ0jwxpQmSB1z3UHmw,6135
17
- aihub/models/user_system.py,sha256=58f4w5g_SHUhX4vvJK6RXChCr6IDjX4i957suWYaxg8,12249
21
+ aihub/models/task_center.py,sha256=D4cc3fd4zOhQH5X8VdQmdHckrnYjBGhjg55dBaJkous,6209
22
+ aihub/models/user_system.py,sha256=__JLHIUFCi2Ke3Wg7v0G5hqE2WoNJNTG4Gsj5E6vv3o,12259
18
23
  aihub/models/workflow_center.py,sha256=4xtI1WZ38ceXJ8gwDBj-QNjOiRlLO_8kGiQybdudJPY,20121
19
24
  aihub/services/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
20
25
  aihub/services/artifact.py,sha256=lfOrgOT2AlH1w-75NLcQGOhVWdhmJcWD1gESPpUzqUw,11257
21
26
  aihub/services/data_warehouse.py,sha256=awvlJdggo8ph6sXweXXVp4GLRuUSD46LoD0QQksXRts,2964
22
27
  aihub/services/dataset_management.py,sha256=R7mFsJ1dNOI_p5yNj_rQdLolRC0UKEN4WejE7uOjVlE,21379
23
28
  aihub/services/document_center.py,sha256=dG67Ji-DOnzL2t-4x4gVfMt9fbSj_IjVHCLw5R-VTkQ,1813
24
- aihub/services/eval.py,sha256=CweTUkWSECqAEbccUCl2YlF7ZQsfuZKOWg3UFDaZv10,5619
29
+ aihub/services/eval.py,sha256=n1ytGzPJz-bwRyHoXaAugh7-u7Dak4aMYWklX3X_Pso,7287
25
30
  aihub/services/labelfree.py,sha256=xua62UWhVXTxJjHRyy86waaormnJjmpQwepcARBy_h0,1450
26
- aihub/services/model_center.py,sha256=QZXlldPZrbC6YkVG3eGw5_53qvFAim2QlXg3DflByTA,6215
31
+ aihub/services/model_center.py,sha256=x42_Xo66IxE6ni8mAMLPF_QBRxBvEU-lXrcF8Er2o-I,11404
27
32
  aihub/services/model_training_platform.py,sha256=38o6HJnyi3htFzpX7qj6UhzdqTchcXLRTYU0nM7ffJg,10176
28
33
  aihub/services/quota_schedule_management.py,sha256=UYOMwjXxJTgkpN6Rv5GzlcejtpZfu23PXlSKr0WihTY,9586
29
34
  aihub/services/reporter.py,sha256=ot93SmhxgwDJOzlHSCwlxDOuSydTWUEUQ-Ctp97wJBQ,669
30
35
  aihub/services/tag_resource_management.py,sha256=Bm_inSIzZbTc-e4LU9kvwtsPpM_yLwm8xzdrALjb6uY,2666
31
- aihub/services/task_center.py,sha256=ljy4lhyqVe2lnytp1h72mliqXUbSvEELT9KmxxPKdKc,8003
32
- aihub/services/user_system.py,sha256=IqWL4bnsKyyzuGT5l6adnw0qNXlH9PSo1-C_pFyOSzA,18868
36
+ aihub/services/task_center.py,sha256=UJXSo-8wjGvxAey2QPer84NrZ9t4xJK6FRQdJkm4o7w,8175
37
+ aihub/services/user_system.py,sha256=1OKqQDTwuaLILeNk8yA2g1CG6BMX9MsJZFZw_-PIlAg,19141
33
38
  aihub/services/workflow_center.py,sha256=caKxOlba0J1s1RUK6RUm1ndJSwAcZXEakRanu3sGKPU,17468
34
39
  aihub/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
35
40
  aihub/utils/di.py,sha256=vFUzno5WbRKu6-pj8Hnz9IqT7xb9UDZQ4qpOFH1YAtM,11812
36
41
  aihub/utils/download.py,sha256=ZZVbcC-PnN3PumV7ZiJ_-srkt4HPPovu2F6Faa2RrPE,1830
37
42
  aihub/utils/http.py,sha256=AmfHHNjptuuSFx2T1twWCnerR_hLN_gd0lUs8z36ERA,547
38
- aihub/utils/s3.py,sha256=ISIBP-XdBPkURpXnN56ZnIWokOOg2SRUh_qvxJk-G1Q,2187
39
- intellif_aihub-0.1.21.dist-info/licenses/LICENSE,sha256=QwcOLU5TJoTeUhuIXzhdCEEDDvorGiC6-3YTOl4TecE,11356
40
- intellif_aihub-0.1.21.dist-info/METADATA,sha256=3E24k8VYdgjj3EyXtxZHC4NMpYtMAD_hmPu2aX5MJ4o,2949
41
- intellif_aihub-0.1.21.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
42
- intellif_aihub-0.1.21.dist-info/top_level.txt,sha256=vIvTtSIN73xv46BpYM-ctVGnyOiUQ9EWP_6ngvdIlvw,6
43
- intellif_aihub-0.1.21.dist-info/RECORD,,
43
+ aihub/utils/s3.py,sha256=_HFL5QJQqOF8WuEX8RWGPFKYtad_lGn-jsNzTIfXjHM,3977
44
+ intellif_aihub-0.1.23.dist-info/licenses/LICENSE,sha256=QwcOLU5TJoTeUhuIXzhdCEEDDvorGiC6-3YTOl4TecE,11356
45
+ intellif_aihub-0.1.23.dist-info/METADATA,sha256=p921kZhhTqFeDE6VsN8HpSDer_emgD5-vswwgppOqwo,2978
46
+ intellif_aihub-0.1.23.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
47
+ intellif_aihub-0.1.23.dist-info/entry_points.txt,sha256=PfgnpEJlG76kFmrCdTvfRIRNsZO1Xu1pTEH2S5DSO1M,45
48
+ intellif_aihub-0.1.23.dist-info/top_level.txt,sha256=vIvTtSIN73xv46BpYM-ctVGnyOiUQ9EWP_6ngvdIlvw,6
49
+ intellif_aihub-0.1.23.dist-info/RECORD,,
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ aihub = aihub.cli.main:app