deepfos 1.1.60__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.
- deepfos/__init__.py +6 -0
- deepfos/_version.py +21 -0
- deepfos/algo/__init__.py +0 -0
- deepfos/algo/graph.py +171 -0
- deepfos/algo/segtree.py +31 -0
- deepfos/api/V1_1/__init__.py +0 -0
- deepfos/api/V1_1/business_model.py +119 -0
- deepfos/api/V1_1/dimension.py +599 -0
- deepfos/api/V1_1/models/__init__.py +0 -0
- deepfos/api/V1_1/models/business_model.py +1033 -0
- deepfos/api/V1_1/models/dimension.py +2768 -0
- deepfos/api/V1_2/__init__.py +0 -0
- deepfos/api/V1_2/dimension.py +285 -0
- deepfos/api/V1_2/models/__init__.py +0 -0
- deepfos/api/V1_2/models/dimension.py +2923 -0
- deepfos/api/__init__.py +0 -0
- deepfos/api/account.py +167 -0
- deepfos/api/accounting_engines.py +147 -0
- deepfos/api/app.py +626 -0
- deepfos/api/approval_process.py +198 -0
- deepfos/api/base.py +983 -0
- deepfos/api/business_model.py +160 -0
- deepfos/api/consolidation.py +129 -0
- deepfos/api/consolidation_process.py +106 -0
- deepfos/api/datatable.py +341 -0
- deepfos/api/deep_pipeline.py +61 -0
- deepfos/api/deepconnector.py +36 -0
- deepfos/api/deepfos_task.py +92 -0
- deepfos/api/deepmodel.py +188 -0
- deepfos/api/dimension.py +486 -0
- deepfos/api/financial_model.py +319 -0
- deepfos/api/journal_model.py +119 -0
- deepfos/api/journal_template.py +132 -0
- deepfos/api/memory_financial_model.py +98 -0
- deepfos/api/models/__init__.py +3 -0
- deepfos/api/models/account.py +483 -0
- deepfos/api/models/accounting_engines.py +756 -0
- deepfos/api/models/app.py +1338 -0
- deepfos/api/models/approval_process.py +1043 -0
- deepfos/api/models/base.py +234 -0
- deepfos/api/models/business_model.py +805 -0
- deepfos/api/models/consolidation.py +711 -0
- deepfos/api/models/consolidation_process.py +248 -0
- deepfos/api/models/datatable_mysql.py +427 -0
- deepfos/api/models/deep_pipeline.py +55 -0
- deepfos/api/models/deepconnector.py +28 -0
- deepfos/api/models/deepfos_task.py +386 -0
- deepfos/api/models/deepmodel.py +308 -0
- deepfos/api/models/dimension.py +1576 -0
- deepfos/api/models/financial_model.py +1796 -0
- deepfos/api/models/journal_model.py +341 -0
- deepfos/api/models/journal_template.py +854 -0
- deepfos/api/models/memory_financial_model.py +478 -0
- deepfos/api/models/platform.py +178 -0
- deepfos/api/models/python.py +221 -0
- deepfos/api/models/reconciliation_engine.py +411 -0
- deepfos/api/models/reconciliation_report.py +161 -0
- deepfos/api/models/role_strategy.py +884 -0
- deepfos/api/models/smartlist.py +237 -0
- deepfos/api/models/space.py +1137 -0
- deepfos/api/models/system.py +1065 -0
- deepfos/api/models/variable.py +463 -0
- deepfos/api/models/workflow.py +946 -0
- deepfos/api/platform.py +199 -0
- deepfos/api/python.py +90 -0
- deepfos/api/reconciliation_engine.py +181 -0
- deepfos/api/reconciliation_report.py +64 -0
- deepfos/api/role_strategy.py +234 -0
- deepfos/api/smartlist.py +69 -0
- deepfos/api/space.py +582 -0
- deepfos/api/system.py +372 -0
- deepfos/api/variable.py +154 -0
- deepfos/api/workflow.py +264 -0
- deepfos/boost/__init__.py +6 -0
- deepfos/boost/py_jstream.py +89 -0
- deepfos/boost/py_pandas.py +20 -0
- deepfos/cache.py +121 -0
- deepfos/config.py +6 -0
- deepfos/core/__init__.py +27 -0
- deepfos/core/cube/__init__.py +10 -0
- deepfos/core/cube/_base.py +462 -0
- deepfos/core/cube/constants.py +21 -0
- deepfos/core/cube/cube.py +408 -0
- deepfos/core/cube/formula.py +707 -0
- deepfos/core/cube/syscube.py +532 -0
- deepfos/core/cube/typing.py +7 -0
- deepfos/core/cube/utils.py +238 -0
- deepfos/core/dimension/__init__.py +11 -0
- deepfos/core/dimension/_base.py +506 -0
- deepfos/core/dimension/dimcreator.py +184 -0
- deepfos/core/dimension/dimension.py +472 -0
- deepfos/core/dimension/dimexpr.py +271 -0
- deepfos/core/dimension/dimmember.py +155 -0
- deepfos/core/dimension/eledimension.py +22 -0
- deepfos/core/dimension/filters.py +99 -0
- deepfos/core/dimension/sysdimension.py +168 -0
- deepfos/core/logictable/__init__.py +5 -0
- deepfos/core/logictable/_cache.py +141 -0
- deepfos/core/logictable/_operator.py +663 -0
- deepfos/core/logictable/nodemixin.py +673 -0
- deepfos/core/logictable/sqlcondition.py +609 -0
- deepfos/core/logictable/tablemodel.py +497 -0
- deepfos/db/__init__.py +36 -0
- deepfos/db/cipher.py +660 -0
- deepfos/db/clickhouse.py +191 -0
- deepfos/db/connector.py +195 -0
- deepfos/db/daclickhouse.py +171 -0
- deepfos/db/dameng.py +101 -0
- deepfos/db/damysql.py +189 -0
- deepfos/db/dbkits.py +358 -0
- deepfos/db/deepengine.py +99 -0
- deepfos/db/deepmodel.py +82 -0
- deepfos/db/deepmodel_kingbase.py +83 -0
- deepfos/db/edb.py +214 -0
- deepfos/db/gauss.py +83 -0
- deepfos/db/kingbase.py +83 -0
- deepfos/db/mysql.py +184 -0
- deepfos/db/oracle.py +131 -0
- deepfos/db/postgresql.py +192 -0
- deepfos/db/sqlserver.py +99 -0
- deepfos/db/utils.py +135 -0
- deepfos/element/__init__.py +89 -0
- deepfos/element/accounting.py +348 -0
- deepfos/element/apvlprocess.py +215 -0
- deepfos/element/base.py +398 -0
- deepfos/element/bizmodel.py +1269 -0
- deepfos/element/datatable.py +2467 -0
- deepfos/element/deep_pipeline.py +186 -0
- deepfos/element/deepconnector.py +59 -0
- deepfos/element/deepmodel.py +1806 -0
- deepfos/element/dimension.py +1254 -0
- deepfos/element/fact_table.py +427 -0
- deepfos/element/finmodel.py +1485 -0
- deepfos/element/journal.py +840 -0
- deepfos/element/journal_template.py +943 -0
- deepfos/element/pyscript.py +412 -0
- deepfos/element/reconciliation.py +553 -0
- deepfos/element/rolestrategy.py +243 -0
- deepfos/element/smartlist.py +457 -0
- deepfos/element/variable.py +756 -0
- deepfos/element/workflow.py +560 -0
- deepfos/exceptions/__init__.py +239 -0
- deepfos/exceptions/hook.py +86 -0
- deepfos/lazy.py +104 -0
- deepfos/lazy_import.py +84 -0
- deepfos/lib/__init__.py +0 -0
- deepfos/lib/_javaobj.py +366 -0
- deepfos/lib/asynchronous.py +879 -0
- deepfos/lib/concurrency.py +107 -0
- deepfos/lib/constant.py +39 -0
- deepfos/lib/decorator.py +310 -0
- deepfos/lib/deepchart.py +778 -0
- deepfos/lib/deepux.py +477 -0
- deepfos/lib/discovery.py +273 -0
- deepfos/lib/edb_lexer.py +789 -0
- deepfos/lib/eureka.py +156 -0
- deepfos/lib/filterparser.py +751 -0
- deepfos/lib/httpcli.py +106 -0
- deepfos/lib/jsonstreamer.py +80 -0
- deepfos/lib/msg.py +394 -0
- deepfos/lib/nacos.py +225 -0
- deepfos/lib/patch.py +92 -0
- deepfos/lib/redis.py +241 -0
- deepfos/lib/serutils.py +181 -0
- deepfos/lib/stopwatch.py +99 -0
- deepfos/lib/subtask.py +572 -0
- deepfos/lib/sysutils.py +703 -0
- deepfos/lib/utils.py +1003 -0
- deepfos/local.py +160 -0
- deepfos/options.py +670 -0
- deepfos/translation.py +237 -0
- deepfos-1.1.60.dist-info/METADATA +33 -0
- deepfos-1.1.60.dist-info/RECORD +175 -0
- deepfos-1.1.60.dist-info/WHEEL +5 -0
- deepfos-1.1.60.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,412 @@
|
|
|
1
|
+
import asyncio.exceptions
|
|
2
|
+
import json
|
|
3
|
+
import threading
|
|
4
|
+
import time
|
|
5
|
+
from abc import ABC
|
|
6
|
+
from contextlib import contextmanager
|
|
7
|
+
from importlib import import_module
|
|
8
|
+
from math import ceil
|
|
9
|
+
from typing import Any, Dict, Tuple
|
|
10
|
+
from urllib.parse import quote_plus
|
|
11
|
+
|
|
12
|
+
from loguru import logger
|
|
13
|
+
|
|
14
|
+
from deepfos import OPTION
|
|
15
|
+
from deepfos.api.app import AppAPI
|
|
16
|
+
from deepfos.api.models.python import PyRunInfo
|
|
17
|
+
from deepfos.api.python import PythonAPI
|
|
18
|
+
from deepfos.element.base import ElementBase
|
|
19
|
+
from deepfos.exceptions import (
|
|
20
|
+
ResultTimeOutError,
|
|
21
|
+
PyTaskRevokedError,
|
|
22
|
+
PyTaskRunTimeError,
|
|
23
|
+
PyTaskInvalidError,
|
|
24
|
+
PyTaskConcurrencyExceed,
|
|
25
|
+
PyTaskTimeLimitExceed,
|
|
26
|
+
APIResponseError,
|
|
27
|
+
)
|
|
28
|
+
from deepfos.lib.asynchronous import future_property
|
|
29
|
+
from deepfos.lib.constant import UNSET
|
|
30
|
+
from deepfos.lib.redis import RedisCli
|
|
31
|
+
|
|
32
|
+
__all__ = [
|
|
33
|
+
'PythonScript',
|
|
34
|
+
'OnlineTask',
|
|
35
|
+
'LocalTask',
|
|
36
|
+
]
|
|
37
|
+
|
|
38
|
+
ONLINE_MODE = (
|
|
39
|
+
OPTION.module.src_task is not None
|
|
40
|
+
and OPTION.module.src_celeryapp is not None
|
|
41
|
+
and OPTION.module.src_options is not None
|
|
42
|
+
and OPTION.module.src_errors_classes is not None
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
if ONLINE_MODE: # pragma: no cover
|
|
46
|
+
try:
|
|
47
|
+
import celery.states as cstates # noqa
|
|
48
|
+
from celery.exceptions import TaskRevokedError, TimeoutError # noqa
|
|
49
|
+
from celery.result import allow_join_result # noqa
|
|
50
|
+
except ImportError:
|
|
51
|
+
ONLINE_MODE = False
|
|
52
|
+
|
|
53
|
+
if ONLINE_MODE: # pragma: no cover
|
|
54
|
+
try:
|
|
55
|
+
pyrunner = import_module(OPTION.module.src_task).run # noqa
|
|
56
|
+
AsyncResult = import_module(OPTION.module.src_celeryapp).celery_app.AsyncResult # noqa
|
|
57
|
+
SERVER_OPTION = import_module(OPTION.module.src_options).OPTION # noqa
|
|
58
|
+
PyExecutionError = import_module(OPTION.module.src_errors_classes).PyExecutionError # noqa
|
|
59
|
+
|
|
60
|
+
assert SERVER_OPTION.redis.mode == 'single', 'Only supported in redis single mode'
|
|
61
|
+
|
|
62
|
+
redis_addr = SERVER_OPTION.redis.addr
|
|
63
|
+
redis_password = quote_plus(SERVER_OPTION.redis.password)
|
|
64
|
+
|
|
65
|
+
CONCURRENCY_KEY_PREFIX = f'celery_concurrency_task:{OPTION.general.task_info.get("worker_name")}'
|
|
66
|
+
redis_cli = RedisCli(f"redis://:{redis_password}@{redis_addr}/13")
|
|
67
|
+
CONCURRENCY_KEY = None
|
|
68
|
+
GLOBAL_LOCK = None
|
|
69
|
+
|
|
70
|
+
except (ImportError, AssertionError):
|
|
71
|
+
ONLINE_MODE = False
|
|
72
|
+
|
|
73
|
+
LOCAL_LOCK = threading.Lock()
|
|
74
|
+
|
|
75
|
+
WAITING_TASKS = 0
|
|
76
|
+
|
|
77
|
+
_on_const = {
|
|
78
|
+
'NaN': None
|
|
79
|
+
}.__getitem__
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def maybe_prepare_redis_lock():
|
|
83
|
+
global CONCURRENCY_KEY
|
|
84
|
+
global GLOBAL_LOCK
|
|
85
|
+
if CONCURRENCY_KEY is None:
|
|
86
|
+
CONCURRENCY_KEY = redis_cli.lock(
|
|
87
|
+
f'{CONCURRENCY_KEY_PREFIX}:{OPTION.general.task_info["task_id"]}',
|
|
88
|
+
renew_interval=2, expire_sec=4, blocking_timeout=None
|
|
89
|
+
)
|
|
90
|
+
if GLOBAL_LOCK is None:
|
|
91
|
+
GLOBAL_LOCK = redis_cli.lock(
|
|
92
|
+
CONCURRENCY_KEY_PREFIX,
|
|
93
|
+
renew_interval=1, expire_sec=2, blocking_timeout=None
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
class AbstractPythonTask(ABC):
|
|
98
|
+
task_id = UNSET
|
|
99
|
+
|
|
100
|
+
def get_result(self, timeout: int = None): # pragma: no cover
|
|
101
|
+
"""获取当前脚本执行结果
|
|
102
|
+
|
|
103
|
+
Args:
|
|
104
|
+
timeout: 获取等待超时时间,默认为None,意味着会等待直到有结果
|
|
105
|
+
|
|
106
|
+
"""
|
|
107
|
+
raise NotImplementedError
|
|
108
|
+
|
|
109
|
+
def terminate(self): # pragma: no cover
|
|
110
|
+
"""取消当前脚本
|
|
111
|
+
|
|
112
|
+
Important:
|
|
113
|
+
只有非结束状态的脚本可以被取消
|
|
114
|
+
|
|
115
|
+
"""
|
|
116
|
+
raise NotImplementedError
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
errcode_map = {
|
|
120
|
+
28030001: PyTaskRunTimeError,
|
|
121
|
+
28030003: PyTaskRevokedError,
|
|
122
|
+
28030005: ResultTimeOutError,
|
|
123
|
+
28030006: PyTaskTimeLimitExceed,
|
|
124
|
+
28040001: PyTaskInvalidError,
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
class LocalTask(AbstractPythonTask):
|
|
129
|
+
"""本地任务实例
|
|
130
|
+
|
|
131
|
+
Args:
|
|
132
|
+
parameter: 任务入参
|
|
133
|
+
manager: PythonScript实例,用于提供元素信息
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
"""
|
|
137
|
+
|
|
138
|
+
def __init__(self, parameter, manager: 'PythonScript'):
|
|
139
|
+
self.manager = manager
|
|
140
|
+
self.task_id = manager.api.script.run(
|
|
141
|
+
PyRunInfo.construct_from(manager.element_info, parameter=parameter)
|
|
142
|
+
)
|
|
143
|
+
logger.debug(f'python脚本[id:{self.task_id}]任务信息已发送')
|
|
144
|
+
|
|
145
|
+
def get_result(self, timeout: int = None):
|
|
146
|
+
start_time = time.time()
|
|
147
|
+
remaining_time = interval = min(max(OPTION.api.timeout - 1, 1), 5)
|
|
148
|
+
if timeout is not None:
|
|
149
|
+
remaining_time = min(interval, timeout)
|
|
150
|
+
|
|
151
|
+
while timeout is None or remaining_time > 0:
|
|
152
|
+
try:
|
|
153
|
+
return self.manager.api.script.result(
|
|
154
|
+
self.task_id,
|
|
155
|
+
timeout=remaining_time
|
|
156
|
+
)
|
|
157
|
+
except APIResponseError as e:
|
|
158
|
+
if e.code not in errcode_map:
|
|
159
|
+
raise
|
|
160
|
+
|
|
161
|
+
err_cls = errcode_map[e.code]
|
|
162
|
+
if err_cls is not ResultTimeOutError:
|
|
163
|
+
raise errcode_map[e.code](str(e)) from None
|
|
164
|
+
|
|
165
|
+
delta_time = time.time() - start_time
|
|
166
|
+
remaining_time = (
|
|
167
|
+
ceil(min(interval, timeout - delta_time))
|
|
168
|
+
if timeout is not None else interval
|
|
169
|
+
)
|
|
170
|
+
|
|
171
|
+
raise ResultTimeOutError() from None
|
|
172
|
+
|
|
173
|
+
def terminate(self):
|
|
174
|
+
return self.manager.api.script.terminate(self.task_id)
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
class OnlineTask(AbstractPythonTask):
|
|
178
|
+
"""线上任务实例
|
|
179
|
+
|
|
180
|
+
Args:
|
|
181
|
+
parameter: 任务入参
|
|
182
|
+
manager: PythonScript实例,用于提供元素信息
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
"""
|
|
186
|
+
|
|
187
|
+
def __init__(self, parameter, manager: 'PythonScript'):
|
|
188
|
+
if not ONLINE_MODE:
|
|
189
|
+
raise NotImplementedError('OnlineTask实例只能在线上环境使用')
|
|
190
|
+
|
|
191
|
+
task = pyrunner.apply_async(
|
|
192
|
+
args=(parameter,
|
|
193
|
+
*manager.env)
|
|
194
|
+
)
|
|
195
|
+
self.task_id = task.id
|
|
196
|
+
|
|
197
|
+
logger.debug(f'python脚本[id:{self.task_id}]任务信息已发送')
|
|
198
|
+
|
|
199
|
+
def _get_valid_task(self):
|
|
200
|
+
task = AsyncResult(self.task_id)
|
|
201
|
+
if task.status is cstates.PENDING: # pragma: no cover
|
|
202
|
+
raise PyTaskInvalidError()
|
|
203
|
+
|
|
204
|
+
return task
|
|
205
|
+
|
|
206
|
+
@contextmanager
|
|
207
|
+
def _ensure_valid_concurrency(self):
|
|
208
|
+
global WAITING_TASKS
|
|
209
|
+
maybe_prepare_redis_lock()
|
|
210
|
+
global CONCURRENCY_KEY
|
|
211
|
+
global GLOBAL_LOCK
|
|
212
|
+
|
|
213
|
+
with LOCAL_LOCK:
|
|
214
|
+
if not CONCURRENCY_KEY.locked() and WAITING_TASKS == 0: # noqa
|
|
215
|
+
with GLOBAL_LOCK:
|
|
216
|
+
con_num = len(list(redis_cli.client.scan_iter(f'{CONCURRENCY_KEY_PREFIX}:*')))
|
|
217
|
+
|
|
218
|
+
if (SERVER_OPTION.celery.autoscale_max_concurreny - con_num) <= OPTION.general.preserve_concurrency:
|
|
219
|
+
raise PyTaskConcurrencyExceed(
|
|
220
|
+
OPTION.general.task_info.get("worker_name"),
|
|
221
|
+
con_num
|
|
222
|
+
)
|
|
223
|
+
|
|
224
|
+
with GLOBAL_LOCK:
|
|
225
|
+
CONCURRENCY_KEY.do_hold() # noqa
|
|
226
|
+
|
|
227
|
+
WAITING_TASKS = WAITING_TASKS + 1
|
|
228
|
+
try:
|
|
229
|
+
yield
|
|
230
|
+
finally:
|
|
231
|
+
with LOCAL_LOCK:
|
|
232
|
+
WAITING_TASKS = WAITING_TASKS - 1
|
|
233
|
+
if WAITING_TASKS == 0:
|
|
234
|
+
with GLOBAL_LOCK:
|
|
235
|
+
CONCURRENCY_KEY.release() # noqa
|
|
236
|
+
|
|
237
|
+
def get_result(self, timeout: int = None):
|
|
238
|
+
task = self._get_valid_task()
|
|
239
|
+
|
|
240
|
+
with self._ensure_valid_concurrency():
|
|
241
|
+
with allow_join_result():
|
|
242
|
+
try:
|
|
243
|
+
ret, *std = task.get(timeout=timeout)
|
|
244
|
+
return json.loads(ret, parse_constant=_on_const)
|
|
245
|
+
except TimeoutError:
|
|
246
|
+
raise ResultTimeOutError() from None
|
|
247
|
+
except TaskRevokedError:
|
|
248
|
+
raise PyTaskRevokedError() from None
|
|
249
|
+
except PyExecutionError as e:
|
|
250
|
+
raise PyTaskRunTimeError(e.stderr) from None
|
|
251
|
+
except Exception as e:
|
|
252
|
+
raise PyTaskRunTimeError(e) from None
|
|
253
|
+
|
|
254
|
+
def terminate(self):
|
|
255
|
+
task = self._get_valid_task()
|
|
256
|
+
|
|
257
|
+
if task.status in cstates.READY_STATES:
|
|
258
|
+
logger.warning('python脚本已结束')
|
|
259
|
+
return
|
|
260
|
+
|
|
261
|
+
task.revoke(terminate=True)
|
|
262
|
+
logger.info(f'python脚本[id:{self.task_id}]已取消')
|
|
263
|
+
|
|
264
|
+
def status(self):
|
|
265
|
+
return self._get_valid_task().status
|
|
266
|
+
|
|
267
|
+
|
|
268
|
+
class PythonScript(ElementBase[PythonAPI]):
|
|
269
|
+
"""Python脚本对象
|
|
270
|
+
|
|
271
|
+
Args:
|
|
272
|
+
task_name: 任务名称
|
|
273
|
+
should_log: 仅在线上执行时有效,脚本是否记录执行日志,
|
|
274
|
+
线下执行时,该值与脚本元素配置项“记录执行日志”保持一致
|
|
275
|
+
|
|
276
|
+
|
|
277
|
+
"""
|
|
278
|
+
def __init__(
|
|
279
|
+
self,
|
|
280
|
+
element_name: str,
|
|
281
|
+
folder_id: str = None,
|
|
282
|
+
path: str = None,
|
|
283
|
+
task_name: str = None,
|
|
284
|
+
should_log: bool = False
|
|
285
|
+
):
|
|
286
|
+
self.should_log = should_log
|
|
287
|
+
self.task_name = task_name
|
|
288
|
+
super().__init__(
|
|
289
|
+
element_name=element_name, folder_id=folder_id, path=path
|
|
290
|
+
)
|
|
291
|
+
|
|
292
|
+
@future_property
|
|
293
|
+
async def env(self) -> Tuple[str, str, Dict]:
|
|
294
|
+
if not ONLINE_MODE:
|
|
295
|
+
raise NotImplementedError('只在线上环境中可获得env值')
|
|
296
|
+
|
|
297
|
+
ele_info = await self.wait_for('element_info')
|
|
298
|
+
python_path = '/'.join([
|
|
299
|
+
SERVER_OPTION.general.py_root,
|
|
300
|
+
OPTION.api.header['space'],
|
|
301
|
+
OPTION.api.header['app']]
|
|
302
|
+
)
|
|
303
|
+
if self._path is not None:
|
|
304
|
+
folder = self._path.strip('\\/') \
|
|
305
|
+
.replace('/', '.').replace('\\', '.')
|
|
306
|
+
else:
|
|
307
|
+
path = await AppAPI(sync=False).folder.get_folder_full(ele_info.folderId)
|
|
308
|
+
folder = path.strip('\\/').replace('/', '.').replace('\\', '.')
|
|
309
|
+
|
|
310
|
+
if not folder:
|
|
311
|
+
module = self.element_name
|
|
312
|
+
else:
|
|
313
|
+
module = '.'.join([folder, self.element_name])
|
|
314
|
+
|
|
315
|
+
return (
|
|
316
|
+
module,
|
|
317
|
+
python_path,
|
|
318
|
+
{
|
|
319
|
+
'header': OPTION.api.header,
|
|
320
|
+
'server': SERVER_OPTION.server.to_dict(),
|
|
321
|
+
'element_desc': {},
|
|
322
|
+
'should_log': self.should_log,
|
|
323
|
+
'compressed_flag': False,
|
|
324
|
+
'task_type': "NATIVE",
|
|
325
|
+
'return_structure_data': None,
|
|
326
|
+
'return_structure_type': None,
|
|
327
|
+
'enable_return_structure': False,
|
|
328
|
+
'task_name': self.task_name,
|
|
329
|
+
'use_eureka': OPTION.discovery.enabled
|
|
330
|
+
}
|
|
331
|
+
)
|
|
332
|
+
|
|
333
|
+
def run(self, parameter: Any = None, timeout: int = None):
|
|
334
|
+
"""发送python脚本任务信息并获取执行结果
|
|
335
|
+
|
|
336
|
+
Args:
|
|
337
|
+
parameter: 脚本入参
|
|
338
|
+
timeout: 获取等待超时时间,默认为None,意味着会等待直到有结果
|
|
339
|
+
|
|
340
|
+
.. admonition:: 示例
|
|
341
|
+
|
|
342
|
+
.. code-block:: python
|
|
343
|
+
|
|
344
|
+
from deepfos.element.pyscript import PythonScript
|
|
345
|
+
|
|
346
|
+
script = PythonScript(element_name='test_task',
|
|
347
|
+
path='/',
|
|
348
|
+
should_log=True)
|
|
349
|
+
|
|
350
|
+
script.run(parameter={'a': 1})
|
|
351
|
+
|
|
352
|
+
线上执行时,将执行发送当前空间内元素路径为'/',元素名为test_task的python脚本的任务,
|
|
353
|
+
并等待结果,且由于初始化时should_log为True,其在作业管理中将更新作业信息
|
|
354
|
+
|
|
355
|
+
|
|
356
|
+
See Also:
|
|
357
|
+
:meth: `run_async`
|
|
358
|
+
:class:`LocalTask`
|
|
359
|
+
:class:`OnlineTask`
|
|
360
|
+
|
|
361
|
+
"""
|
|
362
|
+
task = self.run_async(parameter)
|
|
363
|
+
return task.get_result(timeout)
|
|
364
|
+
|
|
365
|
+
def run_async(self, parameter: Any = None) -> AbstractPythonTask:
|
|
366
|
+
"""发送python脚本任务信息并返回Task实例
|
|
367
|
+
|
|
368
|
+
该方法不会等待任务执行结果,任务信息将被提交至celery任务队列,
|
|
369
|
+
待有可用并发数时执行,执行结果可通过Task实例的 `get_result` 方法得到
|
|
370
|
+
|
|
371
|
+
Args:
|
|
372
|
+
parameter: 脚本入参
|
|
373
|
+
|
|
374
|
+
|
|
375
|
+
Returns: python脚本任务id
|
|
376
|
+
|
|
377
|
+
.. admonition:: 示例
|
|
378
|
+
|
|
379
|
+
.. code-block:: python
|
|
380
|
+
|
|
381
|
+
from deepfos.element.pyscript import PythonScript
|
|
382
|
+
|
|
383
|
+
script = PythonScript(element_name='test_task',
|
|
384
|
+
path='/',
|
|
385
|
+
should_log=True)
|
|
386
|
+
|
|
387
|
+
script.run_async(parameter={'a': 1})
|
|
388
|
+
|
|
389
|
+
线上执行时,将执行发送当前空间内元素路径为'/',
|
|
390
|
+
元素名为test_task的python脚本的任务,且由于初始化时should_log为True,
|
|
391
|
+
其在作业管理中将更新作业信息
|
|
392
|
+
|
|
393
|
+
可通过如下代码等待并获得结果,如不使用,任务亦会照常执行,如记录了任务id,
|
|
394
|
+
可通过python组件的/script/result/{任务id}接口得到结果
|
|
395
|
+
|
|
396
|
+
.. code-block:: python
|
|
397
|
+
|
|
398
|
+
res = script.get_result()
|
|
399
|
+
|
|
400
|
+
|
|
401
|
+
See Also:
|
|
402
|
+
:meth:`run`
|
|
403
|
+
:class:`LocalTask`
|
|
404
|
+
:class:`OnlineTask`
|
|
405
|
+
|
|
406
|
+
"""
|
|
407
|
+
if not ONLINE_MODE:
|
|
408
|
+
task = LocalTask(parameter, self)
|
|
409
|
+
else:
|
|
410
|
+
task = OnlineTask(parameter, self)
|
|
411
|
+
|
|
412
|
+
return task
|