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.
Files changed (175) hide show
  1. deepfos/__init__.py +6 -0
  2. deepfos/_version.py +21 -0
  3. deepfos/algo/__init__.py +0 -0
  4. deepfos/algo/graph.py +171 -0
  5. deepfos/algo/segtree.py +31 -0
  6. deepfos/api/V1_1/__init__.py +0 -0
  7. deepfos/api/V1_1/business_model.py +119 -0
  8. deepfos/api/V1_1/dimension.py +599 -0
  9. deepfos/api/V1_1/models/__init__.py +0 -0
  10. deepfos/api/V1_1/models/business_model.py +1033 -0
  11. deepfos/api/V1_1/models/dimension.py +2768 -0
  12. deepfos/api/V1_2/__init__.py +0 -0
  13. deepfos/api/V1_2/dimension.py +285 -0
  14. deepfos/api/V1_2/models/__init__.py +0 -0
  15. deepfos/api/V1_2/models/dimension.py +2923 -0
  16. deepfos/api/__init__.py +0 -0
  17. deepfos/api/account.py +167 -0
  18. deepfos/api/accounting_engines.py +147 -0
  19. deepfos/api/app.py +626 -0
  20. deepfos/api/approval_process.py +198 -0
  21. deepfos/api/base.py +983 -0
  22. deepfos/api/business_model.py +160 -0
  23. deepfos/api/consolidation.py +129 -0
  24. deepfos/api/consolidation_process.py +106 -0
  25. deepfos/api/datatable.py +341 -0
  26. deepfos/api/deep_pipeline.py +61 -0
  27. deepfos/api/deepconnector.py +36 -0
  28. deepfos/api/deepfos_task.py +92 -0
  29. deepfos/api/deepmodel.py +188 -0
  30. deepfos/api/dimension.py +486 -0
  31. deepfos/api/financial_model.py +319 -0
  32. deepfos/api/journal_model.py +119 -0
  33. deepfos/api/journal_template.py +132 -0
  34. deepfos/api/memory_financial_model.py +98 -0
  35. deepfos/api/models/__init__.py +3 -0
  36. deepfos/api/models/account.py +483 -0
  37. deepfos/api/models/accounting_engines.py +756 -0
  38. deepfos/api/models/app.py +1338 -0
  39. deepfos/api/models/approval_process.py +1043 -0
  40. deepfos/api/models/base.py +234 -0
  41. deepfos/api/models/business_model.py +805 -0
  42. deepfos/api/models/consolidation.py +711 -0
  43. deepfos/api/models/consolidation_process.py +248 -0
  44. deepfos/api/models/datatable_mysql.py +427 -0
  45. deepfos/api/models/deep_pipeline.py +55 -0
  46. deepfos/api/models/deepconnector.py +28 -0
  47. deepfos/api/models/deepfos_task.py +386 -0
  48. deepfos/api/models/deepmodel.py +308 -0
  49. deepfos/api/models/dimension.py +1576 -0
  50. deepfos/api/models/financial_model.py +1796 -0
  51. deepfos/api/models/journal_model.py +341 -0
  52. deepfos/api/models/journal_template.py +854 -0
  53. deepfos/api/models/memory_financial_model.py +478 -0
  54. deepfos/api/models/platform.py +178 -0
  55. deepfos/api/models/python.py +221 -0
  56. deepfos/api/models/reconciliation_engine.py +411 -0
  57. deepfos/api/models/reconciliation_report.py +161 -0
  58. deepfos/api/models/role_strategy.py +884 -0
  59. deepfos/api/models/smartlist.py +237 -0
  60. deepfos/api/models/space.py +1137 -0
  61. deepfos/api/models/system.py +1065 -0
  62. deepfos/api/models/variable.py +463 -0
  63. deepfos/api/models/workflow.py +946 -0
  64. deepfos/api/platform.py +199 -0
  65. deepfos/api/python.py +90 -0
  66. deepfos/api/reconciliation_engine.py +181 -0
  67. deepfos/api/reconciliation_report.py +64 -0
  68. deepfos/api/role_strategy.py +234 -0
  69. deepfos/api/smartlist.py +69 -0
  70. deepfos/api/space.py +582 -0
  71. deepfos/api/system.py +372 -0
  72. deepfos/api/variable.py +154 -0
  73. deepfos/api/workflow.py +264 -0
  74. deepfos/boost/__init__.py +6 -0
  75. deepfos/boost/py_jstream.py +89 -0
  76. deepfos/boost/py_pandas.py +20 -0
  77. deepfos/cache.py +121 -0
  78. deepfos/config.py +6 -0
  79. deepfos/core/__init__.py +27 -0
  80. deepfos/core/cube/__init__.py +10 -0
  81. deepfos/core/cube/_base.py +462 -0
  82. deepfos/core/cube/constants.py +21 -0
  83. deepfos/core/cube/cube.py +408 -0
  84. deepfos/core/cube/formula.py +707 -0
  85. deepfos/core/cube/syscube.py +532 -0
  86. deepfos/core/cube/typing.py +7 -0
  87. deepfos/core/cube/utils.py +238 -0
  88. deepfos/core/dimension/__init__.py +11 -0
  89. deepfos/core/dimension/_base.py +506 -0
  90. deepfos/core/dimension/dimcreator.py +184 -0
  91. deepfos/core/dimension/dimension.py +472 -0
  92. deepfos/core/dimension/dimexpr.py +271 -0
  93. deepfos/core/dimension/dimmember.py +155 -0
  94. deepfos/core/dimension/eledimension.py +22 -0
  95. deepfos/core/dimension/filters.py +99 -0
  96. deepfos/core/dimension/sysdimension.py +168 -0
  97. deepfos/core/logictable/__init__.py +5 -0
  98. deepfos/core/logictable/_cache.py +141 -0
  99. deepfos/core/logictable/_operator.py +663 -0
  100. deepfos/core/logictable/nodemixin.py +673 -0
  101. deepfos/core/logictable/sqlcondition.py +609 -0
  102. deepfos/core/logictable/tablemodel.py +497 -0
  103. deepfos/db/__init__.py +36 -0
  104. deepfos/db/cipher.py +660 -0
  105. deepfos/db/clickhouse.py +191 -0
  106. deepfos/db/connector.py +195 -0
  107. deepfos/db/daclickhouse.py +171 -0
  108. deepfos/db/dameng.py +101 -0
  109. deepfos/db/damysql.py +189 -0
  110. deepfos/db/dbkits.py +358 -0
  111. deepfos/db/deepengine.py +99 -0
  112. deepfos/db/deepmodel.py +82 -0
  113. deepfos/db/deepmodel_kingbase.py +83 -0
  114. deepfos/db/edb.py +214 -0
  115. deepfos/db/gauss.py +83 -0
  116. deepfos/db/kingbase.py +83 -0
  117. deepfos/db/mysql.py +184 -0
  118. deepfos/db/oracle.py +131 -0
  119. deepfos/db/postgresql.py +192 -0
  120. deepfos/db/sqlserver.py +99 -0
  121. deepfos/db/utils.py +135 -0
  122. deepfos/element/__init__.py +89 -0
  123. deepfos/element/accounting.py +348 -0
  124. deepfos/element/apvlprocess.py +215 -0
  125. deepfos/element/base.py +398 -0
  126. deepfos/element/bizmodel.py +1269 -0
  127. deepfos/element/datatable.py +2467 -0
  128. deepfos/element/deep_pipeline.py +186 -0
  129. deepfos/element/deepconnector.py +59 -0
  130. deepfos/element/deepmodel.py +1806 -0
  131. deepfos/element/dimension.py +1254 -0
  132. deepfos/element/fact_table.py +427 -0
  133. deepfos/element/finmodel.py +1485 -0
  134. deepfos/element/journal.py +840 -0
  135. deepfos/element/journal_template.py +943 -0
  136. deepfos/element/pyscript.py +412 -0
  137. deepfos/element/reconciliation.py +553 -0
  138. deepfos/element/rolestrategy.py +243 -0
  139. deepfos/element/smartlist.py +457 -0
  140. deepfos/element/variable.py +756 -0
  141. deepfos/element/workflow.py +560 -0
  142. deepfos/exceptions/__init__.py +239 -0
  143. deepfos/exceptions/hook.py +86 -0
  144. deepfos/lazy.py +104 -0
  145. deepfos/lazy_import.py +84 -0
  146. deepfos/lib/__init__.py +0 -0
  147. deepfos/lib/_javaobj.py +366 -0
  148. deepfos/lib/asynchronous.py +879 -0
  149. deepfos/lib/concurrency.py +107 -0
  150. deepfos/lib/constant.py +39 -0
  151. deepfos/lib/decorator.py +310 -0
  152. deepfos/lib/deepchart.py +778 -0
  153. deepfos/lib/deepux.py +477 -0
  154. deepfos/lib/discovery.py +273 -0
  155. deepfos/lib/edb_lexer.py +789 -0
  156. deepfos/lib/eureka.py +156 -0
  157. deepfos/lib/filterparser.py +751 -0
  158. deepfos/lib/httpcli.py +106 -0
  159. deepfos/lib/jsonstreamer.py +80 -0
  160. deepfos/lib/msg.py +394 -0
  161. deepfos/lib/nacos.py +225 -0
  162. deepfos/lib/patch.py +92 -0
  163. deepfos/lib/redis.py +241 -0
  164. deepfos/lib/serutils.py +181 -0
  165. deepfos/lib/stopwatch.py +99 -0
  166. deepfos/lib/subtask.py +572 -0
  167. deepfos/lib/sysutils.py +703 -0
  168. deepfos/lib/utils.py +1003 -0
  169. deepfos/local.py +160 -0
  170. deepfos/options.py +670 -0
  171. deepfos/translation.py +237 -0
  172. deepfos-1.1.60.dist-info/METADATA +33 -0
  173. deepfos-1.1.60.dist-info/RECORD +175 -0
  174. deepfos-1.1.60.dist-info/WHEEL +5 -0
  175. deepfos-1.1.60.dist-info/top_level.txt +1 -0
