PyGeoModel 1.0.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.
Files changed (28) hide show
  1. ogmsServer2/__init__.py +33 -0
  2. ogmsServer2/base.py +38 -0
  3. ogmsServer2/constants.py +21 -0
  4. ogmsServer2/data/PGA.tif +0 -0
  5. ogmsServer2/data/baseclip.tif +0 -0
  6. ogmsServer2/data/intensity.tif +0 -0
  7. ogmsServer2/data//345/234/260/351/234/207/347/276/244/345/217/221/346/273/221/345/235/241/346/246/202/347/216/207/350/257/204/344/274/260/351/242/204/350/255/246/346/250/241/345/236/213_67c32dc057e89375/LandSlide-outputIntensitypbtyTif.tif +0 -0
  8. ogmsServer2/data//345/234/260/351/234/207/347/276/244/345/217/221/346/273/221/345/235/241/346/246/202/347/216/207/350/257/204/344/274/260/351/242/204/350/255/246/346/250/241/345/236/213_67c32dc057e89375/LandSlide-outputPGApbtyTif.tif +0 -0
  9. ogmsServer2/data//345/234/260/351/234/207/347/276/244/345/217/221/346/273/221/345/235/241/346/246/202/347/216/207/350/257/204/344/274/260/351/242/204/350/255/246/346/250/241/345/236/213_7972c0716caa1213/LandSlide-outputIntensitypbtyTif.tif +0 -0
  10. ogmsServer2/data//345/234/260/351/234/207/347/276/244/345/217/221/346/273/221/345/235/241/346/246/202/347/216/207/350/257/204/344/274/260/351/242/204/350/255/246/346/250/241/345/236/213_7972c0716caa1213/LandSlide-outputPGApbtyTif.tif +0 -0
  11. ogmsServer2/data//345/234/260/351/234/207/347/276/244/345/217/221/346/273/221/345/235/241/346/246/202/347/216/207/350/257/204/344/274/260/351/242/204/350/255/246/346/250/241/345/236/213_a044c410df669372/LandSlide-outputIntensitypbtyTif.tif +0 -0
  12. ogmsServer2/data//345/234/260/351/234/207/347/276/244/345/217/221/346/273/221/345/235/241/346/246/202/347/216/207/350/257/204/344/274/260/351/242/204/350/255/246/346/250/241/345/236/213_a044c410df669372/LandSlide-outputPGApbtyTif.tif +0 -0
  13. ogmsServer2/data//345/234/260/351/234/207/347/276/244/345/217/221/346/273/221/345/235/241/346/246/202/347/216/207/350/257/204/344/274/260/351/242/204/350/255/246/346/250/241/345/236/213_b6ba56c07bf80c30/LandSlide-outputIntensitypbtyTif.tif +0 -0
  14. ogmsServer2/data//345/234/260/351/234/207/347/276/244/345/217/221/346/273/221/345/235/241/346/246/202/347/216/207/350/257/204/344/274/260/351/242/204/350/255/246/346/250/241/345/236/213_b6ba56c07bf80c30/LandSlide-outputPGApbtyTif.tif +0 -0
  15. ogmsServer2/openModel.py +393 -0
  16. ogmsServer2/openUtils/__init__.py +24 -0
  17. ogmsServer2/openUtils/exceptions.py +80 -0
  18. ogmsServer2/openUtils/http_client.py +247 -0
  19. ogmsServer2/openUtils/mdlUtils.py +116 -0
  20. ogmsServer2/openUtils/parameterValidator.py +55 -0
  21. ogmsServer2/openUtils/stateManager.py +69 -0
  22. pygeomodel-1.0.0.dist-info/METADATA +68 -0
  23. pygeomodel-1.0.0.dist-info/RECORD +28 -0
  24. pygeomodel-1.0.0.dist-info/WHEEL +5 -0
  25. pygeomodel-1.0.0.dist-info/licenses/LICENSE +21 -0
  26. pygeomodel-1.0.0.dist-info/top_level.txt +3 -0
  27. pygeomodel.py +2460 -0
  28. scripts.py +128 -0
