deepfos 1.1.60__py3-none-any.whl → 1.1.78__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/_version.py +3 -3
- deepfos/api/V1_1/models/business_model.py +322 -322
- deepfos/api/V1_1/models/dimension.py +1075 -1075
- deepfos/api/V1_2/models/dimension.py +1119 -1116
- deepfos/api/account.py +1 -0
- deepfos/api/app.py +1 -0
- deepfos/api/base.py +70 -71
- deepfos/api/deep_pipeline.py +1 -1
- deepfos/api/deepconnector.py +3 -3
- deepfos/api/financial_model.py +12 -0
- deepfos/api/models/account.py +130 -130
- deepfos/api/models/accounting_engines.py +250 -250
- deepfos/api/models/app.py +355 -355
- deepfos/api/models/approval_process.py +231 -231
- deepfos/api/models/base.py +49 -209
- deepfos/api/models/business_model.py +239 -239
- deepfos/api/models/consolidation.py +196 -196
- deepfos/api/models/consolidation_process.py +31 -31
- deepfos/api/models/datatable_mysql.py +78 -78
- deepfos/api/models/deep_pipeline.py +20 -9
- deepfos/api/models/deepconnector.py +9 -8
- deepfos/api/models/deepfos_task.py +118 -118
- deepfos/api/models/deepmodel.py +120 -120
- deepfos/api/models/dimension.py +613 -610
- deepfos/api/models/financial_model.py +691 -663
- deepfos/api/models/journal_model.py +120 -120
- deepfos/api/models/journal_template.py +185 -185
- deepfos/api/models/memory_financial_model.py +131 -131
- deepfos/api/models/platform.py +16 -16
- deepfos/api/models/python.py +32 -32
- deepfos/api/models/reconciliation_engine.py +104 -104
- deepfos/api/models/reconciliation_report.py +29 -29
- deepfos/api/models/role_strategy.py +213 -213
- deepfos/api/models/smartlist.py +86 -86
- deepfos/api/models/space.py +312 -312
- deepfos/api/models/system.py +299 -297
- deepfos/api/models/variable.py +131 -131
- deepfos/api/models/workflow.py +290 -270
- deepfos/api/platform.py +3 -1
- deepfos/api/space.py +1 -0
- deepfos/api/system.py +1 -0
- deepfos/api/workflow.py +8 -0
- deepfos/cache.py +50 -4
- deepfos/element/bizmodel.py +2 -2
- deepfos/element/deep_pipeline.py +29 -16
- deepfos/element/deepconnector.py +36 -1
- deepfos/element/deepmodel.py +591 -332
- deepfos/element/dimension.py +30 -17
- deepfos/element/finmodel.py +542 -101
- deepfos/element/journal.py +20 -10
- deepfos/element/rolestrategy.py +4 -4
- deepfos/element/variable.py +23 -17
- deepfos/element/workflow.py +60 -3
- deepfos/exceptions/__init__.py +1 -1
- deepfos/lib/deepchart.py +14 -13
- deepfos/lib/deepux.py +11 -11
- deepfos/lib/discovery.py +3 -0
- deepfos/lib/filterparser.py +2 -2
- deepfos/lib/k8s.py +101 -0
- deepfos/lib/msg.py +34 -8
- deepfos/lib/serutils.py +34 -9
- deepfos/lib/sysutils.py +37 -18
- deepfos/lib/utils.py +62 -2
- deepfos/options.py +39 -8
- {deepfos-1.1.60.dist-info → deepfos-1.1.78.dist-info}/METADATA +7 -7
- {deepfos-1.1.60.dist-info → deepfos-1.1.78.dist-info}/RECORD +68 -67
- {deepfos-1.1.60.dist-info → deepfos-1.1.78.dist-info}/WHEEL +0 -0
- {deepfos-1.1.60.dist-info → deepfos-1.1.78.dist-info}/top_level.txt +0 -0
deepfos/api/platform.py
CHANGED
|
@@ -93,7 +93,8 @@ class StdFileAPI(ChildAPI):
|
|
|
93
93
|
|
|
94
94
|
|
|
95
95
|
"""
|
|
96
|
-
|
|
96
|
+
# platform server does not recognize 7bit encoding
|
|
97
|
+
data = FormData(quote_fields=False)
|
|
97
98
|
data.add_field('file', file, filename=file_name)
|
|
98
99
|
return {'body': data,
|
|
99
100
|
'param': {
|
|
@@ -174,6 +175,7 @@ class FilePyAPI(ChildAPI):
|
|
|
174
175
|
class PlatformAPI(RootAPI):
|
|
175
176
|
"""文件上传服务接口"""
|
|
176
177
|
prefix = lambda: OPTION.server.platform_file
|
|
178
|
+
server_name = "platform-file-server"
|
|
177
179
|
|
|
178
180
|
@cached_property
|
|
179
181
|
def file(self) -> StdFileAPI:
|
deepfos/api/space.py
CHANGED
deepfos/api/system.py
CHANGED
deepfos/api/workflow.py
CHANGED
|
@@ -188,6 +188,14 @@ class ProcessTask(ChildAPI):
|
|
|
188
188
|
"""
|
|
189
189
|
return {'body': userTaskQueryDTO}
|
|
190
190
|
|
|
191
|
+
@get('outcomes')
|
|
192
|
+
def outcomes(self, taskId: str) -> Union[List[OutComeDto], Awaitable[List[OutComeDto]]]:
|
|
193
|
+
"""
|
|
194
|
+
获取用户任务outcome
|
|
195
|
+
|
|
196
|
+
"""
|
|
197
|
+
return {'param': {'taskId': taskId}}
|
|
198
|
+
|
|
191
199
|
|
|
192
200
|
class Version(ChildAPI):
|
|
193
201
|
endpoint = '/version'
|
deepfos/cache.py
CHANGED
|
@@ -106,16 +106,62 @@ class SpaceSeperatedBase(CustomedCache):
|
|
|
106
106
|
|
|
107
107
|
|
|
108
108
|
class AppSeperatedTTLCache(TTLCache, AppSeperatedBase):
|
|
109
|
-
|
|
109
|
+
def popitem(self):
|
|
110
|
+
"""Remove and return the `(key, value)` pair least recently used that
|
|
111
|
+
has not already expired.
|
|
112
|
+
|
|
113
|
+
"""
|
|
114
|
+
with self.timer as time:
|
|
115
|
+
self.expire(time)
|
|
116
|
+
try:
|
|
117
|
+
key = next(iter(self._TTLCache__links))
|
|
118
|
+
except StopIteration:
|
|
119
|
+
raise KeyError("%s is empty" % type(self).__name__) from None
|
|
120
|
+
else:
|
|
121
|
+
value = TTLCache.__getitem__(self, key)
|
|
122
|
+
TTLCache.__delitem__(self, key)
|
|
123
|
+
return key, value
|
|
110
124
|
|
|
111
125
|
|
|
112
126
|
class SpaceSeperatedTTLCache(TTLCache, SpaceSeperatedBase):
|
|
113
|
-
|
|
127
|
+
def popitem(self):
|
|
128
|
+
"""Remove and return the `(key, value)` pair least recently used that
|
|
129
|
+
has not already expired.
|
|
130
|
+
|
|
131
|
+
"""
|
|
132
|
+
with self.timer as time:
|
|
133
|
+
self.expire(time)
|
|
134
|
+
try:
|
|
135
|
+
key = next(iter(self._TTLCache__links))
|
|
136
|
+
except StopIteration:
|
|
137
|
+
raise KeyError("%s is empty" % type(self).__name__) from None
|
|
138
|
+
else:
|
|
139
|
+
value = TTLCache.__getitem__(self, key)
|
|
140
|
+
TTLCache.__delitem__(self, key)
|
|
141
|
+
return key, value
|
|
114
142
|
|
|
115
143
|
|
|
116
144
|
class AppSeperatedLRUCache(LRUCache, AppSeperatedBase):
|
|
117
|
-
|
|
145
|
+
def popitem(self):
|
|
146
|
+
"""Remove and return the `(key, value)` pair least recently used."""
|
|
147
|
+
try:
|
|
148
|
+
key = next(iter(self._LRUCache__order))
|
|
149
|
+
except StopIteration:
|
|
150
|
+
raise KeyError("%s is empty" % type(self).__name__) from None
|
|
151
|
+
else:
|
|
152
|
+
value = LRUCache.__getitem__(self, key)
|
|
153
|
+
LRUCache.__delitem__(self, key)
|
|
154
|
+
return key, value
|
|
118
155
|
|
|
119
156
|
|
|
120
157
|
class SpaceSeperatedLRUCache(LRUCache, SpaceSeperatedBase):
|
|
121
|
-
|
|
158
|
+
def popitem(self):
|
|
159
|
+
"""Remove and return the `(key, value)` pair least recently used."""
|
|
160
|
+
try:
|
|
161
|
+
key = next(iter(self._LRUCache__order))
|
|
162
|
+
except StopIteration:
|
|
163
|
+
raise KeyError("%s is empty" % type(self).__name__) from None
|
|
164
|
+
else:
|
|
165
|
+
value = LRUCache.__getitem__(self, key)
|
|
166
|
+
LRUCache.__delitem__(self, key)
|
|
167
|
+
return key, value
|
deepfos/element/bizmodel.py
CHANGED
|
@@ -57,8 +57,8 @@ def dataframe_to_records(
|
|
|
57
57
|
|
|
58
58
|
|
|
59
59
|
class TableNode(MetaTable):
|
|
60
|
-
table_structure: TableStructure = None
|
|
61
|
-
name: str = None
|
|
60
|
+
table_structure: Optional[TableStructure] = None
|
|
61
|
+
name: Optional[str] = None
|
|
62
62
|
|
|
63
63
|
|
|
64
64
|
def create_table(struct: TableStructure, parent: BaseTable = None) -> TableNode:
|
deepfos/element/deep_pipeline.py
CHANGED
|
@@ -1,17 +1,19 @@
|
|
|
1
1
|
import asyncio
|
|
2
2
|
import time
|
|
3
|
+
import warnings
|
|
3
4
|
from math import ceil
|
|
4
5
|
from typing import Any, TYPE_CHECKING, List
|
|
5
6
|
|
|
6
7
|
from deepfos import OPTION
|
|
7
8
|
from deepfos.api.deep_pipeline import DeepPipelineAPI
|
|
8
|
-
from deepfos.api.models.deep_pipeline import RunInfo, FlowInfo
|
|
9
|
+
from deepfos.api.models.deep_pipeline import RunInfo, FlowInfo, RunInfoWithParam
|
|
9
10
|
from deepfos.element.base import ElementBase, SyncMeta
|
|
10
11
|
from deepfos.exceptions import (
|
|
11
12
|
APIResponseError, RunIdInvalid, RunTerminated,
|
|
12
13
|
ReleaseFlowTimeout, RunFailedError, ReleaseFlowNotExists,
|
|
13
14
|
)
|
|
14
15
|
from deepfos.lib.asynchronous import future_property
|
|
16
|
+
from deepfos.lib.constant import UNSET
|
|
15
17
|
from deepfos.lib.decorator import cached_property
|
|
16
18
|
|
|
17
19
|
errcode_map = {
|
|
@@ -47,7 +49,7 @@ class AsyncDeepPipeline(ElementBase[DeepPipelineAPI]):
|
|
|
47
49
|
|
|
48
50
|
async def run(
|
|
49
51
|
self,
|
|
50
|
-
parameter: Any =
|
|
52
|
+
parameter: Any = UNSET,
|
|
51
53
|
timeout: int = None,
|
|
52
54
|
in_process: bool = True,
|
|
53
55
|
) -> Any:
|
|
@@ -57,25 +59,29 @@ class AsyncDeepPipeline(ElementBase[DeepPipelineAPI]):
|
|
|
57
59
|
Args:
|
|
58
60
|
parameter: 执行参数
|
|
59
61
|
timeout: 超时时间(秒)
|
|
60
|
-
in_process:
|
|
62
|
+
in_process: 是否在同一个进程执行(仅作新旧兼容,实际只会在同一个进程执行,即不带启停启动)
|
|
61
63
|
|
|
62
64
|
Returns:
|
|
63
65
|
执行结果
|
|
64
66
|
"""
|
|
65
|
-
|
|
67
|
+
if not in_process:
|
|
68
|
+
warnings.warn(
|
|
69
|
+
'同步启动固定为同一个进程执行(不带启停启动),in_process参数为False不会影响该行为'
|
|
70
|
+
)
|
|
71
|
+
run_id = await self.run_async(parameter, True)
|
|
66
72
|
return await self.result(run_id, timeout)
|
|
67
73
|
|
|
68
74
|
async def run_async(
|
|
69
75
|
self,
|
|
70
|
-
parameter: Any =
|
|
71
|
-
in_process: bool =
|
|
76
|
+
parameter: Any = UNSET,
|
|
77
|
+
in_process: bool = False,
|
|
72
78
|
) -> str:
|
|
73
79
|
"""
|
|
74
80
|
异步启动数据流
|
|
75
81
|
|
|
76
82
|
Args:
|
|
77
83
|
parameter: 执行参数
|
|
78
|
-
in_process:
|
|
84
|
+
in_process: 是否在同一个进程执行,默认False,即带启停启动
|
|
79
85
|
|
|
80
86
|
Returns:
|
|
81
87
|
执行ID
|
|
@@ -83,14 +89,21 @@ class AsyncDeepPipeline(ElementBase[DeepPipelineAPI]):
|
|
|
83
89
|
if not self.has_approved_release:
|
|
84
90
|
raise ReleaseFlowNotExists('暂无启用中状态的数据流版本')
|
|
85
91
|
|
|
86
|
-
|
|
87
|
-
RunInfo(
|
|
92
|
+
if parameter is UNSET:
|
|
93
|
+
payload = RunInfo(
|
|
94
|
+
elementName=self.element_name,
|
|
95
|
+
folderId=self.element_info.folderId,
|
|
96
|
+
inProcess=in_process
|
|
97
|
+
)
|
|
98
|
+
else:
|
|
99
|
+
payload = RunInfoWithParam(
|
|
88
100
|
elementName=self.element_name,
|
|
89
101
|
parameter=parameter,
|
|
90
102
|
folderId=self.element_info.folderId,
|
|
91
103
|
inProcess=in_process
|
|
92
104
|
)
|
|
93
|
-
|
|
105
|
+
|
|
106
|
+
return await self.async_api.run.run_async(payload)
|
|
94
107
|
|
|
95
108
|
async def result(self, run_id: str, timeout: int = None) -> Any:
|
|
96
109
|
"""
|
|
@@ -134,14 +147,14 @@ class AsyncDeepPipeline(ElementBase[DeepPipelineAPI]):
|
|
|
134
147
|
async def run_batch(
|
|
135
148
|
self,
|
|
136
149
|
parameters: List[Any],
|
|
137
|
-
in_process: bool =
|
|
150
|
+
in_process: bool = False,
|
|
138
151
|
) -> List[str]:
|
|
139
152
|
"""
|
|
140
153
|
批量异步启动数据流
|
|
141
154
|
|
|
142
155
|
Args:
|
|
143
156
|
parameters: 执行参数列表
|
|
144
|
-
in_process:
|
|
157
|
+
in_process: 是否在同一个进程执行,默认False,即带启停启动
|
|
145
158
|
|
|
146
159
|
Returns:
|
|
147
160
|
执行ID列表
|
|
@@ -162,7 +175,7 @@ class DeepPipeline(AsyncDeepPipeline, metaclass=SyncMeta):
|
|
|
162
175
|
if TYPE_CHECKING: # pragma: no cover
|
|
163
176
|
def run(
|
|
164
177
|
self,
|
|
165
|
-
parameter: Any =
|
|
178
|
+
parameter: Any = UNSET,
|
|
166
179
|
timeout: int = None,
|
|
167
180
|
in_process: bool = True,
|
|
168
181
|
) -> Any:
|
|
@@ -170,8 +183,8 @@ class DeepPipeline(AsyncDeepPipeline, metaclass=SyncMeta):
|
|
|
170
183
|
|
|
171
184
|
def run_async(
|
|
172
185
|
self,
|
|
173
|
-
parameter: Any =
|
|
174
|
-
in_process: bool =
|
|
186
|
+
parameter: Any = UNSET,
|
|
187
|
+
in_process: bool = False,
|
|
175
188
|
) -> str:
|
|
176
189
|
...
|
|
177
190
|
|
|
@@ -181,6 +194,6 @@ class DeepPipeline(AsyncDeepPipeline, metaclass=SyncMeta):
|
|
|
181
194
|
def run_batch(
|
|
182
195
|
self,
|
|
183
196
|
parameters: List[Any],
|
|
184
|
-
in_process: bool =
|
|
197
|
+
in_process: bool = False,
|
|
185
198
|
):
|
|
186
199
|
...
|
deepfos/element/deepconnector.py
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import base64
|
|
2
|
+
import binascii
|
|
3
|
+
import os
|
|
2
4
|
|
|
3
5
|
from deepfos.api.deepconnector import DeepConnectorAPI
|
|
4
6
|
from deepfos.api.models import BaseModel
|
|
7
|
+
from deepfos.db.cipher import AES
|
|
5
8
|
from deepfos.element.base import ElementBase, SyncMeta
|
|
6
9
|
from deepfos.lib.asynchronous import future_property
|
|
7
10
|
from deepfos.lib.decorator import cached_property
|
|
@@ -9,6 +12,22 @@ from deepfos.lib.decorator import cached_property
|
|
|
9
12
|
__all__ = ['AsyncDeepConnector', 'DeepConnector', 'ConnectionInfo']
|
|
10
13
|
|
|
11
14
|
|
|
15
|
+
def decrypt(secret, cipher_text, encoding='utf8'):
|
|
16
|
+
pwd_padded = b''
|
|
17
|
+
for i in range(len(cipher_text))[::32]:
|
|
18
|
+
pwd_padded += AES(secret).decrypt(
|
|
19
|
+
base64.b16decode(cipher_text[i: i + 32])
|
|
20
|
+
)
|
|
21
|
+
if pwd_padded[-1] in range(1, 17):
|
|
22
|
+
pad_length = pwd_padded[-1]
|
|
23
|
+
pad_char = chr(pwd_padded[-1])
|
|
24
|
+
guess_pad = pad_char * pwd_padded[-1]
|
|
25
|
+
|
|
26
|
+
if pwd_padded.decode(encoding).endswith(guess_pad):
|
|
27
|
+
return pwd_padded.decode(encoding)[:-pad_length:]
|
|
28
|
+
return pwd_padded.decode(encoding)
|
|
29
|
+
|
|
30
|
+
|
|
12
31
|
class ConnectionInfo(BaseModel):
|
|
13
32
|
host: str
|
|
14
33
|
port: int
|
|
@@ -45,12 +64,28 @@ class AsyncDeepConnector(ElementBase[DeepConnectorAPI]):
|
|
|
45
64
|
info = await api.datasource.connection_info(
|
|
46
65
|
element_info=ele_info,
|
|
47
66
|
)
|
|
67
|
+
if info.encryptType == 'AES':
|
|
68
|
+
try:
|
|
69
|
+
password = decrypt(
|
|
70
|
+
os.environ.get('EXPORT_DEEPFOS_AES_KEY', '!ABCD-EFGH-IJKL@').encode(),
|
|
71
|
+
info.password,
|
|
72
|
+
encoding='utf-8'
|
|
73
|
+
)
|
|
74
|
+
except ValueError:
|
|
75
|
+
raise ValueError(
|
|
76
|
+
'连接器连接信息解密失败,请检查公共环境变量:EXPORT_DEEPFOS_AES_KEY'
|
|
77
|
+
) from None
|
|
78
|
+
else:
|
|
79
|
+
try:
|
|
80
|
+
password = base64.decodebytes(info.password.encode()).decode()
|
|
81
|
+
except binascii.Error:
|
|
82
|
+
password = info.password
|
|
48
83
|
return ConnectionInfo(
|
|
49
84
|
host=info.connectionHost,
|
|
50
85
|
port=info.connectionPort,
|
|
51
86
|
db=info.dbName,
|
|
52
87
|
user=info.username,
|
|
53
|
-
password=
|
|
88
|
+
password=password,
|
|
54
89
|
dbtype=info.serviceName,
|
|
55
90
|
)
|
|
56
91
|
|