@@ -0,0 +1,756 @@
1
+ from enum import Enum
2
+ from typing import List, Dict, Union, Any, Callable, TYPE_CHECKING
3
+ import pandas as pd
4
+ import datetime
5
+
6
+ from deepfos.api.models.variable import VariableValueDTO, VariableVO, UpdateVariavlesDTO, ValueTypeMapDTO, \
7
+ BaseElementDetail
8
+ from deepfos.api.variable import VariableAPI
9
+ from deepfos.element.base import ElementBase, SyncMeta
10
+ from deepfos.element.dimension import Dimension
11
+ from deepfos.element.smartlist import SmartList
12
+ from deepfos.exceptions import VariableUpdateError, VariableCreateError
13
+ from deepfos.lib.utils import Group, GroupDict
14
+ from deepfos.lib.constant import UNSET
15
+ from deepfos.lib.asynchronous import future_property
16
+
17
+
18
+ __all__ = [
19
+ 'Variable',
20
+ 'AsyncVariable',
21
+ 'DateType'
22
+ ]
23
+
24
+
25
+ class GlobalVariable(VariableValueDTO):
26
+ description: dict = {'zh-cn': None, 'en': None}
27
+ scope: int = 1
28
+ status: bool = True
29
+
30
+
31
+ class UserVariable(VariableValueDTO):
32
+ description: dict = {'zh-cn': None, 'en': None}
33
+ scope: int = 2
34
+ status: bool = True
35
+
36
+
37
+ class VariableTypeId(int, Enum):
38
+ #: TEXT - 文本
39
+ TEXT = 1
40
+ #: NUMBER - 数字
41
+ NUMBER = 15
42
+ #: SML - 值列表
43
+ SML = 3
44
+ #: DIM - 维度
45
+ DIM = 8
46
+ #: DATE - 日期时间
47
+ DATE = 11
48
+ #: CUSTOM_LIST - 自定义列表
49
+ CUSTOM_LIST = 13
50
+
51
+
52
+ class DateType(str, Enum):
53
+ #: 年
54
+ year = "1"
55
+ #: 年月
56
+ year_month = "2"
57
+ #: 年月日
58
+ year_month_day = "3"
59
+ #: 年月日时间
60
+ year_month_day_time = "4"
61
+
62
+
63
+ class TextValueMap(ValueTypeMapDTO):
64
+ #: 变量类型代码
65
+ valueType: int = VariableTypeId.TEXT
66
+ valueKey: str = "1"
67
+ #: 文本长度
68
+ length: int = 255
69
+
70
+
71
+ class NumberValueMap(ValueTypeMapDTO):
72
+ #: 变量类型代码
73
+ valueType: int = VariableTypeId.NUMBER
74
+ #: 整数长度
75
+ maxLen: int = None
76
+ #: 小数长度
77
+ digitLen: int = None
78
+ #: 允许等于最小值
79
+ minEqual: bool = True
80
+ #: 最小值
81
+ minimun: int = None
82
+ #: 允许等于最大值
83
+ maxEqual: bool = True
84
+ #: 最大值
85
+ maximun: int = None
86
+ #: 是否显示为百分比
87
+ percentage: bool = False
88
+
89
+
90
+ class SmartListValueMap(ValueTypeMapDTO):
91
+ #: 变量类型代码
92
+ valueType: int = VariableTypeId.SML
93
+ #: 元素详情(由smartlist提取后的元素信息)
94
+ elementDetail: BaseElementDetail = None
95
+ #: 值列表元素名称
96
+ valueKey: str = None
97
+ #: 是否选择多个值列表成员
98
+ selectedMulti: bool = False
99
+ #: 多选值列表的成员值列表
100
+ valueField: List[str] = []
101
+ #: 多选成员数上限
102
+ multipleChoiceLimit: int = None
103
+
104
+
105
+ class DimensionValueMap(ValueTypeMapDTO):
106
+ #: 变量类型代码
107
+ valueType: int = VariableTypeId.DIM
108
+ #: 元素详情(由Dimension提取后的元素信息)
109
+ elementDetail: BaseElementDetail = None
110
+ #: 维度元素名称
111
+ dimensionName: str = None
112
+ #: 维度表达式
113
+ valueKey: str = None
114
+ #: 是否选择多个值列表成员
115
+ selectedMulti: bool = False
116
+ #: 多选成员数上限
117
+ multipleChoiceLimit: int = None
118
+
119
+
120
+ class DateValueMap(ValueTypeMapDTO):
121
+ #: 变量类型代码
122
+ valueType: int = VariableTypeId.DATE
123
+ #: 对应年份格式的编号字符串
124
+ valueKey: str = DateType.year_month_day_time
125
+
126
+
127
+ class CustomListValueMap(ValueTypeMapDTO):
128
+ #: 变量类型代码
129
+ valueType: int = VariableTypeId.CUSTOM_LIST
130
+ #: 自定义列表表达式(多个值请用“,”分开。示例: 1,2,3)
131
+ valueKey: str = None
132
+ #: 是否选择多个值列表成员
133
+ selectedMulti: bool = False
134
+ #: 多选成员数上限
135
+ multipleChoiceLimit: int = None
136
+
137
+
138
+ # -----------------------------------------------------------------------------
139
+ # typing
140
+ T_Number = Union[int, float]
141
+ T_Date = Union[pd.Timestamp, datetime.datetime, str]
142
+ T_Variable = Union[GlobalVariable, UserVariable]
143
+ T_VarValue = Union[T_Number, T_Date, List[str]]
144
+
145
+
146
+ def value_adaptor(var_type: int) -> Callable[[Any], str]:
147
+ if var_type == VariableTypeId.DATE:
148
+ def handle(value: T_Date):
149
+ if not isinstance(value, str):
150
+ value = value.strftime('%Y-%m-%d %H:%M:%S')
151
+ return value
152
+ elif var_type == VariableTypeId.NUMBER:
153
+ def handle(value: T_Number):
154
+ return str(value)
155
+ else:
156
+ def handle(value: Union[str, List[str]]):
157
+ if isinstance(value, list):
158
+ value = ','.join(map(str, value))
159
+ return value
160
+
161
+ def guard_none_handle(value):
162
+ if value is None:
163
+ return value
164
+ else:
165
+ return handle(value)
166
+
167
+ return guard_none_handle
168
+
169
+
170
+ # -----------------------------------------------------------------------------
171
+ # core
172
+ class AsyncVariable(ElementBase[VariableAPI]):
173
+ """变量
174
+
175
+ 为了防止将变量元素本身与变量元素保存的变量值混淆。在本节文档中,
176
+ 将变量元素称为 **“变量”** ,各变量值称为 **“变量成员”** 或简称为 **“成员”**。
177
+ """
178
+ def __init__(
179
+ self,
180
+ element_name: str,
181
+ folder_id: str = None,
182
+ path: str = None,
183
+ server_name: str = None,
184
+ ):
185
+ self.__group = Group()
186
+ self.__description = None
187
+ self.__gv_memo = None
188
+ self.__uv_memo = None
189
+ super().__init__(element_name=element_name, folder_id=folder_id, path=path, server_name=server_name)
190
+
191
+ @property
192
+ def _group(self) -> Group:
193
+ if self.__gv_memo is None:
194
+ _ = self._gv_memo
195
+ if self.__uv_memo is None:
196
+ _ = self._uv_memo
197
+ return self.__group
198
+
199
+ @property
200
+ def _gv_memo(self) -> GroupDict[str, GlobalVariable]:
201
+ if self.__gv_memo is None:
202
+ self.__gv_memo = GroupDict(self.__group)
203
+ for gv in self.meta.globalVariables:
204
+ self.__gv_memo[gv.name] = gv
205
+
206
+ return self.__gv_memo
207
+
208
+ @property
209
+ def _uv_memo(self) -> GroupDict[str, UserVariable]:
210
+ if self.__uv_memo is None:
211
+ self.__uv_memo = GroupDict(self.__group)
212
+ for uv in self.meta.userVariables:
213
+ self.__uv_memo[uv.name] = uv
214
+
215
+ return self.__uv_memo
216
+
217
+ @property
218
+ def _description(self) -> Dict[str, str]:
219
+ if not self.__description:
220
+ self.__description = self.meta.description
221
+
222
+ return self.__description
223
+
224
+ @future_property
225
+ async def meta(self) -> VariableVO:
226
+ """系统中的变量列表的元数据信息"""
227
+ api = await self.wait_for('async_api')
228
+ ele_info = await self.wait_for('element_info')
229
+ return await api.variable.query(
230
+ folderId=ele_info.folderId,
231
+ elementName=ele_info.elementName,
232
+ )
233
+
234
+ def __getitem__(self, name: str) -> T_VarValue:
235
+ """
236
+ 根据变量成员名获取成员值
237
+
238
+ 当为用户变量时,返回自定义变量
239
+
240
+ Args:
241
+ name: 变量成员名
242
+
243
+ Returns:
244
+ 变量的值
245
+
246
+ See Also:
247
+ - :meth:`get`
248
+ - :meth:`get_value`
249
+
250
+ """
251
+ return self.get_value(name, is_customize_value=True)
252
+
253
+ def get(self, name: str, default: str = None) -> T_VarValue:
254
+ """
255
+ 根据变量成员名获取成员值
256
+
257
+ 当为用户变量时,返回自定义变量
258
+
259
+ Args:
260
+ name: 变量成员名
261
+ default: 变量名不存在时的默认值
262
+
263
+ Returns:
264
+ 变量的值
265
+
266
+ See Also:
267
+ :meth:`get_value`
268
+
269
+ """
270
+ return self.get_value(name, is_customize_value=True, default=default)
271
+
272
+ @staticmethod
273
+ def _maybe_list(value, cast: Callable[[str], Any] = None):
274
+ if not value:
275
+ return value
276
+ if cast is None:
277
+ cast = lambda x: x
278
+ if len(val_list := value.split(',')) == 1:
279
+ return cast(val_list[0])
280
+ return [cast(val) for val in val_list]
281
+
282
+ def get_value(
283
+ self,
284
+ name: str,
285
+ is_customize_value: bool = True,
286
+ default: Any = UNSET,
287
+ auto_cast: bool = True,
288
+ obj_hook: Callable[[str], Any] = None
289
+ ) -> T_VarValue:
290
+ """
291
+ 根据变量成员名获取成员值
292
+
293
+ Args:
294
+ name: 变量成员名
295
+ is_customize_value: 是否为用户变量时配置的自定义值,在获取用户变量时会查看该值
296
+ default: 变量不存在时的默认值
297
+ auto_cast: 是否对变量值做自动转换
298
+ obj_hook: 自定义的变量转换函数
299
+
300
+
301
+ .. admonition:: 示例
302
+
303
+ 例如变量成员 ``ctm_list`` 为自定义列表,存的值为1,2,3。
304
+ 在使用默认参数的情况下,此方法将返回 ['1', '2', '3']。
305
+
306
+ 如果希望返回整数列表[1, 2, 3],可以传入 ``obj_hook`` 使用自定义逻辑
307
+
308
+ .. code-block:: python
309
+
310
+ var = Variable('test_var')
311
+
312
+ def hook(value):
313
+ return [int(v) for v in value.split(',')]
314
+
315
+ var.get_value('ctm_list', obj_hook=hook)
316
+
317
+ Returns:
318
+ 变量的值
319
+ """
320
+ if name in self._gv_memo:
321
+ var = self._gv_memo[name]
322
+ is_customize_value = False
323
+ elif name in self._uv_memo:
324
+ var = self._uv_memo[name]
325
+ elif default is UNSET:
326
+ raise KeyError(f"Variable : {name} not exist.")
327
+ else:
328
+ return default
329
+
330
+ value = var.userValue if is_customize_value else var.value
331
+
332
+ if obj_hook is not None:
333
+ return obj_hook(value)
334
+
335
+ if not auto_cast:
336
+ cast = None
337
+ elif var.valueType == VariableTypeId.NUMBER:
338
+ cast = float
339
+ elif var.valueType == VariableTypeId.DATE:
340
+ cast = pd.to_datetime
341
+ else:
342
+ cast = None
343
+
344
+ return self._maybe_list(value, cast)
345
+
346
+ def __setitem__(self, key: str, value: T_VarValue):
347
+ """更新变量成员的值
348
+
349
+ 根据变量名称与变量值,更新变量的值。全局变量时即为变量的值,
350
+
351
+ """
352
+ self.update_value(key, value, is_customize_value=True)
353
+
354
+ def update_value(
355
+ self,
356
+ name: str,
357
+ update_value: T_VarValue,
358
+ is_customize_value: bool = True
359
+ ):
360
+ """更新变量成员的值
361
+
362
+ 根据变量名称与变量值,更新变量的值。全局变量时即为变量的值,
363
+ 用户变量时即为自定义值,为用户变量默认值时,需置 ``is_customize_value`` 为
364
+ ``False``
365
+
366
+ Args:
367
+ name: 变量成员名称
368
+ update_value: 需更新的值
369
+ is_customize_value: 是否更新自定义值(仅对用户变量生效)
370
+ """
371
+ variable = self.get_variable(name)
372
+ value = value_adaptor(variable.valueType)(update_value)
373
+
374
+ if is_customize_value and name in self._uv_memo:
375
+ variable.userValue = value
376
+ else:
377
+ variable.value = value
378
+
379
+ async def save(self):
380
+ """
381
+ 保存变量
382
+
383
+ 将当前元素内变量信息保存至系统
384
+ """
385
+ payload = UpdateVariavlesDTO.construct_from(
386
+ self.meta, description=self._description,
387
+ globalVariables=list(self._gv_memo.values()),
388
+ userVariables=list(self._uv_memo.values()),
389
+ moduleId=self.api.module_id
390
+ )
391
+ return await self._update_impl(payload=payload)
392
+
393
+ async def _update_impl(self, payload: UpdateVariavlesDTO):
394
+ await self.async_api.variable.update(payload)
395
+ # 使memo的缓存失效
396
+ self.__gv_memo = None
397
+ self.__uv_memo = None
398
+ self.__description = None
399
+ self.__group.clear()
400
+ # 使meta重置
401
+ self.__class__.meta.reset(self)
402
+
403
+ @property
404
+ def variables(self) -> Dict[str, T_Variable]:
405
+ """
406
+ 所有变量成员
407
+
408
+ Returns:
409
+ 以name为键名,Variable为内容的字典
410
+ """
411
+ all_variable = {}
412
+ if self._gv_memo:
413
+ all_variable.update(self._gv_memo)
414
+ if self._uv_memo:
415
+ all_variable.update(self._uv_memo)
416
+ return all_variable
417
+
418
+ def get_variable(self, name: str) -> T_Variable:
419
+ """
420
+ 根据变量成员名获取成员
421
+
422
+ Args:
423
+ name: 变量成员名
424
+
425
+ Returns:
426
+ GlobalVariable或UserVariable类型的对象
427
+ """
428
+ if name in self._gv_memo:
429
+ return self._gv_memo[name]
430
+ elif name in self._uv_memo:
431
+ return self._uv_memo[name]
432
+ else:
433
+ raise KeyError(f"Variable : {name} not exist.")
434
+
435
+ def _add_variable(
436
+ self,
437
+ name: str,
438
+ value_map: Union[
439
+ TextValueMap, NumberValueMap, SmartListValueMap,
440
+ DimensionValueMap, DateValueMap, CustomListValueMap
441
+ ],
442
+ value: Union[str, List[str]],
443
+ description: Dict[str, str],
444
+ is_global: bool,
445
+ is_customize_value: bool
446
+ ):
447
+ """新增单个变量
448
+
449
+ Args:
450
+ name: 变量成员名
451
+ value_map: 变量类型
452
+ value: 变量值
453
+ description: 变量描述
454
+ is_global: 是否为全局变量
455
+ is_customize_value: 值是否为用户变量时配置的自定义值
456
+ """
457
+ if name in self._group.keys():
458
+ raise VariableCreateError(f"Variable: {name} already exist. "
459
+ "Please use update instead.")
460
+ if is_global:
461
+ self._gv_memo[name] = variable = \
462
+ GlobalVariable(
463
+ name=name,
464
+ valueType=value_map.valueType,
465
+ valueTypeMap=value_map
466
+ )
467
+ else:
468
+ self._uv_memo[name] = variable = \
469
+ UserVariable(
470
+ name=name,
471
+ valueType=value_map.valueType,
472
+ valueTypeMap=value_map
473
+ )
474
+
475
+ if description:
476
+ variable.description = description
477
+
478
+ if value:
479
+ self.update_value(name, value, is_customize_value)
480
+
481
+ def add_text(
482
+ self,
483
+ name: str,
484
+ value: Union[str, List[str]] = None,
485
+ description: Dict[str, str] = None,
486
+ is_global: bool = False,
487
+ is_customize_value: bool = True,
488
+ length: int = 255
489
+ ):
490
+ """新增单个文本变量成员
491
+
492
+ Args:
493
+ name: 变量成员名
494
+ value: 变量值
495
+ description: 变量描述
496
+ is_global: 是否为全局变量
497
+ is_customize_value: 值是否为用户变量时配置的自定义值
498
+ length: 文本长度
499
+
500
+ """
501
+ value = value_adaptor(VariableTypeId.TEXT)(value)
502
+ value_map = TextValueMap(length=length)
503
+ self._add_variable(name=name, value_map=value_map, value=value,
504
+ description=description,
505
+ is_customize_value=is_customize_value,
506
+ is_global=is_global)
507
+
508
+ def add_number(
509
+ self,
510
+ name: str,
511
+ value: T_Number = None,
512
+ description: Dict[str, str] = None,
513
+ is_global: bool = False,
514
+ is_customize_value: bool = True,
515
+ int_length: int = 13,
516
+ digit_length: int = 6,
517
+ min_equal: bool = True,
518
+ minimun: int = None,
519
+ max_equal: bool = True,
520
+ maximun: int = None,
521
+ percentage: bool = False
522
+ ):
523
+ """新增单个数字变量成员
524
+
525
+ Args:
526
+ name: 变量成员名
527
+ value: 变量值
528
+ description: 变量描述
529
+ is_global: 是否为全局变量
530
+ is_customize_value: 值是否为用户变量时配置的自定义值
531
+ int_length: 整数长度
532
+ digit_length: 小数长度
533
+ min_equal: 允许等于最小值
534
+ minimun: 最小值
535
+ max_equal: 允许等于最大值
536
+ maximun: 最大值
537
+ percentage: 是否显示为百分比
538
+
539
+ """
540
+ value = value_adaptor(VariableTypeId.NUMBER)(value)
541
+ value_map = NumberValueMap(maxLen=int_length, digitLen=digit_length, minEqual=min_equal, minimun=minimun,
542
+ maxEqual=max_equal, maximun=maximun, percentage=percentage)
543
+ self._add_variable(name=name, value_map=value_map, value=str(value),
544
+ description=description,
545
+ is_customize_value=is_customize_value,
546
+ is_global=is_global)
547
+
548
+ def add_smartlist(
549
+ self,
550
+ name: str,
551
+ smart_list: SmartList,
552
+ value: Union[str, List[str]] = None,
553
+ description: Dict[str, str] = None,
554
+ is_global: bool = False,
555
+ is_customize_value: bool = True,
556
+ selected_multi: bool = False,
557
+ multi_member_list: List[str] = None,
558
+ multiple_choice_limit: int = None
559
+ ):
560
+ """新增单个值列表变量成员
561
+
562
+ Args:
563
+ name: 变量成员名
564
+ smart_list: 值列表对象(必填)
565
+ value: 变量值
566
+ description: 变量描述
567
+ is_global: 是否为全局变量
568
+ is_customize_value: 值是否为用户变量时配置的自定义值
569
+ selected_multi: 是否选择多个值列表成员
570
+ multi_member_list: 多选值列表的成员值列表
571
+ multiple_choice_limit: 多选成员数上限
572
+ """
573
+ if multi_member_list is None:
574
+ multi_member_list = []
575
+
576
+ value = value_adaptor(VariableTypeId.SML)(value)
577
+
578
+ element_detail = BaseElementDetail.construct_from(smart_list.element_info, elementType="SML")
579
+ value_map = SmartListValueMap(elementDetail=element_detail,
580
+ valueKey=smart_list.element_info.elementName,
581
+ selectedMulti=selected_multi,
582
+ valueField=multi_member_list,
583
+ multipleChoiceLimit=multiple_choice_limit)
584
+
585
+ self._add_variable(name=name, value_map=value_map, value=value,
586
+ description=description,
587
+ is_customize_value=is_customize_value,
588
+ is_global=is_global)
589
+
590
+ def add_dimension(
591
+ self,
592
+ name: str,
593
+ dim: Dimension,
594
+ dim_expression: str,
595
+ value: Union[str, List[str]] = None,
596
+ description: Dict[str, str] = None,
597
+ is_global: bool = False,
598
+ is_customize_value: bool = True,
599
+ selected_multi: bool = False,
600
+ multiple_choice_limit: int = None
601
+ ):
602
+ """新增单个维度变量成员
603
+
604
+ Args:
605
+ name: 变量成员名
606
+ dim: 维度对象(必填)
607
+ dim_expression: 维度表达式(必填)
608
+ value: 变量值
609
+ description: 变量描述
610
+ is_global: 是否为全局变量
611
+ is_customize_value: 值是否为用户变量时配置的自定义值
612
+ selected_multi: 是否选择多个值列表成员
613
+ multiple_choice_limit: 多选成员数上限
614
+ """
615
+
616
+ value = value_adaptor(VariableTypeId.DIM)(value)
617
+ element_detail = BaseElementDetail.construct_from(dim.element_info, elementType="DIM")
618
+ value_map = DimensionValueMap(elementDetail=element_detail,
619
+ dimensionName=dim.element_info.elementName,
620
+ valueKey=dim_expression,
621
+ selectedMulti=selected_multi,
622
+ multipleChoiceLimit=multiple_choice_limit)
623
+
624
+ self._add_variable(name=name, value_map=value_map, value=value,
625
+ description=description,
626
+ is_customize_value=is_customize_value,
627
+ is_global=is_global)
628
+
629
+ def add_date(
630
+ self,
631
+ name: str,
632
+ date_format: str = DateType.year_month_day_time,
633
+ value: T_Date = None,
634
+ description: Dict[str, str] = None,
635
+ is_global: bool = False,
636
+ is_customize_value: bool = True
637
+ ):
638
+ """新增单个日期变量成员
639
+
640
+ Args:
641
+ name: 变量成员名
642
+ value: 变量值
643
+ date_format: 对应年份格式的编号(必填,建议使用枚举类DateType的值)
644
+ description: 变量描述
645
+ is_global: 是否为全局变量
646
+ is_customize_value: 值是否为用户变量时配置的自定义值
647
+
648
+ """
649
+ value = value_adaptor(VariableTypeId.DATE)(value)
650
+ value_map = DateValueMap(valueKey=date_format)
651
+ self._add_variable(name=name, value_map=value_map, value=value,
652
+ description=description,
653
+ is_customize_value=is_customize_value,
654
+ is_global=is_global)
655
+
656
+ def add_custom_list(
657
+ self,
658
+ name: str,
659
+ custom_list: List[Union[int, float]],
660
+ value: Union[str, List[str]] = None,
661
+ description: Dict[str, str] = None,
662
+ is_global: bool = False,
663
+ is_customize_value: bool = True,
664
+ selected_multi: bool = False,
665
+ multiple_choice_limit: int = None
666
+ ):
667
+ """新增单个自定义列表变量成员
668
+
669
+ Args:
670
+ name: 变量成员名
671
+ custom_list: 自定义列表
672
+ value: 变量值
673
+ description: 变量描述
674
+ is_global: 是否为全局变量
675
+ is_customize_value: 值是否为用户变量时配置的自定义值
676
+ selected_multi: 是否选择多个值列表成员
677
+ multiple_choice_limit: 多选成员数上限
678
+
679
+ """
680
+ value = value_adaptor(VariableTypeId.CUSTOM_LIST)(value)
681
+ list_expr = ','.join(map(str, custom_list))
682
+ value_map = CustomListValueMap(valueKey=list_expr,
683
+ selectedMulti=selected_multi,
684
+ multipleChoiceLimit=multiple_choice_limit)
685
+ self._add_variable(name=name, value_map=value_map, value=value,
686
+ description=description,
687
+ is_customize_value=is_customize_value,
688
+ is_global=is_global)
689
+
690
+ def _update_valuetype(
691
+ self,
692
+ name,
693
+ value_map: Union[
694
+ TextValueMap, NumberValueMap, SmartListValueMap,
695
+ DimensionValueMap, DateValueMap, CustomListValueMap]
696
+ ):
697
+ """根据变量名称与变量值,更新变量的变量类型(逻辑属性)
698
+
699
+ Args:
700
+ name: 变量成员名
701
+ value_map: 变量类型(逻辑属性)
702
+ """
703
+ variable = self.get_variable(name)
704
+ variable.valueType = value_map.valueType
705
+ variable.valueTypeMap = value_map
706
+
707
+ def update_description(
708
+ self,
709
+ name: str,
710
+ en_description: str = None,
711
+ zh_cn_description: str = None
712
+ ):
713
+ """根据变量成员名称,更新变量成员的描述
714
+
715
+ Args:
716
+ name: 变量成员名
717
+ en_description: 变量英文描述
718
+ zh_cn_description: 变量中文描述
719
+ """
720
+ description = {'zh-cn': zh_cn_description, 'en': en_description}
721
+ variable = self.get_variable(name)
722
+ variable.description = description
723
+
724
+ def delete_variables(self, *name: str, silent: bool = True):
725
+ """删除变量成员
726
+
727
+ 根据变量成员名列表删除多个变量
728
+
729
+ Args:
730
+ *name: 变量成员名
731
+ silent: 当变量不存在时,是报错还是静默处理。默认True, 即静默处理。
732
+ """
733
+ not_exist = []
734
+ for n in name:
735
+ if n in self._gv_memo:
736
+ del self._gv_memo[n]
737
+ elif n in self._uv_memo:
738
+ del self._uv_memo[n]
739
+ else:
740
+ not_exist.append(n)
741
+ if not_exist and not silent:
742
+ raise VariableUpdateError(f"Variable: {not_exist} not exist.")
743
+
744
+ def __contains__(self, item):
745
+ return item in self._group.keys()
746
+
747
+ def __len__(self):
748
+ return len(self._group.keys())
749
+
750
+
751
+ class Variable(AsyncVariable, metaclass=SyncMeta):
752
+ synchronize = ('save', )
753
+
754
+ if TYPE_CHECKING: # pragma: no cover
755
+ def save(self):
756
+ ...