@@ -0,0 +1,33 @@
1
+ """
2
+ Author: DiChen
3
+ Date: 2024-09-06 14:24:53
4
+ LastEditors: DiChen
5
+ LastEditTime: 2024-09-09 18:36:39
6
+ """
7
+
8
+ ################public lib################
9
+ import urllib.parse
10
+ import time
11
+
12
+ ################private lib################
13
+ from .base import Service
14
+
15
+ from .openUtils import *
16
+ from . import constants as C
17
+ from . import openModel
18
+ __all__ = [
19
+ "urllib",
20
+ "time",
21
+ "Service",
22
+ "openModel",
23
+ "C",
24
+ "MDL",
25
+ "HttpClient",
26
+ "PV",
27
+ "StateManager",
28
+ "NotValueError",
29
+ "modelStatusError",
30
+ "calTimeoutError",
31
+ "UploadFileError",
32
+ "MDLVaildParamsError",
33
+ ]
ogmsServer2/base.py ADDED
@@ -0,0 +1,38 @@
1
+ """
2
+ Author: DiChen
3
+ Date: 2024-09-06 15:22:20
4
+ LastEditors: DiChen
5
+ LastEditTime: 2024-09-11 18:37:16
6
+ """
7
+
8
+ import sys
9
+ from . import constants as C
10
+ from .openUtils.http_client import HttpClient
11
+
12
+
13
+ class Service:
14
+ def __init__(self, token: str = None):
15
+ # res = HttpClient.hander_response(
16
+ # HttpClient.get_sync(
17
+ # url="http://www.baidu.com"
18
+ # )
19
+ # )
20
+ self.token: str = token
21
+ self.portalUrl = C.basePortalUrl
22
+ self.managerUrl = C.baseManagerUrl
23
+ self.dataUrl = C.baseDataUrl
24
+ if not (self.portalUrl or self.managerUrl or self.dataUrl):
25
+ print("读取配置文件有误,请联系管理员!")
26
+ sys.exit(1)
27
+ self._validateToken()
28
+
29
+ #########################private#########################################
30
+ def _validateToken(self):
31
+ res = HttpClient.hander_response(
32
+ HttpClient.get_sync(
33
+ self.portalUrl + C.CHECK_SDK, params={"token": self.token}
34
+ )
35
+ ).get("json", {})
36
+ if res.get("data") != 1:
37
+ print("token无效,请联系管理员!")
38
+ sys.exit(1)
@@ -0,0 +1,21 @@
1
+ """
2
+ Author: DiChen
3
+ Date: 2024-09-10 18:54:44
4
+ LastEditors: DiChen
5
+ LastEditTime: 2024-09-10 18:54:56
6
+ """
7
+
8
+ ###################### configPath######################
9
+ basePortalUrl = "http://222.192.7.75"
10
+ # basePortalUrl = "http://172.21.212.251:7777"
11
+ baseManagerUrl = "http://222.192.7.75/managerServer"
12
+ baseDataUrl = "http://222.192.7.75/dataTransferServer"
13
+
14
+
15
+ ###################### apiPath########################
16
+ CHECK_MODEL = "/computableModel/ModelInfo_name/"
17
+ CHECK_MODEL_SERVICE = "/GeoModeling/task/verify/"
18
+ INVOKE_MODEL = "/GeoModeling/computableModel/invoke"
19
+ REFRESH_RECORD = "/GeoModeling/computableModel/refreshTaskRecord"
20
+ UPLOAD_DATA = "/data/"
21
+ CHECK_SDK = "/sdk/check_test/"
Binary file
Binary file
Binary file
@@ -0,0 +1,393 @@
1
+ """
2
+ Author: DiChen
3
+ Date: 2024-09-06 15:14:57
4
+ LastEditors: DiChen
5
+ LastEditTime: 2024-09-07 00:16:30
6
+ """
7
+
8
+ from . import *
9
+ import secrets
10
+ import os
11
+
12
+
13
+ class OGMSTask(Service):
14
+ def __init__(self, origin_lists: dict, token: str = None):
15
+ super().__init__(token=token)
16
+ self.status: None | int = None
17
+ self.username = token
18
+ PV.v_empty(origin_lists, "origin lists")
19
+ self.origin_lists = origin_lists
20
+ self.subscirbe_lists = {}
21
+ self.tid = None
22
+ # 对输入的参数进行校验、文件上传等操作
23
+
24
+ def wait4Status(self, timeout: int = 7200):
25
+ try:
26
+ start_time = time.time()
27
+ stateManager = StateManager()
28
+ stateManager.checkInputStatus(PV.v_status(self._refresh()))
29
+ while stateManager.hasStatus(0b100) is False:
30
+ stateManager.checkInputStatus(PV.v_status(self._refresh()))
31
+ if time.time() - start_time > timeout:
32
+ raise calTimeoutError()
33
+ time.sleep(3)
34
+ return {
35
+ "outputs": self.outputs,
36
+ }
37
+
38
+ except NotValueError or modelStatusError as e:
39
+ print(e)
40
+ exit(1)
41
+
42
+ def configInputData(self, params: dict):
43
+ try:
44
+ PV.v_empty(params, "params list")
45
+ lists = {"inputs": self._uploadData(
46
+ params), "username": self.username}
47
+ return self._mergeData(lists)
48
+ except NotValueError or UploadFileError or MDLVaildParamsError as e:
49
+ print(e)
50
+ exit(1)
51
+
52
+ ######################## private################################
53
+ def _uploadData(self, pathList: dict):
54
+ inputs = {}
55
+ for category, files in pathList.items():
56
+ inputs[category] = {}
57
+ for key, value in files.items():
58
+ # 判断是数值参数还是文件参数
59
+ if isinstance(value, (str, int, float)) and not str(value).startswith('/'):
60
+ # 数值参数:生成XML,上传并返回url;同时保留children用于填充值
61
+ xml_content = self._create_value_xml(str(key), str(value))
62
+ xml_url = self._upload_xml_string(
63
+ xml_content, f"{key}.xml")
64
+ inputs[category][key] = {
65
+ "name": f"{key}.xml",
66
+ "url": xml_url,
67
+ "children": [{str(key): str(value)}],
68
+ }
69
+ else:
70
+ # 文件参数:上传文件并获取URL
71
+ file_path = str(value)
72
+ file_name = file_path.split("/")[-1]
73
+ inputs[category][key] = {
74
+ "name": file_name,
75
+ "url": self._getUploadData(file_path),
76
+ }
77
+ return inputs
78
+
79
+ def _getUploadData(self, path: str):
80
+ res = (
81
+ HttpClient.hander_response(
82
+ HttpClient.post_sync(
83
+ self.dataUrl + C.UPLOAD_DATA, files={"datafile": open(path, "rb")}
84
+ )
85
+ )
86
+ .get("json", {})
87
+ .get("data", {})
88
+ )
89
+ if res.get("id"):
90
+ return self.dataUrl+C.UPLOAD_DATA + res.get(
91
+ "id"
92
+ )
93
+ raise UploadFileError()
94
+
95
+ def _create_value_xml(self, name: str, value: str) -> str:
96
+ """根据数值参数生成与服务端兼容的XML内容。"""
97
+ # 参考 testify 目录示例:
98
+ # <Dataset> <XDO name="system_efficiency" kernelType="string" value="0.8" /> </Dataset>
99
+ return f'<Dataset> <XDO name="{name}" kernelType="string" value="{value}" /> </Dataset>'
100
+
101
+ def _upload_xml_string(self, xml_content: str, filename: str) -> str:
102
+ """将XML字符串写入临时文件并复用文件上传接口,返回url。"""
103
+ import tempfile
104
+ import os
105
+
106
+ with tempfile.NamedTemporaryFile(mode="w", suffix=".xml", delete=False, encoding="utf-8") as tmp_file:
107
+ tmp_file.write(xml_content)
108
+ tmp_path = tmp_file.name
109
+ try:
110
+ return self._getUploadData(tmp_path)
111
+ finally:
112
+ if os.path.exists(tmp_path):
113
+ os.unlink(tmp_path)
114
+
115
+ def _mergeData(self, params: dict):
116
+ def extract_file_suffix(filename: str) -> str:
117
+ """提取文件名的后缀名."""
118
+ return filename.split(".")[-1] if "." in filename else ""
119
+
120
+ def update_input_item(input_item: dict, event_data: dict):
121
+ """
122
+ 根据 input_data 中的 event_data 更新 origin_data 中的 input_item。
123
+ 支持处理直接传递的 'value' 字段和children结构。
124
+ """
125
+ # ✅ 处理直接传递value的情况(数值参数)
126
+ if "value" in event_data and "url" not in event_data:
127
+ # 数值参数:如 {"value": "0.8"}
128
+ if "children" in input_item and input_item["children"]:
129
+ child = input_item["children"][0]
130
+ child["value"] = event_data["value"]
131
+ input_item["suffix"] = "xml" # 数值参数使用xml格式
132
+ return # 早返回,避免执行后面的逻辑
133
+
134
+ # 原有的处理逻辑
135
+ if "children" in event_data:
136
+ input_item["suffix"] = "xml" # 如果有 children,后缀名固定为 xml
137
+ for child in input_item.get("children", []):
138
+ event_name = child["eventName"]
139
+ for b_child in event_data["children"]:
140
+ if event_name in b_child:
141
+ child["value"] = b_child[event_name]
142
+ else:
143
+ if "name" in event_data:
144
+ input_item["suffix"] = extract_file_suffix(
145
+ event_data["name"])
146
+
147
+ if "url" in event_data:
148
+ input_item["url"] = event_data["url"]
149
+
150
+ def fill_data_with_input(input_data: dict, origin_data: dict) -> dict:
151
+ """根据 input_data 填补 origin_data."""
152
+ for input_item in origin_data.get("inputs", []):
153
+ state_name = input_item.get("statename")
154
+ event_name = input_item.get("event")
155
+
156
+ PV.v_empty(state_name, "State name")
157
+ PV.v_empty(event_name, "Event name")
158
+
159
+ state_data = input_data["inputs"].get(state_name)
160
+ if state_data and event_name in state_data:
161
+ update_input_item(input_item, state_data[event_name])
162
+ origin_data["username"] = input_data.get("username")
163
+ return origin_data
164
+
165
+ filled_origin_data = fill_data_with_input(params, self.origin_lists)
166
+ return self._validData(filled_origin_data)
167
+
168
+ def _validData(self, merge_data: dict):
169
+ def validate_event(event):
170
+ errors = []
171
+ event_name = f"{event.get('statename')}-{event.get('event')}"
172
+
173
+ # 检查是否是数值参数(有children但没有url)
174
+ is_numeric_param = "children" in event and not event.get("url")
175
+
176
+ if event.get("optional") == "False":
177
+ # 必填项
178
+ if is_numeric_param:
179
+ # 数值参数:只检查children和suffix
180
+ if not event.get("suffix"):
181
+ errors.append(f"{event_name}的文件格式有误!")
182
+ for child in event["children"]:
183
+ if not child.get("value"):
184
+ errors.append(f"{event_name}子参数有误")
185
+ else:
186
+ # 文件参数:检查url和suffix
187
+ if not event.get("url"):
188
+ errors.append(f"{event_name}的中转数据信息有误!")
189
+ if not event.get("suffix"):
190
+ errors.append(f"{event_name}的文件有误!")
191
+ elif event.get("optional") == "True":
192
+ # 选填项
193
+ if event.get("url") or event.get("suffix") or "children" in event:
194
+ if not (event.get("url") and event.get("suffix")):
195
+ errors.append(f"{event_name}子参数有误!")
196
+ if "children" in event:
197
+ for child in event["children"]:
198
+ if not child.get("value"):
199
+ errors.append(f"{event_name}子参数不能为空!")
200
+
201
+ return errors
202
+
203
+ def process_inputs(inputs):
204
+ errors = []
205
+ valid_inputs = []
206
+ for event in inputs:
207
+ event_errors = validate_event(event)
208
+ if event_errors:
209
+ errors.extend(event_errors)
210
+ else:
211
+ if event.get("optional") == "True":
212
+ if not (
213
+ event.get("url")
214
+ or event.get("suffix")
215
+ or "children" in event
216
+ ):
217
+ continue
218
+ valid_inputs.append(event)
219
+ return valid_inputs, errors
220
+
221
+ def check_username(username):
222
+ errors = []
223
+ if not username:
224
+ errors.append("no token")
225
+ return errors
226
+
227
+ errors = check_username(merge_data.get("username"))
228
+
229
+ # 处理 inputs
230
+ valid_inputs, input_errors = process_inputs(
231
+ merge_data.get("inputs", []))
232
+ errors.extend(input_errors)
233
+
234
+ # 更新数据
235
+ merge_data["inputs"] = valid_inputs
236
+
237
+ # 打印错误信息
238
+ if errors:
239
+ raise MDLVaildParamsError("\n".join(errors))
240
+ else:
241
+ self.subscirbe_lists = merge_data
242
+ return 1
243
+
244
+ def _refresh(self):
245
+ PV.v_empty(self.modelSign, "Model sign")
246
+ res = HttpClient.hander_response(
247
+ HttpClient.post_sync(
248
+ url=self.managerUrl + C.REFRESH_RECORD, json=self.modelSign
249
+ )
250
+ ).get("json", {})
251
+ if res.get("code") == 1:
252
+ if res.get("data").get("status") != 2:
253
+ return res.get("data").get("status")
254
+ else:
255
+ hasValue = False
256
+ for output in res["data"]["outputs"]:
257
+ if output.get("url") is not None and output.get("url") != "":
258
+ url = output.get("url")
259
+ # updated_url = url.replace(
260
+ # "http://112.4.132.6:8083",
261
+ # "http://geomodeling.njnu.edu.cn/dataTransferServer",
262
+ # )
263
+ output["url"] = url
264
+ hasValue = True
265
+ if hasValue is False:
266
+ return -1
267
+ for output in res["data"]["outputs"]:
268
+ if "[" in output.get("url"):
269
+ output["multiple"] = True
270
+ self.outputs = res["data"]["outputs"]
271
+ return 2
272
+ return -2
273
+
274
+
275
+ class OGMSAccess(Service):
276
+ def __init__(self, modelName: str, token: str = None):
277
+ super().__init__(token=token)
278
+ PV.v_empty(modelName, "Model name")
279
+ self.modelName = modelName
280
+ self.outputs = []
281
+ if self._checkModelService(pid=self._checkModel(modelName=modelName)):
282
+ print("Model service is ready!")
283
+ else:
284
+ print("Model service is not ready, please try again later!")
285
+ exit(1)
286
+
287
+ def createTask(self, params: dict):
288
+ PV.v_empty(params, "Params")
289
+ task = OGMSTask(self.originLists, self.token)
290
+ if task.configInputData(params) and self._subscribeTask(task):
291
+ result = task.wait4Status()
292
+ self.outputs = result["outputs"]
293
+ return self.outputs
294
+
295
+ def downloadAllData(self):
296
+
297
+ s_id = secrets.token_hex(8)
298
+ downloadFilesNum = 0
299
+ downlaodedFilesNum = 0
300
+ if not self.outputs:
301
+ print("没有可下载的数据")
302
+ return False
303
+
304
+ for output in self.outputs:
305
+ statename = output["statename"]
306
+ event = output["event"]
307
+ url = output["url"]
308
+ suffix = output["suffix"]
309
+ # 构建文件名
310
+ base_filename = f"{statename}-{event}"
311
+ filename = f"{base_filename}.{suffix}"
312
+ counter = 1
313
+
314
+ file_path = "./data/" + self.modelName + "_" + s_id + "/" + filename
315
+
316
+ dir_path = os.path.dirname(file_path)
317
+ if not os.path.exists(dir_path):
318
+ os.makedirs(dir_path)
319
+
320
+ # 检查文件是否存在
321
+ while os.path.exists(file_path):
322
+ filename = f"{base_filename}_{counter}.{suffix}"
323
+ file_path = "./data/" + self.modelName + "_" + s_id + "/" + filename
324
+ counter += 1
325
+ downloadFilesNum = downloadFilesNum + 1
326
+ # 下载文件并保存
327
+ content = HttpClient.hander_response(HttpClient.get_file_sync(url=url)).get(
328
+ "content", {}
329
+ )
330
+ if content:
331
+ with open(file_path, "wb") as f:
332
+ f.write(content)
333
+ print(f"Downloaded {filename}")
334
+ downlaodedFilesNum = downlaodedFilesNum + 1
335
+ else:
336
+ print(f"Failed to download {url}")
337
+ if downlaodedFilesNum == 0:
338
+ print("Failed to download files")
339
+ return False
340
+ if downloadFilesNum == downlaodedFilesNum:
341
+ print("All files downloaded successfully")
342
+ return True
343
+ else:
344
+ print("Failed to download some files")
345
+ return True
346
+
347
+ ######################## private################################
348
+ def _checkModel(self, modelName: str):
349
+ PV.v_empty(modelName, "Model name")
350
+ res = (
351
+ HttpClient.hander_response(
352
+ HttpClient.get_sync(
353
+ self.portalUrl + C.CHECK_MODEL +
354
+ urllib.parse.quote(modelName)
355
+ )
356
+ )
357
+ .get("json", {})
358
+ .get("data", {})
359
+ )
360
+ if res.get("md5"):
361
+ self.originLists = MDL().resolvingMDL(res)
362
+ if self.originLists:
363
+ return res.get("md5")
364
+ return 0
365
+
366
+ def _checkModelService(self, pid: str):
367
+ PV.v_empty(pid, "Model pid")
368
+ if (
369
+ HttpClient.hander_response(
370
+ HttpClient.get_sync(
371
+ self.managerUrl + C.CHECK_MODEL_SERVICE + pid)
372
+ )
373
+ .get("json", {})
374
+ .get("data", {})
375
+ == True
376
+ ):
377
+ return 1
378
+ return 0
379
+
380
+ def _subscribeTask(self, task):
381
+ res = HttpClient.hander_response(
382
+ HttpClient.post_sync(
383
+ self.managerUrl + C.INVOKE_MODEL, json=task.subscirbe_lists
384
+ )
385
+ ).get("json", {})
386
+ if res.get("code") == 1:
387
+ task.ip = res.get("data").get("ip")
388
+ task.port = res.get("data").get("port")
389
+ task.tid = res.get("data").get("tid")
390
+ task.modelSign = {"port": task.port,
391
+ "ip": task.ip, "tid": task.tid}
392
+ return 1
393
+ raise NotValueError("Model invoke error!")
@@ -0,0 +1,24 @@
1
+ """
2
+ Author: DiChen
3
+ Date: 2024-09-06 17:19:37
4
+ LastEditors: DiChen
5
+ LastEditTime: 2024-09-09 18:37:27
6
+ """
7
+
8
+ from .exceptions import *
9
+ from .http_client import HttpClient
10
+ from .parameterValidator import ParameterValidator as PV
11
+ from .stateManager import StateManager
12
+ from .mdlUtils import MDL
13
+
14
+ __all__ = [
15
+ "MDL",
16
+ "HttpClient",
17
+ "PV",
18
+ "StateManager",
19
+ "NotValueError",
20
+ "modelStatusError",
21
+ "calTimeoutError",
22
+ "UploadFileError",
23
+ "MDLVaildParamsError",
24
+ ]
@@ -0,0 +1,80 @@
1
+ """
2
+ Author: DiChen
3
+ Date: 2024-09-08 11:46:48
4
+ LastEditors: DiChen
5
+ LastEditTime: 2024-09-09 21:59:50
6
+ """
7
+
8
+ """
9
+ Author: DiChen
10
+ Date: 2024-09-08 11:46:48
11
+ LastEditors: DiChen
12
+ LastEditTime: 2024-09-08 11:46:51
13
+ """
14
+
15
+ # exceptions.py
16
+
17
+
18
+ # 基础自定义异常类
19
+ class MyBaseError(Exception):
20
+ """自定义基础异常类"""
21
+
22
+ def __init__(self, message, error_code=None):
23
+ super().__init__(message)
24
+ self.error_code = error_code
25
+
26
+ def __str__(self):
27
+ if self.error_code:
28
+ return f"[Error {self.error_code}]: {self.args[0]}"
29
+ else:
30
+ return self.args[0]
31
+
32
+
33
+ # 具体的自定义异常类
34
+ class NotValueError(MyBaseError):
35
+ """data is none"""
36
+
37
+ def __init__(self, message="not Value", error_code=1001):
38
+ super().__init__(message, error_code)
39
+
40
+
41
+ class DatabaseError(MyBaseError):
42
+ """database error"""
43
+
44
+ def __init__(self, message="database error", error_code=1002):
45
+ super().__init__(message, error_code)
46
+
47
+
48
+ class NetworkError(MyBaseError):
49
+ """network error"""
50
+
51
+ def __init__(self, message="network error", error_code=1003):
52
+ super().__init__(message, error_code)
53
+
54
+
55
+ class modelStatusError(MyBaseError):
56
+ """model status error"""
57
+
58
+ def __init__(self, message="model status error", error_code=1004):
59
+ super().__init__(message, error_code)
60
+
61
+
62
+ class calTimeoutError(MyBaseError):
63
+ """model calculate timeout error"""
64
+
65
+ def __init__(self, message="model calculate timeout error", error_code=1005):
66
+ super().__init__(message, error_code)
67
+
68
+
69
+ class UploadFileError(MyBaseError):
70
+ """upload file error"""
71
+
72
+ def __init__(self, message="upload file error", error_code=1006):
73
+ super().__init__(message, error_code)
74
+
75
+
76
+ class MDLVaildParamsError(MyBaseError):
77
+ """MDL vaild params error"""
78
+
79
+ def __init__(self, message="MDL vaild params error", error_code=1007):
80
+ super().__init__(message, error_code)