squirrels 0.3.2__py3-none-any.whl → 0.4.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.
Potentially problematic release.
This version of squirrels might be problematic. Click here for more details.
- squirrels/__init__.py +7 -3
- squirrels/_api_response_models.py +96 -72
- squirrels/_api_server.py +375 -201
- squirrels/_authenticator.py +23 -22
- squirrels/_command_line.py +70 -46
- squirrels/_connection_set.py +23 -25
- squirrels/_constants.py +29 -78
- squirrels/_dashboards_io.py +61 -0
- squirrels/_environcfg.py +53 -50
- squirrels/_initializer.py +184 -141
- squirrels/_manifest.py +168 -195
- squirrels/_models.py +159 -292
- squirrels/_package_loader.py +7 -8
- squirrels/_parameter_configs.py +173 -141
- squirrels/_parameter_sets.py +49 -38
- squirrels/_py_module.py +7 -7
- squirrels/_seeds.py +13 -12
- squirrels/_utils.py +114 -54
- squirrels/_version.py +1 -1
- squirrels/arguments/init_time_args.py +16 -10
- squirrels/arguments/run_time_args.py +89 -24
- squirrels/dashboards.py +82 -0
- squirrels/data_sources.py +212 -232
- squirrels/dateutils.py +29 -26
- squirrels/package_data/assets/index.css +1 -1
- squirrels/package_data/assets/index.js +27 -18
- squirrels/package_data/base_project/.gitignore +2 -2
- squirrels/package_data/base_project/connections.yml +1 -1
- squirrels/package_data/base_project/dashboards/dashboard_example.py +32 -0
- squirrels/package_data/base_project/dashboards.yml +10 -0
- squirrels/package_data/base_project/docker/.dockerignore +9 -4
- squirrels/package_data/base_project/docker/Dockerfile +7 -6
- squirrels/package_data/base_project/docker/compose.yml +1 -1
- squirrels/package_data/base_project/env.yml +2 -2
- squirrels/package_data/base_project/models/dbviews/{database_view1.py → dbview_example.py} +2 -1
- squirrels/package_data/base_project/models/dbviews/{database_view1.sql → dbview_example.sql} +3 -2
- squirrels/package_data/base_project/models/federates/{dataset_example.py → federate_example.py} +6 -6
- squirrels/package_data/base_project/models/federates/{dataset_example.sql → federate_example.sql} +1 -1
- squirrels/package_data/base_project/parameters.yml +6 -4
- squirrels/package_data/base_project/pyconfigs/auth.py +1 -1
- squirrels/package_data/base_project/pyconfigs/connections.py +1 -1
- squirrels/package_data/base_project/pyconfigs/context.py +38 -10
- squirrels/package_data/base_project/pyconfigs/parameters.py +15 -7
- squirrels/package_data/base_project/squirrels.yml.j2 +14 -7
- squirrels/package_data/templates/index.html +3 -3
- squirrels/parameter_options.py +103 -106
- squirrels/parameters.py +347 -195
- squirrels/project.py +378 -0
- squirrels/user_base.py +14 -6
- {squirrels-0.3.2.dist-info → squirrels-0.4.0.dist-info}/METADATA +12 -23
- squirrels-0.4.0.dist-info/RECORD +60 -0
- squirrels/_timer.py +0 -23
- squirrels-0.3.2.dist-info/RECORD +0 -56
- {squirrels-0.3.2.dist-info → squirrels-0.4.0.dist-info}/LICENSE +0 -0
- {squirrels-0.3.2.dist-info → squirrels-0.4.0.dist-info}/WHEEL +0 -0
- {squirrels-0.3.2.dist-info → squirrels-0.4.0.dist-info}/entry_points.txt +0 -0
squirrels/parameters.py
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
|
-
from typing import Callable, Type,
|
|
2
|
+
from typing import Callable, Type, TypeVar, Sequence, Any
|
|
3
3
|
from dataclasses import dataclass
|
|
4
4
|
from datetime import datetime, date
|
|
5
5
|
from decimal import Decimal
|
|
6
6
|
from abc import ABCMeta, abstractmethod
|
|
7
7
|
|
|
8
|
-
from . import _parameter_configs as
|
|
9
|
-
from . import _api_response_models as arm, _utils as
|
|
8
|
+
from . import _parameter_configs as _pc, _parameter_sets as ps, parameter_options as _po, data_sources as d
|
|
9
|
+
from . import _api_response_models as arm, _utils as _u
|
|
10
|
+
|
|
11
|
+
IntOrFloat = TypeVar("IntOrFloat", int, float)
|
|
10
12
|
|
|
11
13
|
|
|
12
14
|
@dataclass
|
|
@@ -14,7 +16,7 @@ class Parameter(metaclass=ABCMeta):
|
|
|
14
16
|
"""
|
|
15
17
|
Abstract class for all parameter widgets
|
|
16
18
|
"""
|
|
17
|
-
_config:
|
|
19
|
+
_config: _pc.ParameterConfig
|
|
18
20
|
|
|
19
21
|
@abstractmethod
|
|
20
22
|
def is_enabled(self) -> bool:
|
|
@@ -22,18 +24,39 @@ class Parameter(metaclass=ABCMeta):
|
|
|
22
24
|
|
|
23
25
|
@staticmethod
|
|
24
26
|
@abstractmethod
|
|
25
|
-
def _ParameterConfigType() -> Type:
|
|
27
|
+
def _ParameterConfigType() -> Type[_pc.ParameterConfig]:
|
|
26
28
|
pass
|
|
27
29
|
|
|
30
|
+
@classmethod
|
|
31
|
+
def _CreateWithOptionsHelper(
|
|
32
|
+
cls, name: str, label: str, all_options: Sequence[_po.ParameterOption | dict], *, description: str = "",
|
|
33
|
+
user_attribute: str | None = None, parent_name: str | None = None, **kwargs
|
|
34
|
+
) -> None:
|
|
35
|
+
param_config_type = cls._ParameterConfigType()
|
|
36
|
+
param_config = param_config_type(
|
|
37
|
+
name, label, all_options, description=description, user_attribute=user_attribute, parent_name=parent_name, **kwargs
|
|
38
|
+
)
|
|
39
|
+
ps.ParameterConfigsSetIO.obj.add(param_config)
|
|
40
|
+
|
|
41
|
+
@classmethod
|
|
42
|
+
def Create(
|
|
43
|
+
cls, name: str, label: str, all_options: Sequence[_po.ParameterOption | dict], *, description: str = "",
|
|
44
|
+
user_attribute: str | None = None, parent_name: str | None = None, **kwargs
|
|
45
|
+
) -> None:
|
|
46
|
+
"""
|
|
47
|
+
DEPRECATED. Use CreateWithOptions instead
|
|
48
|
+
"""
|
|
49
|
+
cls._CreateWithOptionsHelper(name, label, all_options, description=description, user_attribute=user_attribute, parent_name=parent_name)
|
|
50
|
+
|
|
28
51
|
@classmethod
|
|
29
52
|
def CreateWithOptions(
|
|
30
|
-
cls, name: str, label: str, all_options: Sequence[
|
|
31
|
-
user_attribute:
|
|
53
|
+
cls, name: str, label: str, all_options: Sequence[_po.ParameterOption | dict], *, description: str = "",
|
|
54
|
+
user_attribute: str | None = None, parent_name: str | None = None, **kwargs
|
|
32
55
|
) -> None:
|
|
33
56
|
"""
|
|
34
57
|
Method for creating the configurations for a Parameter that may include user attribute or parent
|
|
35
58
|
|
|
36
|
-
|
|
59
|
+
Arguments:
|
|
37
60
|
name: The name of the parameter
|
|
38
61
|
label: The display label for the parameter
|
|
39
62
|
all_options: All options associated to this parameter regardless of the user group or parent parameter option they depend on
|
|
@@ -41,35 +64,33 @@ class Parameter(metaclass=ABCMeta):
|
|
|
41
64
|
user_attribute: The user attribute that may cascade the options for this parameter. Default is None
|
|
42
65
|
parent_name: Name of parent parameter that may cascade the options for this parameter. Default is None (no parent)
|
|
43
66
|
"""
|
|
44
|
-
|
|
45
|
-
param_config = param_config_type(name, label, all_options, description=description, user_attribute=user_attribute,
|
|
46
|
-
parent_name=parent_name)
|
|
47
|
-
ps.ParameterConfigsSetIO.obj.add(param_config)
|
|
48
|
-
|
|
49
|
-
@classmethod
|
|
50
|
-
def Create(
|
|
51
|
-
cls, name: str, label: str, all_options: Sequence[Union[po.ParameterOption, dict]], *, description: str = "",
|
|
52
|
-
user_attribute: Optional[str] = None, parent_name: Optional[str] = None, **kwargs
|
|
53
|
-
) -> None:
|
|
54
|
-
"""
|
|
55
|
-
DEPRECATED. Use CreateWithOptions instead
|
|
56
|
-
"""
|
|
57
|
-
cls.CreateWithOptions(name, label, all_options, description=description, user_attribute=user_attribute, parent_name=parent_name)
|
|
67
|
+
cls._CreateWithOptionsHelper(name, label, all_options, description=description, user_attribute=user_attribute, parent_name=parent_name)
|
|
58
68
|
|
|
59
69
|
@classmethod
|
|
60
70
|
@abstractmethod
|
|
61
71
|
def CreateSimple(cls, name: str, label: str, *args, description: str = "", **kwargs) -> None:
|
|
62
72
|
pass
|
|
73
|
+
|
|
74
|
+
@classmethod
|
|
75
|
+
def _CreateFromSourceHelper(
|
|
76
|
+
cls, name: str, label: str, data_source: d.DataSource | dict, *, extra_args: dict = {}, description: str = "",
|
|
77
|
+
user_attribute: str | None = None, parent_name: str | None = None
|
|
78
|
+
) -> None:
|
|
79
|
+
param_config = _pc.DataSourceParameterConfig(
|
|
80
|
+
cls._ParameterConfigType(), name, label, data_source, description=description, user_attribute=user_attribute,
|
|
81
|
+
parent_name=parent_name, extra_args=extra_args
|
|
82
|
+
)
|
|
83
|
+
ps.ParameterConfigsSetIO.obj.add(param_config)
|
|
63
84
|
|
|
64
85
|
@classmethod
|
|
65
86
|
def CreateFromSource(
|
|
66
|
-
cls, name: str, label: str, data_source:
|
|
67
|
-
user_attribute:
|
|
87
|
+
cls, name: str, label: str, data_source: d.DataSource | dict, *, description: str = "",
|
|
88
|
+
user_attribute: str | None = None, parent_name: str | None = None, **kwargs
|
|
68
89
|
) -> None:
|
|
69
90
|
"""
|
|
70
91
|
Method for creating the configurations for any Parameter that uses a DataSource to receive the options
|
|
71
92
|
|
|
72
|
-
|
|
93
|
+
Arguments:
|
|
73
94
|
name: The name of the parameter
|
|
74
95
|
label: The display label for the parameter
|
|
75
96
|
data_source: The lookup table to use for this parameter
|
|
@@ -77,25 +98,28 @@ class Parameter(metaclass=ABCMeta):
|
|
|
77
98
|
user_attribute: The user attribute that may cascade the options for this parameter. Default is None
|
|
78
99
|
parent_name: Name of parent parameter that may cascade the options for this parameter. Default is None (no parent)
|
|
79
100
|
"""
|
|
80
|
-
|
|
81
|
-
param_config = pc.DataSourceParameterConfig(param_config_type, name, label, data_source, description=description,
|
|
82
|
-
user_attribute=user_attribute, parent_name=parent_name)
|
|
83
|
-
ps.ParameterConfigsSetIO.obj.add(param_config)
|
|
101
|
+
cls._CreateFromSourceHelper(name, label, data_source, description=description, user_attribute=user_attribute, parent_name=parent_name)
|
|
84
102
|
|
|
85
103
|
def _enquote(self, value: str) -> str:
|
|
86
104
|
return "'" + value.replace("'", "''") + "'"
|
|
87
105
|
|
|
88
|
-
def
|
|
106
|
+
def _validate_input_date(self, input_date: date | str, curr_option: _po._DateTypeParameterOption) -> date:
|
|
107
|
+
if isinstance(input_date, str):
|
|
108
|
+
try:
|
|
109
|
+
input_date = datetime.strptime(input_date.strip(), "%Y-%m-%d").date()
|
|
110
|
+
except ValueError:
|
|
111
|
+
raise self._config._invalid_input_error(str(input_date), "Must be a date in YYYY-MM-DD format.")
|
|
112
|
+
|
|
89
113
|
try:
|
|
90
|
-
return
|
|
91
|
-
except
|
|
92
|
-
self._config.
|
|
114
|
+
return curr_option._validate_date(input_date)
|
|
115
|
+
except _u.ConfigurationError as e:
|
|
116
|
+
raise self._config._invalid_input_error(str(input_date), str(e))
|
|
93
117
|
|
|
94
|
-
def _validate_number(self, input_number:
|
|
118
|
+
def _validate_number(self, input_number: _po.Number, curr_option: _po._NumericParameterOption) -> Decimal:
|
|
95
119
|
try:
|
|
96
120
|
return curr_option._validate_value(input_number)
|
|
97
|
-
except
|
|
98
|
-
self._config.
|
|
121
|
+
except _u.ConfigurationError as e:
|
|
122
|
+
raise self._config._invalid_input_error(str(input_number), str(e))
|
|
99
123
|
|
|
100
124
|
@abstractmethod
|
|
101
125
|
def _to_json_dict0(self) -> dict:
|
|
@@ -120,8 +144,8 @@ class Parameter(metaclass=ABCMeta):
|
|
|
120
144
|
|
|
121
145
|
@dataclass
|
|
122
146
|
class _SelectionParameter(Parameter):
|
|
123
|
-
_config:
|
|
124
|
-
_options: Sequence[
|
|
147
|
+
_config: _pc.SelectionParameterConfig
|
|
148
|
+
_options: Sequence[_po.SelectParameterOption]
|
|
125
149
|
|
|
126
150
|
def __post_init__(self):
|
|
127
151
|
self._options = tuple(self._options)
|
|
@@ -135,7 +159,7 @@ class _SelectionParameter(Parameter):
|
|
|
135
159
|
|
|
136
160
|
def _validate_selected_id_in_options(self, selected_id):
|
|
137
161
|
if selected_id not in (x._identifier for x in self._options):
|
|
138
|
-
self._config.
|
|
162
|
+
raise self._config._invalid_input_error(selected_id, f"The selected id {selected_id} does not exist in available options.")
|
|
139
163
|
|
|
140
164
|
@abstractmethod
|
|
141
165
|
def _to_json_dict0(self) -> dict:
|
|
@@ -158,8 +182,8 @@ class SingleSelectParameter(_SelectionParameter):
|
|
|
158
182
|
options: The parameter options that are currently selectable
|
|
159
183
|
selected_id: The ID of the selected option
|
|
160
184
|
"""
|
|
161
|
-
_config:
|
|
162
|
-
_selected_id:
|
|
185
|
+
_config: _pc.SingleSelectParameterConfig
|
|
186
|
+
_selected_id: str | None
|
|
163
187
|
|
|
164
188
|
def __post_init__(self):
|
|
165
189
|
super().__post_init__()
|
|
@@ -171,16 +195,16 @@ class SingleSelectParameter(_SelectionParameter):
|
|
|
171
195
|
|
|
172
196
|
@staticmethod
|
|
173
197
|
def _ParameterConfigType():
|
|
174
|
-
return
|
|
198
|
+
return _pc.SingleSelectParameterConfig
|
|
175
199
|
|
|
176
200
|
@classmethod
|
|
177
201
|
def CreateSimple(
|
|
178
|
-
cls, name: str, label: str, all_options: Sequence[
|
|
202
|
+
cls, name: str, label: str, all_options: Sequence[_po.SelectParameterOption], *, description: str = "", **kwargs
|
|
179
203
|
) -> None:
|
|
180
204
|
"""
|
|
181
205
|
Method for creating the configurations for a Parameter that doesn't involve user attributes or parent parameters
|
|
182
206
|
|
|
183
|
-
|
|
207
|
+
Arguments:
|
|
184
208
|
name: The name of the parameter
|
|
185
209
|
label: The display label for the parameter
|
|
186
210
|
all_options: All options associated to this parameter regardless of the user group or parent parameter option they depend on
|
|
@@ -189,12 +213,12 @@ class SingleSelectParameter(_SelectionParameter):
|
|
|
189
213
|
cls.CreateWithOptions(name, label, all_options, description=description)
|
|
190
214
|
|
|
191
215
|
def get_selected(
|
|
192
|
-
self, field:
|
|
193
|
-
) ->
|
|
216
|
+
self, field: str | None = None, *, default_field: str | None = None, default: Any = None, **kwargs
|
|
217
|
+
) -> _po.SelectParameterOption | Any | None:
|
|
194
218
|
"""
|
|
195
219
|
Gets the selected single-select option or selected custom field
|
|
196
220
|
|
|
197
|
-
|
|
221
|
+
Arguments:
|
|
198
222
|
field: If field is not None, the method gets this field from the "custom_fields" attribute of the selected option.
|
|
199
223
|
Otherwise, returns the class object of the selected option
|
|
200
224
|
default_field: If field does not exist for a parameter option and default_field is not None, the default_field is used
|
|
@@ -210,50 +234,76 @@ class SingleSelectParameter(_SelectionParameter):
|
|
|
210
234
|
if field is not None:
|
|
211
235
|
selected = selected.get_custom_field(field, default_field=default_field, default=default)
|
|
212
236
|
return selected
|
|
213
|
-
return
|
|
237
|
+
return _u.process_if_not_none(self._selected_id, get_selected_from_id)
|
|
238
|
+
|
|
239
|
+
def get_selected_quoted(self, field: str, *, default_field: str | None = None, default: str | None = None, **kwargs) -> str | None:
|
|
240
|
+
"""
|
|
241
|
+
Gets the selected single-select option surrounded by single quotes
|
|
242
|
+
|
|
243
|
+
Arguments:
|
|
244
|
+
field: The "custom_fields" attribute of the selected option.
|
|
245
|
+
default_field: If field does not exist for a parameter option and default_field is not None, the default_field is used
|
|
246
|
+
as the "field" instead.
|
|
247
|
+
default: If field does not exist for a parameter option, default_field is None, but default is not None, then the default
|
|
248
|
+
is returned as the selected field. Does nothing if default_field is not None
|
|
249
|
+
|
|
250
|
+
Returns:
|
|
251
|
+
A string surrounded by single quotes
|
|
252
|
+
"""
|
|
253
|
+
selected_value = self.get_selected(field, default_field=default_field, default=default)
|
|
254
|
+
|
|
255
|
+
def _enquote(x: Any) -> str:
|
|
256
|
+
if not isinstance(selected_value, str):
|
|
257
|
+
raise _u.ConfigurationError(
|
|
258
|
+
f"Method 'get_selected_quoted' can only be used on fields with only string values"
|
|
259
|
+
)
|
|
260
|
+
return self._enquote(x)
|
|
261
|
+
|
|
262
|
+
return _u.process_if_not_none(selected_value, _enquote)
|
|
214
263
|
|
|
215
|
-
def get_selected_id(self, **kwargs) ->
|
|
264
|
+
def get_selected_id(self, **kwargs) -> str | None:
|
|
216
265
|
"""
|
|
217
266
|
Gets the ID of the selected option
|
|
218
267
|
|
|
219
268
|
Returns:
|
|
220
269
|
A string ID or None if there are no selectable options
|
|
221
270
|
"""
|
|
222
|
-
def get_id(x:
|
|
223
|
-
|
|
271
|
+
def get_id(x: _po.SelectParameterOption):
|
|
272
|
+
return x._identifier
|
|
273
|
+
return _u.process_if_not_none(self.get_selected(), get_id)
|
|
224
274
|
|
|
225
|
-
def get_selected_id_quoted(self, **kwargs) ->
|
|
275
|
+
def get_selected_id_quoted(self, **kwargs) -> str | None:
|
|
226
276
|
"""
|
|
227
277
|
Gets the ID of the selected option surrounded by single quotes
|
|
228
278
|
|
|
229
279
|
Returns:
|
|
230
280
|
A string or None if there are no selectable options
|
|
231
281
|
"""
|
|
232
|
-
return
|
|
282
|
+
return _u.process_if_not_none(self.get_selected_id(), self._enquote)
|
|
233
283
|
|
|
234
|
-
def get_selected_label(self, **kwargs) ->
|
|
284
|
+
def get_selected_label(self, **kwargs) -> str | None:
|
|
235
285
|
"""
|
|
236
286
|
Gets the label of the selected option
|
|
237
287
|
|
|
238
288
|
Returns:
|
|
239
289
|
A string or None if there are no selectable options
|
|
240
290
|
"""
|
|
241
|
-
def get_label(x:
|
|
242
|
-
return
|
|
291
|
+
def get_label(x: _po.SelectParameterOption): return x._label
|
|
292
|
+
return _u.process_if_not_none(self.get_selected(), get_label)
|
|
243
293
|
|
|
244
|
-
def get_selected_label_quoted(self, **kwargs) ->
|
|
294
|
+
def get_selected_label_quoted(self, **kwargs) -> str | None:
|
|
245
295
|
"""
|
|
246
296
|
Gets the label of the selected option surrounded by single quotes
|
|
247
297
|
|
|
248
298
|
Returns:
|
|
249
299
|
A string or None if there are no selectable options
|
|
250
300
|
"""
|
|
251
|
-
return
|
|
301
|
+
return _u.process_if_not_none(self.get_selected_label(), self._enquote)
|
|
252
302
|
|
|
253
303
|
def _get_selected_ids_as_list(self) -> Sequence[str]:
|
|
254
304
|
selected_id = self.get_selected_id()
|
|
255
305
|
if selected_id is not None:
|
|
256
|
-
return (
|
|
306
|
+
return (selected_id,)
|
|
257
307
|
else:
|
|
258
308
|
return tuple()
|
|
259
309
|
|
|
@@ -269,7 +319,7 @@ class SingleSelectParameter(_SelectionParameter):
|
|
|
269
319
|
return output
|
|
270
320
|
|
|
271
321
|
def _get_response_model0(self):
|
|
272
|
-
return arm.SingleSelectParameterModel
|
|
322
|
+
return arm.SingleSelectParameterModel if self.is_enabled() else arm.NoneParameterModel
|
|
273
323
|
|
|
274
324
|
|
|
275
325
|
@dataclass
|
|
@@ -282,7 +332,7 @@ class MultiSelectParameter(_SelectionParameter):
|
|
|
282
332
|
options: The parameter options that are currently selectable
|
|
283
333
|
selected_ids: A sequence of IDs of the selected options
|
|
284
334
|
"""
|
|
285
|
-
_config:
|
|
335
|
+
_config: _pc.MultiSelectParameterConfig
|
|
286
336
|
_selected_ids: Sequence[str]
|
|
287
337
|
|
|
288
338
|
def __post_init__(self):
|
|
@@ -293,18 +343,18 @@ class MultiSelectParameter(_SelectionParameter):
|
|
|
293
343
|
|
|
294
344
|
@staticmethod
|
|
295
345
|
def _ParameterConfigType():
|
|
296
|
-
return
|
|
346
|
+
return _pc.MultiSelectParameterConfig
|
|
297
347
|
|
|
298
348
|
@classmethod
|
|
299
349
|
def CreateWithOptions(
|
|
300
|
-
cls, name: str, label: str, all_options: Sequence[
|
|
350
|
+
cls, name: str, label: str, all_options: Sequence[_po.SelectParameterOption | dict], *, description: str = "",
|
|
301
351
|
show_select_all: bool = True, order_matters: bool = False, none_is_all: bool = True,
|
|
302
|
-
user_attribute:
|
|
352
|
+
user_attribute: str | None = None, parent_name: str | None = None, **kwargs
|
|
303
353
|
) -> None:
|
|
304
354
|
"""
|
|
305
355
|
Method for creating the configurations for a MultiSelectParameter that may include user attribute or parent
|
|
306
356
|
|
|
307
|
-
|
|
357
|
+
Arguments:
|
|
308
358
|
name: The name of the parameter
|
|
309
359
|
label: The display label for the parameter
|
|
310
360
|
all_options: All options associated to this parameter regardless of the user group or parent parameter option they depend on
|
|
@@ -315,35 +365,34 @@ class MultiSelectParameter(_SelectionParameter):
|
|
|
315
365
|
user_attribute: The user attribute that may cascade the options for this parameter. Default is None
|
|
316
366
|
parent_name: Name of parent parameter that may cascade the options for this parameter. Default is None (no parent)
|
|
317
367
|
"""
|
|
318
|
-
|
|
368
|
+
cls._CreateWithOptionsHelper(
|
|
319
369
|
name, label, all_options, description=description, user_attribute=user_attribute, parent_name=parent_name,
|
|
320
370
|
show_select_all=show_select_all, order_matters=order_matters, none_is_all=none_is_all
|
|
321
371
|
)
|
|
322
|
-
ps.ParameterConfigsSetIO.obj.add(param_config)
|
|
323
372
|
|
|
324
373
|
@classmethod
|
|
325
374
|
def Create(
|
|
326
|
-
cls, name: str, label: str, all_options: Sequence[
|
|
375
|
+
cls, name: str, label: str, all_options: Sequence[_po.SelectParameterOption | dict], *, description: str = "",
|
|
327
376
|
show_select_all: bool = True, order_matters: bool = False, none_is_all: bool = True,
|
|
328
|
-
user_attribute:
|
|
377
|
+
user_attribute: str | None = None, parent_name: str | None = None, **kwargs
|
|
329
378
|
) -> None:
|
|
330
379
|
"""
|
|
331
380
|
DEPRECATED. Use CreateWithOptions instead
|
|
332
381
|
"""
|
|
333
|
-
cls.
|
|
334
|
-
name, label, all_options, description=description,
|
|
335
|
-
order_matters=order_matters, none_is_all=none_is_all
|
|
382
|
+
cls._CreateWithOptionsHelper(
|
|
383
|
+
name, label, all_options, description=description, user_attribute=user_attribute, parent_name=parent_name,
|
|
384
|
+
show_select_all=show_select_all, order_matters=order_matters, none_is_all=none_is_all
|
|
336
385
|
)
|
|
337
386
|
|
|
338
387
|
@classmethod
|
|
339
388
|
def CreateSimple(
|
|
340
|
-
cls, name: str, label: str, all_options: Sequence[
|
|
389
|
+
cls, name: str, label: str, all_options: Sequence[_po.SelectParameterOption], *, description: str = "",
|
|
341
390
|
show_select_all: bool = True, order_matters: bool = False, none_is_all: bool = True, **kwargs
|
|
342
391
|
) -> None:
|
|
343
392
|
"""
|
|
344
393
|
Method for creating the configurations for a MultiSelectParameter that doesn't involve user attributes or parent parameters
|
|
345
394
|
|
|
346
|
-
|
|
395
|
+
Arguments:
|
|
347
396
|
name: The name of the parameter
|
|
348
397
|
label: The display label for the parameter
|
|
349
398
|
all_options: All options associated to this parameter regardless of the user group or parent parameter option they depend on
|
|
@@ -359,14 +408,14 @@ class MultiSelectParameter(_SelectionParameter):
|
|
|
359
408
|
|
|
360
409
|
@classmethod
|
|
361
410
|
def CreateFromSource(
|
|
362
|
-
cls, name: str, label: str, data_source:
|
|
411
|
+
cls, name: str, label: str, data_source: d.SelectDataSource | dict, *, description: str = "",
|
|
363
412
|
show_select_all: bool = True, order_matters: bool = False, none_is_all: bool = True,
|
|
364
|
-
user_attribute:
|
|
413
|
+
user_attribute: str | None = None, parent_name: str | None = None, **kwargs
|
|
365
414
|
) -> None:
|
|
366
415
|
"""
|
|
367
416
|
Method for creating the configurations for a MultiSelectParameter that uses a SelectDataSource to receive the options
|
|
368
417
|
|
|
369
|
-
|
|
418
|
+
Arguments:
|
|
370
419
|
name: The name of the parameter
|
|
371
420
|
label: The display label for the parameter
|
|
372
421
|
data_source: The lookup table to use for this parameter
|
|
@@ -380,11 +429,10 @@ class MultiSelectParameter(_SelectionParameter):
|
|
|
380
429
|
extra_args = {
|
|
381
430
|
"show_select_all": show_select_all, "order_matters": order_matters, "none_is_all": none_is_all
|
|
382
431
|
}
|
|
383
|
-
|
|
384
|
-
|
|
432
|
+
cls._CreateFromSourceHelper(
|
|
433
|
+
name, label, data_source, extra_args=extra_args, description=description,
|
|
385
434
|
user_attribute=user_attribute, parent_name=parent_name
|
|
386
435
|
)
|
|
387
|
-
ps.ParameterConfigsSetIO.obj.add(param_config)
|
|
388
436
|
|
|
389
437
|
def has_non_empty_selection(self) -> bool:
|
|
390
438
|
"""
|
|
@@ -399,12 +447,12 @@ class MultiSelectParameter(_SelectionParameter):
|
|
|
399
447
|
return len(self._selected_ids) > 0
|
|
400
448
|
|
|
401
449
|
def get_selected_list(
|
|
402
|
-
self, field:
|
|
403
|
-
) -> Sequence[
|
|
450
|
+
self, field: str | None = None, *, default_field: str | None = None, default: Any = None, **kwargs
|
|
451
|
+
) -> Sequence[_po.SelectParameterOption | Any]:
|
|
404
452
|
"""
|
|
405
453
|
Gets the sequence of the selected option(s) or a sequence of selected custom fields
|
|
406
454
|
|
|
407
|
-
|
|
455
|
+
Arguments:
|
|
408
456
|
field: If field is not None, the method gets this field from the "custom_fields" attribute of the selected options.
|
|
409
457
|
Otherwise, returns the class objects of the selected options
|
|
410
458
|
default_field: If field does not exist for a parameter option and default_field is not None, the default_field is used
|
|
@@ -424,6 +472,70 @@ class MultiSelectParameter(_SelectionParameter):
|
|
|
424
472
|
selected_list = [selected.get_custom_field(field, default_field=default_field, default=default) for selected in selected_list]
|
|
425
473
|
|
|
426
474
|
return tuple(selected_list)
|
|
475
|
+
|
|
476
|
+
def _get_selected_list_of_strings(
|
|
477
|
+
self, method: str, field: str, default_field: str | None, default: str | None, **kwargs
|
|
478
|
+
) -> list[str]:
|
|
479
|
+
selected_list = self.get_selected_list(field, default_field=default_field, default=default)
|
|
480
|
+
list_of_strings: list[str] = []
|
|
481
|
+
for selected in selected_list:
|
|
482
|
+
if not isinstance(selected, str):
|
|
483
|
+
raise _u.ConfigurationError(
|
|
484
|
+
f"Method '{method}' can only be used on fields with only string values"
|
|
485
|
+
)
|
|
486
|
+
list_of_strings.append(selected)
|
|
487
|
+
return list_of_strings
|
|
488
|
+
|
|
489
|
+
def get_selected_list_joined(self, field: str, *, default_field: str | None = None, default: str | None = None, **kwargs) -> str:
|
|
490
|
+
"""
|
|
491
|
+
Gets the selected custom fields joined by comma
|
|
492
|
+
|
|
493
|
+
Arguments:
|
|
494
|
+
field: The "custom_fields" attribute of the selected options.
|
|
495
|
+
default_field: If field does not exist for a parameter option and default_field is not None, the default_field is used
|
|
496
|
+
as the "field" instead.
|
|
497
|
+
default: If field does not exist for a parameter option, default_field is None, but default is not None, the default
|
|
498
|
+
is returned as the selected field. Does nothing if default_field is not None
|
|
499
|
+
|
|
500
|
+
Returns:
|
|
501
|
+
A string
|
|
502
|
+
"""
|
|
503
|
+
list_of_strings = self._get_selected_list_of_strings("get_selected_list_joined", field, default_field, default)
|
|
504
|
+
return ','.join(list_of_strings)
|
|
505
|
+
|
|
506
|
+
def get_selected_list_quoted(self, field: str, *, default_field: str | None = None, default: str | None = None, **kwargs) -> tuple[str, ...]:
|
|
507
|
+
"""
|
|
508
|
+
Gets the selected custom fields surrounded by single quotes
|
|
509
|
+
|
|
510
|
+
Arguments:
|
|
511
|
+
field: The "custom_fields" attribute of the selected options.
|
|
512
|
+
default_field: If field does not exist for a parameter option and default_field is not None, the default_field is used
|
|
513
|
+
as the "field" instead.
|
|
514
|
+
default: If field does not exist for a parameter option, default_field is None, but default is not None, the default
|
|
515
|
+
is returned as the selected field. Does nothing if default_field is not None
|
|
516
|
+
|
|
517
|
+
Returns:
|
|
518
|
+
A tuple of strings
|
|
519
|
+
"""
|
|
520
|
+
list_of_strings = self._get_selected_list_of_strings("get_selected_list_quoted", field, default_field, default)
|
|
521
|
+
return tuple(self._enquote(x) for x in list_of_strings)
|
|
522
|
+
|
|
523
|
+
def get_selected_list_quoted_joined(self, field: str, *, default_field: str | None = None, default: str | None = None, **kwargs) -> str:
|
|
524
|
+
"""
|
|
525
|
+
Gets the selected custom fields surrounded by single quotes and joined by comma
|
|
526
|
+
|
|
527
|
+
Arguments:
|
|
528
|
+
field: The "custom_fields" attribute of the selected options.
|
|
529
|
+
default_field: If field does not exist for a parameter option and default_field is not None, the default_field is used
|
|
530
|
+
as the "field" instead.
|
|
531
|
+
default: If field does not exist for a parameter option, default_field is None, but default is not None, the default
|
|
532
|
+
is returned as the selected field. Does nothing if default_field is not None
|
|
533
|
+
|
|
534
|
+
Returns:
|
|
535
|
+
A string
|
|
536
|
+
"""
|
|
537
|
+
list_of_strings = self._get_selected_list_of_strings("get_selected_list_quoted_joined", field, default_field, default)
|
|
538
|
+
return ','.join(self._enquote(x) for x in list_of_strings)
|
|
427
539
|
|
|
428
540
|
def get_selected_ids_as_list(self, **kwargs) -> Sequence[str]:
|
|
429
541
|
"""
|
|
@@ -514,11 +626,29 @@ class MultiSelectParameter(_SelectionParameter):
|
|
|
514
626
|
return output
|
|
515
627
|
|
|
516
628
|
def _get_response_model0(self):
|
|
517
|
-
return arm.MultiSelectParameterModel
|
|
629
|
+
return arm.MultiSelectParameterModel if self.is_enabled() else arm.NoneParameterModel
|
|
630
|
+
|
|
631
|
+
|
|
632
|
+
@dataclass
|
|
633
|
+
class _DateTypeParameter(Parameter):
|
|
634
|
+
_curr_option: _po._DateTypeParameterOption | None
|
|
635
|
+
|
|
636
|
+
def is_enabled(self) -> bool:
|
|
637
|
+
return self._curr_option is not None
|
|
638
|
+
|
|
639
|
+
def _cast_optional_date_to_str(self, date: date | None) -> str | None:
|
|
640
|
+
return None if date is None else date.strftime("%Y-%m-%d")
|
|
641
|
+
|
|
642
|
+
def _to_json_dict0(self):
|
|
643
|
+
output = super()._to_json_dict0()
|
|
644
|
+
if self._curr_option is not None:
|
|
645
|
+
output["min_date"] = self._cast_optional_date_to_str(self._curr_option._min_date)
|
|
646
|
+
output["max_date"] = self._cast_optional_date_to_str(self._curr_option._max_date)
|
|
647
|
+
return output
|
|
518
648
|
|
|
519
649
|
|
|
520
650
|
@dataclass
|
|
521
|
-
class DateParameter(
|
|
651
|
+
class DateParameter(_DateTypeParameter):
|
|
522
652
|
"""
|
|
523
653
|
Class for date parameter widgets.
|
|
524
654
|
|
|
@@ -527,56 +657,58 @@ class DateParameter(Parameter):
|
|
|
527
657
|
curr_option: The current option showing for defaults based on user attribute and selection of parent
|
|
528
658
|
selected_date: The selected date
|
|
529
659
|
"""
|
|
530
|
-
_config:
|
|
531
|
-
_curr_option:
|
|
532
|
-
_selected_date:
|
|
660
|
+
_config: _pc.DateParameterConfig
|
|
661
|
+
_curr_option: _po.DateParameterOption | None
|
|
662
|
+
_selected_date: date | str | None
|
|
533
663
|
|
|
534
664
|
def __post_init__(self):
|
|
535
|
-
self.
|
|
665
|
+
if self._curr_option is not None and self._selected_date is not None:
|
|
666
|
+
self._selected_date = self._validate_input_date(self._selected_date, self._curr_option)
|
|
536
667
|
|
|
537
668
|
def is_enabled(self) -> bool:
|
|
538
669
|
return self._curr_option is not None
|
|
539
670
|
|
|
540
671
|
@staticmethod
|
|
541
672
|
def _ParameterConfigType():
|
|
542
|
-
return
|
|
673
|
+
return _pc.DateParameterConfig
|
|
543
674
|
|
|
544
675
|
@classmethod
|
|
545
676
|
def CreateSimple(
|
|
546
|
-
cls, name: str, label: str, default_date:
|
|
547
|
-
date_format: str = '%Y-%m-%d', **kwargs
|
|
677
|
+
cls, name: str, label: str, default_date: str | date, *, description: str = "",
|
|
678
|
+
min_date: str | date | None = None, max_date: str | date | None = None, date_format: str = '%Y-%m-%d', **kwargs
|
|
548
679
|
) -> None:
|
|
549
680
|
"""
|
|
550
681
|
Method for creating the configurations for a Parameter that doesn't involve user attributes or parent parameters
|
|
551
682
|
|
|
552
|
-
|
|
683
|
+
Arguments:
|
|
553
684
|
name: The name of the parameter
|
|
554
685
|
label: The display label for the parameter
|
|
555
686
|
default_date: Default date for this option
|
|
556
687
|
description: Explains the meaning of the parameter
|
|
557
688
|
date_format: Format of the default date, default is '%Y-%m-%d'
|
|
558
689
|
"""
|
|
559
|
-
single_param_option =
|
|
690
|
+
single_param_option = _po.DateParameterOption(default_date, min_date=min_date, max_date=max_date, date_format=date_format)
|
|
560
691
|
cls.CreateWithOptions(name, label, (single_param_option,), description=description)
|
|
561
692
|
|
|
562
|
-
def get_selected_date(self, *, date_format: str = None, **kwargs) -> str:
|
|
693
|
+
def get_selected_date(self, *, date_format: str | None = None, **kwargs) -> str:
|
|
563
694
|
"""
|
|
564
695
|
Gets selected date as string
|
|
565
696
|
|
|
566
|
-
|
|
697
|
+
Arguments:
|
|
567
698
|
date_format: The date format (see Python's datetime formats). If not specified, self.date_format is used
|
|
568
699
|
|
|
569
700
|
Returns:
|
|
570
701
|
A string
|
|
571
702
|
"""
|
|
703
|
+
assert self._curr_option is not None and isinstance(self._selected_date, date), "Parameter is not enabled"
|
|
572
704
|
date_format = self._curr_option._date_format if date_format is None else date_format
|
|
573
705
|
return self._selected_date.strftime(date_format)
|
|
574
706
|
|
|
575
|
-
def get_selected_date_quoted(self, *, date_format: str = None, **kwargs) -> str:
|
|
707
|
+
def get_selected_date_quoted(self, *, date_format: str | None = None, **kwargs) -> str:
|
|
576
708
|
"""
|
|
577
709
|
Gets selected date as string surrounded by single quotes
|
|
578
710
|
|
|
579
|
-
|
|
711
|
+
Arguments:
|
|
580
712
|
date_format: The date format (see Python's datetime formats). If not specified, self.date_format is used
|
|
581
713
|
|
|
582
714
|
Returns:
|
|
@@ -601,11 +733,11 @@ class DateParameter(Parameter):
|
|
|
601
733
|
return output
|
|
602
734
|
|
|
603
735
|
def _get_response_model0(self):
|
|
604
|
-
return arm.DateParameterModel if self.is_enabled() else arm.
|
|
736
|
+
return arm.DateParameterModel if self.is_enabled() else arm.NoneParameterModel
|
|
605
737
|
|
|
606
738
|
|
|
607
739
|
@dataclass
|
|
608
|
-
class DateRangeParameter(
|
|
740
|
+
class DateRangeParameter(_DateTypeParameter):
|
|
609
741
|
"""
|
|
610
742
|
Class for date range parameter widgets.
|
|
611
743
|
|
|
@@ -615,31 +747,35 @@ class DateRangeParameter(Parameter):
|
|
|
615
747
|
selected_start_date: The selected start date
|
|
616
748
|
selected_end_date: The selected end date
|
|
617
749
|
"""
|
|
618
|
-
_config:
|
|
619
|
-
_curr_option:
|
|
620
|
-
_selected_start_date:
|
|
621
|
-
_selected_end_date:
|
|
750
|
+
_config: _pc.DateRangeParameterConfig
|
|
751
|
+
_curr_option: _po.DateRangeParameterOption | None
|
|
752
|
+
_selected_start_date: date | str | None
|
|
753
|
+
_selected_end_date: date | str | None
|
|
622
754
|
|
|
623
755
|
def __post_init__(self):
|
|
624
|
-
self.
|
|
625
|
-
|
|
756
|
+
if self._curr_option is not None:
|
|
757
|
+
if self._selected_start_date is not None:
|
|
758
|
+
self._selected_start_date = self._validate_input_date(self._selected_start_date, self._curr_option)
|
|
759
|
+
if self._selected_end_date is not None:
|
|
760
|
+
self._selected_end_date = self._validate_input_date(self._selected_end_date, self._curr_option)
|
|
626
761
|
|
|
627
762
|
def is_enabled(self) -> bool:
|
|
628
763
|
return self._curr_option is not None
|
|
629
764
|
|
|
630
765
|
@staticmethod
|
|
631
766
|
def _ParameterConfigType():
|
|
632
|
-
return
|
|
767
|
+
return _pc.DateRangeParameterConfig
|
|
633
768
|
|
|
634
769
|
@classmethod
|
|
635
770
|
def CreateSimple(
|
|
636
|
-
cls, name: str, label: str, default_start_date:
|
|
637
|
-
description: str = "",
|
|
771
|
+
cls, name: str, label: str, default_start_date: str | date, default_end_date: str | date, *,
|
|
772
|
+
description: str = "", min_date: str | date | None = None, max_date: str | date | None = None,
|
|
773
|
+
date_format: str = '%Y-%m-%d', **kwargs
|
|
638
774
|
) -> None:
|
|
639
775
|
"""
|
|
640
776
|
Method for creating the configurations for a Parameter that doesn't involve user attributes or parent parameters
|
|
641
777
|
|
|
642
|
-
|
|
778
|
+
Arguments:
|
|
643
779
|
name: The name of the parameter
|
|
644
780
|
label: The display label for the parameter
|
|
645
781
|
default_start_date: Default start date for this option
|
|
@@ -647,27 +783,30 @@ class DateRangeParameter(Parameter):
|
|
|
647
783
|
description: Explains the meaning of the parameter
|
|
648
784
|
date_format: Format of the default date, default is '%Y-%m-%d'
|
|
649
785
|
"""
|
|
650
|
-
single_param_option =
|
|
786
|
+
single_param_option = _po.DateRangeParameterOption(
|
|
787
|
+
default_start_date, default_end_date, min_date=min_date, max_date=max_date, date_format=date_format
|
|
788
|
+
)
|
|
651
789
|
cls.CreateWithOptions(name, label, (single_param_option,), description=description)
|
|
652
790
|
|
|
653
|
-
def get_selected_start_date(self, *, date_format: str = None, **kwargs) -> str:
|
|
791
|
+
def get_selected_start_date(self, *, date_format: str | None = None, **kwargs) -> str:
|
|
654
792
|
"""
|
|
655
793
|
Gets selected start date as string
|
|
656
794
|
|
|
657
|
-
|
|
795
|
+
Arguments:
|
|
658
796
|
date_format: The date format (see Python's datetime formats). If not specified, self.date_format is used
|
|
659
797
|
|
|
660
798
|
Returns:
|
|
661
799
|
A string
|
|
662
800
|
"""
|
|
801
|
+
assert self._curr_option is not None and isinstance(self._selected_start_date, date), "Parameter is not enabled"
|
|
663
802
|
date_format = self._curr_option._date_format if date_format is None else date_format
|
|
664
803
|
return self._selected_start_date.strftime(date_format)
|
|
665
804
|
|
|
666
|
-
def get_selected_start_date_quoted(self, *, date_format: str = None, **kwargs) -> str:
|
|
805
|
+
def get_selected_start_date_quoted(self, *, date_format: str | None = None, **kwargs) -> str:
|
|
667
806
|
"""
|
|
668
807
|
Gets selected start date as string surrounded by single quotes
|
|
669
808
|
|
|
670
|
-
|
|
809
|
+
Arguments:
|
|
671
810
|
date_format: The date format (see Python's datetime formats). If not specified, self.date_format is used
|
|
672
811
|
|
|
673
812
|
Returns:
|
|
@@ -675,24 +814,25 @@ class DateRangeParameter(Parameter):
|
|
|
675
814
|
"""
|
|
676
815
|
return self._enquote(self.get_selected_start_date(date_format=date_format))
|
|
677
816
|
|
|
678
|
-
def get_selected_end_date(self, *, date_format: str = None, **kwargs) -> str:
|
|
817
|
+
def get_selected_end_date(self, *, date_format: str | None = None, **kwargs) -> str:
|
|
679
818
|
"""
|
|
680
819
|
Gets selected end date as string
|
|
681
820
|
|
|
682
|
-
|
|
821
|
+
Arguments:
|
|
683
822
|
date_format: The date format (see Python's datetime formats). If not specified, self.date_format is used
|
|
684
823
|
|
|
685
824
|
Returns:
|
|
686
825
|
A string
|
|
687
826
|
"""
|
|
827
|
+
assert self._curr_option is not None and isinstance(self._selected_end_date, date), "Parameter is not enabled"
|
|
688
828
|
date_format = self._curr_option._date_format if date_format is None else date_format
|
|
689
829
|
return self._selected_end_date.strftime(date_format)
|
|
690
830
|
|
|
691
|
-
def get_selected_end_date_quoted(self, *, date_format: str = None, **kwargs) -> str:
|
|
831
|
+
def get_selected_end_date_quoted(self, *, date_format: str | None = None, **kwargs) -> str:
|
|
692
832
|
"""
|
|
693
833
|
Gets selected end date as string surrounded by single quotes
|
|
694
834
|
|
|
695
|
-
|
|
835
|
+
Arguments:
|
|
696
836
|
date_format: The date format (see Python's datetime formats). If not specified, self.date_format is used
|
|
697
837
|
|
|
698
838
|
Returns:
|
|
@@ -716,11 +856,27 @@ class DateRangeParameter(Parameter):
|
|
|
716
856
|
return output
|
|
717
857
|
|
|
718
858
|
def _get_response_model0(self):
|
|
719
|
-
return arm.DateRangeParameterModel if self.is_enabled() else arm.
|
|
859
|
+
return arm.DateRangeParameterModel if self.is_enabled() else arm.NoneParameterModel
|
|
720
860
|
|
|
721
861
|
|
|
722
862
|
@dataclass
|
|
723
|
-
class
|
|
863
|
+
class _NumberTypeParameter(Parameter):
|
|
864
|
+
_curr_option: _po._NumericParameterOption | None
|
|
865
|
+
|
|
866
|
+
def is_enabled(self) -> bool:
|
|
867
|
+
return self._curr_option is not None
|
|
868
|
+
|
|
869
|
+
def _to_json_dict0(self):
|
|
870
|
+
output = super()._to_json_dict0()
|
|
871
|
+
if self._curr_option is not None:
|
|
872
|
+
output["min_value"] = float(self._curr_option._min_value)
|
|
873
|
+
output["max_value"] = float(self._curr_option._max_value)
|
|
874
|
+
output["increment"] = float(self._curr_option._increment)
|
|
875
|
+
return output
|
|
876
|
+
|
|
877
|
+
|
|
878
|
+
@dataclass
|
|
879
|
+
class NumberParameter(_NumberTypeParameter):
|
|
724
880
|
"""
|
|
725
881
|
Class for number parameter widgets.
|
|
726
882
|
|
|
@@ -729,31 +885,29 @@ class NumberParameter(Parameter):
|
|
|
729
885
|
curr_option: The current option showing for defaults based on user attribute and selection of parent
|
|
730
886
|
selected_value: The selected integer or decimal number
|
|
731
887
|
"""
|
|
732
|
-
_config:
|
|
733
|
-
_curr_option:
|
|
734
|
-
_selected_value:
|
|
888
|
+
_config: _pc.NumberParameterConfig
|
|
889
|
+
_curr_option: _po.NumberParameterOption | None
|
|
890
|
+
_selected_value: _po.Number | None
|
|
735
891
|
|
|
736
892
|
def __post_init__(self):
|
|
737
|
-
self.
|
|
738
|
-
|
|
739
|
-
def is_enabled(self) -> bool:
|
|
740
|
-
return self._curr_option is not None
|
|
893
|
+
if self._curr_option is not None and self._selected_value is not None:
|
|
894
|
+
self._selected_value = self._validate_number(self._selected_value, self._curr_option)
|
|
741
895
|
|
|
742
896
|
@staticmethod
|
|
743
897
|
def _ParameterConfigType():
|
|
744
|
-
return
|
|
898
|
+
return _pc.NumberParameterConfig
|
|
745
899
|
|
|
746
900
|
@classmethod
|
|
747
901
|
def CreateSimple(
|
|
748
|
-
cls, name: str, label: str, min_value:
|
|
749
|
-
increment:
|
|
902
|
+
cls, name: str, label: str, min_value: _po.Number, max_value: _po.Number, *, description: str = "",
|
|
903
|
+
increment: _po.Number = 1, default_value: _po.Number | None = None, **kwargs
|
|
750
904
|
) -> None:
|
|
751
905
|
"""
|
|
752
906
|
Method for creating the configurations for a Parameter that doesn't involve user attributes or parent parameters
|
|
753
907
|
|
|
754
908
|
* Note that the "Number" type denotes an int, a Decimal (from decimal module), or a string that can be parsed to Decimal
|
|
755
909
|
|
|
756
|
-
|
|
910
|
+
Arguments:
|
|
757
911
|
name: The name of the parameter
|
|
758
912
|
label: The display label for the parameter
|
|
759
913
|
min_value: Minimum selectable value
|
|
@@ -762,7 +916,7 @@ class NumberParameter(Parameter):
|
|
|
762
916
|
increment: Increment of selectable values, and must fit evenly between min_value and max_value
|
|
763
917
|
default_value: Default value for this option, and must be selectable based on min_value, max_value, and increment
|
|
764
918
|
"""
|
|
765
|
-
single_param_option =
|
|
919
|
+
single_param_option = _po.NumberParameterOption(min_value, max_value, increment=increment, default_value=default_value)
|
|
766
920
|
cls.CreateWithOptions(name, label, (single_param_option,), description=description)
|
|
767
921
|
|
|
768
922
|
def get_selected_value(self, **kwargs) -> float:
|
|
@@ -772,6 +926,7 @@ class NumberParameter(Parameter):
|
|
|
772
926
|
Returns:
|
|
773
927
|
float
|
|
774
928
|
"""
|
|
929
|
+
assert self._selected_value is not None, "Parameter is not enabled"
|
|
775
930
|
return float(self._selected_value)
|
|
776
931
|
|
|
777
932
|
def _to_json_dict0(self):
|
|
@@ -783,16 +938,15 @@ class NumberParameter(Parameter):
|
|
|
783
938
|
"""
|
|
784
939
|
output = super()._to_json_dict0()
|
|
785
940
|
if self.is_enabled():
|
|
786
|
-
output.update(self._curr_option._to_json_dict())
|
|
787
941
|
output["selected_value"] = self.get_selected_value()
|
|
788
942
|
return output
|
|
789
943
|
|
|
790
944
|
def _get_response_model0(self):
|
|
791
|
-
return arm.NumberParameterModel if self.is_enabled() else arm.
|
|
945
|
+
return arm.NumberParameterModel if self.is_enabled() else arm.NoneParameterModel
|
|
792
946
|
|
|
793
947
|
|
|
794
948
|
@dataclass
|
|
795
|
-
class NumberRangeParameter(
|
|
949
|
+
class NumberRangeParameter(_NumberTypeParameter):
|
|
796
950
|
"""
|
|
797
951
|
Class for number range parameter widgets.
|
|
798
952
|
|
|
@@ -802,26 +956,26 @@ class NumberRangeParameter(Parameter):
|
|
|
802
956
|
selected_lower_value: The selected lower integer or decimal number
|
|
803
957
|
selected_upper_value: The selected upper integer or decimal number
|
|
804
958
|
"""
|
|
805
|
-
_config:
|
|
806
|
-
_curr_option:
|
|
807
|
-
_selected_lower_value:
|
|
808
|
-
_selected_upper_value:
|
|
959
|
+
_config: _pc.NumberRangeParameterConfig
|
|
960
|
+
_curr_option: _po.NumberRangeParameterOption | None
|
|
961
|
+
_selected_lower_value: _po.Number | None
|
|
962
|
+
_selected_upper_value: _po.Number | None
|
|
809
963
|
|
|
810
964
|
def __post_init__(self):
|
|
811
|
-
self.
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
965
|
+
if self._curr_option is not None:
|
|
966
|
+
if self._selected_lower_value is not None:
|
|
967
|
+
self._selected_lower_value = self._validate_number(self._selected_lower_value, self._curr_option)
|
|
968
|
+
if self._selected_upper_value is not None:
|
|
969
|
+
self._selected_upper_value = self._validate_number(self._selected_upper_value, self._curr_option)
|
|
816
970
|
|
|
817
971
|
@staticmethod
|
|
818
972
|
def _ParameterConfigType():
|
|
819
|
-
return
|
|
973
|
+
return _pc.NumberRangeParameterConfig
|
|
820
974
|
|
|
821
975
|
@classmethod
|
|
822
976
|
def CreateSimple(
|
|
823
|
-
cls, name: str, label: str, min_value:
|
|
824
|
-
increment:
|
|
977
|
+
cls, name: str, label: str, min_value: _po.Number, max_value: _po.Number, *, description: str = "",
|
|
978
|
+
increment: _po.Number = 1, default_lower_value: _po.Number | None = None, default_upper_value: _po.Number | None = None,
|
|
825
979
|
**kwargs
|
|
826
980
|
) -> None:
|
|
827
981
|
"""
|
|
@@ -829,7 +983,7 @@ class NumberRangeParameter(Parameter):
|
|
|
829
983
|
|
|
830
984
|
* Note that the "Number" type denotes an int, a Decimal (from decimal module), or a string that can be parsed to Decimal
|
|
831
985
|
|
|
832
|
-
|
|
986
|
+
Arguments:
|
|
833
987
|
name: The name of the parameter
|
|
834
988
|
label: The display label for the parameter
|
|
835
989
|
min_value: Minimum selectable value
|
|
@@ -840,7 +994,7 @@ class NumberRangeParameter(Parameter):
|
|
|
840
994
|
default_upper_value: Default upper value for this option, and must be selectable based on min_value, max_value, and increment.
|
|
841
995
|
Must also be greater than default_lower_value
|
|
842
996
|
"""
|
|
843
|
-
single_param_option =
|
|
997
|
+
single_param_option = _po.NumberRangeParameterOption(
|
|
844
998
|
min_value, max_value, increment=increment, default_lower_value=default_lower_value, default_upper_value=default_upper_value
|
|
845
999
|
)
|
|
846
1000
|
cls.CreateWithOptions(name, label, (single_param_option,), description=description)
|
|
@@ -852,6 +1006,7 @@ class NumberRangeParameter(Parameter):
|
|
|
852
1006
|
Returns:
|
|
853
1007
|
float
|
|
854
1008
|
"""
|
|
1009
|
+
assert self._selected_lower_value is not None, "Parameter is not enabled"
|
|
855
1010
|
return float(self._selected_lower_value)
|
|
856
1011
|
|
|
857
1012
|
def get_selected_upper_value(self, **kwargs) -> float:
|
|
@@ -861,6 +1016,7 @@ class NumberRangeParameter(Parameter):
|
|
|
861
1016
|
Returns:
|
|
862
1017
|
float
|
|
863
1018
|
"""
|
|
1019
|
+
assert self._selected_upper_value is not None, "Parameter is not enabled"
|
|
864
1020
|
return float(self._selected_upper_value)
|
|
865
1021
|
|
|
866
1022
|
def _to_json_dict0(self):
|
|
@@ -871,14 +1027,13 @@ class NumberRangeParameter(Parameter):
|
|
|
871
1027
|
A dictionary for the JSON object
|
|
872
1028
|
"""
|
|
873
1029
|
output = super()._to_json_dict0()
|
|
874
|
-
if self.
|
|
875
|
-
output.update(self._curr_option._to_json_dict())
|
|
1030
|
+
if self.is_enabled():
|
|
876
1031
|
output['selected_lower_value'] = self.get_selected_lower_value()
|
|
877
1032
|
output['selected_upper_value'] = self.get_selected_upper_value()
|
|
878
1033
|
return output
|
|
879
1034
|
|
|
880
1035
|
def _get_response_model0(self):
|
|
881
|
-
return arm.NumberRangeParameterModel if self.is_enabled() else arm.
|
|
1036
|
+
return arm.NumberRangeParameterModel if self.is_enabled() else arm.NoneParameterModel
|
|
882
1037
|
|
|
883
1038
|
|
|
884
1039
|
@dataclass
|
|
@@ -886,7 +1041,7 @@ class TextValue:
|
|
|
886
1041
|
_value_do_not_touch: str
|
|
887
1042
|
|
|
888
1043
|
def __repr__(self):
|
|
889
|
-
raise
|
|
1044
|
+
raise _u.ConfigurationError(
|
|
890
1045
|
"Cannot convert TextValue directly to string (to avoid SQL injection). Try using it through placeholders instead"
|
|
891
1046
|
)
|
|
892
1047
|
|
|
@@ -896,7 +1051,7 @@ class TextValue:
|
|
|
896
1051
|
|
|
897
1052
|
This method returns a new object and leaves the original the same.
|
|
898
1053
|
|
|
899
|
-
|
|
1054
|
+
Arguments:
|
|
900
1055
|
str_to_str_function: A function that accepts a string and returns a string
|
|
901
1056
|
|
|
902
1057
|
Returns:
|
|
@@ -904,7 +1059,7 @@ class TextValue:
|
|
|
904
1059
|
"""
|
|
905
1060
|
new_value = str_to_str_function(self._value_do_not_touch)
|
|
906
1061
|
if not isinstance(new_value, str):
|
|
907
|
-
raise
|
|
1062
|
+
raise _u.ConfigurationError("Function provided must return string")
|
|
908
1063
|
return TextValue(new_value)
|
|
909
1064
|
|
|
910
1065
|
def apply_percent_wrap(self) -> TextValue:
|
|
@@ -920,7 +1075,7 @@ class TextValue:
|
|
|
920
1075
|
"""
|
|
921
1076
|
Transforms the entered text with a function that takes a string and returns a boolean.
|
|
922
1077
|
|
|
923
|
-
|
|
1078
|
+
Arguments:
|
|
924
1079
|
str_to_bool_function: A function that accepts a string and returns a boolean.
|
|
925
1080
|
|
|
926
1081
|
Returns:
|
|
@@ -928,14 +1083,14 @@ class TextValue:
|
|
|
928
1083
|
"""
|
|
929
1084
|
new_value = str_to_bool_function(self._value_do_not_touch)
|
|
930
1085
|
if not isinstance(new_value, bool):
|
|
931
|
-
raise
|
|
1086
|
+
raise _u.ConfigurationError("Function provided must return bool")
|
|
932
1087
|
return new_value
|
|
933
1088
|
|
|
934
|
-
def apply_as_number(self, str_to_num_function: Callable[[str],
|
|
1089
|
+
def apply_as_number(self, str_to_num_function: Callable[[str], IntOrFloat]) -> IntOrFloat:
|
|
935
1090
|
"""
|
|
936
1091
|
Transforms the entered text with a function that takes a string and returns an int or float.
|
|
937
1092
|
|
|
938
|
-
|
|
1093
|
+
Arguments:
|
|
939
1094
|
str_to_num_function: A function that accepts a string and returns an int or float.
|
|
940
1095
|
|
|
941
1096
|
Returns:
|
|
@@ -943,14 +1098,14 @@ class TextValue:
|
|
|
943
1098
|
"""
|
|
944
1099
|
new_value = str_to_num_function(self._value_do_not_touch)
|
|
945
1100
|
if not isinstance(new_value, (int, float)):
|
|
946
|
-
raise
|
|
1101
|
+
raise _u.ConfigurationError("Function provided must return a number")
|
|
947
1102
|
return new_value
|
|
948
1103
|
|
|
949
1104
|
def apply_as_datetime(self, str_to_datetime_function: Callable[[str], datetime]) -> datetime:
|
|
950
1105
|
"""
|
|
951
1106
|
Transforms the entered text with a function that takes a string and returns a datetime object.
|
|
952
1107
|
|
|
953
|
-
|
|
1108
|
+
Arguments:
|
|
954
1109
|
str_to_datetime_function: A function that accepts a string and returns a datetime object.
|
|
955
1110
|
|
|
956
1111
|
Returns:
|
|
@@ -958,7 +1113,7 @@ class TextValue:
|
|
|
958
1113
|
"""
|
|
959
1114
|
new_value = str_to_datetime_function(self._value_do_not_touch)
|
|
960
1115
|
if not isinstance(new_value, datetime):
|
|
961
|
-
raise
|
|
1116
|
+
raise _u.ConfigurationError("Function provided must return datetime")
|
|
962
1117
|
return new_value
|
|
963
1118
|
|
|
964
1119
|
|
|
@@ -967,33 +1122,33 @@ class TextParameter(Parameter):
|
|
|
967
1122
|
"""
|
|
968
1123
|
Class for text parameter widgets.
|
|
969
1124
|
"""
|
|
970
|
-
_config:
|
|
971
|
-
_curr_option:
|
|
972
|
-
_entered_text: str
|
|
1125
|
+
_config: _pc.TextParameterConfig
|
|
1126
|
+
_curr_option: _po.TextParameterOption | None
|
|
1127
|
+
_entered_text: str | None
|
|
973
1128
|
|
|
974
1129
|
def __post_init__(self):
|
|
975
|
-
|
|
976
|
-
|
|
1130
|
+
if self.is_enabled() and isinstance(self._entered_text, str):
|
|
1131
|
+
try:
|
|
977
1132
|
self._entered_text = self._config.validate_entered_text(self._entered_text)
|
|
978
|
-
|
|
979
|
-
|
|
1133
|
+
except _u.ConfigurationError as e:
|
|
1134
|
+
raise self._config._invalid_input_error(self._entered_text, str(e))
|
|
980
1135
|
|
|
981
1136
|
def is_enabled(self) -> bool:
|
|
982
1137
|
return self._curr_option is not None
|
|
983
|
-
|
|
1138
|
+
|
|
984
1139
|
@staticmethod
|
|
985
1140
|
def _ParameterConfigType():
|
|
986
|
-
return
|
|
1141
|
+
return _pc.TextParameterConfig
|
|
987
1142
|
|
|
988
1143
|
@classmethod
|
|
989
1144
|
def CreateWithOptions(
|
|
990
|
-
cls, name: str, label: str, all_options: Sequence[
|
|
991
|
-
input_type: str = "text", user_attribute:
|
|
1145
|
+
cls, name: str, label: str, all_options: Sequence[_po.TextParameterOption | dict], *, description: str = "",
|
|
1146
|
+
input_type: str = "text", user_attribute: str | None = None, parent_name: str | None = None, **kwargs
|
|
992
1147
|
) -> None:
|
|
993
1148
|
"""
|
|
994
1149
|
Method for creating the configurations for a MultiSelectParameter that may include user attribute or parent
|
|
995
1150
|
|
|
996
|
-
|
|
1151
|
+
Arguments:
|
|
997
1152
|
name: The name of the parameter
|
|
998
1153
|
label: The display label for the parameter
|
|
999
1154
|
all_options: All options associated to this parameter regardless of the user group or parent parameter option they depend on
|
|
@@ -1002,21 +1157,19 @@ class TextParameter(Parameter):
|
|
|
1002
1157
|
user_attribute: The user attribute that may cascade the options for this parameter. Default is None
|
|
1003
1158
|
parent_name: Name of parent parameter that may cascade the options for this parameter. Default is None (no parent)
|
|
1004
1159
|
"""
|
|
1005
|
-
|
|
1006
|
-
name, label, all_options, description=description, input_type=input_type, user_attribute=user_attribute,
|
|
1007
|
-
parent_name=parent_name
|
|
1160
|
+
cls._CreateWithOptionsHelper(
|
|
1161
|
+
name, label, all_options, description=description, input_type=input_type, user_attribute=user_attribute, parent_name=parent_name
|
|
1008
1162
|
)
|
|
1009
|
-
ps.ParameterConfigsSetIO.obj.add(param_config)
|
|
1010
1163
|
|
|
1011
1164
|
@classmethod
|
|
1012
1165
|
def Create(
|
|
1013
|
-
cls, name: str, label: str, all_options: Sequence[
|
|
1014
|
-
input_type: str = "text", user_attribute:
|
|
1166
|
+
cls, name: str, label: str, all_options: Sequence[_po.TextParameterOption | dict], *, description: str = "",
|
|
1167
|
+
input_type: str = "text", user_attribute: str | None = None, parent_name: str | None = None, **kwargs
|
|
1015
1168
|
) -> None:
|
|
1016
1169
|
"""
|
|
1017
1170
|
DEPRECATED. Use CreateWithOptions instead
|
|
1018
1171
|
"""
|
|
1019
|
-
cls.
|
|
1172
|
+
cls._CreateWithOptionsHelper(
|
|
1020
1173
|
name, label, all_options, description=description, input_type=input_type, user_attribute=user_attribute, parent_name=parent_name
|
|
1021
1174
|
)
|
|
1022
1175
|
|
|
@@ -1027,25 +1180,25 @@ class TextParameter(Parameter):
|
|
|
1027
1180
|
"""
|
|
1028
1181
|
Method for creating the configurations for a Parameter that doesn't involve user attributes or parent parameters
|
|
1029
1182
|
|
|
1030
|
-
|
|
1183
|
+
Arguments:
|
|
1031
1184
|
name: The name of the parameter
|
|
1032
1185
|
label: The display label for the parameter
|
|
1033
1186
|
description: Explains the meaning of the parameter
|
|
1034
1187
|
default_text: Default input text for this option. Optional, default is empty string.
|
|
1035
1188
|
input_type: The type of input field to use. Must be one of "text", "textarea", "number", "color", "date", "datetime-local", "month", "time", and "password". Optional, default is "text". More information on input types other than "textarea" can be found at https://www.w3schools.com/html/html_form_input_types.asp. More information on "textarea" can be found at https://www.w3schools.com/tags/tag_textarea.asp
|
|
1036
1189
|
"""
|
|
1037
|
-
single_param_option =
|
|
1190
|
+
single_param_option = _po.TextParameterOption(default_text=default_text)
|
|
1038
1191
|
cls.CreateWithOptions(name, label, (single_param_option,), description=description, input_type=input_type)
|
|
1039
1192
|
|
|
1040
1193
|
@classmethod
|
|
1041
1194
|
def CreateFromSource(
|
|
1042
|
-
cls, name: str, label: str, data_source:
|
|
1043
|
-
input_type: str = "text", user_attribute:
|
|
1195
|
+
cls, name: str, label: str, data_source: d.TextDataSource | dict, *, description: str = "",
|
|
1196
|
+
input_type: str = "text", user_attribute: str | None = None, parent_name: str | None = None, **kwargs
|
|
1044
1197
|
) -> None:
|
|
1045
1198
|
"""
|
|
1046
1199
|
Method for creating the configurations for a MultiSelectParameter that uses a SelectDataSource to receive the options
|
|
1047
1200
|
|
|
1048
|
-
|
|
1201
|
+
Arguments:
|
|
1049
1202
|
name: The name of the parameter
|
|
1050
1203
|
label: The display label for the parameter
|
|
1051
1204
|
data_source: The lookup table to use for this parameter
|
|
@@ -1057,11 +1210,9 @@ class TextParameter(Parameter):
|
|
|
1057
1210
|
extra_args = {
|
|
1058
1211
|
"input_type": input_type
|
|
1059
1212
|
}
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
user_attribute=user_attribute, parent_name=parent_name
|
|
1213
|
+
cls._CreateFromSourceHelper(
|
|
1214
|
+
name, label, data_source, extra_args=extra_args, description=description, user_attribute=user_attribute, parent_name=parent_name
|
|
1063
1215
|
)
|
|
1064
|
-
ps.ParameterConfigsSetIO.obj.add(param_config)
|
|
1065
1216
|
|
|
1066
1217
|
def get_entered_text(self, **kwargs) -> TextValue:
|
|
1067
1218
|
"""
|
|
@@ -1070,6 +1221,7 @@ class TextParameter(Parameter):
|
|
|
1070
1221
|
Returns:
|
|
1071
1222
|
A TextValue object
|
|
1072
1223
|
"""
|
|
1224
|
+
assert isinstance(self._entered_text, str), "Parameter is not enabled"
|
|
1073
1225
|
return TextValue(self._entered_text)
|
|
1074
1226
|
|
|
1075
1227
|
def get_entered_int(self, **kwargs) -> int:
|
|
@@ -1079,7 +1231,7 @@ class TextParameter(Parameter):
|
|
|
1079
1231
|
Returns: int
|
|
1080
1232
|
"""
|
|
1081
1233
|
if self._config.input_type != "number":
|
|
1082
|
-
raise
|
|
1234
|
+
raise _u.ConfigurationError("Method 'get_entered_int' requires TextParameter to have input type 'number'")
|
|
1083
1235
|
text = self.get_entered_text()
|
|
1084
1236
|
return text.apply_as_number(int)
|
|
1085
1237
|
|
|
@@ -1091,7 +1243,7 @@ class TextParameter(Parameter):
|
|
|
1091
1243
|
"""
|
|
1092
1244
|
applicable_input_types = ["date", "datetime-local", "month", "time"]
|
|
1093
1245
|
if self._config.input_type not in applicable_input_types:
|
|
1094
|
-
raise
|
|
1246
|
+
raise _u.ConfigurationError(f"Method 'get_entered_datetime' requires TextParameter to have one of these input types: {applicable_input_types}")
|
|
1095
1247
|
text = self.get_entered_text()
|
|
1096
1248
|
|
|
1097
1249
|
date_formats = { "date": "%Y-%m-%d", "datetime-local": "%Y-%m-%dT%H:%M", "month": "%Y-%m", "time": "%H:%M" }
|
|
@@ -1106,9 +1258,9 @@ class TextParameter(Parameter):
|
|
|
1106
1258
|
"""
|
|
1107
1259
|
output = super()._to_json_dict0()
|
|
1108
1260
|
output['input_type'] = self._config.input_type
|
|
1109
|
-
if self.
|
|
1261
|
+
if self.is_enabled():
|
|
1110
1262
|
output['entered_text'] = self._entered_text
|
|
1111
1263
|
return output
|
|
1112
1264
|
|
|
1113
1265
|
def _get_response_model0(self):
|
|
1114
|
-
return arm.TextParameterModel if self.is_enabled() else arm.
|
|
1266
|
+
return arm.TextParameterModel if self.is_enabled() else arm.NoneParameterModel
|