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/parameter_options.py
CHANGED
|
@@ -1,42 +1,58 @@
|
|
|
1
|
-
from typing import Iterable, Optional, Union,
|
|
1
|
+
from typing import Set, Iterable, Optional, Union, Any
|
|
2
2
|
from dataclasses import dataclass, field
|
|
3
3
|
from decimal import Decimal, InvalidOperation as InvalidDecimalConversion
|
|
4
|
-
from datetime import datetime
|
|
4
|
+
from datetime import datetime, date
|
|
5
|
+
from abc import ABCMeta, abstractmethod
|
|
5
6
|
|
|
6
|
-
from
|
|
7
|
+
from ._utils import ConfigurationError
|
|
7
8
|
|
|
8
9
|
Number = Union[Decimal, int, str]
|
|
9
10
|
|
|
10
11
|
|
|
11
12
|
@dataclass
|
|
12
|
-
class ParameterOption:
|
|
13
|
+
class ParameterOption(metaclass=ABCMeta):
|
|
13
14
|
"""
|
|
14
|
-
Abstract class
|
|
15
|
+
Abstract class for parameter options
|
|
15
16
|
"""
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
)
|
|
17
|
+
_user_groups: Set[str] # = field(default_factory=frozenset, kw_only=True)
|
|
18
|
+
_parent_option_ids: Set[str] # = field(default_factory=frozenset, kw_only=True)
|
|
19
|
+
|
|
20
|
+
@abstractmethod
|
|
21
|
+
def __init__(
|
|
22
|
+
self, *, user_groups: Union[Iterable[str], str] = frozenset(), parent_option_ids: Union[Iterable[str], str] = frozenset(), **kwargs
|
|
23
|
+
) -> None:
|
|
24
|
+
self._user_groups = frozenset({user_groups} if isinstance(user_groups, str) else user_groups)
|
|
25
|
+
self._parent_option_ids = frozenset({parent_option_ids} if isinstance(parent_option_ids, str) else parent_option_ids)
|
|
25
26
|
|
|
26
|
-
def
|
|
27
|
+
def _validate_lower_upper_values(self, lower_label: str, lower_value: Union[Decimal, date],
|
|
28
|
+
upper_label: str, upper_value: Union[Decimal, date]):
|
|
29
|
+
if lower_value > upper_value:
|
|
30
|
+
raise ConfigurationError(f'The {lower_label} "{lower_value}" must be less than or equal to the {upper_label} "{upper_value}"')
|
|
31
|
+
|
|
32
|
+
def _is_valid(self, user_group: Optional[str], selected_parent_option_ids: Optional[Iterable[str]]) -> bool:
|
|
27
33
|
"""
|
|
28
|
-
Checks if this option is valid given the selected parent options.
|
|
34
|
+
Checks if this option is valid given the selected parent options and user group of user if applicable.
|
|
29
35
|
|
|
30
36
|
Parameters:
|
|
31
|
-
|
|
37
|
+
user_group: The value of the user's "user group attribute". Only None when "user_group_attr" is not specified
|
|
38
|
+
for the Parameter object. Note that when user is None but "user_group_attr" is specified, an error is thrown
|
|
39
|
+
selected_parent_option_ids: List of selected option ids from the parent parameter. Only None when the Parameter
|
|
40
|
+
object has no parent parameter.
|
|
32
41
|
|
|
33
42
|
Returns:
|
|
34
43
|
True if valid, False otherwise
|
|
35
44
|
"""
|
|
36
|
-
if
|
|
37
|
-
return
|
|
38
|
-
|
|
39
|
-
|
|
45
|
+
if user_group is not None and user_group not in self._user_groups:
|
|
46
|
+
return False
|
|
47
|
+
|
|
48
|
+
if selected_parent_option_ids is not None and self._parent_option_ids.isdisjoint(selected_parent_option_ids):
|
|
49
|
+
return False
|
|
50
|
+
|
|
51
|
+
return True
|
|
52
|
+
|
|
53
|
+
@abstractmethod
|
|
54
|
+
def _to_json_dict(self):
|
|
55
|
+
return {}
|
|
40
56
|
|
|
41
57
|
|
|
42
58
|
@dataclass
|
|
@@ -45,92 +61,148 @@ class SelectParameterOption(ParameterOption):
|
|
|
45
61
|
Parameter option for a select parameter
|
|
46
62
|
|
|
47
63
|
Attributes:
|
|
64
|
+
identifier: Unique identifier for this option that never changes over time
|
|
65
|
+
label: Human readable label that gets shown as a dropdown option
|
|
66
|
+
is_default: True if this is a default option, False otherwise
|
|
67
|
+
user_groups: The user groups this parameter option would show for if "user_group_attr" is specified in the Parameter object
|
|
68
|
+
parent_option_ids: Set of parent option ids this parameter option would show for if "parent" is specified in the Parameter object
|
|
69
|
+
custom_fields: Dictionary to associate custom attributes to the parameter option
|
|
48
70
|
"""
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
parent_option_ids: Iterable[str] = frozenset()
|
|
71
|
+
_identifier: str
|
|
72
|
+
_label: str
|
|
73
|
+
_is_default: bool # = field(default=False, kw_only=True)
|
|
74
|
+
custom_fields: dict[str, Any] # = field(default_factory=False, kw_only=True)
|
|
54
75
|
|
|
55
|
-
def __init__(
|
|
56
|
-
|
|
57
|
-
|
|
76
|
+
def __init__(
|
|
77
|
+
self, id: str, label: str, *, is_default: bool = False, user_groups: Union[Iterable[str], str] = frozenset(),
|
|
78
|
+
parent_option_ids: Union[Iterable[str], str] = frozenset(), custom_fields: dict[str, Any] = {}, **kwargs
|
|
79
|
+
) -> None:
|
|
58
80
|
"""
|
|
59
81
|
Constructor for SelectParameterOption
|
|
60
82
|
|
|
61
83
|
Parameters:
|
|
62
|
-
|
|
63
|
-
label: Human readable label that gets shown as a dropdown option
|
|
64
|
-
is_default: True if this is a default option, False otherwise
|
|
65
|
-
parent_option_id: Identifier of the parent option, or None if this is a top-level option
|
|
66
|
-
parent_option_ids: Set of parent option ids (only used if parent_option_id is None)
|
|
67
|
-
custom_fields: Dictionary to associate custom attributes to the parameter option
|
|
84
|
+
...see Attributes of SelectParameterOption
|
|
68
85
|
**kwargs: Any additional keyword arguments specified (except the ones above) gets included into custom_fields as well
|
|
69
86
|
"""
|
|
70
|
-
|
|
71
|
-
self.
|
|
72
|
-
self.
|
|
73
|
-
self.
|
|
74
|
-
self.parent_option_ids = parent_option_ids
|
|
87
|
+
super().__init__(user_groups=user_groups, parent_option_ids=parent_option_ids)
|
|
88
|
+
self._identifier = id
|
|
89
|
+
self._label = label
|
|
90
|
+
self._is_default = is_default
|
|
75
91
|
self.custom_fields = {
|
|
76
|
-
**kwargs, **custom_fields,
|
|
92
|
+
**kwargs, **custom_fields, **self._to_json_dict()
|
|
77
93
|
}
|
|
78
|
-
super().__post_init__()
|
|
79
94
|
|
|
80
|
-
def get_custom_field(self, field: str, default_field: Optional[str] = None, default: Any = None) -> Any:
|
|
95
|
+
def get_custom_field(self, field: str, *, default_field: Optional[str] = None, default: Any = None, **kwargs) -> Any:
|
|
81
96
|
"""
|
|
82
97
|
Get field value from the custom_fields attribute
|
|
83
98
|
|
|
84
99
|
Parameters:
|
|
85
100
|
field: The key to use to fetch the custom field from "custom_fields"
|
|
86
|
-
default_field: If field does not exist in "custom_fields", then this is used instead as the field (if not None)
|
|
87
|
-
default: If field does not exist
|
|
101
|
+
default_field: If value at "field" key does not exist in "custom_fields", then this is used instead as the field (if not None)
|
|
102
|
+
default: If value at "field" or "default_field" (if not None) key does not exist in "custom_fields", then this value
|
|
103
|
+
is used as default, or throws an error if None
|
|
88
104
|
|
|
89
105
|
Returns:
|
|
90
106
|
The type of the custom field
|
|
91
107
|
"""
|
|
92
108
|
if default_field is not None:
|
|
93
|
-
default = self.get_custom_field(default_field)
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
109
|
+
default = self.get_custom_field(default_field, default=default)
|
|
110
|
+
|
|
111
|
+
if default is not None:
|
|
112
|
+
selected_field = self.custom_fields.get(field, default)
|
|
113
|
+
else:
|
|
114
|
+
try:
|
|
98
115
|
selected_field = self.custom_fields[field]
|
|
99
|
-
|
|
100
|
-
|
|
116
|
+
except KeyError as e:
|
|
117
|
+
raise ConfigurationError(f"Field '{field}' must exist for parameter option {self._to_json_dict()}") from e
|
|
101
118
|
|
|
102
119
|
return selected_field
|
|
103
120
|
|
|
104
|
-
def
|
|
105
|
-
return {'id': self.
|
|
121
|
+
def _to_json_dict(self):
|
|
122
|
+
return {'id': self._identifier, 'label': self._label}
|
|
106
123
|
|
|
107
124
|
|
|
108
125
|
@dataclass
|
|
109
|
-
class
|
|
126
|
+
class _DateTypeParameterOption(ParameterOption):
|
|
110
127
|
"""
|
|
111
|
-
|
|
128
|
+
Abstract class (or type) for date type parameter options
|
|
129
|
+
"""
|
|
130
|
+
_date_format: str # = field(default="%Y-%m-%d", kw_only=True)
|
|
112
131
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
date_format:
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
date_format: str = '%Y-%m-%d'
|
|
121
|
-
parent_option_id: Optional[str] = field(default=None, repr=False)
|
|
122
|
-
parent_option_ids: Iterable[str] = frozenset()
|
|
123
|
-
|
|
124
|
-
def __post_init__(self) -> None:
|
|
125
|
-
super().__post_init__()
|
|
126
|
-
self.default_date = self._validate_date(self.default_date) \
|
|
127
|
-
if isinstance(self.default_date, str) else self.default_date
|
|
132
|
+
@abstractmethod
|
|
133
|
+
def __init__(
|
|
134
|
+
self, *, date_format: str = '%Y-%m-%d', user_groups: Union[Iterable[str], str] = frozenset(),
|
|
135
|
+
parent_option_ids: Union[Iterable[str], str] = frozenset(), **kwargs
|
|
136
|
+
) -> None:
|
|
137
|
+
super().__init__(user_groups=user_groups, parent_option_ids=parent_option_ids)
|
|
138
|
+
self._date_format = date_format
|
|
128
139
|
|
|
129
|
-
def _validate_date(self, date_str: str) ->
|
|
140
|
+
def _validate_date(self, date_str: Union[str, date]) -> date:
|
|
130
141
|
try:
|
|
131
|
-
return datetime.strptime(date_str, self.
|
|
142
|
+
return datetime.strptime(date_str, self._date_format).date() if isinstance(date_str, str) else date_str
|
|
132
143
|
except ValueError as e:
|
|
133
144
|
raise ConfigurationError(f'Invalid format for date "{date_str}".') from e
|
|
145
|
+
|
|
146
|
+
def _to_json_dict(self):
|
|
147
|
+
return {}
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
@dataclass
|
|
151
|
+
class DateParameterOption(_DateTypeParameterOption):
|
|
152
|
+
"""
|
|
153
|
+
Parameter option for default dates if it varies based on selection of another parameter
|
|
154
|
+
|
|
155
|
+
Attributes:
|
|
156
|
+
default_date: Default date for this option
|
|
157
|
+
date_format: Format of the default date, default is '%Y-%m-%d'
|
|
158
|
+
user_groups: The user groups this parameter option would show for if "user_group_attr" is specified in the Parameter object
|
|
159
|
+
parent_option_ids: Set of parent option ids this parameter option would show for if "parent" is specified in the Parameter object
|
|
160
|
+
"""
|
|
161
|
+
_default_date: date
|
|
162
|
+
|
|
163
|
+
def __init__(
|
|
164
|
+
self, default_date: Union[str, date], *, date_format: str = '%Y-%m-%d', user_groups: Union[Iterable[str], str] = frozenset(),
|
|
165
|
+
parent_option_ids: Union[Iterable[str], str] = frozenset(), **kwargs
|
|
166
|
+
) -> None:
|
|
167
|
+
"""
|
|
168
|
+
Constructor for DateParameterOption
|
|
169
|
+
|
|
170
|
+
Parameters:
|
|
171
|
+
...see Attributes of DateParameterOption
|
|
172
|
+
"""
|
|
173
|
+
super().__init__(date_format=date_format, user_groups=user_groups, parent_option_ids=parent_option_ids)
|
|
174
|
+
self._default_date = self._validate_date(default_date)
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
@dataclass
|
|
178
|
+
class DateRangeParameterOption(_DateTypeParameterOption):
|
|
179
|
+
"""
|
|
180
|
+
Parameter option for default dates if it varies based on selection of another parameter
|
|
181
|
+
|
|
182
|
+
Attributes:
|
|
183
|
+
default_start_date: Default start date for this option
|
|
184
|
+
default_end_date: Default end date for this option
|
|
185
|
+
date_format: Format of the default date, default is '%Y-%m-%d'
|
|
186
|
+
user_groups: The user groups this parameter option would show for if "user_group_attr" is specified in the Parameter object
|
|
187
|
+
parent_option_ids: Set of parent option ids this parameter option would show for if "parent" is specified in the Parameter object
|
|
188
|
+
"""
|
|
189
|
+
_default_start_date: date
|
|
190
|
+
_default_end_date: date
|
|
191
|
+
|
|
192
|
+
def __init__(
|
|
193
|
+
self, default_start_date: Union[str, date], default_end_date: Union[str, date], *, date_format: str = '%Y-%m-%d',
|
|
194
|
+
user_groups: Union[Iterable[str], str] = frozenset(), parent_option_ids: Union[Iterable[str], str] = frozenset(), **kwargs
|
|
195
|
+
) -> None:
|
|
196
|
+
"""
|
|
197
|
+
Constructor for DateRangeParameterOption
|
|
198
|
+
|
|
199
|
+
Parameters:
|
|
200
|
+
...see Attributes of DateRangeParameterOption
|
|
201
|
+
"""
|
|
202
|
+
super().__init__(date_format=date_format, user_groups=user_groups, parent_option_ids=parent_option_ids)
|
|
203
|
+
self._default_start_date = self._validate_date(default_start_date)
|
|
204
|
+
self._default_end_date = self._validate_date(default_end_date)
|
|
205
|
+
self._validate_lower_upper_values("default_start_date", self._default_start_date, "default_end_date", self._default_end_date)
|
|
134
206
|
|
|
135
207
|
|
|
136
208
|
@dataclass
|
|
@@ -138,47 +210,56 @@ class _NumericParameterOption(ParameterOption):
|
|
|
138
210
|
"""
|
|
139
211
|
Abstract class (or type) for numeric parameter options
|
|
140
212
|
"""
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
213
|
+
_min_value: Decimal
|
|
214
|
+
_max_value: Decimal
|
|
215
|
+
_increment: Decimal # = field(default=1, kw_only=True)
|
|
144
216
|
|
|
145
|
-
|
|
146
|
-
|
|
217
|
+
@abstractmethod
|
|
218
|
+
def __init__(
|
|
219
|
+
self, min_value: Number, max_value: Number, *, increment: Number = 1, user_groups: Union[Iterable[str], str] = frozenset(),
|
|
220
|
+
parent_option_ids: Union[Iterable[str], str] = frozenset(), **kwargs
|
|
221
|
+
) -> None:
|
|
222
|
+
super().__init__(user_groups=user_groups, parent_option_ids=parent_option_ids)
|
|
147
223
|
try:
|
|
148
|
-
self.
|
|
149
|
-
self.
|
|
150
|
-
self.
|
|
224
|
+
self._min_value = Decimal(min_value)
|
|
225
|
+
self._max_value = Decimal(max_value)
|
|
226
|
+
self._increment = Decimal(increment)
|
|
151
227
|
except InvalidDecimalConversion as e:
|
|
152
228
|
raise ConfigurationError(f'Could not convert either min, max, or increment to number') from e
|
|
153
229
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
return min_value <= value <= self.max_value
|
|
230
|
+
self._validate_lower_upper_values("min_value", self._min_value, "max_value", self._max_value)
|
|
231
|
+
|
|
232
|
+
if (self._max_value - self._min_value) % self._increment != 0:
|
|
233
|
+
raise ConfigurationError(f'The increment "{self._increment}" must fit evenly between ' +
|
|
234
|
+
f'the min_value "{self._min_value}" and max_value "{self._max_value}"')
|
|
235
|
+
|
|
236
|
+
def __value_in_range(self, value: Decimal) -> bool:
|
|
237
|
+
return self._min_value <= value <= self._max_value
|
|
163
238
|
|
|
164
|
-
def
|
|
165
|
-
diff = (value -
|
|
166
|
-
return diff >= 0 and diff % self.
|
|
239
|
+
def __value_on_increment(self, value: Decimal) -> bool:
|
|
240
|
+
diff = (value - self._min_value)
|
|
241
|
+
return diff >= 0 and diff % self._increment == 0
|
|
167
242
|
|
|
168
|
-
def _validate_value(self, value: Number
|
|
169
|
-
min_value = self.min_value if min_value is None else min_value
|
|
243
|
+
def _validate_value(self, value: Number) -> Decimal:
|
|
170
244
|
try:
|
|
171
245
|
value = Decimal(value)
|
|
172
246
|
except InvalidDecimalConversion as e:
|
|
173
247
|
raise ConfigurationError(f'Could not convert "{value}" to number', e)
|
|
174
248
|
|
|
175
|
-
if not self.
|
|
249
|
+
if not self.__value_in_range(value):
|
|
176
250
|
raise ConfigurationError(f'The selected value "{value}" is outside of bounds ' +
|
|
177
251
|
'"{min_value}" and "{self.max_value}"')
|
|
178
|
-
if not self.
|
|
252
|
+
if not self.__value_on_increment(value):
|
|
179
253
|
raise ConfigurationError(f'The difference between selected value "{value}" and lower value ' +
|
|
180
254
|
'"{min_value}" must be a multiple of increment "{self.increment}"')
|
|
181
255
|
return value
|
|
256
|
+
|
|
257
|
+
def _to_json_dict(self):
|
|
258
|
+
return {
|
|
259
|
+
"min_value": str(self._min_value),
|
|
260
|
+
"max_value": str(self._max_value),
|
|
261
|
+
"increment": str(self._increment)
|
|
262
|
+
}
|
|
182
263
|
|
|
183
264
|
|
|
184
265
|
@dataclass
|
|
@@ -191,20 +272,29 @@ class NumberParameterOption(_NumericParameterOption):
|
|
|
191
272
|
max_value: Maximum selectable value
|
|
192
273
|
increment: Increment of selectable values, and must fit evenly between min_value and max_value
|
|
193
274
|
default_value: Default value for this option, and must be selectable based on min_value, max_value, and increment
|
|
194
|
-
|
|
195
|
-
parent_option_ids: Set of parent option ids
|
|
275
|
+
user_groups: The user groups this parameter option would show for if "user_group_attr" is specified in the Parameter object
|
|
276
|
+
parent_option_ids: Set of parent option ids this parameter option would show for if "parent" is specified in the Parameter object
|
|
196
277
|
"""
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
278
|
+
_default_value: Decimal # = field(default=None, kw_only=True)
|
|
279
|
+
|
|
280
|
+
def __init__(
|
|
281
|
+
self, min_value: Number, max_value: Number, *, increment: Number = 1, default_value: Optional[Number] = None,
|
|
282
|
+
user_groups: Union[Iterable[str], str] = frozenset(), parent_option_ids: Union[Iterable[str], str] = frozenset(), **kwargs
|
|
283
|
+
) -> None:
|
|
284
|
+
"""
|
|
285
|
+
Constructor for NumberParameterOption
|
|
286
|
+
|
|
287
|
+
* Note that the "Number" type denotes an int, a Decimal (from decimal module), or a string that can be parsed to Decimal
|
|
200
288
|
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
289
|
+
Parameters:
|
|
290
|
+
...see Attributes of NumberParameterOption
|
|
291
|
+
"""
|
|
292
|
+
super().__init__(min_value, max_value, increment=increment, user_groups=user_groups, parent_option_ids=parent_option_ids)
|
|
293
|
+
self._default_value = self._validate_value(default_value) if default_value is not None else self._min_value
|
|
204
294
|
|
|
205
295
|
|
|
206
296
|
@dataclass
|
|
207
|
-
class
|
|
297
|
+
class NumberRangeParameterOption(_NumericParameterOption):
|
|
208
298
|
"""
|
|
209
299
|
Parameter option for default numeric ranges if it varies based on selection of another parameter
|
|
210
300
|
|
|
@@ -215,19 +305,26 @@ class NumRangeParameterOption(_NumericParameterOption):
|
|
|
215
305
|
default_lower_value: Default lower value for this option, and must be selectable based on min_value, max_value, and increment
|
|
216
306
|
default_upper_value: Default upper value for this option, and must be selectable based on min_value, max_value, and increment.
|
|
217
307
|
Must also be greater than default_lower_value
|
|
218
|
-
|
|
219
|
-
parent_option_ids: Set of parent option ids
|
|
308
|
+
user_groups: The user groups this parameter option would show for if "user_group_attr" is specified in the Parameter object
|
|
309
|
+
parent_option_ids: Set of parent option ids this parameter option would show for if "parent" is specified in the Parameter object
|
|
220
310
|
"""
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
parent_option_id: Optional[str] = field(default=None, repr=False)
|
|
224
|
-
parent_option_ids: Iterable[str] = frozenset()
|
|
225
|
-
|
|
226
|
-
def __post_init__(self) -> None:
|
|
227
|
-
super().__post_init__()
|
|
228
|
-
self.default_lower_value = self._validate_value(self.default_lower_value)
|
|
229
|
-
self.default_upper_value = self._validate_value(self.default_upper_value, self.default_lower_value)
|
|
311
|
+
_default_lower_value: Decimal # = field(default=None, kw_only=True)
|
|
312
|
+
_default_upper_value: Decimal # = field(default=None, kw_only=True)
|
|
230
313
|
|
|
314
|
+
def __init__(
|
|
315
|
+
self, min_value: Number, max_value: Number, *, increment: Number = 1, default_lower_value: Optional[Number] = None,
|
|
316
|
+
default_upper_value: Optional[Number] = None, user_groups: Union[Iterable[str], str] = frozenset(),
|
|
317
|
+
parent_option_ids: Union[Iterable[str], str] = frozenset(), **kwargs
|
|
318
|
+
) -> None:
|
|
319
|
+
"""
|
|
320
|
+
Constructor for NumberRangeParameterOption
|
|
321
|
+
|
|
322
|
+
* Note that the "Number" type denotes an int, a Decimal (from decimal module), or a string that can be parsed to Decimal
|
|
231
323
|
|
|
232
|
-
|
|
233
|
-
|
|
324
|
+
Parameters:
|
|
325
|
+
...see Attributes of NumberRangeParameterOption
|
|
326
|
+
"""
|
|
327
|
+
super().__init__(min_value, max_value, increment=increment, user_groups=user_groups, parent_option_ids=parent_option_ids)
|
|
328
|
+
self._default_lower_value = self._validate_value(default_lower_value) if default_lower_value is not None else self._min_value
|
|
329
|
+
self._default_upper_value = self._validate_value(default_upper_value) if default_upper_value is not None else self._max_value
|
|
330
|
+
self._validate_lower_upper_values("default_lower_value", self._default_lower_value, "default_upper_value", self._default_upper_value)
|