squirrels 0.1.1.post1__py3-none-any.whl → 0.2.0.dev0__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 +10 -16
- squirrels/_api_server.py +234 -80
- squirrels/_authenticator.py +84 -0
- squirrels/_command_line.py +60 -72
- squirrels/_connection_set.py +96 -0
- squirrels/_constants.py +114 -33
- squirrels/_environcfg.py +77 -0
- squirrels/_initializer.py +126 -67
- squirrels/_manifest.py +195 -168
- squirrels/_models.py +495 -0
- squirrels/_package_loader.py +26 -0
- squirrels/_parameter_configs.py +401 -0
- squirrels/_parameter_sets.py +188 -0
- squirrels/_py_module.py +60 -0
- squirrels/_timer.py +36 -0
- squirrels/_utils.py +81 -49
- squirrels/_version.py +2 -2
- squirrels/arguments/init_time_args.py +32 -0
- squirrels/arguments/run_time_args.py +82 -0
- squirrels/data_sources.py +380 -155
- squirrels/dateutils.py +86 -57
- squirrels/package_data/base_project/Dockerfile +15 -0
- squirrels/package_data/base_project/connections.yml +7 -0
- squirrels/package_data/base_project/database/{sample_database.db → expenses.db} +0 -0
- squirrels/package_data/base_project/environcfg.yml +29 -0
- squirrels/package_data/base_project/ignores/.dockerignore +8 -0
- squirrels/package_data/base_project/ignores/.gitignore +7 -0
- squirrels/package_data/base_project/models/dbviews/database_view1.py +36 -0
- squirrels/package_data/base_project/models/dbviews/database_view1.sql +15 -0
- squirrels/package_data/base_project/models/federates/dataset_example.py +20 -0
- squirrels/package_data/base_project/models/federates/dataset_example.sql +3 -0
- squirrels/package_data/base_project/parameters.yml +109 -0
- squirrels/package_data/base_project/pyconfigs/auth.py +47 -0
- squirrels/package_data/base_project/pyconfigs/connections.py +28 -0
- squirrels/package_data/base_project/pyconfigs/context.py +45 -0
- squirrels/package_data/base_project/pyconfigs/parameters.py +55 -0
- squirrels/package_data/base_project/seeds/mocks/category.csv +3 -0
- squirrels/package_data/base_project/seeds/mocks/max_filter.csv +2 -0
- squirrels/package_data/base_project/seeds/mocks/subcategory.csv +6 -0
- squirrels/package_data/base_project/squirrels.yml.j2 +57 -0
- squirrels/package_data/base_project/tmp/.gitignore +2 -0
- squirrels/package_data/static/script.js +159 -63
- squirrels/package_data/static/style.css +79 -15
- squirrels/package_data/static/widgets.js +133 -0
- squirrels/package_data/templates/index.html +65 -23
- squirrels/package_data/templates/index2.html +22 -0
- squirrels/parameter_options.py +216 -119
- squirrels/parameters.py +407 -478
- squirrels/user_base.py +58 -0
- squirrels-0.2.0.dev0.dist-info/METADATA +126 -0
- squirrels-0.2.0.dev0.dist-info/RECORD +56 -0
- {squirrels-0.1.1.post1.dist-info → squirrels-0.2.0.dev0.dist-info}/WHEEL +1 -2
- squirrels-0.2.0.dev0.dist-info/entry_points.txt +3 -0
- squirrels/_credentials_manager.py +0 -87
- squirrels/_module_loader.py +0 -37
- squirrels/_parameter_set.py +0 -151
- squirrels/_renderer.py +0 -286
- squirrels/_timed_imports.py +0 -37
- squirrels/connection_set.py +0 -126
- squirrels/package_data/base_project/.gitignore +0 -4
- squirrels/package_data/base_project/connections.py +0 -20
- squirrels/package_data/base_project/datasets/sample_dataset/context.py +0 -22
- squirrels/package_data/base_project/datasets/sample_dataset/database_view1.py +0 -29
- squirrels/package_data/base_project/datasets/sample_dataset/database_view1.sql.j2 +0 -12
- squirrels/package_data/base_project/datasets/sample_dataset/final_view.py +0 -11
- squirrels/package_data/base_project/datasets/sample_dataset/final_view.sql.j2 +0 -3
- squirrels/package_data/base_project/datasets/sample_dataset/parameters.py +0 -47
- squirrels/package_data/base_project/datasets/sample_dataset/selections.cfg +0 -9
- squirrels/package_data/base_project/squirrels.yaml +0 -22
- squirrels-0.1.1.post1.dist-info/METADATA +0 -67
- squirrels-0.1.1.post1.dist-info/RECORD +0 -40
- squirrels-0.1.1.post1.dist-info/entry_points.txt +0 -2
- squirrels-0.1.1.post1.dist-info/top_level.txt +0 -1
- {squirrels-0.1.1.post1.dist-info → squirrels-0.2.0.dev0.dist-info}/LICENSE +0 -0
squirrels/parameters.py
CHANGED
|
@@ -1,210 +1,164 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
|
-
from typing import Type, Sequence,
|
|
2
|
+
from typing import Type, Sequence, Optional, Union, Any
|
|
3
3
|
from dataclasses import dataclass
|
|
4
|
-
from datetime import datetime
|
|
4
|
+
from datetime import datetime, date
|
|
5
5
|
from decimal import Decimal
|
|
6
|
-
import
|
|
6
|
+
from abc import ABCMeta, abstractmethod
|
|
7
7
|
|
|
8
|
-
from
|
|
9
|
-
from squirrels.data_sources import DataSource
|
|
10
|
-
from squirrels._parameter_set import ParameterSetBase
|
|
11
|
-
from squirrels._timed_imports import pandas as pd
|
|
8
|
+
from . import _parameter_configs as pc, _parameter_sets as ps, parameter_options as po, data_sources as d, _utils as u
|
|
12
9
|
|
|
13
10
|
|
|
14
11
|
@dataclass
|
|
15
|
-
class Parameter:
|
|
12
|
+
class Parameter(metaclass=ABCMeta):
|
|
16
13
|
"""
|
|
17
|
-
Abstract class for all parameter
|
|
14
|
+
Abstract class for all parameter widgets
|
|
18
15
|
"""
|
|
19
|
-
|
|
20
|
-
name: str
|
|
21
|
-
label: str
|
|
22
|
-
all_options: Sequence[po.ParameterOption]
|
|
23
|
-
is_hidden: bool
|
|
24
|
-
parent: Optional[_SelectionParameter]
|
|
16
|
+
_config: pc.ParameterConfig
|
|
25
17
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
new_param.parent._add_child_mutate(new_param)
|
|
37
|
-
return new_param.refresh(parent)
|
|
38
|
-
|
|
39
|
-
def refresh(self, parent: Optional[_SelectionParameter] = None) -> Parameter:
|
|
18
|
+
@staticmethod
|
|
19
|
+
@abstractmethod
|
|
20
|
+
def _ParameterConfigType() -> Type:
|
|
21
|
+
pass
|
|
22
|
+
|
|
23
|
+
@classmethod
|
|
24
|
+
def Create(
|
|
25
|
+
cls, name: str, label: str, all_options: Sequence[Union[po.ParameterOption, dict]], *, is_hidden: bool = False,
|
|
26
|
+
user_attribute: Optional[str] = None, parent_name: Optional[str] = None, **kwargs
|
|
27
|
+
) -> None:
|
|
40
28
|
"""
|
|
41
|
-
|
|
29
|
+
Method for creating the configurations for a Parameter that may include user attribute or parent
|
|
42
30
|
|
|
43
31
|
Parameters:
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
32
|
+
name: The name of the parameter
|
|
33
|
+
label: The display label for the parameter
|
|
34
|
+
all_options: All options associated to this parameter regardless of the user group or parent parameter option they depend on
|
|
35
|
+
is_hidden: Whether the parameter is hidden in the parameters API response. Default is False
|
|
36
|
+
user_attribute: The user attribute that may cascade the options for this parameter. Default is None
|
|
37
|
+
parent_name: Name of parent parameter that may cascade the options for this parameter. Default is None (no parent)
|
|
48
38
|
"""
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
return param_copy
|
|
39
|
+
param_config_type = cls._ParameterConfigType()
|
|
40
|
+
param_config = param_config_type(name, label, all_options, is_hidden=is_hidden, user_attribute=user_attribute,
|
|
41
|
+
parent_name=parent_name, **kwargs)
|
|
42
|
+
ps.ParameterConfigsSetIO.obj.add(param_config)
|
|
54
43
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
raise u.AbstractMethodCallError(self.__class__, "with_selection")
|
|
44
|
+
@classmethod
|
|
45
|
+
@abstractmethod
|
|
46
|
+
def CreateSimple(cls, name: str, label: str, *args, is_hidden: bool = False, **kwargs) -> None:
|
|
47
|
+
pass
|
|
60
48
|
|
|
61
|
-
|
|
49
|
+
@classmethod
|
|
50
|
+
def CreateFromSource(
|
|
51
|
+
cls, name: str, label: str, data_source: Union[d.DataSource , dict], *, is_hidden: bool = False,
|
|
52
|
+
user_attribute: Optional[str] = None, parent_name: Optional[str] = None, **kwargs
|
|
53
|
+
) -> None:
|
|
62
54
|
"""
|
|
63
|
-
|
|
55
|
+
Method for creating the configurations for any Parameter that uses a DataSource to received the options
|
|
64
56
|
|
|
65
|
-
|
|
66
|
-
|
|
57
|
+
Parameters:
|
|
58
|
+
name: The name of the parameter
|
|
59
|
+
label: The display label for the parameter
|
|
60
|
+
data_source: The lookup table to use for this parameter
|
|
61
|
+
is_hidden: Whether the parameter is hidden in the parameters API response. Default is False
|
|
62
|
+
user_attribute: The user attribute that may cascade the options for this parameter. Default is None
|
|
63
|
+
parent_name: Name of parent parameter that may cascade the options for this parameter. Default is None (no parent)
|
|
67
64
|
"""
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
def _set_default_as_selection_mutate(self) -> None:
|
|
73
|
-
raise u.AbstractMethodCallError(self.__class__, "_set_default_as_selection_mutate")
|
|
74
|
-
|
|
75
|
-
def _refresh_mutate(self) -> None:
|
|
76
|
-
if self.parent is not None and hasattr(self, 'curr_option'):
|
|
77
|
-
self.curr_option = next(self._get_valid_options_iterator())
|
|
78
|
-
self._set_default_as_selection_mutate()
|
|
79
|
-
|
|
80
|
-
def _get_valid_options_iterator(self) -> Iterator[po.ParameterOption]:
|
|
81
|
-
selected_parent_option_ids = self.parent._get_selected_ids_as_list()
|
|
82
|
-
return (x for x in self.all_options if x.is_valid(selected_parent_option_ids))
|
|
83
|
-
|
|
84
|
-
def _raise_invalid_input_error(self, selection: str, more_details: str = '', e: Exception = None) -> None:
|
|
85
|
-
raise u.InvalidInputError(f'Selected value "{selection}" is not valid for parameter "{self.name}". ' + more_details) from e
|
|
86
|
-
|
|
87
|
-
def _verify_parent_is_single_select(self) -> None:
|
|
88
|
-
if not isinstance(self.parent, SingleSelectParameter):
|
|
89
|
-
raise u.ConfigurationError(f'For "{self.name}", it''s not a selection parameter, so its parent must be a SingleSelectParameter')
|
|
90
|
-
|
|
91
|
-
def _verify_parent_options_have_one_child_each(self) -> None:
|
|
92
|
-
accum_set = set()
|
|
93
|
-
for option in self.all_options:
|
|
94
|
-
if not accum_set.isdisjoint(option.parent_option_ids):
|
|
95
|
-
raise u.ConfigurationError(f'For "{self.name}", it''s not a selection parameter, so no two options can share the same parent option')
|
|
96
|
-
accum_set = accum_set.union(option.parent_option_ids)
|
|
97
|
-
if len(accum_set) != len(self.parent.options):
|
|
98
|
-
raise u.ConfigurationError(f'For "{self.name}", all parent option ids must exist across all options')
|
|
99
|
-
|
|
100
|
-
def _set_parent_and_options(self, parent: SingleSelectParameter, all_options: Sequence[po.ParameterOption]) -> None:
|
|
101
|
-
self.parent = parent
|
|
102
|
-
self.all_options = all_options
|
|
103
|
-
self._verify_parent_is_single_select()
|
|
104
|
-
self._verify_parent_options_have_one_child_each()
|
|
105
|
-
|
|
106
|
-
def _accum_all_dependent_params(self, param_set: ParameterSetBase) -> None:
|
|
107
|
-
param_set.add_parameter(self)
|
|
65
|
+
param_config_type = cls._ParameterConfigType()
|
|
66
|
+
param_config = pc.DataSourceParameterConfig(param_config_type, name, label, data_source, is_hidden=is_hidden,
|
|
67
|
+
user_attribute=user_attribute, parent_name=parent_name)
|
|
68
|
+
ps.ParameterConfigsSetIO.obj.add(param_config)
|
|
108
69
|
|
|
109
70
|
def _enquote(self, value: str) -> str:
|
|
110
71
|
return "'" + value.replace("'", "''") + "'"
|
|
111
|
-
|
|
112
|
-
def
|
|
72
|
+
|
|
73
|
+
def _validate_date(self, input_date: str) -> date:
|
|
74
|
+
try:
|
|
75
|
+
return datetime.strptime(input_date.strip(), "%Y-%m-%d").date() if isinstance(input_date, str) else input_date
|
|
76
|
+
except ValueError as e:
|
|
77
|
+
self._config._raise_invalid_input_error(input_date, 'Invalid selection for date.', e)
|
|
78
|
+
|
|
79
|
+
def _validate_number(self, input_number: po.Number, curr_option: po._NumericParameterOption) -> Decimal:
|
|
80
|
+
try:
|
|
81
|
+
return curr_option._validate_value(input_number)
|
|
82
|
+
except u.ConfigurationError as e:
|
|
83
|
+
self._config._raise_invalid_input_error(input_number, 'Invalid selection for number.', e)
|
|
84
|
+
|
|
85
|
+
@abstractmethod
|
|
86
|
+
def to_json_dict0(self) -> dict:
|
|
113
87
|
"""
|
|
114
88
|
Helper method to convert the derived Parameter class into a JSON dictionary
|
|
115
89
|
"""
|
|
116
|
-
return
|
|
117
|
-
'widget_type': self.widget_type,
|
|
118
|
-
'name': self.name,
|
|
119
|
-
'label': self.label
|
|
120
|
-
}
|
|
90
|
+
return self._config.to_json_dict0()
|
|
121
91
|
|
|
122
92
|
|
|
123
93
|
@dataclass
|
|
124
94
|
class _SelectionParameter(Parameter):
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
self.parent._add_child_mutate(self)
|
|
131
|
-
self._refresh_mutate()
|
|
132
|
-
|
|
133
|
-
def _add_child_mutate(self, child: Parameter) -> None:
|
|
134
|
-
self.children.append(child)
|
|
135
|
-
self.trigger_refresh = True
|
|
136
|
-
|
|
137
|
-
def _refresh_mutate(self) -> None:
|
|
138
|
-
if self.parent is not None:
|
|
139
|
-
self.options = tuple(self._get_valid_options_iterator())
|
|
140
|
-
self._set_default_as_selection_mutate()
|
|
141
|
-
self.children = [child.refresh(self) for child in self.children]
|
|
95
|
+
_config: pc.SelectionParameterConfig
|
|
96
|
+
_options: Sequence[po.SelectParameterOption]
|
|
97
|
+
|
|
98
|
+
def __post_init__(self):
|
|
99
|
+
self._options = tuple(self._options)
|
|
142
100
|
|
|
101
|
+
@abstractmethod
|
|
143
102
|
def _get_selected_ids_as_list(self) -> Sequence[str]:
|
|
144
|
-
|
|
103
|
+
pass
|
|
145
104
|
|
|
146
|
-
def
|
|
147
|
-
|
|
105
|
+
def _validate_selected_id_in_options(self, selected_id):
|
|
106
|
+
if selected_id not in (x._identifier for x in self._options):
|
|
107
|
+
self._config._raise_invalid_input_error(selected_id)
|
|
148
108
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
return selected_id
|
|
152
|
-
else:
|
|
153
|
-
self._raise_invalid_input_error(selected_id)
|
|
154
|
-
|
|
155
|
-
def _accum_all_dependent_params(self, param_set: ParameterSetBase) -> None:
|
|
156
|
-
super()._accum_all_dependent_params(param_set)
|
|
157
|
-
for child in self.children:
|
|
158
|
-
child._accum_all_dependent_params(param_set)
|
|
159
|
-
|
|
160
|
-
def to_json_dict(self):
|
|
109
|
+
@abstractmethod
|
|
110
|
+
def to_json_dict0(self):
|
|
161
111
|
"""
|
|
162
112
|
Helper method to convert the derived selection parameter class into a JSON object
|
|
163
113
|
"""
|
|
164
|
-
output = super().
|
|
165
|
-
output['options'] = [x.
|
|
166
|
-
output['trigger_refresh'] = self.trigger_refresh
|
|
114
|
+
output = super().to_json_dict0()
|
|
115
|
+
output['options'] = [x._to_json_dict() for x in self._options]
|
|
167
116
|
return output
|
|
168
117
|
|
|
169
118
|
|
|
170
119
|
@dataclass
|
|
171
120
|
class SingleSelectParameter(_SelectionParameter):
|
|
172
121
|
"""
|
|
173
|
-
Class
|
|
174
|
-
"""
|
|
175
|
-
selected_id: Optional[str]
|
|
122
|
+
Class for single-select parameter widgets.
|
|
176
123
|
|
|
177
|
-
|
|
178
|
-
|
|
124
|
+
Attributes:
|
|
125
|
+
config: The config for this widget parameter (for immutable attributes like name, label, all possible options, etc)
|
|
126
|
+
options: The parameter options that are currently selectable
|
|
127
|
+
selected_id: The ID of the selected option
|
|
128
|
+
"""
|
|
129
|
+
_config: pc.SingleSelectParameterConfig
|
|
130
|
+
_selected_id: Optional[str]
|
|
131
|
+
|
|
132
|
+
def __post_init__(self):
|
|
133
|
+
super().__post_init__()
|
|
134
|
+
if len(self._options) > 0:
|
|
135
|
+
assert self._selected_id != None
|
|
136
|
+
self._validate_selected_id_in_options(self._selected_id)
|
|
137
|
+
else:
|
|
138
|
+
self._selected_id = None
|
|
139
|
+
|
|
140
|
+
@staticmethod
|
|
141
|
+
def _ParameterConfigType():
|
|
142
|
+
return pc.SingleSelectParameterConfig
|
|
143
|
+
|
|
144
|
+
@classmethod
|
|
145
|
+
def CreateSimple(
|
|
146
|
+
cls, name: str, label: str, all_options: Sequence[po.SelectParameterOption], *, is_hidden: bool = False, **kwargs
|
|
147
|
+
) -> None:
|
|
179
148
|
"""
|
|
180
|
-
|
|
149
|
+
Method for creating the configurations for a Parameter that doesn't involve user attributes or parent parameters
|
|
181
150
|
|
|
182
151
|
Parameters:
|
|
183
152
|
name: The name of the parameter
|
|
184
153
|
label: The display label for the parameter
|
|
185
|
-
all_options:
|
|
186
|
-
is_hidden: Whether the parameter is hidden in the parameters API response. Default is False
|
|
187
|
-
parent: The parent parameter that may cascade the options for this parameter. Default is no parent
|
|
188
|
-
"""
|
|
189
|
-
super().__init__("SingleSelectParameter", name, label, all_options, is_hidden, parent)
|
|
190
|
-
|
|
191
|
-
def with_selection(self, selection: str) -> SingleSelectParameter:
|
|
154
|
+
all_options: All options associated to this parameter regardless of the user group or parent parameter option they depend on
|
|
155
|
+
is_hidden: Whether the parameter is hidden in the parameters API response. Default is False
|
|
192
156
|
"""
|
|
193
|
-
|
|
157
|
+
cls.Create(name, label, all_options, is_hidden=is_hidden)
|
|
194
158
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
Returns:
|
|
199
|
-
A new copy of SingleSelectParameter with the selection applied
|
|
200
|
-
"""
|
|
201
|
-
param_copy = copy.copy(self)
|
|
202
|
-
param_copy.selected_id = self._validate_selected_id_in_options(selection)
|
|
203
|
-
param_copy.children = [child.refresh(param_copy) for child in param_copy.children]
|
|
204
|
-
return param_copy
|
|
205
|
-
|
|
206
|
-
def get_selected(self, field: Optional[str] = None, *, default_field: Optional[str] = None,
|
|
207
|
-
default: Any = None) -> Union[po.SelectParameterOption, str]:
|
|
159
|
+
def get_selected(
|
|
160
|
+
self, field: Optional[str] = None, *, default_field: Optional[str] = None, default: Any = None, **kwargs
|
|
161
|
+
) -> Union[po.SelectParameterOption, Any, None]:
|
|
208
162
|
"""
|
|
209
163
|
Gets the selected single-select option or selected custom field
|
|
210
164
|
|
|
@@ -219,115 +173,133 @@ class SingleSelectParameter(_SelectionParameter):
|
|
|
219
173
|
Returns:
|
|
220
174
|
A SelectParameterOption class object if no field is provided, or the type of the custom field
|
|
221
175
|
"""
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
176
|
+
def get_selected_from_id(identifier: str):
|
|
177
|
+
selected = next(x for x in self._options if x._identifier == identifier)
|
|
178
|
+
if field is not None:
|
|
179
|
+
selected = selected.get_custom_field(field, default_field=default_field, default=default)
|
|
180
|
+
return selected
|
|
181
|
+
return u.process_if_not_none(self._selected_id, get_selected_from_id)
|
|
226
182
|
|
|
227
|
-
def get_selected_id(self) -> str:
|
|
183
|
+
def get_selected_id(self, **kwargs) -> Optional[str]:
|
|
228
184
|
"""
|
|
229
185
|
Gets the ID of the selected option
|
|
230
186
|
|
|
231
187
|
Returns:
|
|
232
|
-
A string ID
|
|
188
|
+
A string ID or None if there are no selectable options
|
|
233
189
|
"""
|
|
234
|
-
|
|
190
|
+
def get_id(x: po.SelectParameterOption): return x._identifier
|
|
191
|
+
return u.process_if_not_none(self.get_selected(), get_id)
|
|
235
192
|
|
|
236
|
-
def get_selected_id_quoted(self) -> str:
|
|
193
|
+
def get_selected_id_quoted(self, **kwargs) -> Optional[str]:
|
|
237
194
|
"""
|
|
238
195
|
Gets the ID of the selected option surrounded by single quotes
|
|
239
196
|
|
|
240
197
|
Returns:
|
|
241
|
-
A string
|
|
198
|
+
A string or None if there are no selectable options
|
|
242
199
|
"""
|
|
243
|
-
return
|
|
200
|
+
return u.process_if_not_none(self.get_selected_id(), self._enquote)
|
|
244
201
|
|
|
245
|
-
def get_selected_label(self) -> str:
|
|
202
|
+
def get_selected_label(self, **kwargs) -> Optional[str]:
|
|
246
203
|
"""
|
|
247
204
|
Gets the label of the selected option
|
|
248
205
|
|
|
249
206
|
Returns:
|
|
250
|
-
A string
|
|
207
|
+
A string or None if there are no selectable options
|
|
251
208
|
"""
|
|
252
|
-
|
|
209
|
+
def get_label(x: po.SelectParameterOption): return x._label
|
|
210
|
+
return u.process_if_not_none(self.get_selected(), get_label)
|
|
253
211
|
|
|
254
|
-
def get_selected_label_quoted(self) -> str:
|
|
212
|
+
def get_selected_label_quoted(self, **kwargs) -> Optional[str]:
|
|
255
213
|
"""
|
|
256
214
|
Gets the label of the selected option surrounded by single quotes
|
|
257
215
|
|
|
258
216
|
Returns:
|
|
259
|
-
A string
|
|
217
|
+
A string or None if there are no selectable options
|
|
260
218
|
"""
|
|
261
|
-
return
|
|
262
|
-
|
|
263
|
-
# Overriding for refresh method
|
|
219
|
+
return u.process_if_not_none(self.get_selected_label(), self._enquote)
|
|
220
|
+
|
|
264
221
|
def _get_selected_ids_as_list(self) -> Sequence[str]:
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
default_id = self.options[0].identifier if len(self.options) > 0 else None
|
|
271
|
-
return default_id
|
|
222
|
+
selected_id = self.get_selected_id()
|
|
223
|
+
if selected_id is not None:
|
|
224
|
+
return (self.get_selected_id(),)
|
|
225
|
+
else:
|
|
226
|
+
return tuple()
|
|
272
227
|
|
|
273
|
-
def
|
|
274
|
-
self.selected_id = self._get_default()
|
|
275
|
-
|
|
276
|
-
def to_json_dict(self) -> Dict:
|
|
228
|
+
def to_json_dict0(self) -> dict:
|
|
277
229
|
"""
|
|
278
230
|
Converts this parameter as a JSON object for the parameters API response
|
|
279
231
|
|
|
280
232
|
Returns:
|
|
281
233
|
A dictionary for the JSON object
|
|
282
234
|
"""
|
|
283
|
-
output = super().
|
|
284
|
-
output['selected_id'] = self.
|
|
235
|
+
output = super().to_json_dict0()
|
|
236
|
+
output['selected_id'] = self._selected_id
|
|
285
237
|
return output
|
|
286
238
|
|
|
287
239
|
|
|
288
240
|
@dataclass
|
|
289
241
|
class MultiSelectParameter(_SelectionParameter):
|
|
290
242
|
"""
|
|
291
|
-
Class
|
|
243
|
+
Class for multi-select parameter widgets.
|
|
244
|
+
|
|
245
|
+
Attributes:
|
|
246
|
+
config: The config for this widget parameter (for immutable attributes like name, label, all possible options, etc)
|
|
247
|
+
options: The parameter options that are currently selectable
|
|
248
|
+
selected_ids: A sequence of IDs of the selected options
|
|
292
249
|
"""
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
order_matters: bool
|
|
250
|
+
_config: pc.MultiSelectParameterConfig
|
|
251
|
+
_selected_ids: Sequence[str]
|
|
296
252
|
|
|
297
|
-
def
|
|
298
|
-
|
|
253
|
+
def __post_init__(self):
|
|
254
|
+
super().__post_init__()
|
|
255
|
+
self._selected_ids = tuple(self._selected_ids)
|
|
256
|
+
for selected_id in self._selected_ids:
|
|
257
|
+
self._validate_selected_id_in_options(selected_id)
|
|
258
|
+
|
|
259
|
+
@staticmethod
|
|
260
|
+
def _ParameterConfigType():
|
|
261
|
+
return pc.MultiSelectParameterConfig
|
|
262
|
+
|
|
263
|
+
@classmethod
|
|
264
|
+
def Create(
|
|
265
|
+
cls, name: str, label: str, all_options: Sequence[Union[po.SelectParameterOption, dict]], *, include_all: bool = True,
|
|
266
|
+
order_matters: bool = False, is_hidden: bool = False, user_attribute: Optional[str] = None, parent_name: Optional[str] = None,
|
|
267
|
+
**kwargs
|
|
268
|
+
) -> None:
|
|
299
269
|
"""
|
|
300
|
-
|
|
270
|
+
Method for creating the configurations for a Parameter that may include user attribute or parent
|
|
301
271
|
|
|
302
272
|
Parameters:
|
|
303
273
|
name: The name of the parameter
|
|
304
274
|
label: The display label for the parameter
|
|
305
|
-
all_options:
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
275
|
+
all_options: All options associated to this parameter regardless of the user group or parent parameter option they depend on
|
|
276
|
+
include_all: Whether having no options selected is equivalent to all selectable options selected
|
|
277
|
+
order_matters: Whether the order of the selections made matter
|
|
278
|
+
is_hidden: Whether the parameter is hidden in the parameters API response. Default is False
|
|
279
|
+
user_attribute: The user attribute that may cascade the options for this parameter. Default is None
|
|
280
|
+
parent_name: Name of parent parameter that may cascade the options for this parameter. Default is None (no parent)
|
|
310
281
|
"""
|
|
311
|
-
super().
|
|
312
|
-
|
|
313
|
-
self.order_matters = order_matters
|
|
282
|
+
super(cls, cls).Create(name, label, all_options, include_all=include_all, order_matters=order_matters, is_hidden=is_hidden,
|
|
283
|
+
user_attribute=user_attribute, parent_name=parent_name)
|
|
314
284
|
|
|
315
|
-
|
|
285
|
+
@classmethod
|
|
286
|
+
def CreateSimple(
|
|
287
|
+
cls, name: str, label: str, all_options: Sequence[po.SelectParameterOption], *, include_all: bool = True,
|
|
288
|
+
order_matters: bool = False, is_hidden: bool = False, **kwargs
|
|
289
|
+
) -> None:
|
|
316
290
|
"""
|
|
317
|
-
|
|
291
|
+
Method for creating the configurations for a Parameter that doesn't involve user attributes or parent parameters
|
|
318
292
|
|
|
319
293
|
Parameters:
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
294
|
+
name: The name of the parameter
|
|
295
|
+
label: The display label for the parameter
|
|
296
|
+
all_options: All options associated to this parameter regardless of the user group or parent parameter option they depend on
|
|
297
|
+
include_all: Whether having no options selected is equivalent to all selectable options selected
|
|
298
|
+
order_matters: Whether the order of the selections made matter
|
|
299
|
+
is_hidden: Whether the parameter is hidden in the parameters API response. Default is False
|
|
324
300
|
"""
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
param_copy.selected_ids = tuple(self._validate_selected_id_in_options(x) for x in selection_split)
|
|
328
|
-
param_copy.children = [child.refresh(param_copy) for child in self.children]
|
|
329
|
-
return param_copy
|
|
330
|
-
|
|
301
|
+
cls.Create(name, label, all_options, include_all=include_all, order_matters=order_matters, is_hidden=is_hidden)
|
|
302
|
+
|
|
331
303
|
def has_non_empty_selection(self) -> bool:
|
|
332
304
|
"""
|
|
333
305
|
Returns True if more than zero options were selected. False otherwise.
|
|
@@ -338,10 +310,11 @@ class MultiSelectParameter(_SelectionParameter):
|
|
|
338
310
|
Returns:
|
|
339
311
|
A boolean
|
|
340
312
|
"""
|
|
341
|
-
return len(self.
|
|
313
|
+
return len(self._selected_ids) > 0
|
|
342
314
|
|
|
343
|
-
def get_selected_list(
|
|
344
|
-
|
|
315
|
+
def get_selected_list(
|
|
316
|
+
self, field: Optional[str] = None, *, default_field: Optional[str] = None, default: Any = None, **kwargs
|
|
317
|
+
) -> Sequence[Union[po.SelectParameterOption, Any]]:
|
|
345
318
|
"""
|
|
346
319
|
Gets the sequence of the selected option(s) or a sequence of selected custom fields
|
|
347
320
|
|
|
@@ -356,35 +329,35 @@ class MultiSelectParameter(_SelectionParameter):
|
|
|
356
329
|
Returns:
|
|
357
330
|
A sequence of SelectParameterOption class objects or sequence of type of custom field
|
|
358
331
|
"""
|
|
359
|
-
if not self.has_non_empty_selection() and self.include_all:
|
|
360
|
-
selected_list = self.
|
|
332
|
+
if not self.has_non_empty_selection() and self._config.include_all:
|
|
333
|
+
selected_list = self._options
|
|
361
334
|
else:
|
|
362
|
-
selected_list = (x for x in self.
|
|
335
|
+
selected_list = (x for x in self._options if x._identifier in self._selected_ids)
|
|
363
336
|
|
|
364
337
|
if field is not None:
|
|
365
|
-
selected_list = [selected.get_custom_field(field, default_field, default) for selected in selected_list]
|
|
338
|
+
selected_list = [selected.get_custom_field(field, default_field=default_field, default=default) for selected in selected_list]
|
|
366
339
|
|
|
367
340
|
return tuple(selected_list)
|
|
368
341
|
|
|
369
|
-
def get_selected_ids_as_list(self) -> Sequence[str]:
|
|
342
|
+
def get_selected_ids_as_list(self, **kwargs) -> Sequence[str]:
|
|
370
343
|
"""
|
|
371
344
|
Gets the sequence of ID(s) of the selected option(s)
|
|
372
345
|
|
|
373
346
|
Returns:
|
|
374
347
|
A sequence of strings
|
|
375
348
|
"""
|
|
376
|
-
return tuple(x.
|
|
349
|
+
return tuple(x._identifier for x in self.get_selected_list())
|
|
377
350
|
|
|
378
|
-
def get_selected_ids_joined(self) -> str:
|
|
351
|
+
def get_selected_ids_joined(self, **kwargs) -> str:
|
|
379
352
|
"""
|
|
380
353
|
Gets the ID(s) of the selected option(s) joined by comma
|
|
381
354
|
|
|
382
355
|
Returns:
|
|
383
356
|
A string
|
|
384
357
|
"""
|
|
385
|
-
return ',
|
|
358
|
+
return ','.join(self.get_selected_ids_as_list())
|
|
386
359
|
|
|
387
|
-
def get_selected_ids_quoted_as_list(self) -> Sequence[str]:
|
|
360
|
+
def get_selected_ids_quoted_as_list(self, **kwargs) -> Sequence[str]:
|
|
388
361
|
"""
|
|
389
362
|
Gets the sequence of ID(s) of the selected option(s) surrounded by single quotes
|
|
390
363
|
|
|
@@ -393,34 +366,34 @@ class MultiSelectParameter(_SelectionParameter):
|
|
|
393
366
|
"""
|
|
394
367
|
return tuple(self._enquote(x) for x in self.get_selected_ids_as_list())
|
|
395
368
|
|
|
396
|
-
def get_selected_ids_quoted_joined(self) -> str:
|
|
369
|
+
def get_selected_ids_quoted_joined(self, **kwargs) -> str:
|
|
397
370
|
"""
|
|
398
371
|
Gets the ID(s) of the selected option(s) surrounded by single quotes and joined by comma
|
|
399
372
|
|
|
400
373
|
Returns:
|
|
401
374
|
A string
|
|
402
375
|
"""
|
|
403
|
-
return ',
|
|
376
|
+
return ','.join(self.get_selected_ids_quoted_as_list())
|
|
404
377
|
|
|
405
|
-
def get_selected_labels_as_list(self) -> Sequence[str]:
|
|
378
|
+
def get_selected_labels_as_list(self, **kwargs) -> Sequence[str]:
|
|
406
379
|
"""
|
|
407
380
|
Gets the sequence of label(s) of the selected option(s)
|
|
408
381
|
|
|
409
382
|
Returns:
|
|
410
383
|
A sequence of strings
|
|
411
384
|
"""
|
|
412
|
-
return tuple(x.
|
|
385
|
+
return tuple(x._label for x in self.get_selected_list())
|
|
413
386
|
|
|
414
|
-
def get_selected_labels_joined(self) -> str:
|
|
387
|
+
def get_selected_labels_joined(self, **kwargs) -> str:
|
|
415
388
|
"""
|
|
416
389
|
Gets the label(s) of the selected option(s) joined by comma
|
|
417
390
|
|
|
418
391
|
Returns:
|
|
419
392
|
A string
|
|
420
393
|
"""
|
|
421
|
-
return ',
|
|
394
|
+
return ','.join(self.get_selected_labels_as_list())
|
|
422
395
|
|
|
423
|
-
def get_selected_labels_quoted_as_list(self) -> Sequence[str]:
|
|
396
|
+
def get_selected_labels_quoted_as_list(self, **kwargs) -> Sequence[str]:
|
|
424
397
|
"""
|
|
425
398
|
Gets the sequence of label(s) of the selected option(s) surrounded by single quotes
|
|
426
399
|
|
|
@@ -429,97 +402,68 @@ class MultiSelectParameter(_SelectionParameter):
|
|
|
429
402
|
"""
|
|
430
403
|
return tuple(self._enquote(x) for x in self.get_selected_labels_as_list())
|
|
431
404
|
|
|
432
|
-
def get_selected_labels_quoted_joined(self) -> str:
|
|
405
|
+
def get_selected_labels_quoted_joined(self, **kwargs) -> str:
|
|
433
406
|
"""
|
|
434
407
|
Gets the label(s) of the selected option(s) surrounded by single quotes and joined by comma
|
|
435
408
|
|
|
436
409
|
Returns:
|
|
437
410
|
A string
|
|
438
411
|
"""
|
|
439
|
-
return ',
|
|
440
|
-
|
|
441
|
-
def _get_selected_ids_as_list(self) -> Sequence[str]:
|
|
412
|
+
return ','.join(self.get_selected_labels_quoted_as_list())
|
|
413
|
+
|
|
414
|
+
def _get_selected_ids_as_list(self, **kwargs) -> Sequence[str]:
|
|
442
415
|
return self.get_selected_ids_as_list()
|
|
443
416
|
|
|
444
|
-
def
|
|
445
|
-
return tuple(self._get_default_iterator())
|
|
446
|
-
|
|
447
|
-
def _set_default_as_selection_mutate(self):
|
|
448
|
-
self.selected_ids = self._get_default()
|
|
449
|
-
|
|
450
|
-
def to_json_dict(self):
|
|
417
|
+
def to_json_dict0(self):
|
|
451
418
|
"""
|
|
452
419
|
Converts this parameter as a JSON object for the parameters API response
|
|
453
420
|
|
|
454
421
|
Returns:
|
|
455
422
|
A dictionary for the JSON object
|
|
456
423
|
"""
|
|
457
|
-
output = super().
|
|
458
|
-
output['selected_ids'] = list(self.
|
|
459
|
-
output['include_all'] = self.include_all
|
|
460
|
-
output['order_matters'] = self.order_matters
|
|
424
|
+
output = super().to_json_dict0()
|
|
425
|
+
output['selected_ids'] = list(self._selected_ids)
|
|
461
426
|
return output
|
|
462
427
|
|
|
463
428
|
|
|
464
429
|
@dataclass
|
|
465
430
|
class DateParameter(Parameter):
|
|
466
431
|
"""
|
|
467
|
-
Class
|
|
468
|
-
"""
|
|
469
|
-
curr_option: po.DateParameterOption
|
|
470
|
-
selected_date: datetime
|
|
432
|
+
Class for date parameter widgets.
|
|
471
433
|
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
434
|
+
Attributes:
|
|
435
|
+
config: The config for this widget parameter (for immutable attributes like name, label, all possible options, etc)
|
|
436
|
+
curr_option: The current option showing for defaults based on user attribute and selection of parent
|
|
437
|
+
selected_date: The selected date
|
|
438
|
+
"""
|
|
439
|
+
_curr_option: po.DateParameterOption
|
|
440
|
+
_selected_date: Union[date, str]
|
|
476
441
|
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
label: The display label for the parameter
|
|
480
|
-
default_date: The default selected date
|
|
481
|
-
date_format: The format of the default_date. Default is '%Y-%m-%d'
|
|
482
|
-
is_hidden: Whether the parameter is hidden in the parameters API response. Default is False
|
|
483
|
-
"""
|
|
484
|
-
self.curr_option = po.DateParameterOption(default_date, date_format)
|
|
485
|
-
all_options = (self.curr_option,)
|
|
486
|
-
super().__init__("DateParameter", name, label, all_options, is_hidden, None)
|
|
487
|
-
self._set_default_as_selection_mutate()
|
|
442
|
+
def __post_init__(self):
|
|
443
|
+
self._selected_date: date = self._validate_date(self._selected_date)
|
|
488
444
|
|
|
489
445
|
@staticmethod
|
|
490
|
-
def
|
|
491
|
-
|
|
446
|
+
def _ParameterConfigType():
|
|
447
|
+
return pc.DateParameterConfig
|
|
448
|
+
|
|
449
|
+
@classmethod
|
|
450
|
+
def CreateSimple(
|
|
451
|
+
cls, name: str, label: str, default_date: Union[str, date], *, date_format: str = '%Y-%m-%d', is_hidden: bool = False, **kwargs
|
|
452
|
+
) -> None:
|
|
492
453
|
"""
|
|
493
|
-
|
|
454
|
+
Method for creating the configurations for a Parameter that doesn't involve user attributes or parent parameters
|
|
494
455
|
|
|
495
456
|
Parameters:
|
|
496
457
|
name: The name of the parameter
|
|
497
458
|
label: The display label for the parameter
|
|
498
|
-
|
|
499
|
-
|
|
459
|
+
default_date: Default date for this option
|
|
460
|
+
date_format: Format of the default date, default is '%Y-%m-%d'
|
|
500
461
|
is_hidden: Whether the parameter is hidden in the parameters API response. Default is False
|
|
501
462
|
"""
|
|
502
|
-
|
|
503
|
-
|
|
463
|
+
single_param_option = po.DateParameterOption(default_date, date_format=date_format)
|
|
464
|
+
cls.Create(name, label, (single_param_option,), is_hidden=is_hidden)
|
|
504
465
|
|
|
505
|
-
def
|
|
506
|
-
"""
|
|
507
|
-
Applies the selected date to this widget parameter
|
|
508
|
-
|
|
509
|
-
Parameters:
|
|
510
|
-
selection: The date string which must be in yyyy-mm-dd format (regardless of self.date_format value)
|
|
511
|
-
|
|
512
|
-
Returns:
|
|
513
|
-
A new copy of DateParameter with the selection applied
|
|
514
|
-
"""
|
|
515
|
-
param_copy = copy.copy(self)
|
|
516
|
-
try:
|
|
517
|
-
param_copy.selected_date = datetime.strptime(selection, "%Y-%m-%d")
|
|
518
|
-
except ValueError as e:
|
|
519
|
-
self._raise_invalid_input_error(selection, 'Invalid selection for date.', e)
|
|
520
|
-
return param_copy
|
|
521
|
-
|
|
522
|
-
def get_selected_date(self, date_format: str = None) -> str:
|
|
466
|
+
def get_selected_date(self, *, date_format: str = None, **kwargs) -> str:
|
|
523
467
|
"""
|
|
524
468
|
Gets selected date as string
|
|
525
469
|
|
|
@@ -529,10 +473,10 @@ class DateParameter(Parameter):
|
|
|
529
473
|
Returns:
|
|
530
474
|
A string
|
|
531
475
|
"""
|
|
532
|
-
date_format = self.
|
|
533
|
-
return self.
|
|
476
|
+
date_format = self._curr_option._date_format if date_format is None else date_format
|
|
477
|
+
return self._selected_date.strftime(date_format)
|
|
534
478
|
|
|
535
|
-
def get_selected_date_quoted(self, date_format: str = None) -> str:
|
|
479
|
+
def get_selected_date_quoted(self, *, date_format: str = None, **kwargs) -> str:
|
|
536
480
|
"""
|
|
537
481
|
Gets selected date as string surrounded by single quotes
|
|
538
482
|
|
|
@@ -542,12 +486,9 @@ class DateParameter(Parameter):
|
|
|
542
486
|
Returns:
|
|
543
487
|
A string
|
|
544
488
|
"""
|
|
545
|
-
return self._enquote(self.get_selected_date(date_format))
|
|
546
|
-
|
|
547
|
-
def _set_default_as_selection_mutate(self) -> None:
|
|
548
|
-
self.selected_date = self.curr_option.default_date
|
|
489
|
+
return self._enquote(self.get_selected_date(date_format=date_format))
|
|
549
490
|
|
|
550
|
-
def
|
|
491
|
+
def to_json_dict0(self):
|
|
551
492
|
"""
|
|
552
493
|
Converts this parameter as a JSON object for the parameters API response
|
|
553
494
|
|
|
@@ -556,271 +497,259 @@ class DateParameter(Parameter):
|
|
|
556
497
|
Returns:
|
|
557
498
|
A dictionary for the JSON object
|
|
558
499
|
"""
|
|
559
|
-
output = super().
|
|
560
|
-
output
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
@dataclass
|
|
565
|
-
class _NumericParameter(Parameter):
|
|
566
|
-
curr_option: po.NumericParameterOption
|
|
567
|
-
|
|
568
|
-
def to_json_dict(self):
|
|
569
|
-
"""
|
|
570
|
-
Helper method to converts numeric parameters into JSON objects for the parameters API response
|
|
571
|
-
|
|
572
|
-
Returns:
|
|
573
|
-
A dictionary for the JSON object
|
|
574
|
-
"""
|
|
575
|
-
output = super().to_json_dict()
|
|
576
|
-
output['min_value'] = str(self.curr_option.min_value)
|
|
577
|
-
output['max_value'] = str(self.curr_option.max_value)
|
|
578
|
-
output['increment'] = str(self.curr_option.increment)
|
|
500
|
+
output = super().to_json_dict0()
|
|
501
|
+
output.update(self._curr_option._to_json_dict())
|
|
502
|
+
output['selected_date'] = self.get_selected_date(date_format="%Y-%m-%d")
|
|
579
503
|
return output
|
|
580
504
|
|
|
581
505
|
|
|
582
506
|
@dataclass
|
|
583
|
-
class
|
|
507
|
+
class DateRangeParameter(Parameter):
|
|
584
508
|
"""
|
|
585
|
-
Class
|
|
509
|
+
Class for date range parameter widgets.
|
|
510
|
+
|
|
511
|
+
Attributes:
|
|
512
|
+
config: The config for this widget parameter (for immutable attributes like name, label, all possible options, etc)
|
|
513
|
+
curr_option: The current option showing for defaults based on user attribute and selection of parent
|
|
514
|
+
selected_start_date: The selected start date
|
|
515
|
+
selected_end_date: The selected end date
|
|
586
516
|
"""
|
|
587
|
-
|
|
517
|
+
_curr_option: po.DateRangeParameterOption
|
|
518
|
+
_selected_start_date: Union[date, str]
|
|
519
|
+
_selected_end_date: Union[date, str]
|
|
520
|
+
|
|
521
|
+
def __post_init__(self):
|
|
522
|
+
self._selected_start_date: date = self._validate_date(self._selected_start_date)
|
|
523
|
+
self._selected_end_date: date = self._validate_date(self._selected_end_date)
|
|
524
|
+
|
|
525
|
+
@staticmethod
|
|
526
|
+
def _ParameterConfigType():
|
|
527
|
+
return pc.DateRangeParameterConfig
|
|
588
528
|
|
|
589
|
-
|
|
590
|
-
|
|
529
|
+
@classmethod
|
|
530
|
+
def CreateSimple(
|
|
531
|
+
cls, name: str, label: str, default_start_date: Union[str, date], default_end_date: Union[str, date],
|
|
532
|
+
*, date_format: str = '%Y-%m-%d', is_hidden: bool = False, **kwargs
|
|
533
|
+
) -> None:
|
|
591
534
|
"""
|
|
592
|
-
|
|
535
|
+
Method for creating the configurations for a Parameter that doesn't involve user attributes or parent parameters
|
|
593
536
|
|
|
594
537
|
Parameters:
|
|
595
538
|
name: The name of the parameter
|
|
596
539
|
label: The display label for the parameter
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
default_value: The default selection. Can be of type Decimal, integer, or number parsable string. Default is min_value
|
|
540
|
+
default_start_date: Default start date for this option
|
|
541
|
+
default_end_date: Default end date for this option
|
|
542
|
+
date_format: Format of the default date, default is '%Y-%m-%d'
|
|
601
543
|
is_hidden: Whether the parameter is hidden in the parameters API response. Default is False
|
|
602
544
|
"""
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
all_options = (curr_option,)
|
|
606
|
-
super().__init__("NumberParameter", name, label, all_options, is_hidden, None, curr_option)
|
|
607
|
-
self._set_default_as_selection_mutate()
|
|
545
|
+
single_param_option = po.DateRangeParameterOption(default_start_date, default_end_date, date_format=date_format)
|
|
546
|
+
cls.Create(name, label, (single_param_option,), is_hidden=is_hidden)
|
|
608
547
|
|
|
609
|
-
|
|
610
|
-
def WithParent(name: str, label: str, all_options: Sequence[po.NumberParameterOption], parent: SingleSelectParameter, *,
|
|
611
|
-
is_hidden: bool = False) -> DateParameter:
|
|
548
|
+
def get_selected_start_date(self, *, date_format: str = None, **kwargs) -> str:
|
|
612
549
|
"""
|
|
613
|
-
|
|
550
|
+
Gets selected start date as string
|
|
614
551
|
|
|
615
552
|
Parameters:
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
553
|
+
date_format: The date format (see Python's datetime formats). If not specified, self.date_format is used
|
|
554
|
+
|
|
555
|
+
Returns:
|
|
556
|
+
A string
|
|
557
|
+
"""
|
|
558
|
+
date_format = self._curr_option._date_format if date_format is None else date_format
|
|
559
|
+
return self._selected_start_date.strftime(date_format)
|
|
560
|
+
|
|
561
|
+
def get_selected_start_date_quoted(self, *, date_format: str = None, **kwargs) -> str:
|
|
562
|
+
"""
|
|
563
|
+
Gets selected start date as string surrounded by single quotes
|
|
564
|
+
|
|
565
|
+
Parameters:
|
|
566
|
+
date_format: The date format (see Python's datetime formats). If not specified, self.date_format is used
|
|
567
|
+
|
|
568
|
+
Returns:
|
|
569
|
+
A string
|
|
621
570
|
"""
|
|
622
|
-
|
|
623
|
-
return Parameter.WithParent(all_options, parent, new_param)
|
|
571
|
+
return self._enquote(self.get_selected_start_date(date_format=date_format))
|
|
624
572
|
|
|
625
|
-
def
|
|
573
|
+
def get_selected_end_date(self, *, date_format: str = None, **kwargs) -> str:
|
|
626
574
|
"""
|
|
627
|
-
|
|
575
|
+
Gets selected end date as string
|
|
628
576
|
|
|
629
577
|
Parameters:
|
|
630
|
-
|
|
631
|
-
|
|
578
|
+
date_format: The date format (see Python's datetime formats). If not specified, self.date_format is used
|
|
579
|
+
|
|
632
580
|
Returns:
|
|
633
|
-
A
|
|
581
|
+
A string
|
|
634
582
|
"""
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
param_copy.selected_value = param_copy.curr_option._validate_value(selection)
|
|
638
|
-
except u.ConfigurationError as e:
|
|
639
|
-
self._raise_invalid_input_error(selection, 'Invalid selection for number parameter.', e)
|
|
640
|
-
return param_copy
|
|
583
|
+
date_format = self._curr_option._date_format if date_format is None else date_format
|
|
584
|
+
return self._selected_end_date.strftime(date_format)
|
|
641
585
|
|
|
642
|
-
def
|
|
586
|
+
def get_selected_end_date_quoted(self, *, date_format: str = None, **kwargs) -> str:
|
|
643
587
|
"""
|
|
644
|
-
|
|
588
|
+
Gets selected end date as string surrounded by single quotes
|
|
589
|
+
|
|
590
|
+
Parameters:
|
|
591
|
+
date_format: The date format (see Python's datetime formats). If not specified, self.date_format is used
|
|
645
592
|
|
|
646
593
|
Returns:
|
|
647
|
-
A
|
|
594
|
+
A string
|
|
648
595
|
"""
|
|
649
|
-
return
|
|
596
|
+
return self._enquote(self.get_selected_end_date(date_format=date_format))
|
|
650
597
|
|
|
651
|
-
def
|
|
652
|
-
self.curr_option: po.NumberParameterOption
|
|
653
|
-
self.selected_value = self.curr_option.default_value
|
|
654
|
-
|
|
655
|
-
def to_json_dict(self):
|
|
598
|
+
def to_json_dict0(self):
|
|
656
599
|
"""
|
|
657
600
|
Converts this parameter as a JSON object for the parameters API response
|
|
658
601
|
|
|
602
|
+
The "selected_date" field will always be in yyyy-mm-dd format
|
|
603
|
+
|
|
659
604
|
Returns:
|
|
660
605
|
A dictionary for the JSON object
|
|
661
606
|
"""
|
|
662
|
-
output = super().
|
|
663
|
-
output
|
|
607
|
+
output = super().to_json_dict0()
|
|
608
|
+
output.update(self._curr_option._to_json_dict())
|
|
609
|
+
output['selected_start_date'] = self.get_selected_start_date(date_format="%Y-%m-%d")
|
|
610
|
+
output['selected_end_date'] = self.get_selected_end_date(date_format="%Y-%m-%d")
|
|
664
611
|
return output
|
|
665
612
|
|
|
666
613
|
|
|
667
614
|
@dataclass
|
|
668
|
-
class
|
|
615
|
+
class NumberParameter(Parameter):
|
|
669
616
|
"""
|
|
670
|
-
Class
|
|
671
|
-
"""
|
|
672
|
-
selected_lower_value: Decimal
|
|
673
|
-
selected_upper_value: Decimal
|
|
617
|
+
Class for number parameter widgets.
|
|
674
618
|
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
619
|
+
Attributes:
|
|
620
|
+
config: The config for this widget parameter (for immutable attributes like name, label, all possible options, etc)
|
|
621
|
+
curr_option: The current option showing for defaults based on user attribute and selection of parent
|
|
622
|
+
selected_value: The selected integer or decimal number
|
|
623
|
+
"""
|
|
624
|
+
_curr_option: po.NumberParameterOption
|
|
625
|
+
_selected_value: po.Number
|
|
679
626
|
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
label: The display label for the parameter
|
|
683
|
-
min_value: The minimum bound for selection. Can be of type Decimal, integer, or number parsable string
|
|
684
|
-
max_value: The maxixmum bound for selection. Can be of type Decimal, integer, or number parsable string
|
|
685
|
-
increment: The increment for allowable selections. Can be of type Decimal, integer, or number parsable string. Default is 1
|
|
686
|
-
default_lower_value: The default lower selection. Can be of type Decimal, integer, or number parsable string. Default is min_value
|
|
687
|
-
default_upper_value: The default upper selection. Can be of type Decimal, integer, or number parsable string. Default is max_value
|
|
688
|
-
is_hidden: Whether the parameter is hidden in the parameters API response. Default is False
|
|
689
|
-
"""
|
|
690
|
-
default_lower_value = default_lower_value if default_lower_value is not None else min_value
|
|
691
|
-
default_upper_value = default_upper_value if default_upper_value is not None else max_value
|
|
692
|
-
curr_option = po.NumRangeParameterOption(min_value, max_value, increment, default_lower_value, default_upper_value)
|
|
693
|
-
all_options = (curr_option,)
|
|
694
|
-
super().__init__("NumRangeParameter", name, label, all_options, is_hidden, None, curr_option)
|
|
695
|
-
self._set_default_as_selection_mutate()
|
|
627
|
+
def __post_init__(self):
|
|
628
|
+
self._selected_value: Decimal = self._validate_number(self._selected_value, self._curr_option)
|
|
696
629
|
|
|
697
630
|
@staticmethod
|
|
698
|
-
def
|
|
699
|
-
|
|
700
|
-
"""
|
|
701
|
-
A factory method to construct a NumRangeParameter with a parent parameter
|
|
631
|
+
def _ParameterConfigType():
|
|
632
|
+
return pc.NumberParameterConfig
|
|
702
633
|
|
|
634
|
+
@classmethod
|
|
635
|
+
def CreateSimple(
|
|
636
|
+
cls, name: str, label: str, min_value: po.Number, max_value: po.Number, *, increment: po.Number = 1,
|
|
637
|
+
default_value: Optional[po.Number] = None, is_hidden: bool = False, **kwargs
|
|
638
|
+
) -> None:
|
|
639
|
+
"""
|
|
640
|
+
Method for creating the configurations for a Parameter that doesn't involve user attributes or parent parameters
|
|
641
|
+
|
|
642
|
+
* Note that the "Number" type denotes an int, a Decimal (from decimal module), or a string that can be parsed to Decimal
|
|
643
|
+
|
|
703
644
|
Parameters:
|
|
704
645
|
name: The name of the parameter
|
|
705
646
|
label: The display label for the parameter
|
|
706
|
-
|
|
707
|
-
|
|
647
|
+
min_value: Minimum selectable value
|
|
648
|
+
max_value: Maximum selectable value
|
|
649
|
+
increment: Increment of selectable values, and must fit evenly between min_value and max_value
|
|
650
|
+
default_value: Default value for this option, and must be selectable based on min_value, max_value, and increment
|
|
708
651
|
is_hidden: Whether the parameter is hidden in the parameters API response. Default is False
|
|
709
652
|
"""
|
|
710
|
-
|
|
711
|
-
|
|
653
|
+
single_param_option = po.NumberParameterOption(min_value, max_value, increment=increment, default_value=default_value)
|
|
654
|
+
cls.Create(name, label, (single_param_option,), is_hidden=is_hidden)
|
|
712
655
|
|
|
713
|
-
def
|
|
656
|
+
def get_selected_value(self, **kwargs) -> str:
|
|
714
657
|
"""
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
Parameters:
|
|
718
|
-
selection: The lower and upper selected numbers joined by comma (with no spaces)
|
|
719
|
-
|
|
720
|
-
Returns:
|
|
721
|
-
A new copy of NumRangeParameter with the selection applied
|
|
722
|
-
"""
|
|
723
|
-
try:
|
|
724
|
-
lower, upper = selection.split(',')
|
|
725
|
-
except ValueError as e:
|
|
726
|
-
self._raise_invalid_input_error(selection, "Range parameter selection must be two numbers joined by comma.", e)
|
|
727
|
-
|
|
728
|
-
param_copy = copy.copy(self)
|
|
729
|
-
try:
|
|
730
|
-
param_copy.selected_lower_value = param_copy.curr_option._validate_value(lower)
|
|
731
|
-
param_copy.selected_upper_value = param_copy.curr_option._validate_value(upper, param_copy.selected_lower_value)
|
|
732
|
-
except u.ConfigurationError as e:
|
|
733
|
-
self._raise_invalid_input_error(selection, 'Invalid selection for range parameter.', e)
|
|
734
|
-
return param_copy
|
|
735
|
-
|
|
736
|
-
def get_selected_lower_value(self) -> str:
|
|
737
|
-
"""
|
|
738
|
-
Get the selected lower number
|
|
739
|
-
|
|
740
|
-
Returns:
|
|
741
|
-
A number parsable string of the selected number
|
|
742
|
-
"""
|
|
743
|
-
return str(self.selected_lower_value)
|
|
744
|
-
|
|
745
|
-
def get_selected_upper_value(self) -> str:
|
|
746
|
-
"""
|
|
747
|
-
Get the selected upper number
|
|
658
|
+
Get the selected number
|
|
748
659
|
|
|
749
660
|
Returns:
|
|
750
661
|
A number parsable string of the selected number
|
|
751
662
|
"""
|
|
752
|
-
return str(self.
|
|
753
|
-
|
|
754
|
-
def
|
|
755
|
-
self.curr_option: po.NumRangeParameterOption
|
|
756
|
-
self.selected_lower_value = self.curr_option.default_lower_value
|
|
757
|
-
self.selected_upper_value = self.curr_option.default_upper_value
|
|
758
|
-
|
|
759
|
-
def to_json_dict(self):
|
|
663
|
+
return str(self._selected_value)
|
|
664
|
+
|
|
665
|
+
def to_json_dict0(self):
|
|
760
666
|
"""
|
|
761
667
|
Converts this parameter as a JSON object for the parameters API response
|
|
762
668
|
|
|
763
669
|
Returns:
|
|
764
670
|
A dictionary for the JSON object
|
|
765
671
|
"""
|
|
766
|
-
output = super().
|
|
767
|
-
output
|
|
768
|
-
output['
|
|
672
|
+
output = super().to_json_dict0()
|
|
673
|
+
output.update(self._curr_option._to_json_dict())
|
|
674
|
+
output['selected_value'] = self.get_selected_value()
|
|
769
675
|
return output
|
|
770
676
|
|
|
771
677
|
|
|
772
678
|
@dataclass
|
|
773
|
-
class
|
|
679
|
+
class NumberRangeParameter(Parameter):
|
|
774
680
|
"""
|
|
775
|
-
Class for
|
|
681
|
+
Class for number range parameter widgets.
|
|
682
|
+
|
|
683
|
+
Attributes:
|
|
684
|
+
config: The config for this widget parameter (for immutable attributes like name, label, all possible options, etc)
|
|
685
|
+
curr_option: The current option showing for defaults based on user attribute and selection of parent
|
|
686
|
+
selected_lower_value: The selected lower integer or decimal number
|
|
687
|
+
selected_upper_value: The selected upper integer or decimal number
|
|
776
688
|
"""
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
689
|
+
_curr_option: po.NumberRangeParameterOption
|
|
690
|
+
_selected_lower_value: po.Number
|
|
691
|
+
_selected_upper_value: po.Number
|
|
780
692
|
|
|
781
|
-
def
|
|
782
|
-
|
|
693
|
+
def __post_init__(self):
|
|
694
|
+
self._selected_lower_value: Decimal = self._validate_number(self._selected_lower_value, self._curr_option)
|
|
695
|
+
self._selected_upper_value: Decimal = self._validate_number(self._selected_upper_value, self._curr_option)
|
|
696
|
+
|
|
697
|
+
@staticmethod
|
|
698
|
+
def _ParameterConfigType():
|
|
699
|
+
return pc.NumberRangeParameterConfig
|
|
700
|
+
|
|
701
|
+
@classmethod
|
|
702
|
+
def CreateSimple(
|
|
703
|
+
cls, name: str, label: str, min_value: po.Number, max_value: po.Number, *, increment: po.Number = 1,
|
|
704
|
+
default_lower_value: Optional[po.Number] = None, default_upper_value: Optional[po.Number] = None, is_hidden: bool = False, **kwargs
|
|
705
|
+
) -> None:
|
|
783
706
|
"""
|
|
784
|
-
|
|
707
|
+
Method for creating the configurations for a Parameter that doesn't involve user attributes or parent parameters
|
|
708
|
+
|
|
709
|
+
* Note that the "Number" type denotes an int, a Decimal (from decimal module), or a string that can be parsed to Decimal
|
|
785
710
|
|
|
786
711
|
Parameters:
|
|
787
|
-
parameter_class: The class of widget parameter to convert to
|
|
788
712
|
name: The name of the parameter
|
|
789
713
|
label: The display label for the parameter
|
|
790
|
-
|
|
714
|
+
min_value: Minimum selectable value
|
|
715
|
+
max_value: Maximum selectable value
|
|
716
|
+
increment: Increment of selectable values, and must fit evenly between min_value and max_value
|
|
717
|
+
default_lower_value: Default lower value for this option, and must be selectable based on min_value, max_value, and increment
|
|
718
|
+
default_upper_value: Default upper value for this option, and must be selectable based on min_value, max_value, and increment.
|
|
719
|
+
Must also be greater than default_lower_value
|
|
791
720
|
is_hidden: Whether the parameter is hidden in the parameters API response. Default is False
|
|
792
|
-
parent: The parent parameter that may cascade the options for this parameter. Default is no parent
|
|
793
721
|
"""
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
722
|
+
single_param_option = po.NumberRangeParameterOption(min_value, max_value, increment=increment, default_lower_value=default_lower_value,
|
|
723
|
+
default_upper_value=default_upper_value)
|
|
724
|
+
cls.Create(name, label, (single_param_option,), is_hidden=is_hidden)
|
|
725
|
+
|
|
726
|
+
def get_selected_lower_value(self, **kwargs) -> str:
|
|
727
|
+
"""
|
|
728
|
+
Get the selected lower value number
|
|
798
729
|
|
|
799
|
-
|
|
730
|
+
Returns:
|
|
731
|
+
A number parsable string of the selected number
|
|
800
732
|
"""
|
|
801
|
-
|
|
733
|
+
return str(self._selected_lower_value)
|
|
802
734
|
|
|
803
|
-
|
|
804
|
-
|
|
735
|
+
def get_selected_upper_value(self, **kwargs) -> str:
|
|
736
|
+
"""
|
|
737
|
+
Get the selected upper value number
|
|
805
738
|
|
|
806
739
|
Returns:
|
|
807
|
-
|
|
740
|
+
A number parsable string of the selected number
|
|
808
741
|
"""
|
|
809
|
-
return self.
|
|
810
|
-
|
|
811
|
-
def
|
|
742
|
+
return str(self._selected_upper_value)
|
|
743
|
+
|
|
744
|
+
def to_json_dict0(self):
|
|
812
745
|
"""
|
|
813
746
|
Converts this parameter as a JSON object for the parameters API response
|
|
814
747
|
|
|
815
748
|
Returns:
|
|
816
749
|
A dictionary for the JSON object
|
|
817
750
|
"""
|
|
818
|
-
output = super().
|
|
819
|
-
output
|
|
820
|
-
output['
|
|
751
|
+
output = super().to_json_dict0()
|
|
752
|
+
output.update(self._curr_option._to_json_dict())
|
|
753
|
+
output['selected_lower_value'] = self.get_selected_lower_value()
|
|
754
|
+
output['selected_upper_value'] = self.get_selected_upper_value()
|
|
821
755
|
return output
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
# Types:
|
|
825
|
-
SelectionParameter = Union[SingleSelectParameter, MultiSelectParameter]
|
|
826
|
-
NumericParameter = Union[NumberParameter, NumRangeParameter]
|