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,234 @@
|
|
|
1
|
+
import json
|
|
2
|
+
from collections import defaultdict
|
|
3
|
+
|
|
4
|
+
from pydantic import BaseModel as PydanticBaseModel, Field, validator
|
|
5
|
+
from pydantic.fields import FieldInfo
|
|
6
|
+
# noinspection PyProtectedMember
|
|
7
|
+
from pydantic.main import ModelMetaclass
|
|
8
|
+
from pydantic.generics import GenericModel
|
|
9
|
+
from typing import Any, TypeVar, Generic, no_type_check, Dict
|
|
10
|
+
|
|
11
|
+
__all__ = [
|
|
12
|
+
"HeaderModel",
|
|
13
|
+
"Response",
|
|
14
|
+
"BaseModel",
|
|
15
|
+
"BaseModelPlus",
|
|
16
|
+
"Group",
|
|
17
|
+
"AutoField",
|
|
18
|
+
"GenericResponse",
|
|
19
|
+
"GResponse",
|
|
20
|
+
]
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class Group(FieldInfo):
|
|
24
|
+
def __init__(self, default, group_id, at_least=1, at_most=1, **kwargs):
|
|
25
|
+
"""
|
|
26
|
+
Args:
|
|
27
|
+
default: 默认值,同FieldInfo
|
|
28
|
+
group_id: 组ID,id相同并且属于同一个类的被视为同一组
|
|
29
|
+
at_least: 同组中至少需提供多少参数
|
|
30
|
+
at_most: 同组中至多可以提供多少参数
|
|
31
|
+
**kwargs: 同FieldInfo
|
|
32
|
+
"""
|
|
33
|
+
self.at_most = at_most
|
|
34
|
+
self.at_least = at_least
|
|
35
|
+
self.group_id = group_id
|
|
36
|
+
super().__init__(default, **kwargs)
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
class AutoField(FieldInfo):
|
|
40
|
+
pass
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def _enable_groupfield(group: Dict[str, Group]):
|
|
44
|
+
grp = list(group.values())[-1]
|
|
45
|
+
_field = list(group.keys())[-1]
|
|
46
|
+
at_least, at_most = grp.at_least, grp.at_most
|
|
47
|
+
restriction_msg = f"字段{list(group.keys())}至少需提供{at_least}个," \
|
|
48
|
+
f"至多{at_most}个。"
|
|
49
|
+
for g in group.values():
|
|
50
|
+
g.description = f"{g.description}({restriction_msg})"
|
|
51
|
+
|
|
52
|
+
# noinspection PyUnusedLocal
|
|
53
|
+
def _validator(cls, v, values, field):
|
|
54
|
+
assigned_fields = set(k for k, v in values.items() if v is not None)
|
|
55
|
+
if v is not None:
|
|
56
|
+
assigned_fields.add(field.name)
|
|
57
|
+
|
|
58
|
+
grp_assigned_fields = group.keys() & assigned_fields
|
|
59
|
+
if not at_least <= len(grp_assigned_fields) <= at_most:
|
|
60
|
+
if grp_assigned_fields:
|
|
61
|
+
field_info = f"实际赋值的字段为:{grp_assigned_fields}"
|
|
62
|
+
else:
|
|
63
|
+
field_info = "实际任何字段都未赋值。"
|
|
64
|
+
raise AssertionError(f"{restriction_msg}{field_info}")
|
|
65
|
+
|
|
66
|
+
return f"_validator_{grp.group_id}", \
|
|
67
|
+
validator(_field, always=True, allow_reuse=True)(_validator)
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
class MetaModel(ModelMetaclass):
|
|
71
|
+
@no_type_check # noqa C901
|
|
72
|
+
def __new__(mcs, name, bases, namespace, **kwargs): # noqa C901
|
|
73
|
+
groups = defaultdict(dict)
|
|
74
|
+
ann = namespace.get('__annotations__', {})
|
|
75
|
+
namespace['__autofields__'] = auto_fields = {}
|
|
76
|
+
|
|
77
|
+
for k, v in namespace.items():
|
|
78
|
+
if isinstance(v, Group):
|
|
79
|
+
groups[v.group_id][k] = v
|
|
80
|
+
if isinstance(v, AutoField):
|
|
81
|
+
auto_fields[k] = ann[k]
|
|
82
|
+
ann[k] = Any
|
|
83
|
+
|
|
84
|
+
for grp in groups.values():
|
|
85
|
+
k, v = _enable_groupfield(grp)
|
|
86
|
+
namespace[k] = v
|
|
87
|
+
|
|
88
|
+
cls = super().__new__(mcs, name, bases, namespace, **kwargs)
|
|
89
|
+
return cls
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
class BaseModel(PydanticBaseModel):
|
|
93
|
+
@classmethod
|
|
94
|
+
def construct_from(cls, *models: 'BaseModel', **extra):
|
|
95
|
+
"""
|
|
96
|
+
基于PydanticBaseModel.contruct,删除不在_fields_set中的属性
|
|
97
|
+
"""
|
|
98
|
+
fields_set = set(cls.__fields__.keys())
|
|
99
|
+
attrs = {}
|
|
100
|
+
for m in models:
|
|
101
|
+
attrs.update({
|
|
102
|
+
k: getattr(m, k)
|
|
103
|
+
for k in (m.__fields_set__ & fields_set)
|
|
104
|
+
})
|
|
105
|
+
attrs.update({
|
|
106
|
+
k: extra[k] for
|
|
107
|
+
k in (fields_set & extra.keys())
|
|
108
|
+
})
|
|
109
|
+
|
|
110
|
+
return cls.construct(fields_set, **attrs)
|
|
111
|
+
|
|
112
|
+
@classmethod
|
|
113
|
+
def quick_parse(cls, **fields):
|
|
114
|
+
# todo recursive parse dict to model
|
|
115
|
+
valid_fields = {}
|
|
116
|
+
|
|
117
|
+
for field_name, value in fields.items():
|
|
118
|
+
if field_name not in cls.__fields__:
|
|
119
|
+
continue
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
class BaseModelPlus(BaseModel, metaclass=MetaModel):
|
|
123
|
+
"""
|
|
124
|
+
可支持使用Group定义字段, AutoField定义字段
|
|
125
|
+
|
|
126
|
+
Examples:
|
|
127
|
+
GroupA = functools.partial(Group, group_id='aaa', at_most=2)
|
|
128
|
+
GroupB = functools.partial(Group, group_id='bbb')
|
|
129
|
+
|
|
130
|
+
class TestModel(GroupBaseModel):
|
|
131
|
+
a: str = GroupA(None, description='hello a')
|
|
132
|
+
b: str = GroupA(None, description='hello b')
|
|
133
|
+
c: int = GroupA(None, description='hello c')
|
|
134
|
+
d: int = GroupB(None, description='hello d')
|
|
135
|
+
e: int = GroupB(None, description='hello e')
|
|
136
|
+
|
|
137
|
+
按照上述定义的TestModel,在实例化时,a,b,c字段至少需提供1个,至多2个.
|
|
138
|
+
d, e字段至少提供1个,至多1个。
|
|
139
|
+
并且会在openapi中添加相应描述
|
|
140
|
+
"""
|
|
141
|
+
|
|
142
|
+
def __getattribute__(self, item):
|
|
143
|
+
attr = super().__getattribute__(item)
|
|
144
|
+
|
|
145
|
+
if item.startswith('__'):
|
|
146
|
+
return attr
|
|
147
|
+
if item not in self.__autofields__:
|
|
148
|
+
return attr
|
|
149
|
+
if not isinstance(attr, str):
|
|
150
|
+
return attr
|
|
151
|
+
|
|
152
|
+
model = self.__autofields__[item]
|
|
153
|
+
new_attr = model.construct_from(**json.loads(attr))
|
|
154
|
+
setattr(self, item, new_attr)
|
|
155
|
+
return new_attr
|
|
156
|
+
|
|
157
|
+
def dict(
|
|
158
|
+
self, *, include=None, exclude=None, by_alias=False, skip_defaults=None,
|
|
159
|
+
exclude_unset=False, exclude_defaults=False, exclude_none=False,
|
|
160
|
+
):
|
|
161
|
+
ori_dict = super().dict(
|
|
162
|
+
include=include,
|
|
163
|
+
exclude=exclude,
|
|
164
|
+
skip_defaults=skip_defaults,
|
|
165
|
+
by_alias=by_alias,
|
|
166
|
+
exclude_unset=exclude_unset,
|
|
167
|
+
exclude_defaults=exclude_defaults,
|
|
168
|
+
exclude_none=exclude_none,
|
|
169
|
+
)
|
|
170
|
+
for field in self.__autofields__:
|
|
171
|
+
if not isinstance(ori := ori_dict[field], str):
|
|
172
|
+
ori_dict[field] = json.dumps(ori)
|
|
173
|
+
return ori_dict
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
class HeaderModel(BaseModel):
|
|
177
|
+
app: str
|
|
178
|
+
space: str
|
|
179
|
+
user: str
|
|
180
|
+
language: str
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
class Response(BaseModel):
|
|
184
|
+
status: bool = Field(description='接口状态信息')
|
|
185
|
+
code: int = Field(None, description='接口错误码')
|
|
186
|
+
message: str = Field(None, description='接口错误信息')
|
|
187
|
+
data: Any = Field(None, description='接口返回值')
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
DataT = TypeVar('DataT')
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
class GenericResponse(GenericModel, Generic[DataT]):
|
|
194
|
+
status: bool = Field(description='接口状态信息')
|
|
195
|
+
code: int = Field(None, description='接口错误码')
|
|
196
|
+
message: str = Field(None, description='接口错误信息')
|
|
197
|
+
data: DataT = Field(None, description='接口返回值')
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
class GResponse:
|
|
201
|
+
"""
|
|
202
|
+
特殊的泛型响应模型类
|
|
203
|
+
用于更好地提供响应中data字段的文档信息
|
|
204
|
+
|
|
205
|
+
Examples:
|
|
206
|
+
``GResponse[str, description]`` 可以返回一个 GenericResponse[str] 类型,
|
|
207
|
+
并且description的内容可以展示在接口文档中。
|
|
208
|
+
"""
|
|
209
|
+
memo = {}
|
|
210
|
+
data_desc = Response.__fields__['data'].field_info.description
|
|
211
|
+
|
|
212
|
+
def __class_getitem__(cls, item):
|
|
213
|
+
model_key = (cls, item)
|
|
214
|
+
if model_key in cls.memo:
|
|
215
|
+
return cls.memo[model_key]
|
|
216
|
+
|
|
217
|
+
if isinstance(item, tuple):
|
|
218
|
+
*params, description = item
|
|
219
|
+
ann = item[0]
|
|
220
|
+
else:
|
|
221
|
+
params = (item, )
|
|
222
|
+
ann = item
|
|
223
|
+
description = cls.data_desc
|
|
224
|
+
|
|
225
|
+
model_name = f"Resp{GenericModel.__concrete_name__(params)}{description}"
|
|
226
|
+
|
|
227
|
+
data_field = Field(None, description=description)
|
|
228
|
+
|
|
229
|
+
model = type(model_name, (Response,), {
|
|
230
|
+
'__annotations__': {'data': ann},
|
|
231
|
+
'data': data_field
|
|
232
|
+
})
|
|
233
|
+
cls.memo[model_key] = model
|
|
234
|
+
return model
|