ima-python-sdk 0.1.0__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.
- ima_python_sdk-0.1.0.dist-info/METADATA +93 -0
- ima_python_sdk-0.1.0.dist-info/RECORD +15 -0
- ima_python_sdk-0.1.0.dist-info/WHEEL +5 -0
- ima_python_sdk-0.1.0.dist-info/entry_points.txt +2 -0
- ima_python_sdk-0.1.0.dist-info/licenses/LICENSE +21 -0
- ima_python_sdk-0.1.0.dist-info/top_level.txt +1 -0
- ima_sdk/__init__.py +90 -0
- ima_sdk/cli.py +447 -0
- ima_sdk/client.py +268 -0
- ima_sdk/cos_uploader.py +158 -0
- ima_sdk/file_checker.py +226 -0
- ima_sdk/knowledge_base.py +591 -0
- ima_sdk/logger.py +89 -0
- ima_sdk/notes.py +343 -0
- ima_sdk/types.py +424 -0
ima_sdk/types.py
ADDED
|
@@ -0,0 +1,424 @@
|
|
|
1
|
+
"""IMA OpenAPI 数据类型定义。"""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import enum
|
|
6
|
+
from dataclasses import dataclass, field
|
|
7
|
+
from typing import Dict, List, Optional
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
# ── 枚举 ──────────────────────────────────────────────────────────────────────
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class MediaType(enum.IntEnum):
|
|
14
|
+
"""知识库媒体类型。"""
|
|
15
|
+
|
|
16
|
+
PDF = 1
|
|
17
|
+
WEB = 2
|
|
18
|
+
WORD = 3
|
|
19
|
+
PPT = 4
|
|
20
|
+
EXCEL = 5
|
|
21
|
+
WECHAT_ARTICLE = 6
|
|
22
|
+
MARKDOWN = 7
|
|
23
|
+
IMAGE = 9
|
|
24
|
+
NOTE = 11
|
|
25
|
+
AI_SESSION = 12
|
|
26
|
+
TXT = 13
|
|
27
|
+
XMIND = 14
|
|
28
|
+
AUDIO = 15
|
|
29
|
+
VIDEO = 16 # 不支持通过 API 添加
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class ContentFormat(enum.IntEnum):
|
|
33
|
+
"""笔记内容格式。"""
|
|
34
|
+
|
|
35
|
+
PLAINTEXT = 0
|
|
36
|
+
MARKDOWN = 1
|
|
37
|
+
JSON = 2
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class SearchType(enum.IntEnum):
|
|
41
|
+
"""笔记搜索方式。"""
|
|
42
|
+
|
|
43
|
+
TITLE = 0
|
|
44
|
+
CONTENT = 1
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
class SortType(enum.IntEnum):
|
|
48
|
+
"""笔记排序方式。"""
|
|
49
|
+
|
|
50
|
+
MODIFY_TIME = 0
|
|
51
|
+
CREATE_TIME = 1
|
|
52
|
+
TITLE = 2
|
|
53
|
+
SIZE = 3
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
class FolderType(enum.IntEnum):
|
|
57
|
+
"""笔记本类型。"""
|
|
58
|
+
|
|
59
|
+
USER_CREATED = 0
|
|
60
|
+
ALL_NOTES = 1
|
|
61
|
+
UNCATEGORIZED = 2
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
# ── 知识库数据结构 ────────────────────────────────────────────────────────────
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
@dataclass
|
|
68
|
+
class KnowledgeBaseInfo:
|
|
69
|
+
"""知识库信息。"""
|
|
70
|
+
|
|
71
|
+
id: str = ""
|
|
72
|
+
name: str = ""
|
|
73
|
+
cover_url: str = ""
|
|
74
|
+
description: str = ""
|
|
75
|
+
recommended_questions: List[str] = field(default_factory=list)
|
|
76
|
+
|
|
77
|
+
@classmethod
|
|
78
|
+
def from_dict(cls, d: dict) -> KnowledgeBaseInfo:
|
|
79
|
+
return cls(
|
|
80
|
+
id=d.get("id", ""),
|
|
81
|
+
name=d.get("name", ""),
|
|
82
|
+
cover_url=d.get("cover_url", ""),
|
|
83
|
+
description=d.get("description", ""),
|
|
84
|
+
recommended_questions=d.get("recommended_questions", []),
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
@dataclass
|
|
89
|
+
class KnowledgeInfo:
|
|
90
|
+
"""知识条目。"""
|
|
91
|
+
|
|
92
|
+
media_id: str = ""
|
|
93
|
+
title: str = ""
|
|
94
|
+
parent_folder_id: str = ""
|
|
95
|
+
|
|
96
|
+
@classmethod
|
|
97
|
+
def from_dict(cls, d: dict) -> KnowledgeInfo:
|
|
98
|
+
return cls(
|
|
99
|
+
media_id=d.get("media_id", ""),
|
|
100
|
+
title=d.get("title", ""),
|
|
101
|
+
parent_folder_id=d.get("parent_folder_id", ""),
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
@dataclass
|
|
106
|
+
class KBFolderInfo:
|
|
107
|
+
"""知识库文件夹条目。"""
|
|
108
|
+
|
|
109
|
+
folder_id: str = ""
|
|
110
|
+
name: str = ""
|
|
111
|
+
file_number: int = 0
|
|
112
|
+
folder_number: int = 0
|
|
113
|
+
parent_folder_id: str = ""
|
|
114
|
+
is_top: bool = False
|
|
115
|
+
|
|
116
|
+
@classmethod
|
|
117
|
+
def from_dict(cls, d: dict) -> KBFolderInfo:
|
|
118
|
+
return cls(
|
|
119
|
+
folder_id=d.get("folder_id", ""),
|
|
120
|
+
name=d.get("name", ""),
|
|
121
|
+
file_number=d.get("file_number", 0),
|
|
122
|
+
folder_number=d.get("folder_number", 0),
|
|
123
|
+
parent_folder_id=d.get("parent_folder_id", ""),
|
|
124
|
+
is_top=d.get("is_top", False),
|
|
125
|
+
)
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
@dataclass
|
|
129
|
+
class AddableKnowledgeBaseInfo:
|
|
130
|
+
"""可添加的知识库信息。"""
|
|
131
|
+
|
|
132
|
+
id: str = ""
|
|
133
|
+
name: str = ""
|
|
134
|
+
|
|
135
|
+
@classmethod
|
|
136
|
+
def from_dict(cls, d: dict) -> AddableKnowledgeBaseInfo:
|
|
137
|
+
return cls(id=d.get("id", ""), name=d.get("name", ""))
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
@dataclass
|
|
141
|
+
class SearchedKnowledgeBaseInfo:
|
|
142
|
+
"""搜索到的知识库信息。"""
|
|
143
|
+
|
|
144
|
+
id: str = ""
|
|
145
|
+
name: str = ""
|
|
146
|
+
cover_url: str = ""
|
|
147
|
+
|
|
148
|
+
@classmethod
|
|
149
|
+
def from_dict(cls, d: dict) -> SearchedKnowledgeBaseInfo:
|
|
150
|
+
return cls(
|
|
151
|
+
id=d.get("id", "") or d.get("kb_id", ""),
|
|
152
|
+
name=d.get("name", "") or d.get("kb_name", ""),
|
|
153
|
+
cover_url=d.get("cover_url", ""),
|
|
154
|
+
)
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
@dataclass
|
|
158
|
+
class SearchedKnowledgeInfo:
|
|
159
|
+
"""搜索到的知识条目。"""
|
|
160
|
+
|
|
161
|
+
media_id: str = ""
|
|
162
|
+
title: str = ""
|
|
163
|
+
parent_folder_id: str = ""
|
|
164
|
+
highlight_content: str = ""
|
|
165
|
+
|
|
166
|
+
@classmethod
|
|
167
|
+
def from_dict(cls, d: dict) -> SearchedKnowledgeInfo:
|
|
168
|
+
return cls(
|
|
169
|
+
media_id=d.get("media_id", ""),
|
|
170
|
+
title=d.get("title", ""),
|
|
171
|
+
parent_folder_id=d.get("parent_folder_id", ""),
|
|
172
|
+
highlight_content=d.get("highlight_content", ""),
|
|
173
|
+
)
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
@dataclass
|
|
177
|
+
class ImportURLResult:
|
|
178
|
+
"""URL 导入结果。"""
|
|
179
|
+
|
|
180
|
+
url: str = ""
|
|
181
|
+
ret_code: int = 0
|
|
182
|
+
media_id: str = ""
|
|
183
|
+
|
|
184
|
+
@classmethod
|
|
185
|
+
def from_dict(cls, d: dict) -> ImportURLResult:
|
|
186
|
+
return cls(
|
|
187
|
+
url=d.get("url", ""),
|
|
188
|
+
ret_code=d.get("ret_code", 0),
|
|
189
|
+
media_id=d.get("media_id", ""),
|
|
190
|
+
)
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
@dataclass
|
|
194
|
+
class CosCredential:
|
|
195
|
+
"""COS 上传凭证。"""
|
|
196
|
+
|
|
197
|
+
token: str = ""
|
|
198
|
+
secret_id: str = ""
|
|
199
|
+
secret_key: str = ""
|
|
200
|
+
start_time: int = 0
|
|
201
|
+
expired_time: int = 0
|
|
202
|
+
appid: str = ""
|
|
203
|
+
bucket_name: str = ""
|
|
204
|
+
region: str = ""
|
|
205
|
+
custom_domain: str = ""
|
|
206
|
+
cos_key: str = ""
|
|
207
|
+
|
|
208
|
+
@classmethod
|
|
209
|
+
def from_dict(cls, d: dict) -> CosCredential:
|
|
210
|
+
return cls(
|
|
211
|
+
token=d.get("token", ""),
|
|
212
|
+
secret_id=d.get("secret_id", ""),
|
|
213
|
+
secret_key=d.get("secret_key", ""),
|
|
214
|
+
start_time=int(d.get("start_time", 0)),
|
|
215
|
+
expired_time=int(d.get("expired_time", 0)),
|
|
216
|
+
appid=d.get("appid", ""),
|
|
217
|
+
bucket_name=d.get("bucket_name", ""),
|
|
218
|
+
region=d.get("region", ""),
|
|
219
|
+
custom_domain=d.get("custom_domain", ""),
|
|
220
|
+
cos_key=d.get("cos_key", ""),
|
|
221
|
+
)
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+
@dataclass
|
|
225
|
+
class FileInfo:
|
|
226
|
+
"""文件信息(add_knowledge 使用)。"""
|
|
227
|
+
|
|
228
|
+
cos_key: str = ""
|
|
229
|
+
file_size: int = 0
|
|
230
|
+
last_modify_time: int = 0
|
|
231
|
+
password: str = ""
|
|
232
|
+
file_name: str = ""
|
|
233
|
+
|
|
234
|
+
def to_dict(self) -> dict:
|
|
235
|
+
d: dict = {
|
|
236
|
+
"cos_key": self.cos_key,
|
|
237
|
+
"file_size": self.file_size,
|
|
238
|
+
"file_name": self.file_name,
|
|
239
|
+
}
|
|
240
|
+
if self.last_modify_time:
|
|
241
|
+
d["last_modify_time"] = self.last_modify_time
|
|
242
|
+
if self.password:
|
|
243
|
+
d["password"] = self.password
|
|
244
|
+
return d
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
@dataclass
|
|
248
|
+
class CheckRepeatedNameResult:
|
|
249
|
+
"""文件名重复检查结果。"""
|
|
250
|
+
|
|
251
|
+
name: str = ""
|
|
252
|
+
is_repeated: bool = False
|
|
253
|
+
|
|
254
|
+
@classmethod
|
|
255
|
+
def from_dict(cls, d: dict) -> CheckRepeatedNameResult:
|
|
256
|
+
return cls(name=d.get("name", ""), is_repeated=d.get("is_repeated", False))
|
|
257
|
+
|
|
258
|
+
|
|
259
|
+
@dataclass
|
|
260
|
+
class CreateMediaResult:
|
|
261
|
+
"""创建媒体返回结果。"""
|
|
262
|
+
|
|
263
|
+
media_id: str = ""
|
|
264
|
+
cos_credential: Optional[CosCredential] = None
|
|
265
|
+
|
|
266
|
+
@classmethod
|
|
267
|
+
def from_dict(cls, d: dict) -> CreateMediaResult:
|
|
268
|
+
cred = d.get("cos_credential")
|
|
269
|
+
return cls(
|
|
270
|
+
media_id=d.get("media_id", ""),
|
|
271
|
+
cos_credential=CosCredential.from_dict(cred) if cred else None,
|
|
272
|
+
)
|
|
273
|
+
|
|
274
|
+
|
|
275
|
+
# ── 知识库列表返回结构 ────────────────────────────────────────────────────────
|
|
276
|
+
|
|
277
|
+
|
|
278
|
+
@dataclass
|
|
279
|
+
class KnowledgeListResult:
|
|
280
|
+
"""浏览知识库内容返回结果。"""
|
|
281
|
+
|
|
282
|
+
knowledge_list: List[KnowledgeInfo] = field(default_factory=list)
|
|
283
|
+
folder_list: List[KBFolderInfo] = field(default_factory=list)
|
|
284
|
+
is_end: bool = True
|
|
285
|
+
next_cursor: str = ""
|
|
286
|
+
current_path: List[KBFolderInfo] = field(default_factory=list)
|
|
287
|
+
|
|
288
|
+
@classmethod
|
|
289
|
+
def from_dict(cls, d: dict) -> KnowledgeListResult:
|
|
290
|
+
return cls(
|
|
291
|
+
knowledge_list=[
|
|
292
|
+
KnowledgeInfo.from_dict(i) for i in d.get("knowledge_list", [])
|
|
293
|
+
],
|
|
294
|
+
folder_list=[
|
|
295
|
+
KBFolderInfo.from_dict(i) for i in d.get("folder_list", [])
|
|
296
|
+
],
|
|
297
|
+
is_end=d.get("is_end", True),
|
|
298
|
+
next_cursor=d.get("next_cursor", ""),
|
|
299
|
+
current_path=[
|
|
300
|
+
KBFolderInfo.from_dict(i) for i in d.get("current_path", [])
|
|
301
|
+
],
|
|
302
|
+
)
|
|
303
|
+
|
|
304
|
+
|
|
305
|
+
# ── 笔记数据结构 ─────────────────────────────────────────────────────────────
|
|
306
|
+
|
|
307
|
+
|
|
308
|
+
@dataclass
|
|
309
|
+
class DocBasic:
|
|
310
|
+
"""笔记基本信息。"""
|
|
311
|
+
|
|
312
|
+
doc_id: str = ""
|
|
313
|
+
title: str = ""
|
|
314
|
+
summary: str = ""
|
|
315
|
+
create_time: int = 0
|
|
316
|
+
modify_time: int = 0
|
|
317
|
+
status: int = 0 # 0=正常, 1=已删除
|
|
318
|
+
folder_id: str = ""
|
|
319
|
+
folder_name: str = ""
|
|
320
|
+
|
|
321
|
+
@classmethod
|
|
322
|
+
def from_dict(cls, d: dict) -> DocBasic:
|
|
323
|
+
return cls(
|
|
324
|
+
doc_id=d.get("docid", ""),
|
|
325
|
+
title=d.get("title", ""),
|
|
326
|
+
summary=d.get("summary", ""),
|
|
327
|
+
create_time=d.get("create_time", 0),
|
|
328
|
+
modify_time=d.get("modify_time", 0),
|
|
329
|
+
status=d.get("status", 0),
|
|
330
|
+
folder_id=d.get("folder_id", ""),
|
|
331
|
+
folder_name=d.get("folder_name", ""),
|
|
332
|
+
)
|
|
333
|
+
|
|
334
|
+
|
|
335
|
+
@dataclass
|
|
336
|
+
class NoteFolderItem:
|
|
337
|
+
"""笔记本条目。"""
|
|
338
|
+
|
|
339
|
+
folder_id: str = ""
|
|
340
|
+
name: str = ""
|
|
341
|
+
note_number: int = 0
|
|
342
|
+
create_time: int = 0
|
|
343
|
+
modify_time: int = 0
|
|
344
|
+
parent_folder_id: str = ""
|
|
345
|
+
folder_type: int = 0 # 0=用户自建, 1=全部笔记, 2=未分类
|
|
346
|
+
status: int = 0
|
|
347
|
+
|
|
348
|
+
@classmethod
|
|
349
|
+
def from_dict(cls, d: dict) -> NoteFolderItem:
|
|
350
|
+
# API 返回嵌套结构: folder.basic_info.{fields}
|
|
351
|
+
basic = d
|
|
352
|
+
if "folder" in d:
|
|
353
|
+
folder = d["folder"]
|
|
354
|
+
if "basic_info" in folder:
|
|
355
|
+
basic = folder["basic_info"]
|
|
356
|
+
return cls(
|
|
357
|
+
folder_id=basic.get("folder_id", ""),
|
|
358
|
+
name=basic.get("name", ""),
|
|
359
|
+
note_number=basic.get("note_number", 0),
|
|
360
|
+
create_time=basic.get("create_time", 0),
|
|
361
|
+
modify_time=basic.get("modify_time", 0),
|
|
362
|
+
parent_folder_id=basic.get("parent_folder_id", ""),
|
|
363
|
+
folder_type=basic.get("folder_type", 0),
|
|
364
|
+
status=basic.get("status", 0),
|
|
365
|
+
)
|
|
366
|
+
|
|
367
|
+
|
|
368
|
+
@dataclass
|
|
369
|
+
class NoteBookInfo:
|
|
370
|
+
"""笔记信息(笔记列表返回)。"""
|
|
371
|
+
|
|
372
|
+
doc: DocBasic = field(default_factory=DocBasic)
|
|
373
|
+
|
|
374
|
+
@classmethod
|
|
375
|
+
def from_dict(cls, d: dict) -> NoteBookInfo:
|
|
376
|
+
# API 返回嵌套结构: basic_info.basic_info.{fields}
|
|
377
|
+
basic = d
|
|
378
|
+
if "basic_info" in d:
|
|
379
|
+
inner = d["basic_info"]
|
|
380
|
+
if "basic_info" in inner:
|
|
381
|
+
basic = inner["basic_info"]
|
|
382
|
+
else:
|
|
383
|
+
basic = inner
|
|
384
|
+
return cls(doc=DocBasic.from_dict(basic))
|
|
385
|
+
|
|
386
|
+
|
|
387
|
+
@dataclass
|
|
388
|
+
class SearchedDoc:
|
|
389
|
+
"""搜索到的笔记。"""
|
|
390
|
+
|
|
391
|
+
doc: DocBasic = field(default_factory=DocBasic)
|
|
392
|
+
highlight_info: Dict[str, str] = field(default_factory=dict)
|
|
393
|
+
|
|
394
|
+
@classmethod
|
|
395
|
+
def from_dict(cls, d: dict) -> SearchedDoc:
|
|
396
|
+
doc_data = d.get("doc", {})
|
|
397
|
+
basic = doc_data
|
|
398
|
+
if "basic_info" in doc_data:
|
|
399
|
+
inner = doc_data["basic_info"]
|
|
400
|
+
if "basic_info" in inner:
|
|
401
|
+
basic = inner["basic_info"]
|
|
402
|
+
else:
|
|
403
|
+
basic = inner
|
|
404
|
+
return cls(
|
|
405
|
+
doc=DocBasic.from_dict(basic),
|
|
406
|
+
highlight_info=d.get("highlight_info", {}),
|
|
407
|
+
)
|
|
408
|
+
|
|
409
|
+
|
|
410
|
+
# ── 文件预检结果 ─────────────────────────────────────────────────────────────
|
|
411
|
+
|
|
412
|
+
|
|
413
|
+
@dataclass
|
|
414
|
+
class FileCheckResult:
|
|
415
|
+
"""文件预检结果。"""
|
|
416
|
+
|
|
417
|
+
passed: bool = False
|
|
418
|
+
file_path: str = ""
|
|
419
|
+
file_name: str = ""
|
|
420
|
+
file_ext: str = ""
|
|
421
|
+
file_size: int = 0
|
|
422
|
+
media_type: Optional[int] = None
|
|
423
|
+
content_type: Optional[str] = None
|
|
424
|
+
reason: str = ""
|