syd 0.1.7__py3-none-any.whl → 1.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- syd/__init__.py +1 -1
- syd/flask_deployment/__init__.py +1 -1
- syd/flask_deployment/deployer.py +563 -238
- syd/flask_deployment/static/__init__.py +1 -0
- syd/flask_deployment/static/css/styles.css +280 -0
- syd/flask_deployment/static/js/viewer.js +795 -138
- syd/flask_deployment/templates/__init__.py +1 -0
- syd/flask_deployment/templates/index.html +34 -0
- syd/flask_deployment/testing_principles.md +4 -4
- syd/notebook_deployment/__init__.py +0 -1
- syd/notebook_deployment/deployer.py +124 -213
- syd/notebook_deployment/widgets.py +78 -60
- syd/parameters.py +299 -345
- syd/support.py +195 -0
- syd/viewer.py +310 -347
- syd-1.0.0.dist-info/METADATA +219 -0
- syd-1.0.0.dist-info/RECORD +19 -0
- syd/flask_deployment/components.py +0 -510
- syd/flask_deployment/static/css/viewer.css +0 -82
- syd/flask_deployment/templates/base.html +0 -29
- syd/flask_deployment/templates/viewer.html +0 -51
- syd/notebook_deployment/_ipympl_deployer.py +0 -258
- syd/plotly_deployment/__init__.py +0 -1
- syd/plotly_deployment/components.py +0 -531
- syd/plotly_deployment/deployer.py +0 -376
- syd-0.1.7.dist-info/METADATA +0 -120
- syd-0.1.7.dist-info/RECORD +0 -22
- {syd-0.1.7.dist-info → syd-1.0.0.dist-info}/WHEEL +0 -0
- {syd-0.1.7.dist-info → syd-1.0.0.dist-info}/licenses/LICENSE +0 -0
syd/parameters.py
CHANGED
|
@@ -1,140 +1,18 @@
|
|
|
1
1
|
from typing import List, Any, Tuple, Generic, TypeVar, Optional, Dict, Callable, Union
|
|
2
2
|
from dataclasses import dataclass, field
|
|
3
|
-
from abc import ABC,
|
|
3
|
+
from abc import ABC, abstractmethod
|
|
4
4
|
from enum import Enum
|
|
5
5
|
from copy import deepcopy
|
|
6
|
-
from warnings import warn
|
|
7
|
-
import numpy as np
|
|
8
6
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
Parameters
|
|
18
|
-
----------
|
|
19
|
-
parameter_name : str
|
|
20
|
-
Name of the parameter that failed to be created
|
|
21
|
-
parameter_type : str
|
|
22
|
-
Type of the parameter that failed to be created
|
|
23
|
-
message : str, optional
|
|
24
|
-
Additional error details
|
|
25
|
-
"""
|
|
26
|
-
|
|
27
|
-
def __init__(self, parameter_name: str, parameter_type: str, message: str = None):
|
|
28
|
-
self.parameter_name = parameter_name
|
|
29
|
-
self.parameter_type = parameter_type
|
|
30
|
-
super().__init__(
|
|
31
|
-
f"Failed to create {parameter_type} parameter '{parameter_name}'"
|
|
32
|
-
+ (f": {message}" if message else "")
|
|
33
|
-
)
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
class ParameterUpdateError(Exception):
|
|
37
|
-
"""
|
|
38
|
-
Exception raised when there is an error updating an existing parameter.
|
|
39
|
-
|
|
40
|
-
Parameters
|
|
41
|
-
----------
|
|
42
|
-
parameter_name : str
|
|
43
|
-
Name of the parameter that failed to update
|
|
44
|
-
parameter_type : str
|
|
45
|
-
Type of the parameter that failed to update
|
|
46
|
-
message : str, optional
|
|
47
|
-
Additional error details
|
|
48
|
-
"""
|
|
49
|
-
|
|
50
|
-
def __init__(self, parameter_name: str, parameter_type: str, message: str = None):
|
|
51
|
-
self.parameter_name = parameter_name
|
|
52
|
-
self.parameter_type = parameter_type
|
|
53
|
-
super().__init__(
|
|
54
|
-
f"Failed to update {parameter_type} parameter '{parameter_name}'"
|
|
55
|
-
+ (f": {message}" if message else "")
|
|
56
|
-
)
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
class ParameterUpdateWarning(Warning):
|
|
60
|
-
"""
|
|
61
|
-
Warning raised when there is a non-critical issue updating a parameter.
|
|
62
|
-
|
|
63
|
-
Parameters
|
|
64
|
-
----------
|
|
65
|
-
parameter_name : str
|
|
66
|
-
Name of the parameter that had the warning
|
|
67
|
-
parameter_type : str
|
|
68
|
-
Type of the parameter
|
|
69
|
-
message : str, optional
|
|
70
|
-
Additional warning details
|
|
71
|
-
"""
|
|
72
|
-
|
|
73
|
-
def __init__(self, parameter_name: str, parameter_type: str, message: str = None):
|
|
74
|
-
self.parameter_name = parameter_name
|
|
75
|
-
self.parameter_type = parameter_type
|
|
76
|
-
super().__init__(
|
|
77
|
-
f"Warning updating {parameter_type} parameter '{parameter_name}'"
|
|
78
|
-
+ (f": {message}" if message else "")
|
|
79
|
-
)
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
def get_parameter_attributes(param_class) -> List[str]:
|
|
83
|
-
"""
|
|
84
|
-
Get all valid attributes for a parameter class.
|
|
85
|
-
|
|
86
|
-
Parameters
|
|
87
|
-
----------
|
|
88
|
-
param_class : class
|
|
89
|
-
The parameter class to inspect
|
|
90
|
-
|
|
91
|
-
Returns
|
|
92
|
-
-------
|
|
93
|
-
list of str
|
|
94
|
-
Names of all valid attributes for the parameter class
|
|
95
|
-
"""
|
|
96
|
-
attributes = []
|
|
7
|
+
from .support import (
|
|
8
|
+
NoInitialValue,
|
|
9
|
+
ParameterMeta,
|
|
10
|
+
ParameterUpdateError,
|
|
11
|
+
get_parameter_attributes,
|
|
12
|
+
warn_parameter_update,
|
|
13
|
+
)
|
|
97
14
|
|
|
98
|
-
|
|
99
|
-
for cls in reversed(param_class.__mro__):
|
|
100
|
-
if hasattr(cls, "__annotations__"):
|
|
101
|
-
# Only add annotations that haven't been specified by a more specific class
|
|
102
|
-
for name in cls.__annotations__:
|
|
103
|
-
if not name.startswith("_"):
|
|
104
|
-
attributes.append(name)
|
|
105
|
-
|
|
106
|
-
return attributes
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
class ParameterMeta(ABCMeta):
|
|
110
|
-
_parameter_types = {}
|
|
111
|
-
_parameter_ids = {} # Store unique identifiers for our parameter types
|
|
112
|
-
|
|
113
|
-
def __new__(cls, name, bases, namespace):
|
|
114
|
-
parameter_class = super().__new__(cls, name, bases, namespace)
|
|
115
|
-
if name != "Parameter":
|
|
116
|
-
# Generate a unique ID for this parameter type
|
|
117
|
-
type_id = f"syd.parameters.{name}" # Using fully qualified name
|
|
118
|
-
cls._parameter_ids[name] = type_id
|
|
119
|
-
|
|
120
|
-
# Add ID to the class
|
|
121
|
-
if not hasattr(parameter_class, "_parameter_type_id"):
|
|
122
|
-
setattr(parameter_class, "_parameter_type_id", type_id)
|
|
123
|
-
else:
|
|
124
|
-
if getattr(parameter_class, "_parameter_type_id") != type_id:
|
|
125
|
-
raise ValueError(
|
|
126
|
-
f"Parameter type {name} has multiple IDs: {type_id} and {getattr(parameter_class, '_parameter_type_id')}"
|
|
127
|
-
)
|
|
128
|
-
cls._parameter_types[name] = parameter_class
|
|
129
|
-
return parameter_class
|
|
130
|
-
|
|
131
|
-
def __instancecheck__(cls, instance):
|
|
132
|
-
type_id = cls._parameter_ids.get(cls.__name__)
|
|
133
|
-
if not type_id:
|
|
134
|
-
return False
|
|
135
|
-
|
|
136
|
-
# Check if instance has our type ID
|
|
137
|
-
return getattr(instance.__class__, "_parameter_type_id", None) == type_id
|
|
15
|
+
T = TypeVar("T")
|
|
138
16
|
|
|
139
17
|
|
|
140
18
|
@dataclass
|
|
@@ -216,8 +94,8 @@ class Parameter(Generic[T], ABC, metaclass=ParameterMeta):
|
|
|
216
94
|
|
|
217
95
|
Examples
|
|
218
96
|
--------
|
|
219
|
-
>>> param = FloatParameter("temperature", 20.0,
|
|
220
|
-
>>> param.update({"value": 25.0, "
|
|
97
|
+
>>> param = FloatParameter("temperature", 20.0, min=0, max=100)
|
|
98
|
+
>>> param.update({"value": 25.0, "max": 150})
|
|
221
99
|
"""
|
|
222
100
|
param_copy = deepcopy(self)
|
|
223
101
|
|
|
@@ -292,7 +170,7 @@ class TextParameter(Parameter[str]):
|
|
|
292
170
|
----------
|
|
293
171
|
name : str
|
|
294
172
|
The name of the parameter
|
|
295
|
-
value : str
|
|
173
|
+
value : Union[str, NoInitialValue]
|
|
296
174
|
The initial text value
|
|
297
175
|
|
|
298
176
|
Examples
|
|
@@ -305,8 +183,10 @@ class TextParameter(Parameter[str]):
|
|
|
305
183
|
'Bob'
|
|
306
184
|
"""
|
|
307
185
|
|
|
308
|
-
def __init__(self, name: str, value: str):
|
|
186
|
+
def __init__(self, name: str, value: Union[str, NoInitialValue]):
|
|
309
187
|
self.name = name
|
|
188
|
+
if isinstance(value, NoInitialValue):
|
|
189
|
+
value = ""
|
|
310
190
|
self._value = self._validate(value)
|
|
311
191
|
|
|
312
192
|
def _validate(self, new_value: Any) -> str:
|
|
@@ -335,7 +215,7 @@ class BooleanParameter(Parameter[bool]):
|
|
|
335
215
|
----------
|
|
336
216
|
name : str
|
|
337
217
|
The name of the parameter
|
|
338
|
-
value : bool,
|
|
218
|
+
value : Union[bool, NoInitialValue]
|
|
339
219
|
The initial state (default is True)
|
|
340
220
|
|
|
341
221
|
Examples
|
|
@@ -348,8 +228,10 @@ class BooleanParameter(Parameter[bool]):
|
|
|
348
228
|
False
|
|
349
229
|
"""
|
|
350
230
|
|
|
351
|
-
def __init__(self, name: str, value: bool
|
|
231
|
+
def __init__(self, name: str, value: Union[bool, NoInitialValue]):
|
|
352
232
|
self.name = name
|
|
233
|
+
if isinstance(value, NoInitialValue):
|
|
234
|
+
value = True
|
|
353
235
|
self._value = self._validate(value)
|
|
354
236
|
|
|
355
237
|
def _validate(self, new_value: Any) -> bool:
|
|
@@ -378,7 +260,7 @@ class SelectionParameter(Parameter[Any]):
|
|
|
378
260
|
----------
|
|
379
261
|
name : str
|
|
380
262
|
The name of the parameter
|
|
381
|
-
value : Any
|
|
263
|
+
value : Union[Any, NoInitialValue]
|
|
382
264
|
The initially selected value (must be one of the options)
|
|
383
265
|
options : sequence
|
|
384
266
|
List, tuple, or 1D numpy array of valid choices that can be selected
|
|
@@ -401,9 +283,13 @@ class SelectionParameter(Parameter[Any]):
|
|
|
401
283
|
|
|
402
284
|
options: List[Any]
|
|
403
285
|
|
|
404
|
-
def __init__(
|
|
286
|
+
def __init__(
|
|
287
|
+
self, name: str, value: Union[Any, NoInitialValue], options: Union[List, Tuple]
|
|
288
|
+
):
|
|
405
289
|
self.name = name
|
|
406
290
|
self.options = self._validate_options(options)
|
|
291
|
+
if isinstance(value, NoInitialValue):
|
|
292
|
+
value = self.options[0]
|
|
407
293
|
self._value = self._validate(value)
|
|
408
294
|
|
|
409
295
|
def _validate_options(self, options: Any) -> List[Any]:
|
|
@@ -458,9 +344,42 @@ class SelectionParameter(Parameter[Any]):
|
|
|
458
344
|
Raises:
|
|
459
345
|
ValueError: If value is not in options list
|
|
460
346
|
"""
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
347
|
+
# Direct check for non-float values or when new_value is exactly in options
|
|
348
|
+
if new_value in self.options:
|
|
349
|
+
return new_value
|
|
350
|
+
|
|
351
|
+
# Special handling for numeric values to account for type mismatches
|
|
352
|
+
if isinstance(new_value, (int, float)):
|
|
353
|
+
for option in self.options:
|
|
354
|
+
# For numeric options, compare as floats
|
|
355
|
+
if (
|
|
356
|
+
isinstance(option, (int, float))
|
|
357
|
+
and abs(float(new_value) - float(option)) < 1e-10
|
|
358
|
+
):
|
|
359
|
+
return option
|
|
360
|
+
# Also try string conversion for numeric strings
|
|
361
|
+
elif isinstance(option, str):
|
|
362
|
+
try:
|
|
363
|
+
if abs(float(new_value) - float(option)) < 1e-10:
|
|
364
|
+
return option
|
|
365
|
+
except ValueError:
|
|
366
|
+
pass
|
|
367
|
+
|
|
368
|
+
# Handle string conversion - when new_value is a string but options might be numeric
|
|
369
|
+
if isinstance(new_value, str):
|
|
370
|
+
try:
|
|
371
|
+
# Try to convert to float if possible
|
|
372
|
+
float_value = float(new_value)
|
|
373
|
+
for option in self.options:
|
|
374
|
+
if (
|
|
375
|
+
isinstance(option, (int, float))
|
|
376
|
+
and abs(float_value - float(option)) < 1e-10
|
|
377
|
+
):
|
|
378
|
+
return option
|
|
379
|
+
except ValueError:
|
|
380
|
+
pass
|
|
381
|
+
|
|
382
|
+
raise ValueError(f"Value {new_value} not in options: {self.options}")
|
|
464
383
|
|
|
465
384
|
def _validate_update(self) -> None:
|
|
466
385
|
"""
|
|
@@ -473,13 +392,50 @@ class SelectionParameter(Parameter[Any]):
|
|
|
473
392
|
TypeError: If options is not a list or tuple
|
|
474
393
|
"""
|
|
475
394
|
self.options = self._validate_options(self.options)
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
395
|
+
|
|
396
|
+
# Check if value is directly in options
|
|
397
|
+
if self.value in self.options:
|
|
398
|
+
return
|
|
399
|
+
|
|
400
|
+
# For numeric values, try flexible comparison
|
|
401
|
+
value_found = False
|
|
402
|
+
if isinstance(self.value, (int, float)):
|
|
403
|
+
for option in self.options:
|
|
404
|
+
if (
|
|
405
|
+
isinstance(option, (int, float))
|
|
406
|
+
and abs(float(self.value) - float(option)) < 1e-10
|
|
407
|
+
):
|
|
408
|
+
# Don't update self.value here as we want to keep the original type if possible
|
|
409
|
+
value_found = True
|
|
410
|
+
break
|
|
411
|
+
elif isinstance(option, str):
|
|
412
|
+
try:
|
|
413
|
+
if abs(float(self.value) - float(option)) < 1e-10:
|
|
414
|
+
value_found = True
|
|
415
|
+
break
|
|
416
|
+
except ValueError:
|
|
417
|
+
pass
|
|
418
|
+
|
|
419
|
+
# For string values that might be numeric
|
|
420
|
+
if not value_found and isinstance(self.value, str):
|
|
421
|
+
try:
|
|
422
|
+
float_value = float(self.value)
|
|
423
|
+
for option in self.options:
|
|
424
|
+
if (
|
|
425
|
+
isinstance(option, (int, float))
|
|
426
|
+
and abs(float_value - float(option)) < 1e-10
|
|
427
|
+
):
|
|
428
|
+
value_found = True
|
|
429
|
+
break
|
|
430
|
+
except ValueError:
|
|
431
|
+
pass
|
|
432
|
+
|
|
433
|
+
# If value is not found after all checks, reset to first option
|
|
434
|
+
if not value_found:
|
|
435
|
+
warn_parameter_update(
|
|
436
|
+
self.name,
|
|
437
|
+
type(self).__name__,
|
|
438
|
+
f"Value {self.value} not in options, setting to first option ({self.options[0]})",
|
|
483
439
|
)
|
|
484
440
|
self.value = self.options[0]
|
|
485
441
|
|
|
@@ -497,8 +453,8 @@ class MultipleSelectionParameter(Parameter[List[Any]]):
|
|
|
497
453
|
----------
|
|
498
454
|
name : str
|
|
499
455
|
The name of the parameter
|
|
500
|
-
value :
|
|
501
|
-
List of initially selected values (must all be from options)
|
|
456
|
+
value : Union[List[Any], NoInitialValue]
|
|
457
|
+
List of initially selected values (must all be from options, can be empty)
|
|
502
458
|
options : sequence
|
|
503
459
|
List, tuple, or 1D numpy array of valid choices that can be selected
|
|
504
460
|
|
|
@@ -520,9 +476,16 @@ class MultipleSelectionParameter(Parameter[List[Any]]):
|
|
|
520
476
|
|
|
521
477
|
options: List[Any]
|
|
522
478
|
|
|
523
|
-
def __init__(
|
|
479
|
+
def __init__(
|
|
480
|
+
self,
|
|
481
|
+
name: str,
|
|
482
|
+
value: Union[List[Any], NoInitialValue],
|
|
483
|
+
options: Union[List, Tuple],
|
|
484
|
+
):
|
|
524
485
|
self.name = name
|
|
525
486
|
self.options = self._validate_options(options)
|
|
487
|
+
if isinstance(value, NoInitialValue):
|
|
488
|
+
value = []
|
|
526
489
|
self._value = self._validate(value)
|
|
527
490
|
|
|
528
491
|
def _validate_options(self, options: Any) -> List[Any]:
|
|
@@ -592,22 +555,18 @@ class MultipleSelectionParameter(Parameter[List[Any]]):
|
|
|
592
555
|
def _validate_update(self) -> None:
|
|
593
556
|
self.options = self._validate_options(self.options)
|
|
594
557
|
if not isinstance(self.value, (list, tuple)):
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
f"For parameter {self.name}, value {self.value} is not a list or tuple. Setting to empty list.",
|
|
600
|
-
)
|
|
558
|
+
warn_parameter_update(
|
|
559
|
+
self.name,
|
|
560
|
+
type(self).__name__,
|
|
561
|
+
f"For parameter {self.name}, value {self.value} is not a list or tuple. Setting to empty list.",
|
|
601
562
|
)
|
|
602
563
|
self.value = []
|
|
603
564
|
if not all(val in self.options for val in self.value):
|
|
604
565
|
invalid = [val for val in self.value if val not in self.options]
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
f"For parameter {self.name}, value {self.value} contains invalid selections: {invalid}. Setting to empty list.",
|
|
610
|
-
)
|
|
566
|
+
warn_parameter_update(
|
|
567
|
+
self.name,
|
|
568
|
+
type(self).__name__,
|
|
569
|
+
f"For parameter {self.name}, value {self.value} contains invalid selections: {invalid}. Setting to empty list.",
|
|
611
570
|
)
|
|
612
571
|
self.value = []
|
|
613
572
|
# Keep only unique values while preserving order based on self.options
|
|
@@ -628,39 +587,41 @@ class IntegerParameter(Parameter[int]):
|
|
|
628
587
|
----------
|
|
629
588
|
name : str
|
|
630
589
|
The name of the parameter
|
|
631
|
-
value : int
|
|
632
|
-
Initial value (will be clamped to fit between
|
|
633
|
-
|
|
590
|
+
value : Union[int, NoInitialValue]
|
|
591
|
+
Initial value (will be clamped to fit between min and max)
|
|
592
|
+
min : int
|
|
634
593
|
Minimum allowed value
|
|
635
|
-
|
|
594
|
+
max : int
|
|
636
595
|
Maximum allowed value
|
|
637
596
|
|
|
638
597
|
Examples
|
|
639
598
|
--------
|
|
640
|
-
>>> age = IntegerParameter("age", value=25,
|
|
599
|
+
>>> age = IntegerParameter("age", value=25, min=0, max=120)
|
|
641
600
|
>>> age.value
|
|
642
601
|
25
|
|
643
|
-
>>> age.update({"value": 150}) # Will be clamped to
|
|
602
|
+
>>> age.update({"value": 150}) # Will be clamped to max
|
|
644
603
|
>>> age.value
|
|
645
604
|
120
|
|
646
|
-
>>> age.update({"value": -10}) # Will be clamped to
|
|
605
|
+
>>> age.update({"value": -10}) # Will be clamped to min
|
|
647
606
|
>>> age.value
|
|
648
607
|
0
|
|
649
608
|
"""
|
|
650
609
|
|
|
651
|
-
|
|
652
|
-
|
|
610
|
+
min: int
|
|
611
|
+
max: int
|
|
653
612
|
|
|
654
613
|
def __init__(
|
|
655
614
|
self,
|
|
656
615
|
name: str,
|
|
657
|
-
value: int,
|
|
658
|
-
|
|
659
|
-
|
|
616
|
+
value: Union[int, NoInitialValue],
|
|
617
|
+
min: int,
|
|
618
|
+
max: int,
|
|
660
619
|
):
|
|
661
620
|
self.name = name
|
|
662
|
-
self.
|
|
663
|
-
self.
|
|
621
|
+
self.min = self._validate(min, compare_to_range=False)
|
|
622
|
+
self.max = self._validate(max, compare_to_range=False)
|
|
623
|
+
if isinstance(value, NoInitialValue):
|
|
624
|
+
value = self.min
|
|
664
625
|
self._value = self._validate(value)
|
|
665
626
|
|
|
666
627
|
def _validate(self, new_value: Any, compare_to_range: bool = True) -> int:
|
|
@@ -683,51 +644,45 @@ class IntegerParameter(Parameter[int]):
|
|
|
683
644
|
raise ValueError(f"Value {new_value} cannot be converted to int")
|
|
684
645
|
|
|
685
646
|
if compare_to_range:
|
|
686
|
-
if new_value < self.
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
f"Value {new_value} below minimum {self.min_value}, clamping",
|
|
692
|
-
)
|
|
647
|
+
if new_value < self.min:
|
|
648
|
+
warn_parameter_update(
|
|
649
|
+
self.name,
|
|
650
|
+
type(self).__name__,
|
|
651
|
+
f"Value {new_value} below minimum {self.min}, clamping",
|
|
693
652
|
)
|
|
694
|
-
new_value = self.
|
|
695
|
-
if new_value > self.
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
f"Value {new_value} above maximum {self.max_value}, clamping",
|
|
701
|
-
)
|
|
653
|
+
new_value = self.min
|
|
654
|
+
if new_value > self.max:
|
|
655
|
+
warn_parameter_update(
|
|
656
|
+
self.name,
|
|
657
|
+
type(self).__name__,
|
|
658
|
+
f"Value {new_value} above maximum {self.max}, clamping",
|
|
702
659
|
)
|
|
703
|
-
new_value = self.
|
|
660
|
+
new_value = self.max
|
|
704
661
|
return int(new_value)
|
|
705
662
|
|
|
706
663
|
def _validate_update(self) -> None:
|
|
707
664
|
"""
|
|
708
665
|
Validate complete parameter state after updates.
|
|
709
666
|
|
|
710
|
-
Ensures
|
|
667
|
+
Ensures min <= max, swapping if needed.
|
|
711
668
|
Re-validates current value against potentially updated bounds.
|
|
712
669
|
|
|
713
670
|
Raises:
|
|
714
671
|
ParameterUpdateError: If bounds are invalid (e.g. None when required)
|
|
715
672
|
"""
|
|
716
|
-
if self.
|
|
673
|
+
if self.min is None or self.max is None:
|
|
717
674
|
raise ParameterUpdateError(
|
|
718
675
|
self.name,
|
|
719
676
|
type(self).__name__,
|
|
720
|
-
"IntegerParameter must have both
|
|
677
|
+
"IntegerParameter must have both min and max bounds",
|
|
721
678
|
)
|
|
722
|
-
if self.
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
f"Min value greater than max value, swapping",
|
|
728
|
-
)
|
|
679
|
+
if self.min > self.max:
|
|
680
|
+
warn_parameter_update(
|
|
681
|
+
self.name,
|
|
682
|
+
type(self).__name__,
|
|
683
|
+
f"Min value greater than max value, swapping",
|
|
729
684
|
)
|
|
730
|
-
self.
|
|
685
|
+
self.min, self.max = self.max, self.min
|
|
731
686
|
self.value = self._validate(self.value)
|
|
732
687
|
|
|
733
688
|
|
|
@@ -744,11 +699,11 @@ class FloatParameter(Parameter[float]):
|
|
|
744
699
|
----------
|
|
745
700
|
name : str
|
|
746
701
|
The name of the parameter
|
|
747
|
-
value : float
|
|
748
|
-
Initial value (will be clamped to fit between
|
|
749
|
-
|
|
702
|
+
value : Union[float, NoInitialValue]
|
|
703
|
+
Initial value (will be clamped to fit between min and max)
|
|
704
|
+
min : float
|
|
750
705
|
Minimum allowed value
|
|
751
|
-
|
|
706
|
+
max : float
|
|
752
707
|
Maximum allowed value
|
|
753
708
|
step : float, optional
|
|
754
709
|
Size of each increment (default is 0.001)
|
|
@@ -756,13 +711,13 @@ class FloatParameter(Parameter[float]):
|
|
|
756
711
|
Examples
|
|
757
712
|
--------
|
|
758
713
|
>>> temp = FloatParameter("temperature", value=98.6,
|
|
759
|
-
...
|
|
714
|
+
... min=95.0, max=105.0, step=0.1)
|
|
760
715
|
>>> temp.value
|
|
761
716
|
98.6
|
|
762
717
|
>>> temp.update({"value": 98.67}) # Will be rounded to nearest step
|
|
763
718
|
>>> temp.value
|
|
764
719
|
98.7
|
|
765
|
-
>>> temp.update({"value": 110.0}) # Will be clamped to
|
|
720
|
+
>>> temp.update({"value": 110.0}) # Will be clamped to max
|
|
766
721
|
>>> temp.value
|
|
767
722
|
105.0
|
|
768
723
|
|
|
@@ -774,22 +729,24 @@ class FloatParameter(Parameter[float]):
|
|
|
774
729
|
- step=5.0 allows values like 0.0, 5.0, 10.0, etc.
|
|
775
730
|
"""
|
|
776
731
|
|
|
777
|
-
|
|
778
|
-
|
|
732
|
+
min: float
|
|
733
|
+
max: float
|
|
779
734
|
step: float
|
|
780
735
|
|
|
781
736
|
def __init__(
|
|
782
737
|
self,
|
|
783
738
|
name: str,
|
|
784
|
-
value: float,
|
|
785
|
-
|
|
786
|
-
|
|
739
|
+
value: Union[float, NoInitialValue],
|
|
740
|
+
min: float,
|
|
741
|
+
max: float,
|
|
787
742
|
step: float = 0.001,
|
|
788
743
|
):
|
|
789
744
|
self.name = name
|
|
790
745
|
self.step = step
|
|
791
|
-
self.
|
|
792
|
-
self.
|
|
746
|
+
self.min = self._validate(min, compare_to_range=False)
|
|
747
|
+
self.max = self._validate(max, compare_to_range=False)
|
|
748
|
+
if isinstance(value, NoInitialValue):
|
|
749
|
+
value = self.min
|
|
793
750
|
self._value = self._validate(value)
|
|
794
751
|
|
|
795
752
|
def _validate(self, new_value: Any, compare_to_range: bool = True) -> float:
|
|
@@ -817,24 +774,20 @@ class FloatParameter(Parameter[float]):
|
|
|
817
774
|
new_value = round(new_value / self.step) * self.step
|
|
818
775
|
|
|
819
776
|
if compare_to_range:
|
|
820
|
-
if new_value < self.
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
f"Value {new_value} below minimum {self.min_value}, clamping",
|
|
826
|
-
)
|
|
777
|
+
if new_value < self.min:
|
|
778
|
+
warn_parameter_update(
|
|
779
|
+
self.name,
|
|
780
|
+
type(self).__name__,
|
|
781
|
+
f"Value {new_value} below minimum {self.min}, clamping",
|
|
827
782
|
)
|
|
828
|
-
new_value = self.
|
|
829
|
-
if new_value > self.
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
f"Value {new_value} above maximum {self.max_value}, clamping",
|
|
835
|
-
)
|
|
783
|
+
new_value = self.min
|
|
784
|
+
if new_value > self.max:
|
|
785
|
+
warn_parameter_update(
|
|
786
|
+
self.name,
|
|
787
|
+
type(self).__name__,
|
|
788
|
+
f"Value {new_value} above maximum {self.max}, clamping",
|
|
836
789
|
)
|
|
837
|
-
new_value = self.
|
|
790
|
+
new_value = self.max
|
|
838
791
|
|
|
839
792
|
return float(new_value)
|
|
840
793
|
|
|
@@ -842,27 +795,25 @@ class FloatParameter(Parameter[float]):
|
|
|
842
795
|
"""
|
|
843
796
|
Validate complete parameter state after updates.
|
|
844
797
|
|
|
845
|
-
Ensures
|
|
798
|
+
Ensures min <= max, swapping if needed.
|
|
846
799
|
Re-validates current value against potentially updated bounds.
|
|
847
800
|
|
|
848
801
|
Raises:
|
|
849
802
|
ParameterUpdateError: If bounds are invalid (e.g. None when required)
|
|
850
803
|
"""
|
|
851
|
-
if self.
|
|
804
|
+
if self.min is None or self.max is None:
|
|
852
805
|
raise ParameterUpdateError(
|
|
853
806
|
self.name,
|
|
854
807
|
type(self).__name__,
|
|
855
|
-
"FloatParameter must have both
|
|
808
|
+
"FloatParameter must have both min and max bounds",
|
|
856
809
|
)
|
|
857
|
-
if self.
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
f"Min value greater than max value, swapping",
|
|
863
|
-
)
|
|
810
|
+
if self.min > self.max:
|
|
811
|
+
warn_parameter_update(
|
|
812
|
+
self.name,
|
|
813
|
+
type(self).__name__,
|
|
814
|
+
f"Min value greater than max value, swapping",
|
|
864
815
|
)
|
|
865
|
-
self.
|
|
816
|
+
self.min, self.max = self.max, self.min
|
|
866
817
|
self.value = self._validate(self.value)
|
|
867
818
|
|
|
868
819
|
|
|
@@ -879,17 +830,17 @@ class IntegerRangeParameter(Parameter[Tuple[int, int]]):
|
|
|
879
830
|
----------
|
|
880
831
|
name : str
|
|
881
832
|
The name of the parameter
|
|
882
|
-
value :
|
|
833
|
+
value : Union[Tuple[int, int], NoInitialValue]
|
|
883
834
|
Initial (low, high) values
|
|
884
|
-
|
|
835
|
+
min : int
|
|
885
836
|
Minimum allowed value for both low and high
|
|
886
|
-
|
|
837
|
+
max : int
|
|
887
838
|
Maximum allowed value for both low and high
|
|
888
839
|
|
|
889
840
|
Examples
|
|
890
841
|
--------
|
|
891
842
|
>>> age_range = IntegerRangeParameter("age_range",
|
|
892
|
-
... value=(25, 35),
|
|
843
|
+
... value=(25, 35), min=18, max=100)
|
|
893
844
|
>>> age_range.value
|
|
894
845
|
(25, 35)
|
|
895
846
|
>>> age_range.update({"value": (35, 25)}) # Values will be swapped
|
|
@@ -900,19 +851,21 @@ class IntegerRangeParameter(Parameter[Tuple[int, int]]):
|
|
|
900
851
|
(18, 40)
|
|
901
852
|
"""
|
|
902
853
|
|
|
903
|
-
|
|
904
|
-
|
|
854
|
+
min: int
|
|
855
|
+
max: int
|
|
905
856
|
|
|
906
857
|
def __init__(
|
|
907
858
|
self,
|
|
908
859
|
name: str,
|
|
909
|
-
value: Tuple[int, int],
|
|
910
|
-
|
|
911
|
-
|
|
860
|
+
value: Union[Tuple[int, int], NoInitialValue],
|
|
861
|
+
min: int,
|
|
862
|
+
max: int,
|
|
912
863
|
):
|
|
913
864
|
self.name = name
|
|
914
|
-
self.
|
|
915
|
-
self.
|
|
865
|
+
self.min = self._validate_single(min, context="min")
|
|
866
|
+
self.max = self._validate_single(max, context="max")
|
|
867
|
+
if isinstance(value, NoInitialValue):
|
|
868
|
+
value = (self.min, self.max)
|
|
916
869
|
self._value = self._validate(value)
|
|
917
870
|
|
|
918
871
|
def _validate_single(self, new_value: Any, context: Optional[str] = None) -> int:
|
|
@@ -960,33 +913,27 @@ class IntegerRangeParameter(Parameter[Tuple[int, int]]):
|
|
|
960
913
|
high = self._validate_single(new_value[1])
|
|
961
914
|
|
|
962
915
|
if low > high:
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
f"Low value {low} greater than high value {high}, swapping",
|
|
968
|
-
)
|
|
916
|
+
warn_parameter_update(
|
|
917
|
+
self.name,
|
|
918
|
+
type(self).__name__,
|
|
919
|
+
f"Low value {low} greater than high value {high}, swapping",
|
|
969
920
|
)
|
|
970
921
|
low, high = high, low
|
|
971
922
|
|
|
972
|
-
if low < self.
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
f"Low value {low} below minimum {self.min_value}, clamping",
|
|
978
|
-
)
|
|
923
|
+
if low < self.min:
|
|
924
|
+
warn_parameter_update(
|
|
925
|
+
self.name,
|
|
926
|
+
type(self).__name__,
|
|
927
|
+
f"Low value {low} below minimum {self.min}, clamping",
|
|
979
928
|
)
|
|
980
|
-
low = self.
|
|
981
|
-
if high > self.
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
f"High value {high} above maximum {self.max_value}, clamping",
|
|
987
|
-
)
|
|
929
|
+
low = self.min
|
|
930
|
+
if high > self.max:
|
|
931
|
+
warn_parameter_update(
|
|
932
|
+
self.name,
|
|
933
|
+
type(self).__name__,
|
|
934
|
+
f"High value {high} above maximum {self.max}, clamping",
|
|
988
935
|
)
|
|
989
|
-
high = self.
|
|
936
|
+
high = self.max
|
|
990
937
|
|
|
991
938
|
return (low, high)
|
|
992
939
|
|
|
@@ -994,27 +941,25 @@ class IntegerRangeParameter(Parameter[Tuple[int, int]]):
|
|
|
994
941
|
"""
|
|
995
942
|
Validate complete parameter state after updates.
|
|
996
943
|
|
|
997
|
-
Ensures
|
|
944
|
+
Ensures min <= max, swapping if needed.
|
|
998
945
|
Re-validates current value against potentially updated bounds.
|
|
999
946
|
|
|
1000
947
|
Raises:
|
|
1001
948
|
ParameterUpdateError: If bounds are invalid (e.g. None when required)
|
|
1002
949
|
"""
|
|
1003
|
-
if self.
|
|
950
|
+
if self.min is None or self.max is None:
|
|
1004
951
|
raise ParameterUpdateError(
|
|
1005
952
|
self.name,
|
|
1006
953
|
type(self).__name__,
|
|
1007
|
-
"IntegerRangeParameter must have both
|
|
954
|
+
"IntegerRangeParameter must have both min and max bounds",
|
|
1008
955
|
)
|
|
1009
|
-
if self.
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
f"Min value greater than max value, swapping",
|
|
1015
|
-
)
|
|
956
|
+
if self.min > self.max:
|
|
957
|
+
warn_parameter_update(
|
|
958
|
+
self.name,
|
|
959
|
+
type(self).__name__,
|
|
960
|
+
f"Min value greater than max value, swapping",
|
|
1016
961
|
)
|
|
1017
|
-
self.
|
|
962
|
+
self.min, self.max = self.max, self.min
|
|
1018
963
|
self.value = self._validate(self.value)
|
|
1019
964
|
|
|
1020
965
|
|
|
@@ -1031,11 +976,11 @@ class FloatRangeParameter(Parameter[Tuple[float, float]]):
|
|
|
1031
976
|
----------
|
|
1032
977
|
name : str
|
|
1033
978
|
The name of the parameter
|
|
1034
|
-
value :
|
|
979
|
+
value : Union[Tuple[float, float], NoInitialValue]
|
|
1035
980
|
Initial (low, high) values
|
|
1036
|
-
|
|
981
|
+
min : float
|
|
1037
982
|
Minimum allowed value for both low and high
|
|
1038
|
-
|
|
983
|
+
max : float
|
|
1039
984
|
Maximum allowed value for both low and high
|
|
1040
985
|
step : float, optional
|
|
1041
986
|
Size of each increment (default is 0.001)
|
|
@@ -1043,7 +988,7 @@ class FloatRangeParameter(Parameter[Tuple[float, float]]):
|
|
|
1043
988
|
Examples
|
|
1044
989
|
--------
|
|
1045
990
|
>>> temp_range = FloatRangeParameter("temperature_range",
|
|
1046
|
-
... value=(98.6, 100.4),
|
|
991
|
+
... value=(98.6, 100.4), min=95.0, max=105.0, step=0.1)
|
|
1047
992
|
>>> temp_range.value
|
|
1048
993
|
(98.6, 100.4)
|
|
1049
994
|
>>> temp_range.update({"value": (98.67, 100.0)}) # Low will be rounded
|
|
@@ -1061,22 +1006,24 @@ class FloatRangeParameter(Parameter[Tuple[float, float]]):
|
|
|
1061
1006
|
- step=5.0 allows values like 0.0, 5.0, 10.0, etc.
|
|
1062
1007
|
"""
|
|
1063
1008
|
|
|
1064
|
-
|
|
1065
|
-
|
|
1009
|
+
min: float
|
|
1010
|
+
max: float
|
|
1066
1011
|
step: float
|
|
1067
1012
|
|
|
1068
1013
|
def __init__(
|
|
1069
1014
|
self,
|
|
1070
1015
|
name: str,
|
|
1071
|
-
value: Tuple[float, float],
|
|
1072
|
-
|
|
1073
|
-
|
|
1016
|
+
value: Union[Tuple[float, float], NoInitialValue],
|
|
1017
|
+
min: float,
|
|
1018
|
+
max: float,
|
|
1074
1019
|
step: float = 0.001,
|
|
1075
1020
|
):
|
|
1076
1021
|
self.name = name
|
|
1077
1022
|
self.step = step
|
|
1078
|
-
self.
|
|
1079
|
-
self.
|
|
1023
|
+
self.min = self._validate_single(min, context="min")
|
|
1024
|
+
self.max = self._validate_single(max, context="max")
|
|
1025
|
+
if isinstance(value, NoInitialValue):
|
|
1026
|
+
value = (self.min, self.max)
|
|
1080
1027
|
self._value = self._validate(value)
|
|
1081
1028
|
|
|
1082
1029
|
def _validate_single(self, new_value: Any, context: Optional[str] = None) -> float:
|
|
@@ -1128,33 +1075,27 @@ class FloatRangeParameter(Parameter[Tuple[float, float]]):
|
|
|
1128
1075
|
high = self._validate_single(new_value[1])
|
|
1129
1076
|
|
|
1130
1077
|
if low > high:
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
f"Low value {low} greater than high value {high}, swapping",
|
|
1136
|
-
)
|
|
1078
|
+
warn_parameter_update(
|
|
1079
|
+
self.name,
|
|
1080
|
+
type(self).__name__,
|
|
1081
|
+
f"Low value {low} greater than high value {high}, swapping",
|
|
1137
1082
|
)
|
|
1138
1083
|
low, high = high, low
|
|
1139
1084
|
|
|
1140
|
-
if low < self.
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
f"Low value {low} below minimum {self.min_value}, clamping",
|
|
1146
|
-
)
|
|
1085
|
+
if low < self.min:
|
|
1086
|
+
warn_parameter_update(
|
|
1087
|
+
self.name,
|
|
1088
|
+
type(self).__name__,
|
|
1089
|
+
f"Low value {low} below minimum {self.min}, clamping",
|
|
1147
1090
|
)
|
|
1148
|
-
low = self.
|
|
1149
|
-
if high > self.
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
f"High value {high} above maximum {self.max_value}, clamping",
|
|
1155
|
-
)
|
|
1091
|
+
low = self.min
|
|
1092
|
+
if high > self.max:
|
|
1093
|
+
warn_parameter_update(
|
|
1094
|
+
self.name,
|
|
1095
|
+
type(self).__name__,
|
|
1096
|
+
f"High value {high} above maximum {self.max}, clamping",
|
|
1156
1097
|
)
|
|
1157
|
-
high = self.
|
|
1098
|
+
high = self.max
|
|
1158
1099
|
|
|
1159
1100
|
return (low, high)
|
|
1160
1101
|
|
|
@@ -1162,27 +1103,25 @@ class FloatRangeParameter(Parameter[Tuple[float, float]]):
|
|
|
1162
1103
|
"""
|
|
1163
1104
|
Validate complete parameter state after updates.
|
|
1164
1105
|
|
|
1165
|
-
Ensures
|
|
1106
|
+
Ensures min <= max, swapping if needed.
|
|
1166
1107
|
Re-validates current value against potentially updated bounds.
|
|
1167
1108
|
|
|
1168
1109
|
Raises:
|
|
1169
1110
|
ParameterUpdateError: If bounds are invalid (e.g. None when required)
|
|
1170
1111
|
"""
|
|
1171
|
-
if self.
|
|
1112
|
+
if self.min is None or self.max is None:
|
|
1172
1113
|
raise ParameterUpdateError(
|
|
1173
1114
|
self.name,
|
|
1174
1115
|
type(self).__name__,
|
|
1175
|
-
"FloatRangeParameter must have both
|
|
1116
|
+
"FloatRangeParameter must have both min and max bounds",
|
|
1176
1117
|
)
|
|
1177
|
-
if self.
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
f"Min value greater than max value, swapping",
|
|
1183
|
-
)
|
|
1118
|
+
if self.min > self.max:
|
|
1119
|
+
warn_parameter_update(
|
|
1120
|
+
self.name,
|
|
1121
|
+
type(self).__name__,
|
|
1122
|
+
f"Min value greater than max value, swapping",
|
|
1184
1123
|
)
|
|
1185
|
-
self.
|
|
1124
|
+
self.min, self.max = self.max, self.min
|
|
1186
1125
|
self.value = self._validate(self.value)
|
|
1187
1126
|
|
|
1188
1127
|
|
|
@@ -1199,7 +1138,7 @@ class UnboundedIntegerParameter(Parameter[int]):
|
|
|
1199
1138
|
----------
|
|
1200
1139
|
name : str
|
|
1201
1140
|
The name of the parameter
|
|
1202
|
-
value : int
|
|
1141
|
+
value : Union[int, NoInitialValue]
|
|
1203
1142
|
Initial value
|
|
1204
1143
|
|
|
1205
1144
|
Examples
|
|
@@ -1221,9 +1160,11 @@ class UnboundedIntegerParameter(Parameter[int]):
|
|
|
1221
1160
|
def __init__(
|
|
1222
1161
|
self,
|
|
1223
1162
|
name: str,
|
|
1224
|
-
value: int,
|
|
1163
|
+
value: Union[int, NoInitialValue],
|
|
1225
1164
|
):
|
|
1226
1165
|
self.name = name
|
|
1166
|
+
if isinstance(value, NoInitialValue):
|
|
1167
|
+
value = 0
|
|
1227
1168
|
self._value = self._validate(value)
|
|
1228
1169
|
|
|
1229
1170
|
def _validate(self, new_value: Any) -> int:
|
|
@@ -1269,7 +1210,7 @@ class UnboundedFloatParameter(Parameter[float]):
|
|
|
1269
1210
|
----------
|
|
1270
1211
|
name : str
|
|
1271
1212
|
The name of the parameter
|
|
1272
|
-
value : float
|
|
1213
|
+
value : Union[float, NoInitialValue]
|
|
1273
1214
|
Initial value
|
|
1274
1215
|
step : float, optional
|
|
1275
1216
|
Size of each increment (default is None, meaning no rounding)
|
|
@@ -1300,11 +1241,13 @@ class UnboundedFloatParameter(Parameter[float]):
|
|
|
1300
1241
|
def __init__(
|
|
1301
1242
|
self,
|
|
1302
1243
|
name: str,
|
|
1303
|
-
value: float,
|
|
1244
|
+
value: Union[float, NoInitialValue],
|
|
1304
1245
|
step: Optional[float] = None,
|
|
1305
1246
|
):
|
|
1306
1247
|
self.name = name
|
|
1307
1248
|
self.step = step
|
|
1249
|
+
if isinstance(value, NoInitialValue):
|
|
1250
|
+
value = 0
|
|
1308
1251
|
self._value = self._validate(value)
|
|
1309
1252
|
|
|
1310
1253
|
def _validate(self, new_value: Any) -> float:
|
|
@@ -1336,7 +1279,7 @@ class UnboundedFloatParameter(Parameter[float]):
|
|
|
1336
1279
|
"""
|
|
1337
1280
|
Validate complete parameter state after updates.
|
|
1338
1281
|
|
|
1339
|
-
Ensures
|
|
1282
|
+
Ensures min <= max, swapping if needed.
|
|
1340
1283
|
Re-validates current value against potentially updated bounds.
|
|
1341
1284
|
|
|
1342
1285
|
Raises:
|
|
@@ -1358,8 +1301,8 @@ class ButtonAction(Parameter[None]):
|
|
|
1358
1301
|
----------
|
|
1359
1302
|
name : str
|
|
1360
1303
|
The name of the parameter
|
|
1361
|
-
label : str
|
|
1362
|
-
Text to display on the button
|
|
1304
|
+
label : Union[str, NoInitialValue]
|
|
1305
|
+
Text to display on the button (default is the button's name)
|
|
1363
1306
|
callback : callable
|
|
1364
1307
|
Function to execute when the button is clicked
|
|
1365
1308
|
|
|
@@ -1391,16 +1334,27 @@ class ButtonAction(Parameter[None]):
|
|
|
1391
1334
|
value: None = field(default=None, repr=False)
|
|
1392
1335
|
_is_action: bool = field(default=True, repr=False)
|
|
1393
1336
|
|
|
1394
|
-
def __init__(
|
|
1337
|
+
def __init__(
|
|
1338
|
+
self,
|
|
1339
|
+
name: str,
|
|
1340
|
+
label: Union[str, NoInitialValue],
|
|
1341
|
+
callback: Callable,
|
|
1342
|
+
):
|
|
1395
1343
|
"""
|
|
1396
1344
|
Initialize a button.
|
|
1397
1345
|
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1346
|
+
Parameters
|
|
1347
|
+
----------
|
|
1348
|
+
name : str
|
|
1349
|
+
The name of the parameter
|
|
1350
|
+
label : Union[str, NoInitialValue]
|
|
1351
|
+
Text to display on the button (default is the button's name)
|
|
1352
|
+
callback : callable
|
|
1353
|
+
Function to execute when the button is clicked
|
|
1402
1354
|
"""
|
|
1403
1355
|
self.name = name
|
|
1356
|
+
if isinstance(label, NoInitialValue):
|
|
1357
|
+
label = name
|
|
1404
1358
|
self.label = label
|
|
1405
1359
|
self.callback = callback
|
|
1406
1360
|
self._value = None
|