squirrels 0.5.0b1__py3-none-any.whl → 0.5.0b3__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. dateutils/__init__.py +6 -0
  2. dateutils/_enums.py +25 -0
  3. squirrels/dateutils.py → dateutils/_implementation.py +58 -111
  4. dateutils/types.py +6 -0
  5. squirrels/__init__.py +7 -13
  6. squirrels/_api_server.py +5 -5
  7. squirrels/{arguments/init_time_args.py → _arguments/_init_time_args.py} +2 -2
  8. squirrels/{arguments/run_time_args.py → _arguments/_run_time_args.py} +4 -26
  9. squirrels/_auth.py +2 -2
  10. squirrels/_command_line.py +13 -9
  11. squirrels/_connection_set.py +5 -5
  12. squirrels/_constants.py +1 -1
  13. squirrels/_dashboard_types.py +82 -0
  14. squirrels/_dashboards_io.py +2 -2
  15. squirrels/_data_sources.py +564 -0
  16. squirrels/_exceptions.py +1 -1
  17. squirrels/_initializer.py +82 -58
  18. squirrels/_manifest.py +5 -5
  19. squirrels/_model_builder.py +2 -0
  20. squirrels/_model_configs.py +3 -3
  21. squirrels/_model_queries.py +1 -1
  22. squirrels/_models.py +28 -14
  23. squirrels/{package_data → _package_data}/base_project/dashboards/dashboard_example.py +4 -4
  24. squirrels/{package_data → _package_data}/base_project/dashboards/dashboard_example.yml +2 -2
  25. squirrels/_package_data/base_project/macros/macros_example.sql +17 -0
  26. squirrels/{package_data → _package_data}/base_project/models/builds/build_example.py +2 -2
  27. squirrels/{package_data → _package_data}/base_project/models/builds/build_example.sql +1 -1
  28. squirrels/{package_data → _package_data}/base_project/models/builds/build_example.yml +2 -0
  29. squirrels/{package_data → _package_data}/base_project/models/dbviews/dbview_example.sql +1 -1
  30. squirrels/_package_data/base_project/models/federates/federate_example.py +41 -0
  31. squirrels/_package_data/base_project/models/federates/federate_example.sql +25 -0
  32. squirrels/{package_data → _package_data}/base_project/models/federates/federate_example.yml +6 -6
  33. squirrels/{package_data → _package_data}/base_project/parameters.yml +9 -8
  34. squirrels/_package_data/base_project/pyconfigs/connections.py +14 -0
  35. squirrels/{package_data → _package_data}/base_project/pyconfigs/context.py +14 -16
  36. squirrels/{package_data → _package_data}/base_project/pyconfigs/parameters.py +13 -8
  37. squirrels/{package_data → _package_data}/base_project/pyconfigs/user.py +2 -2
  38. squirrels/_parameter_configs.py +34 -34
  39. squirrels/_parameter_options.py +348 -0
  40. squirrels/_parameter_sets.py +18 -18
  41. squirrels/_parameters.py +1266 -0
  42. squirrels/_project.py +37 -12
  43. squirrels/_utils.py +5 -3
  44. squirrels/arguments.py +2 -0
  45. squirrels/connections.py +1 -0
  46. squirrels/dashboards.py +1 -82
  47. squirrels/data_sources.py +8 -563
  48. squirrels/parameter_options.py +8 -348
  49. squirrels/parameters.py +9 -1266
  50. squirrels/types.py +11 -0
  51. {squirrels-0.5.0b1.dist-info → squirrels-0.5.0b3.dist-info}/METADATA +11 -17
  52. squirrels-0.5.0b3.dist-info/RECORD +80 -0
  53. squirrels/package_data/base_project/macros/macros_example.sql +0 -15
  54. squirrels/package_data/base_project/models/federates/federate_example.py +0 -44
  55. squirrels/package_data/base_project/models/federates/federate_example.sql +0 -17
  56. squirrels/package_data/base_project/pyconfigs/connections.py +0 -14
  57. squirrels-0.5.0b1.dist-info/RECORD +0 -70
  58. /squirrels/{dataset_result.py → _dataset_types.py} +0 -0
  59. /squirrels/{package_data → _package_data}/base_project/.env +0 -0
  60. /squirrels/{package_data → _package_data}/base_project/.env.example +0 -0
  61. /squirrels/{package_data → _package_data}/base_project/assets/expenses.db +0 -0
  62. /squirrels/{package_data → _package_data}/base_project/assets/weather.db +0 -0
  63. /squirrels/{package_data → _package_data}/base_project/connections.yml +0 -0
  64. /squirrels/{package_data → _package_data}/base_project/docker/.dockerignore +0 -0
  65. /squirrels/{package_data → _package_data}/base_project/docker/Dockerfile +0 -0
  66. /squirrels/{package_data → _package_data}/base_project/docker/compose.yml +0 -0
  67. /squirrels/{package_data → _package_data}/base_project/duckdb_init.sql +0 -0
  68. /squirrels/{package_data/base_project/.gitignore → _package_data/base_project/gitignore} +0 -0
  69. /squirrels/{package_data → _package_data}/base_project/models/dbviews/dbview_example.yml +0 -0
  70. /squirrels/{package_data → _package_data}/base_project/models/sources.yml +0 -0
  71. /squirrels/{package_data → _package_data}/base_project/seeds/seed_categories.csv +0 -0
  72. /squirrels/{package_data → _package_data}/base_project/seeds/seed_categories.yml +0 -0
  73. /squirrels/{package_data → _package_data}/base_project/seeds/seed_subcategories.csv +0 -0
  74. /squirrels/{package_data → _package_data}/base_project/seeds/seed_subcategories.yml +0 -0
  75. /squirrels/{package_data → _package_data}/base_project/squirrels.yml.j2 +0 -0
  76. /squirrels/{package_data → _package_data}/base_project/tmp/.gitignore +0 -0
  77. {squirrels-0.5.0b1.dist-info → squirrels-0.5.0b3.dist-info}/WHEEL +0 -0
  78. {squirrels-0.5.0b1.dist-info → squirrels-0.5.0b3.dist-info}/entry_points.txt +0 -0
  79. {squirrels-0.5.0b1.dist-info → squirrels-0.5.0b3.dist-info}/licenses/LICENSE +0 -0
squirrels/parameters.py CHANGED
@@ -1,1266 +1,9 @@
1
- from __future__ import annotations
2
- from typing import Callable, Type, TypeVar, Sequence, Any
3
- from dataclasses import dataclass
4
- from datetime import datetime, date
5
- from decimal import Decimal
6
- from abc import ABCMeta, abstractmethod
7
-
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)
12
-
13
-
14
- @dataclass
15
- class Parameter(metaclass=ABCMeta):
16
- """
17
- Abstract class for all parameter widgets
18
- """
19
- _config: _pc.ParameterConfig
20
-
21
- @abstractmethod
22
- def is_enabled(self) -> bool:
23
- return True
24
-
25
- @staticmethod
26
- @abstractmethod
27
- def _ParameterConfigType() -> Type[_pc.ParameterConfig]:
28
- pass
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
-
51
- @classmethod
52
- def CreateWithOptions(
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
55
- ) -> None:
56
- """
57
- Method for creating the configurations for a Parameter that may include user attribute or parent
58
-
59
- Arguments:
60
- name: The name of the parameter
61
- label: The display label for the parameter
62
- all_options: All options associated to this parameter regardless of the user group or parent parameter option they depend on
63
- description: Explains the meaning of the parameter
64
- user_attribute: The user attribute that may cascade the options for this parameter. Default is None
65
- parent_name: Name of parent parameter that may cascade the options for this parameter. Default is None (no parent)
66
- """
67
- cls._CreateWithOptionsHelper(name, label, all_options, description=description, user_attribute=user_attribute, parent_name=parent_name)
68
-
69
- @classmethod
70
- @abstractmethod
71
- def CreateSimple(cls, name: str, label: str, *args, description: str = "", **kwargs) -> None:
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)
84
-
85
- @classmethod
86
- def CreateFromSource(
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
89
- ) -> None:
90
- """
91
- Method for creating the configurations for any Parameter that uses a DataSource to receive the options
92
-
93
- Arguments:
94
- name: The name of the parameter
95
- label: The display label for the parameter
96
- data_source: The lookup table to use for this parameter
97
- description: Explains the meaning of the parameter
98
- user_attribute: The user attribute that may cascade the options for this parameter. Default is None
99
- parent_name: Name of parent parameter that may cascade the options for this parameter. Default is None (no parent)
100
- """
101
- cls._CreateFromSourceHelper(name, label, data_source, description=description, user_attribute=user_attribute, parent_name=parent_name)
102
-
103
- def _enquote(self, value: str) -> str:
104
- return "'" + value.replace("'", "''") + "'"
105
-
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
-
113
- try:
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))
117
-
118
- def _validate_number(self, input_number: _po.Number, curr_option: _po._NumericParameterOption) -> Decimal:
119
- try:
120
- return curr_option._validate_value(input_number)
121
- except u.ConfigurationError as e:
122
- raise self._config._invalid_input_error(str(input_number), str(e))
123
-
124
- @abstractmethod
125
- def _to_json_dict0(self) -> dict:
126
- """
127
- Helper method to convert the derived Parameter class into a JSON dictionary
128
- """
129
- output = {
130
- "widget_type": self._config.widget_type(), "name": self._config.name,
131
- "label": self._config.label, "description": self._config.description
132
- }
133
- if not self.is_enabled():
134
- output["widget_type"] = "disabled"
135
- return output
136
-
137
- @abstractmethod
138
- def _get_response_model0(self) -> type[arm.ParameterModelBase]:
139
- pass
140
-
141
- def _to_api_response_model0(self) -> arm.ParameterModelBase:
142
- return self._get_response_model0().model_validate(self._to_json_dict0())
143
-
144
-
145
- @dataclass
146
- class _SelectionParameter(Parameter):
147
- _config: _pc.SelectionParameterConfig
148
- _options: Sequence[_po.SelectParameterOption]
149
-
150
- def __post_init__(self):
151
- self._options = tuple(self._options)
152
-
153
- def is_enabled(self) -> bool:
154
- return len(self._options) > 0
155
-
156
- @abstractmethod
157
- def _get_selected_ids_as_list(self) -> Sequence[str]:
158
- pass
159
-
160
- def _validate_selected_id_in_options(self, selected_id):
161
- if selected_id not in (x._identifier for x in self._options):
162
- raise self._config._invalid_input_error(selected_id, f"The selected id {selected_id} does not exist in available options.")
163
-
164
- @abstractmethod
165
- def _to_json_dict0(self) -> dict:
166
- """
167
- Helper method to convert the derived selection parameter class into a JSON object
168
- """
169
- output = super()._to_json_dict0()
170
- output['trigger_refresh'] = self._config.trigger_refresh
171
- output['options'] = [x._to_json_dict() for x in self._options]
172
- return output
173
-
174
-
175
- @dataclass
176
- class SingleSelectParameter(_SelectionParameter):
177
- """
178
- Class for single-select parameter widgets.
179
-
180
- Attributes:
181
- config: The config for this widget parameter (for immutable attributes like name, label, all possible options, etc)
182
- options: The parameter options that are currently selectable
183
- selected_id: The ID of the selected option
184
- """
185
- _config: _pc.SingleSelectParameterConfig
186
- _selected_id: str | None
187
-
188
- def __post_init__(self):
189
- super().__post_init__()
190
- if len(self._options) > 0:
191
- assert self._selected_id != None
192
- self._validate_selected_id_in_options(self._selected_id)
193
- else:
194
- self._selected_id = None
195
-
196
- @staticmethod
197
- def _ParameterConfigType():
198
- return _pc.SingleSelectParameterConfig
199
-
200
- @classmethod
201
- def CreateSimple(
202
- cls, name: str, label: str, all_options: Sequence[_po.SelectParameterOption], *, description: str = "", **kwargs
203
- ) -> None:
204
- """
205
- Method for creating the configurations for a Parameter that doesn't involve user attributes or parent parameters
206
-
207
- Arguments:
208
- name: The name of the parameter
209
- label: The display label for the parameter
210
- all_options: All options associated to this parameter regardless of the user group or parent parameter option they depend on
211
- description: Explains the meaning of the parameter
212
- """
213
- cls.CreateWithOptions(name, label, all_options, description=description)
214
-
215
- def get_selected(
216
- self, field: str | None = None, *, default_field: str | None = None, default: Any = None, **kwargs
217
- ) -> _po.SelectParameterOption | Any | None:
218
- """
219
- Gets the selected single-select option or selected custom field
220
-
221
- Arguments:
222
- field: If field is not None, the method gets this field from the "custom_fields" attribute of the selected option.
223
- Otherwise, returns the class object of the selected option
224
- default_field: If field does not exist for a parameter option and default_field is not None, the default_field is used
225
- as the "field" instead. Does nothing if field is None
226
- default: If field does not exist for a parameter option, default_field is None, but default is not None, then the default
227
- is returned as the selected field. Does nothing if field is None or default_field is not None
228
-
229
- Returns:
230
- A SelectParameterOption class object if no field is provided, or the type of the custom field
231
- """
232
- def get_selected_from_id(identifier: str):
233
- selected = next(x for x in self._options if x._identifier == identifier)
234
- if field is not None:
235
- selected = selected.get_custom_field(field, default_field=default_field, default=default)
236
- return selected
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)
263
-
264
- def get_selected_id(self, **kwargs) -> str | None:
265
- """
266
- Gets the ID of the selected option
267
-
268
- Returns:
269
- A string ID or None if there are no selectable options
270
- """
271
- def get_id(x: _po.SelectParameterOption):
272
- return x._identifier
273
- return u.process_if_not_none(self.get_selected(), get_id)
274
-
275
- def get_selected_id_quoted(self, **kwargs) -> str | None:
276
- """
277
- Gets the ID of the selected option surrounded by single quotes
278
-
279
- Returns:
280
- A string or None if there are no selectable options
281
- """
282
- return u.process_if_not_none(self.get_selected_id(), self._enquote)
283
-
284
- def get_selected_label(self, **kwargs) -> str | None:
285
- """
286
- Gets the label of the selected option
287
-
288
- Returns:
289
- A string or None if there are no selectable options
290
- """
291
- def get_label(x: _po.SelectParameterOption): return x._label
292
- return u.process_if_not_none(self.get_selected(), get_label)
293
-
294
- def get_selected_label_quoted(self, **kwargs) -> str | None:
295
- """
296
- Gets the label of the selected option surrounded by single quotes
297
-
298
- Returns:
299
- A string or None if there are no selectable options
300
- """
301
- return u.process_if_not_none(self.get_selected_label(), self._enquote)
302
-
303
- def _get_selected_ids_as_list(self) -> Sequence[str]:
304
- selected_id = self.get_selected_id()
305
- if selected_id is not None:
306
- return (selected_id,)
307
- else:
308
- return tuple()
309
-
310
- def _to_json_dict0(self) -> dict:
311
- """
312
- Converts this parameter as a JSON object for the parameters API response
313
-
314
- Returns:
315
- A dictionary for the JSON object
316
- """
317
- output = super()._to_json_dict0()
318
- output['selected_id'] = self._selected_id
319
- return output
320
-
321
- def _get_response_model0(self):
322
- return arm.SingleSelectParameterModel if self.is_enabled() else arm.NoneParameterModel
323
-
324
-
325
- @dataclass
326
- class MultiSelectParameter(_SelectionParameter):
327
- """
328
- Class for multi-select parameter widgets.
329
-
330
- Attributes:
331
- config: The config for this widget parameter (for immutable attributes like name, label, all possible options, etc)
332
- options: The parameter options that are currently selectable
333
- selected_ids: A sequence of IDs of the selected options
334
- """
335
- _config: _pc.MultiSelectParameterConfig
336
- _selected_ids: Sequence[str]
337
-
338
- def __post_init__(self):
339
- super().__post_init__()
340
- self._selected_ids = tuple(self._selected_ids)
341
- for selected_id in self._selected_ids:
342
- self._validate_selected_id_in_options(selected_id)
343
-
344
- @staticmethod
345
- def _ParameterConfigType():
346
- return _pc.MultiSelectParameterConfig
347
-
348
- @classmethod
349
- def CreateWithOptions(
350
- cls, name: str, label: str, all_options: Sequence[_po.SelectParameterOption | dict], *, description: str = "",
351
- show_select_all: bool = True, order_matters: bool = False, none_is_all: bool = True,
352
- user_attribute: str | None = None, parent_name: str | None = None, **kwargs
353
- ) -> None:
354
- """
355
- Method for creating the configurations for a MultiSelectParameter that may include user attribute or parent
356
-
357
- Arguments:
358
- name: The name of the parameter
359
- label: The display label for the parameter
360
- all_options: All options associated to this parameter regardless of the user group or parent parameter option they depend on
361
- description: Explains the meaning of the parameter
362
- show_select_all: Communicate to front-end whether to include a "select all" option
363
- order_matters: Communicate to front-end whether the order of the selections made matter
364
- none_is_all: Whether having no options selected is equivalent to all selectable options selected
365
- user_attribute: The user attribute that may cascade the options for this parameter. Default is None
366
- parent_name: Name of parent parameter that may cascade the options for this parameter. Default is None (no parent)
367
- """
368
- cls._CreateWithOptionsHelper(
369
- name, label, all_options, description=description, user_attribute=user_attribute, parent_name=parent_name,
370
- show_select_all=show_select_all, order_matters=order_matters, none_is_all=none_is_all
371
- )
372
-
373
- @classmethod
374
- def Create(
375
- cls, name: str, label: str, all_options: Sequence[_po.SelectParameterOption | dict], *, description: str = "",
376
- show_select_all: bool = True, order_matters: bool = False, none_is_all: bool = True,
377
- user_attribute: str | None = None, parent_name: str | None = None, **kwargs
378
- ) -> None:
379
- """
380
- DEPRECATED. Use CreateWithOptions instead
381
- """
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
385
- )
386
-
387
- @classmethod
388
- def CreateSimple(
389
- cls, name: str, label: str, all_options: Sequence[_po.SelectParameterOption], *, description: str = "",
390
- show_select_all: bool = True, order_matters: bool = False, none_is_all: bool = True, **kwargs
391
- ) -> None:
392
- """
393
- Method for creating the configurations for a MultiSelectParameter that doesn't involve user attributes or parent parameters
394
-
395
- Arguments:
396
- name: The name of the parameter
397
- label: The display label for the parameter
398
- all_options: All options associated to this parameter regardless of the user group or parent parameter option they depend on
399
- description: Explains the meaning of the parameter
400
- show_select_all: Communicate to front-end whether to include a "select all" option
401
- order_matters: Communicate to front-end whether the order of the selections made matter
402
- none_is_all: Whether having no options selected is equivalent to all selectable options selected
403
- """
404
- cls.CreateWithOptions(
405
- name, label, all_options, description=description,
406
- show_select_all=show_select_all, order_matters=order_matters, none_is_all=none_is_all
407
- )
408
-
409
- @classmethod
410
- def CreateFromSource(
411
- cls, name: str, label: str, data_source: d.SelectDataSource | dict, *, description: str = "",
412
- show_select_all: bool = True, order_matters: bool = False, none_is_all: bool = True,
413
- user_attribute: str | None = None, parent_name: str | None = None, **kwargs
414
- ) -> None:
415
- """
416
- Method for creating the configurations for a MultiSelectParameter that uses a SelectDataSource to receive the options
417
-
418
- Arguments:
419
- name: The name of the parameter
420
- label: The display label for the parameter
421
- data_source: The lookup table to use for this parameter
422
- description: Explains the meaning of the parameter
423
- show_select_all: Communicate to front-end whether to include a "select all" option
424
- order_matters: Communicate to front-end whether the order of the selections made matter
425
- none_is_all: Whether having no options selected is equivalent to all selectable options selected
426
- user_attribute: The user attribute that may cascade the options for this parameter. Default is None
427
- parent_name: Name of parent parameter that may cascade the options for this parameter. Default is None (no parent)
428
- """
429
- extra_args = {
430
- "show_select_all": show_select_all, "order_matters": order_matters, "none_is_all": none_is_all
431
- }
432
- cls._CreateFromSourceHelper(
433
- name, label, data_source, extra_args=extra_args, description=description,
434
- user_attribute=user_attribute, parent_name=parent_name
435
- )
436
-
437
- def has_non_empty_selection(self) -> bool:
438
- """
439
- Returns True if more than zero options were selected. False otherwise.
440
-
441
- Note that even when this returns False, all "get_selected" functions would
442
- return the full list of options if "include_all" is set to True
443
-
444
- Returns:
445
- A boolean
446
- """
447
- return len(self._selected_ids) > 0
448
-
449
- def get_selected_list(
450
- self, field: str | None = None, *, default_field: str | None = None, default: Any = None, **kwargs
451
- ) -> Sequence[_po.SelectParameterOption | Any]:
452
- """
453
- Gets the sequence of the selected option(s) or a sequence of selected custom fields
454
-
455
- Arguments:
456
- field: If field is not None, the method gets this field from the "custom_fields" attribute of the selected options.
457
- Otherwise, returns the class objects of the selected options
458
- default_field: If field does not exist for a parameter option and default_field is not None, the default_field is used
459
- as the "field" instead. Does nothing if field is None
460
- default: If field does not exist for a parameter option, default_field is None, but default is not None, the default
461
- is returned as the selected field. Does nothing if field is None or default_field is not None
462
-
463
- Returns:
464
- A sequence of SelectParameterOption class objects or sequence of type of custom field
465
- """
466
- if not self.has_non_empty_selection() and self._config.none_is_all:
467
- selected_list = self._options
468
- else:
469
- selected_list = (x for x in self._options if x._identifier in self._selected_ids)
470
-
471
- if field is not None:
472
- selected_list = [selected.get_custom_field(field, default_field=default_field, default=default) for selected in selected_list]
473
-
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)
539
-
540
- def get_selected_ids_as_list(self, **kwargs) -> Sequence[str]:
541
- """
542
- Gets the sequence of ID(s) of the selected option(s)
543
-
544
- Returns:
545
- A sequence of strings
546
- """
547
- return tuple(x._identifier for x in self.get_selected_list())
548
-
549
- def get_selected_ids_joined(self, **kwargs) -> str:
550
- """
551
- Gets the ID(s) of the selected option(s) joined by comma
552
-
553
- Returns:
554
- A string
555
- """
556
- return ','.join(self.get_selected_ids_as_list())
557
-
558
- def get_selected_ids_quoted_as_list(self, **kwargs) -> Sequence[str]:
559
- """
560
- Gets the sequence of ID(s) of the selected option(s) surrounded by single quotes
561
-
562
- Returns:
563
- A sequence of strings
564
- """
565
- return tuple(self._enquote(x) for x in self.get_selected_ids_as_list())
566
-
567
- def get_selected_ids_quoted_joined(self, **kwargs) -> str:
568
- """
569
- Gets the ID(s) of the selected option(s) surrounded by single quotes and joined by comma
570
-
571
- Returns:
572
- A string
573
- """
574
- return ','.join(self.get_selected_ids_quoted_as_list())
575
-
576
- def get_selected_labels_as_list(self, **kwargs) -> Sequence[str]:
577
- """
578
- Gets the sequence of label(s) of the selected option(s)
579
-
580
- Returns:
581
- A sequence of strings
582
- """
583
- return tuple(x._label for x in self.get_selected_list())
584
-
585
- def get_selected_labels_joined(self, **kwargs) -> str:
586
- """
587
- Gets the label(s) of the selected option(s) joined by comma
588
-
589
- Returns:
590
- A string
591
- """
592
- return ','.join(self.get_selected_labels_as_list())
593
-
594
- def get_selected_labels_quoted_as_list(self, **kwargs) -> Sequence[str]:
595
- """
596
- Gets the sequence of label(s) of the selected option(s) surrounded by single quotes
597
-
598
- Returns:
599
- A sequence of strings
600
- """
601
- return tuple(self._enquote(x) for x in self.get_selected_labels_as_list())
602
-
603
- def get_selected_labels_quoted_joined(self, **kwargs) -> str:
604
- """
605
- Gets the label(s) of the selected option(s) surrounded by single quotes and joined by comma
606
-
607
- Returns:
608
- A string
609
- """
610
- return ','.join(self.get_selected_labels_quoted_as_list())
611
-
612
- def _get_selected_ids_as_list(self, **kwargs) -> Sequence[str]:
613
- return self.get_selected_ids_as_list()
614
-
615
- def _to_json_dict0(self):
616
- """
617
- Converts this parameter as a JSON object for the parameters API response
618
-
619
- Returns:
620
- A dictionary for the JSON object
621
- """
622
- output = super()._to_json_dict0()
623
- output['show_select_all'] = self._config.show_select_all
624
- output['order_matters'] = self._config.order_matters
625
- output['selected_ids'] = list(self._selected_ids)
626
- return output
627
-
628
- def _get_response_model0(self):
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
648
-
649
-
650
- @dataclass
651
- class DateParameter(_DateTypeParameter):
652
- """
653
- Class for date parameter widgets.
654
-
655
- Attributes:
656
- config: The config for this widget parameter (for immutable attributes like name, label, all possible options, etc)
657
- curr_option: The current option showing for defaults based on user attribute and selection of parent
658
- selected_date: The selected date
659
- """
660
- _config: _pc.DateParameterConfig
661
- _curr_option: _po.DateParameterOption | None
662
- _selected_date: date | str | None
663
-
664
- def __post_init__(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)
667
-
668
- def is_enabled(self) -> bool:
669
- return self._curr_option is not None
670
-
671
- @staticmethod
672
- def _ParameterConfigType():
673
- return _pc.DateParameterConfig
674
-
675
- @classmethod
676
- def CreateSimple(
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
679
- ) -> None:
680
- """
681
- Method for creating the configurations for a Parameter that doesn't involve user attributes or parent parameters
682
-
683
- Arguments:
684
- name: The name of the parameter
685
- label: The display label for the parameter
686
- default_date: Default date for this option
687
- description: Explains the meaning of the parameter
688
- date_format: Format of the default date, default is '%Y-%m-%d'
689
- """
690
- single_param_option = _po.DateParameterOption(default_date, min_date=min_date, max_date=max_date, date_format=date_format)
691
- cls.CreateWithOptions(name, label, (single_param_option,), description=description)
692
-
693
- def get_selected_date(self, *, date_format: str | None = None, **kwargs) -> str:
694
- """
695
- Gets selected date as string
696
-
697
- Arguments:
698
- date_format: The date format (see Python's datetime formats). If not specified, self.date_format is used
699
-
700
- Returns:
701
- A string
702
- """
703
- assert self._curr_option is not None and isinstance(self._selected_date, date), "Parameter is not enabled"
704
- date_format = self._curr_option._date_format if date_format is None else date_format
705
- return self._selected_date.strftime(date_format)
706
-
707
- def get_selected_date_quoted(self, *, date_format: str | None = None, **kwargs) -> str:
708
- """
709
- Gets selected date as string surrounded by single quotes
710
-
711
- Arguments:
712
- date_format: The date format (see Python's datetime formats). If not specified, self.date_format is used
713
-
714
- Returns:
715
- A string
716
- """
717
- return self._enquote(self.get_selected_date(date_format=date_format))
718
-
719
- def _to_json_dict0(self):
720
- """
721
- Converts this parameter as a JSON object for the parameters API response
722
-
723
- The "selected_date" field will always be in yyyy-mm-dd format
724
-
725
- Returns:
726
- A dictionary for the JSON object
727
- """
728
- output = super()._to_json_dict0()
729
- if self.is_enabled():
730
- output["selected_date"] = self.get_selected_date(date_format="%Y-%m-%d")
731
- else:
732
- output["selected_date"] = ""
733
- return output
734
-
735
- def _get_response_model0(self):
736
- return arm.DateParameterModel if self.is_enabled() else arm.NoneParameterModel
737
-
738
-
739
- @dataclass
740
- class DateRangeParameter(_DateTypeParameter):
741
- """
742
- Class for date range parameter widgets.
743
-
744
- Attributes:
745
- config: The config for this widget parameter (for immutable attributes like name, label, all possible options, etc)
746
- curr_option: The current option showing for defaults based on user attribute and selection of parent
747
- selected_start_date: The selected start date
748
- selected_end_date: The selected end date
749
- """
750
- _config: _pc.DateRangeParameterConfig
751
- _curr_option: _po.DateRangeParameterOption | None
752
- _selected_start_date: date | str | None
753
- _selected_end_date: date | str | None
754
-
755
- def __post_init__(self):
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)
761
-
762
- def is_enabled(self) -> bool:
763
- return self._curr_option is not None
764
-
765
- @staticmethod
766
- def _ParameterConfigType():
767
- return _pc.DateRangeParameterConfig
768
-
769
- @classmethod
770
- def CreateSimple(
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
774
- ) -> None:
775
- """
776
- Method for creating the configurations for a Parameter that doesn't involve user attributes or parent parameters
777
-
778
- Arguments:
779
- name: The name of the parameter
780
- label: The display label for the parameter
781
- default_start_date: Default start date for this option
782
- default_end_date: Default end date for this option
783
- description: Explains the meaning of the parameter
784
- date_format: Format of the default date, default is '%Y-%m-%d'
785
- """
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
- )
789
- cls.CreateWithOptions(name, label, (single_param_option,), description=description)
790
-
791
- def get_selected_start_date(self, *, date_format: str | None = None, **kwargs) -> str:
792
- """
793
- Gets selected start date as string
794
-
795
- Arguments:
796
- date_format: The date format (see Python's datetime formats). If not specified, self.date_format is used
797
-
798
- Returns:
799
- A string
800
- """
801
- assert self._curr_option is not None and isinstance(self._selected_start_date, date), "Parameter is not enabled"
802
- date_format = self._curr_option._date_format if date_format is None else date_format
803
- return self._selected_start_date.strftime(date_format)
804
-
805
- def get_selected_start_date_quoted(self, *, date_format: str | None = None, **kwargs) -> str:
806
- """
807
- Gets selected start date as string surrounded by single quotes
808
-
809
- Arguments:
810
- date_format: The date format (see Python's datetime formats). If not specified, self.date_format is used
811
-
812
- Returns:
813
- A string
814
- """
815
- return self._enquote(self.get_selected_start_date(date_format=date_format))
816
-
817
- def get_selected_end_date(self, *, date_format: str | None = None, **kwargs) -> str:
818
- """
819
- Gets selected end date as string
820
-
821
- Arguments:
822
- date_format: The date format (see Python's datetime formats). If not specified, self.date_format is used
823
-
824
- Returns:
825
- A string
826
- """
827
- assert self._curr_option is not None and isinstance(self._selected_end_date, date), "Parameter is not enabled"
828
- date_format = self._curr_option._date_format if date_format is None else date_format
829
- return self._selected_end_date.strftime(date_format)
830
-
831
- def get_selected_end_date_quoted(self, *, date_format: str | None = None, **kwargs) -> str:
832
- """
833
- Gets selected end date as string surrounded by single quotes
834
-
835
- Arguments:
836
- date_format: The date format (see Python's datetime formats). If not specified, self.date_format is used
837
-
838
- Returns:
839
- A string
840
- """
841
- return self._enquote(self.get_selected_end_date(date_format=date_format))
842
-
843
- def _to_json_dict0(self):
844
- """
845
- Converts this parameter as a JSON object for the parameters API response
846
-
847
- The "selected_date" field will always be in yyyy-mm-dd format
848
-
849
- Returns:
850
- A dictionary for the JSON object
851
- """
852
- output = super()._to_json_dict0()
853
- if self.is_enabled():
854
- output["selected_start_date"] = self.get_selected_start_date(date_format="%Y-%m-%d")
855
- output["selected_end_date"] = self.get_selected_end_date(date_format="%Y-%m-%d")
856
- return output
857
-
858
- def _get_response_model0(self):
859
- return arm.DateRangeParameterModel if self.is_enabled() else arm.NoneParameterModel
860
-
861
-
862
- @dataclass
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):
880
- """
881
- Class for number parameter widgets.
882
-
883
- Attributes:
884
- config: The config for this widget parameter (for immutable attributes like name, label, all possible options, etc)
885
- curr_option: The current option showing for defaults based on user attribute and selection of parent
886
- selected_value: The selected integer or decimal number
887
- """
888
- _config: _pc.NumberParameterConfig
889
- _curr_option: _po.NumberParameterOption | None
890
- _selected_value: _po.Number | None
891
-
892
- def __post_init__(self):
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)
895
-
896
- @staticmethod
897
- def _ParameterConfigType():
898
- return _pc.NumberParameterConfig
899
-
900
- @classmethod
901
- def CreateSimple(
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
904
- ) -> None:
905
- """
906
- Method for creating the configurations for a Parameter that doesn't involve user attributes or parent parameters
907
-
908
- * Note that the "Number" type denotes an int, a Decimal (from decimal module), or a string that can be parsed to Decimal
909
-
910
- Arguments:
911
- name: The name of the parameter
912
- label: The display label for the parameter
913
- min_value: Minimum selectable value
914
- max_value: Maximum selectable value
915
- description: Explains the meaning of the parameter
916
- increment: Increment of selectable values, and must fit evenly between min_value and max_value
917
- default_value: Default value for this option, and must be selectable based on min_value, max_value, and increment
918
- """
919
- single_param_option = _po.NumberParameterOption(min_value, max_value, increment=increment, default_value=default_value)
920
- cls.CreateWithOptions(name, label, (single_param_option,), description=description)
921
-
922
- def get_selected_value(self, **kwargs) -> float:
923
- """
924
- Get the selected number (converted from Decimal to float)
925
-
926
- Returns:
927
- float
928
- """
929
- assert self._selected_value is not None, "Parameter is not enabled"
930
- return float(self._selected_value)
931
-
932
- def _to_json_dict0(self):
933
- """
934
- Converts this parameter as a JSON object for the parameters API response
935
-
936
- Returns:
937
- A dictionary for the JSON object
938
- """
939
- output = super()._to_json_dict0()
940
- if self.is_enabled():
941
- output["selected_value"] = self.get_selected_value()
942
- return output
943
-
944
- def _get_response_model0(self):
945
- return arm.NumberParameterModel if self.is_enabled() else arm.NoneParameterModel
946
-
947
-
948
- @dataclass
949
- class NumberRangeParameter(_NumberTypeParameter):
950
- """
951
- Class for number range parameter widgets.
952
-
953
- Attributes:
954
- config: The config for this widget parameter (for immutable attributes like name, label, all possible options, etc)
955
- curr_option: The current option showing for defaults based on user attribute and selection of parent
956
- selected_lower_value: The selected lower integer or decimal number
957
- selected_upper_value: The selected upper integer or decimal number
958
- """
959
- _config: _pc.NumberRangeParameterConfig
960
- _curr_option: _po.NumberRangeParameterOption | None
961
- _selected_lower_value: _po.Number | None
962
- _selected_upper_value: _po.Number | None
963
-
964
- def __post_init__(self):
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)
970
-
971
- @staticmethod
972
- def _ParameterConfigType():
973
- return _pc.NumberRangeParameterConfig
974
-
975
- @classmethod
976
- def CreateSimple(
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,
979
- **kwargs
980
- ) -> None:
981
- """
982
- Method for creating the configurations for a Parameter that doesn't involve user attributes or parent parameters
983
-
984
- * Note that the "Number" type denotes an int, a Decimal (from decimal module), or a string that can be parsed to Decimal
985
-
986
- Arguments:
987
- name: The name of the parameter
988
- label: The display label for the parameter
989
- min_value: Minimum selectable value
990
- max_value: Maximum selectable value
991
- description: Explains the meaning of the parameter
992
- increment: Increment of selectable values, and must fit evenly between min_value and max_value
993
- default_lower_value: Default lower value for this option, and must be selectable based on min_value, max_value, and increment
994
- default_upper_value: Default upper value for this option, and must be selectable based on min_value, max_value, and increment.
995
- Must also be greater than default_lower_value
996
- """
997
- single_param_option = _po.NumberRangeParameterOption(
998
- min_value, max_value, increment=increment, default_lower_value=default_lower_value, default_upper_value=default_upper_value
999
- )
1000
- cls.CreateWithOptions(name, label, (single_param_option,), description=description)
1001
-
1002
- def get_selected_lower_value(self, **kwargs) -> float:
1003
- """
1004
- Get the selected lower value number (converted from Decimal to float)
1005
-
1006
- Returns:
1007
- float
1008
- """
1009
- assert self._selected_lower_value is not None, "Parameter is not enabled"
1010
- return float(self._selected_lower_value)
1011
-
1012
- def get_selected_upper_value(self, **kwargs) -> float:
1013
- """
1014
- Get the selected upper value number (converted from Decimal to float)
1015
-
1016
- Returns:
1017
- float
1018
- """
1019
- assert self._selected_upper_value is not None, "Parameter is not enabled"
1020
- return float(self._selected_upper_value)
1021
-
1022
- def _to_json_dict0(self):
1023
- """
1024
- Converts this parameter as a JSON object for the parameters API response
1025
-
1026
- Returns:
1027
- A dictionary for the JSON object
1028
- """
1029
- output = super()._to_json_dict0()
1030
- if self.is_enabled():
1031
- output['selected_lower_value'] = self.get_selected_lower_value()
1032
- output['selected_upper_value'] = self.get_selected_upper_value()
1033
- return output
1034
-
1035
- def _get_response_model0(self):
1036
- return arm.NumberRangeParameterModel if self.is_enabled() else arm.NoneParameterModel
1037
-
1038
-
1039
- @dataclass
1040
- class TextValue:
1041
- _value_do_not_touch: str
1042
-
1043
- def __repr__(self):
1044
- raise u.ConfigurationError(
1045
- "Cannot convert TextValue directly to string (to avoid SQL injection). Try using it through placeholders instead"
1046
- )
1047
-
1048
- def apply(self, str_to_str_function: Callable[[str], str]) -> TextValue:
1049
- """
1050
- Transforms the entered text with a function that takes a string and returns a string.
1051
-
1052
- This method returns a new object and leaves the original the same.
1053
-
1054
- Arguments:
1055
- str_to_str_function: A function that accepts a string and returns a string
1056
-
1057
- Returns:
1058
- A new TextValue with the transformed entered text
1059
- """
1060
- new_value = str_to_str_function(self._value_do_not_touch)
1061
- if not isinstance(new_value, str):
1062
- raise u.ConfigurationError("Function provided must return string")
1063
- return TextValue(new_value)
1064
-
1065
- def apply_percent_wrap(self) -> TextValue:
1066
- """
1067
- Adds percent signs before and after the entered text, and returns a new object, leaving the original the same.
1068
-
1069
- Returns:
1070
- A new TextValue with the transformed entered text
1071
- """
1072
- return self.apply(lambda x: "%"+x+"%")
1073
-
1074
- def apply_as_bool(self, str_to_bool_function: Callable[[str], bool]) -> bool:
1075
- """
1076
- Transforms the entered text with a function that takes a string and returns a boolean.
1077
-
1078
- Arguments:
1079
- str_to_bool_function: A function that accepts a string and returns a boolean.
1080
-
1081
- Returns:
1082
- A boolean for the transformed value
1083
- """
1084
- new_value = str_to_bool_function(self._value_do_not_touch)
1085
- if not isinstance(new_value, bool):
1086
- raise u.ConfigurationError("Function provided must return bool")
1087
- return new_value
1088
-
1089
- def apply_as_number(self, str_to_num_function: Callable[[str], IntOrFloat]) -> IntOrFloat:
1090
- """
1091
- Transforms the entered text with a function that takes a string and returns an int or float.
1092
-
1093
- Arguments:
1094
- str_to_num_function: A function that accepts a string and returns an int or float.
1095
-
1096
- Returns:
1097
- An int or float for the transformed value
1098
- """
1099
- new_value = str_to_num_function(self._value_do_not_touch)
1100
- if not isinstance(new_value, (int, float)):
1101
- raise u.ConfigurationError("Function provided must return a number")
1102
- return new_value
1103
-
1104
- def apply_as_datetime(self, str_to_datetime_function: Callable[[str], datetime]) -> datetime:
1105
- """
1106
- Transforms the entered text with a function that takes a string and returns a datetime object.
1107
-
1108
- Arguments:
1109
- str_to_datetime_function: A function that accepts a string and returns a datetime object.
1110
-
1111
- Returns:
1112
- A datetime object for the transformed value
1113
- """
1114
- new_value = str_to_datetime_function(self._value_do_not_touch)
1115
- if not isinstance(new_value, datetime):
1116
- raise u.ConfigurationError("Function provided must return datetime")
1117
- return new_value
1118
-
1119
-
1120
- @dataclass
1121
- class TextParameter(Parameter):
1122
- """
1123
- Class for text parameter widgets.
1124
- """
1125
- _config: _pc.TextParameterConfig
1126
- _curr_option: _po.TextParameterOption | None
1127
- _entered_text: str | None
1128
-
1129
- def __post_init__(self):
1130
- if self.is_enabled() and isinstance(self._entered_text, str):
1131
- try:
1132
- self._entered_text = self._config.validate_entered_text(self._entered_text)
1133
- except u.ConfigurationError as e:
1134
- raise self._config._invalid_input_error(self._entered_text, str(e))
1135
-
1136
- def is_enabled(self) -> bool:
1137
- return self._curr_option is not None
1138
-
1139
- @staticmethod
1140
- def _ParameterConfigType():
1141
- return _pc.TextParameterConfig
1142
-
1143
- @classmethod
1144
- def CreateWithOptions(
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
1147
- ) -> None:
1148
- """
1149
- Method for creating the configurations for a MultiSelectParameter that may include user attribute or parent
1150
-
1151
- Arguments:
1152
- name: The name of the parameter
1153
- label: The display label for the parameter
1154
- all_options: All options associated to this parameter regardless of the user group or parent parameter option they depend on
1155
- description: Explains the meaning of the parameter
1156
- 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
1157
- user_attribute: The user attribute that may cascade the options for this parameter. Default is None
1158
- parent_name: Name of parent parameter that may cascade the options for this parameter. Default is None (no parent)
1159
- """
1160
- cls._CreateWithOptionsHelper(
1161
- name, label, all_options, description=description, input_type=input_type, user_attribute=user_attribute, parent_name=parent_name
1162
- )
1163
-
1164
- @classmethod
1165
- def Create(
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
1168
- ) -> None:
1169
- """
1170
- DEPRECATED. Use CreateWithOptions instead
1171
- """
1172
- cls._CreateWithOptionsHelper(
1173
- name, label, all_options, description=description, input_type=input_type, user_attribute=user_attribute, parent_name=parent_name
1174
- )
1175
-
1176
- @classmethod
1177
- def CreateSimple(
1178
- cls, name: str, label: str, *, description: str = "", default_text: str = "", input_type: str = "text", **kwargs
1179
- ) -> None:
1180
- """
1181
- Method for creating the configurations for a Parameter that doesn't involve user attributes or parent parameters
1182
-
1183
- Arguments:
1184
- name: The name of the parameter
1185
- label: The display label for the parameter
1186
- description: Explains the meaning of the parameter
1187
- default_text: Default input text for this option. Optional, default is empty string.
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
1189
- """
1190
- single_param_option = _po.TextParameterOption(default_text=default_text)
1191
- cls.CreateWithOptions(name, label, (single_param_option,), description=description, input_type=input_type)
1192
-
1193
- @classmethod
1194
- def CreateFromSource(
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
1197
- ) -> None:
1198
- """
1199
- Method for creating the configurations for a MultiSelectParameter that uses a SelectDataSource to receive the options
1200
-
1201
- Arguments:
1202
- name: The name of the parameter
1203
- label: The display label for the parameter
1204
- data_source: The lookup table to use for this parameter
1205
- description: Explains the meaning of the parameter
1206
- input_type: The type of input field to use. Options are 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
1207
- user_attribute: The user attribute that may cascade the options for this parameter. Default is None
1208
- parent_name: Name of parent parameter that may cascade the options for this parameter. Default is None (no parent)
1209
- """
1210
- extra_args = {
1211
- "input_type": input_type
1212
- }
1213
- cls._CreateFromSourceHelper(
1214
- name, label, data_source, extra_args=extra_args, description=description, user_attribute=user_attribute, parent_name=parent_name
1215
- )
1216
-
1217
- def get_entered_text(self, **kwargs) -> TextValue:
1218
- """
1219
- Get the entered text. Returns a TextValue object that cannot be converted to string except through placeholders.
1220
-
1221
- Returns:
1222
- A TextValue object
1223
- """
1224
- assert isinstance(self._entered_text, str), "Parameter is not enabled"
1225
- return TextValue(self._entered_text)
1226
-
1227
- def get_entered_int(self, **kwargs) -> int:
1228
- """
1229
- Get the entered integer. The TextParameter must be a "number" input type
1230
-
1231
- Returns: int
1232
- """
1233
- if self._config.input_type != "number":
1234
- raise u.ConfigurationError("Method 'get_entered_int' requires TextParameter to have input type 'number'")
1235
- text = self.get_entered_text()
1236
- return text.apply_as_number(int)
1237
-
1238
- def get_entered_datetime(self, **kwargs) -> datetime:
1239
- """
1240
- Get the entered datetime. The TextParameter input type must be one of ["date", "datetime-local", "month", "time"]
1241
-
1242
- Returns: datetime
1243
- """
1244
- applicable_input_types = ["date", "datetime-local", "month", "time"]
1245
- if self._config.input_type not in applicable_input_types:
1246
- raise u.ConfigurationError(f"Method 'get_entered_datetime' requires TextParameter to have one of these input types: {applicable_input_types}")
1247
- text = self.get_entered_text()
1248
-
1249
- date_formats = { "date": "%Y-%m-%d", "datetime-local": "%Y-%m-%dT%H:%M", "month": "%Y-%m", "time": "%H:%M" }
1250
- return text.apply_as_datetime(lambda x: datetime.strptime(x, date_formats[self._config.input_type]))
1251
-
1252
- def _to_json_dict0(self):
1253
- """
1254
- Converts this parameter as a JSON object for the parameters API response
1255
-
1256
- Returns:
1257
- A dictionary for the JSON object
1258
- """
1259
- output = super()._to_json_dict0()
1260
- output['input_type'] = self._config.input_type
1261
- if self.is_enabled():
1262
- output['entered_text'] = self._entered_text
1263
- return output
1264
-
1265
- def _get_response_model0(self):
1266
- return arm.TextParameterModel if self.is_enabled() else arm.NoneParameterModel
1
+ from ._parameters import (
2
+ SingleSelectParameter,
3
+ MultiSelectParameter,
4
+ DateParameter,
5
+ DateRangeParameter,
6
+ NumberParameter,
7
+ NumberRangeParameter,
8
+ TextParameter
9
+ )