syd 0.1.6__py3-none-any.whl → 0.1.7__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 +3 -3
- syd/flask_deployment/__init__.py +1 -0
- syd/flask_deployment/components.py +376 -363
- syd/flask_deployment/deployer.py +247 -283
- syd/flask_deployment/static/css/viewer.css +82 -0
- syd/flask_deployment/static/js/viewer.js +174 -0
- syd/flask_deployment/templates/base.html +23 -20
- syd/flask_deployment/templates/viewer.html +49 -95
- syd/flask_deployment/testing_principles.md +300 -0
- syd/notebook_deployment/__init__.py +1 -1
- syd/notebook_deployment/_ipympl_deployer.py +258 -0
- syd/notebook_deployment/deployer.py +126 -50
- syd/notebook_deployment/widgets.py +142 -69
- syd/parameters.py +93 -180
- syd/plotly_deployment/__init__.py +1 -0
- syd/plotly_deployment/components.py +531 -0
- syd/plotly_deployment/deployer.py +376 -0
- syd/{interactive_viewer.py → viewer.py} +152 -188
- {syd-0.1.6.dist-info → syd-0.1.7.dist-info}/METADATA +26 -12
- syd-0.1.7.dist-info/RECORD +22 -0
- syd/flask_deployment/static/css/styles.css +0 -39
- syd/flask_deployment/static/js/components.js +0 -51
- syd-0.1.6.dist-info/RECORD +0 -18
- {syd-0.1.6.dist-info → syd-0.1.7.dist-info}/WHEEL +0 -0
- {syd-0.1.6.dist-info → syd-0.1.7.dist-info}/licenses/LICENSE +0 -0
syd/parameters.py
CHANGED
|
@@ -1,17 +1,6 @@
|
|
|
1
|
-
from typing import
|
|
2
|
-
List,
|
|
3
|
-
Any,
|
|
4
|
-
Tuple,
|
|
5
|
-
Generic,
|
|
6
|
-
TypeVar,
|
|
7
|
-
Optional,
|
|
8
|
-
Dict,
|
|
9
|
-
Callable,
|
|
10
|
-
Union,
|
|
11
|
-
Sequence,
|
|
12
|
-
)
|
|
1
|
+
from typing import List, Any, Tuple, Generic, TypeVar, Optional, Dict, Callable, Union
|
|
13
2
|
from dataclasses import dataclass, field
|
|
14
|
-
from abc import ABC, abstractmethod
|
|
3
|
+
from abc import ABC, ABCMeta, abstractmethod
|
|
15
4
|
from enum import Enum
|
|
16
5
|
from copy import deepcopy
|
|
17
6
|
from warnings import warn
|
|
@@ -117,8 +106,39 @@ def get_parameter_attributes(param_class) -> List[str]:
|
|
|
117
106
|
return attributes
|
|
118
107
|
|
|
119
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
|
|
138
|
+
|
|
139
|
+
|
|
120
140
|
@dataclass
|
|
121
|
-
class Parameter(Generic[T], ABC):
|
|
141
|
+
class Parameter(Generic[T], ABC, metaclass=ParameterMeta):
|
|
122
142
|
"""
|
|
123
143
|
Base class for all parameter types. Parameters are the building blocks
|
|
124
144
|
for creating interactive GUI elements.
|
|
@@ -265,8 +285,8 @@ class TextParameter(Parameter[str]):
|
|
|
265
285
|
Parameter for text input.
|
|
266
286
|
|
|
267
287
|
Creates a text box in the GUI that accepts any string input.
|
|
268
|
-
See :meth:`~syd.
|
|
269
|
-
:meth:`~syd.
|
|
288
|
+
See :meth:`~syd.viewer.Viewer.add_text` and
|
|
289
|
+
:meth:`~syd.viewer.Viewer.update_text` for usage.
|
|
270
290
|
|
|
271
291
|
Parameters
|
|
272
292
|
----------
|
|
@@ -308,8 +328,8 @@ class BooleanParameter(Parameter[bool]):
|
|
|
308
328
|
Parameter for boolean values.
|
|
309
329
|
|
|
310
330
|
Creates a checkbox in the GUI that can be toggled on/off.
|
|
311
|
-
See :meth:`~syd.
|
|
312
|
-
:meth:`~syd.
|
|
331
|
+
See :meth:`~syd.viewer.Viewer.add_boolean` and
|
|
332
|
+
:meth:`~syd.viewer.Viewer.update_boolean` for usage.
|
|
313
333
|
|
|
314
334
|
Parameters
|
|
315
335
|
----------
|
|
@@ -351,8 +371,8 @@ class SelectionParameter(Parameter[Any]):
|
|
|
351
371
|
Parameter for single selection from a list of options.
|
|
352
372
|
|
|
353
373
|
Creates a dropdown menu in the GUI where users can select one option.
|
|
354
|
-
See :meth:`~syd.
|
|
355
|
-
:meth:`~syd.
|
|
374
|
+
See :meth:`~syd.viewer.Viewer.add_selection` and
|
|
375
|
+
:meth:`~syd.viewer.Viewer.update_selection` for usage.
|
|
356
376
|
|
|
357
377
|
Parameters
|
|
358
378
|
----------
|
|
@@ -412,6 +432,9 @@ class SelectionParameter(Parameter[Any]):
|
|
|
412
432
|
f"Options for parameter {self.name} must be a list or tuple"
|
|
413
433
|
)
|
|
414
434
|
|
|
435
|
+
if not options:
|
|
436
|
+
raise ValueError(f"Options for parameter {self.name} must not be empty")
|
|
437
|
+
|
|
415
438
|
# Verify all options are hashable (needed for comparison)
|
|
416
439
|
try:
|
|
417
440
|
for opt in options:
|
|
@@ -455,7 +478,7 @@ class SelectionParameter(Parameter[Any]):
|
|
|
455
478
|
ParameterUpdateWarning(
|
|
456
479
|
self.name,
|
|
457
480
|
type(self).__name__,
|
|
458
|
-
f"Value {self.value} not in options
|
|
481
|
+
f"Value {self.value} not in options, setting to first option ({self.options[0]})",
|
|
459
482
|
)
|
|
460
483
|
)
|
|
461
484
|
self.value = self.options[0]
|
|
@@ -467,8 +490,8 @@ class MultipleSelectionParameter(Parameter[List[Any]]):
|
|
|
467
490
|
Parameter for multiple selections from a list of options.
|
|
468
491
|
|
|
469
492
|
Creates a set of checkboxes or multi-select dropdown in the GUI.
|
|
470
|
-
See :meth:`~syd.
|
|
471
|
-
:meth:`~syd.
|
|
493
|
+
See :meth:`~syd.viewer.Viewer.add_multiple_selection` and
|
|
494
|
+
:meth:`~syd.viewer.Viewer.update_multiple_selection` for usage.
|
|
472
495
|
|
|
473
496
|
Parameters
|
|
474
497
|
----------
|
|
@@ -525,9 +548,12 @@ class MultipleSelectionParameter(Parameter[List[Any]]):
|
|
|
525
548
|
"""
|
|
526
549
|
if not isinstance(options, (list, tuple)):
|
|
527
550
|
raise TypeError(
|
|
528
|
-
f"Options for parameter {self.name} must be a list or tuple"
|
|
551
|
+
f"Options for parameter {self.name} must be a list or tuple, received {type(options)}"
|
|
529
552
|
)
|
|
530
553
|
|
|
554
|
+
if not options:
|
|
555
|
+
raise ValueError(f"Options for parameter {self.name} must not be empty")
|
|
556
|
+
|
|
531
557
|
# Verify all options are hashable (needed for comparison)
|
|
532
558
|
try:
|
|
533
559
|
for opt in options:
|
|
@@ -580,7 +606,7 @@ class MultipleSelectionParameter(Parameter[List[Any]]):
|
|
|
580
606
|
ParameterUpdateWarning(
|
|
581
607
|
self.name,
|
|
582
608
|
type(self).__name__,
|
|
583
|
-
f"For parameter {self.name}, value {self.value} contains invalid
|
|
609
|
+
f"For parameter {self.name}, value {self.value} contains invalid selections: {invalid}. Setting to empty list.",
|
|
584
610
|
)
|
|
585
611
|
)
|
|
586
612
|
self.value = []
|
|
@@ -595,8 +621,8 @@ class IntegerParameter(Parameter[int]):
|
|
|
595
621
|
Parameter for bounded integer values.
|
|
596
622
|
|
|
597
623
|
Creates a slider in the GUI for selecting whole numbers between bounds.
|
|
598
|
-
See :meth:`~syd.
|
|
599
|
-
:meth:`~syd.
|
|
624
|
+
See :meth:`~syd.viewer.Viewer.add_integer` and
|
|
625
|
+
:meth:`~syd.viewer.Viewer.update_integer` for usage.
|
|
600
626
|
|
|
601
627
|
Parameters
|
|
602
628
|
----------
|
|
@@ -711,8 +737,8 @@ class FloatParameter(Parameter[float]):
|
|
|
711
737
|
Parameter for bounded decimal numbers.
|
|
712
738
|
|
|
713
739
|
Creates a slider in the GUI for selecting numbers between bounds.
|
|
714
|
-
See :meth:`~syd.
|
|
715
|
-
:meth:`~syd.
|
|
740
|
+
See :meth:`~syd.viewer.Viewer.add_float` and
|
|
741
|
+
:meth:`~syd.viewer.Viewer.update_float` for usage.
|
|
716
742
|
|
|
717
743
|
Parameters
|
|
718
744
|
----------
|
|
@@ -725,7 +751,7 @@ class FloatParameter(Parameter[float]):
|
|
|
725
751
|
max_value : float
|
|
726
752
|
Maximum allowed value
|
|
727
753
|
step : float, optional
|
|
728
|
-
Size of each increment (default is 0.
|
|
754
|
+
Size of each increment (default is 0.001)
|
|
729
755
|
|
|
730
756
|
Examples
|
|
731
757
|
--------
|
|
@@ -758,7 +784,7 @@ class FloatParameter(Parameter[float]):
|
|
|
758
784
|
value: float,
|
|
759
785
|
min_value: float,
|
|
760
786
|
max_value: float,
|
|
761
|
-
step: float = 0.
|
|
787
|
+
step: float = 0.001,
|
|
762
788
|
):
|
|
763
789
|
self.name = name
|
|
764
790
|
self.step = step
|
|
@@ -846,8 +872,8 @@ class IntegerRangeParameter(Parameter[Tuple[int, int]]):
|
|
|
846
872
|
Parameter for a range of bounded integer values.
|
|
847
873
|
|
|
848
874
|
Creates a range slider in the GUI for selecting a range of whole numbers.
|
|
849
|
-
See :meth:`~syd.
|
|
850
|
-
:meth:`~syd.
|
|
875
|
+
See :meth:`~syd.viewer.Viewer.add_integer_range` and
|
|
876
|
+
:meth:`~syd.viewer.Viewer.update_integer_range` for usage.
|
|
851
877
|
|
|
852
878
|
Parameters
|
|
853
879
|
----------
|
|
@@ -885,11 +911,11 @@ class IntegerRangeParameter(Parameter[Tuple[int, int]]):
|
|
|
885
911
|
max_value: int,
|
|
886
912
|
):
|
|
887
913
|
self.name = name
|
|
888
|
-
self.min_value = self._validate_single(min_value)
|
|
889
|
-
self.max_value = self._validate_single(max_value)
|
|
914
|
+
self.min_value = self._validate_single(min_value, context="min_value")
|
|
915
|
+
self.max_value = self._validate_single(max_value, context="max_value")
|
|
890
916
|
self._value = self._validate(value)
|
|
891
917
|
|
|
892
|
-
def _validate_single(self, new_value: Any) -> int:
|
|
918
|
+
def _validate_single(self, new_value: Any, context: Optional[str] = None) -> int:
|
|
893
919
|
"""
|
|
894
920
|
Validate and convert a single numeric value.
|
|
895
921
|
|
|
@@ -907,8 +933,11 @@ class IntegerRangeParameter(Parameter[Tuple[int, int]]):
|
|
|
907
933
|
"""
|
|
908
934
|
try:
|
|
909
935
|
return int(new_value)
|
|
910
|
-
except
|
|
911
|
-
|
|
936
|
+
except Exception:
|
|
937
|
+
msg = f"Value {new_value} cannot be converted to int"
|
|
938
|
+
if context:
|
|
939
|
+
msg += f" for {context}"
|
|
940
|
+
raise ValueError(msg)
|
|
912
941
|
|
|
913
942
|
def _validate(self, new_value: Any) -> Tuple[int, int]:
|
|
914
943
|
"""
|
|
@@ -995,8 +1024,8 @@ class FloatRangeParameter(Parameter[Tuple[float, float]]):
|
|
|
995
1024
|
Parameter for a range of bounded decimal numbers.
|
|
996
1025
|
|
|
997
1026
|
Creates a range slider in the GUI for selecting a range of numbers.
|
|
998
|
-
See :meth:`~syd.
|
|
999
|
-
:meth:`~syd.
|
|
1027
|
+
See :meth:`~syd.viewer.Viewer.add_float_range` and
|
|
1028
|
+
:meth:`~syd.viewer.Viewer.update_float_range` for usage.
|
|
1000
1029
|
|
|
1001
1030
|
Parameters
|
|
1002
1031
|
----------
|
|
@@ -1009,7 +1038,7 @@ class FloatRangeParameter(Parameter[Tuple[float, float]]):
|
|
|
1009
1038
|
max_value : float
|
|
1010
1039
|
Maximum allowed value for both low and high
|
|
1011
1040
|
step : float, optional
|
|
1012
|
-
Size of each increment (default is 0.
|
|
1041
|
+
Size of each increment (default is 0.001)
|
|
1013
1042
|
|
|
1014
1043
|
Examples
|
|
1015
1044
|
--------
|
|
@@ -1042,15 +1071,15 @@ class FloatRangeParameter(Parameter[Tuple[float, float]]):
|
|
|
1042
1071
|
value: Tuple[float, float],
|
|
1043
1072
|
min_value: float,
|
|
1044
1073
|
max_value: float,
|
|
1045
|
-
step: float = 0.
|
|
1074
|
+
step: float = 0.001,
|
|
1046
1075
|
):
|
|
1047
1076
|
self.name = name
|
|
1048
1077
|
self.step = step
|
|
1049
|
-
self.min_value = self._validate_single(min_value)
|
|
1050
|
-
self.max_value = self._validate_single(max_value)
|
|
1078
|
+
self.min_value = self._validate_single(min_value, context="min_value")
|
|
1079
|
+
self.max_value = self._validate_single(max_value, context="max_value")
|
|
1051
1080
|
self._value = self._validate(value)
|
|
1052
1081
|
|
|
1053
|
-
def _validate_single(self, new_value: Any) -> float:
|
|
1082
|
+
def _validate_single(self, new_value: Any, context: Optional[str] = None) -> float:
|
|
1054
1083
|
"""
|
|
1055
1084
|
Validate and convert a single numeric value.
|
|
1056
1085
|
|
|
@@ -1068,8 +1097,11 @@ class FloatRangeParameter(Parameter[Tuple[float, float]]):
|
|
|
1068
1097
|
"""
|
|
1069
1098
|
try:
|
|
1070
1099
|
new_value = float(new_value)
|
|
1071
|
-
except
|
|
1072
|
-
|
|
1100
|
+
except Exception:
|
|
1101
|
+
msg = f"Value {new_value} cannot be converted to float"
|
|
1102
|
+
if context:
|
|
1103
|
+
msg += f" for {context}"
|
|
1104
|
+
raise ValueError(msg)
|
|
1073
1105
|
|
|
1074
1106
|
# Round to the nearest step
|
|
1075
1107
|
new_value = round(new_value / self.step) * self.step
|
|
@@ -1160,8 +1192,8 @@ class UnboundedIntegerParameter(Parameter[int]):
|
|
|
1160
1192
|
Parameter for optionally bounded integer values.
|
|
1161
1193
|
|
|
1162
1194
|
Creates a text input box in the GUI for entering whole numbers.
|
|
1163
|
-
See :meth:`~syd.
|
|
1164
|
-
:meth:`~syd.
|
|
1195
|
+
See :meth:`~syd.viewer.Viewer.add_unbounded_integer` and
|
|
1196
|
+
:meth:`~syd.viewer.Viewer.update_unbounded_integer` for usage.
|
|
1165
1197
|
|
|
1166
1198
|
Parameters
|
|
1167
1199
|
----------
|
|
@@ -1169,19 +1201,12 @@ class UnboundedIntegerParameter(Parameter[int]):
|
|
|
1169
1201
|
The name of the parameter
|
|
1170
1202
|
value : int
|
|
1171
1203
|
Initial value
|
|
1172
|
-
min_value : int, optional
|
|
1173
|
-
Minimum allowed value (or None for no minimum)
|
|
1174
|
-
max_value : int, optional
|
|
1175
|
-
Maximum allowed value (or None for no maximum)
|
|
1176
1204
|
|
|
1177
1205
|
Examples
|
|
1178
1206
|
--------
|
|
1179
|
-
>>> count = UnboundedIntegerParameter("count", value=10
|
|
1207
|
+
>>> count = UnboundedIntegerParameter("count", value=10)
|
|
1180
1208
|
>>> count.value
|
|
1181
1209
|
10
|
|
1182
|
-
>>> count.update({"value": -5}) # Will be clamped to min_value
|
|
1183
|
-
>>> count.value
|
|
1184
|
-
0
|
|
1185
1210
|
>>> count.update({"value": 1000000}) # No maximum, so this is allowed
|
|
1186
1211
|
>>> count.value
|
|
1187
1212
|
1000000
|
|
@@ -1189,43 +1214,24 @@ class UnboundedIntegerParameter(Parameter[int]):
|
|
|
1189
1214
|
Notes
|
|
1190
1215
|
-----
|
|
1191
1216
|
Use this instead of IntegerParameter when you:
|
|
1192
|
-
- Don't
|
|
1193
|
-
- Only want to enforce a minimum or maximum, but not both
|
|
1217
|
+
- Don't have any reason to bound the value
|
|
1194
1218
|
- Need to allow very large numbers that would be impractical with a slider
|
|
1195
1219
|
"""
|
|
1196
1220
|
|
|
1197
|
-
min_value: Optional[int]
|
|
1198
|
-
max_value: Optional[int]
|
|
1199
|
-
|
|
1200
1221
|
def __init__(
|
|
1201
1222
|
self,
|
|
1202
1223
|
name: str,
|
|
1203
1224
|
value: int,
|
|
1204
|
-
min_value: Optional[int] = None,
|
|
1205
|
-
max_value: Optional[int] = None,
|
|
1206
1225
|
):
|
|
1207
1226
|
self.name = name
|
|
1208
|
-
self.min_value = (
|
|
1209
|
-
self._validate(min_value, compare_to_range=False)
|
|
1210
|
-
if min_value is not None
|
|
1211
|
-
else None
|
|
1212
|
-
)
|
|
1213
|
-
self.max_value = (
|
|
1214
|
-
self._validate(max_value, compare_to_range=False)
|
|
1215
|
-
if max_value is not None
|
|
1216
|
-
else None
|
|
1217
|
-
)
|
|
1218
1227
|
self._value = self._validate(value)
|
|
1219
1228
|
|
|
1220
|
-
def _validate(self, new_value: Any
|
|
1229
|
+
def _validate(self, new_value: Any) -> int:
|
|
1221
1230
|
"""
|
|
1222
|
-
Validate and convert value to integer
|
|
1223
|
-
|
|
1224
|
-
Handles None min/max values by skipping those bound checks.
|
|
1231
|
+
Validate and convert value to integer.
|
|
1225
1232
|
|
|
1226
1233
|
Args:
|
|
1227
1234
|
new_value: Value to validate
|
|
1228
|
-
compare_to_range: If True, clamps value to any defined min/max bounds
|
|
1229
1235
|
|
|
1230
1236
|
Returns:
|
|
1231
1237
|
Validated integer value
|
|
@@ -1238,50 +1244,15 @@ class UnboundedIntegerParameter(Parameter[int]):
|
|
|
1238
1244
|
except ValueError:
|
|
1239
1245
|
raise ValueError(f"Value {new_value} cannot be converted to int")
|
|
1240
1246
|
|
|
1241
|
-
if compare_to_range:
|
|
1242
|
-
if self.min_value is not None and new_value < self.min_value:
|
|
1243
|
-
warn(
|
|
1244
|
-
ParameterUpdateWarning(
|
|
1245
|
-
self.name,
|
|
1246
|
-
type(self).__name__,
|
|
1247
|
-
f"Value {new_value} below minimum {self.min_value}, clamping",
|
|
1248
|
-
)
|
|
1249
|
-
)
|
|
1250
|
-
new_value = self.min_value
|
|
1251
|
-
if self.max_value is not None and new_value > self.max_value:
|
|
1252
|
-
warn(
|
|
1253
|
-
ParameterUpdateWarning(
|
|
1254
|
-
self.name,
|
|
1255
|
-
type(self).__name__,
|
|
1256
|
-
f"Value {new_value} above maximum {self.max_value}, clamping",
|
|
1257
|
-
)
|
|
1258
|
-
)
|
|
1259
|
-
new_value = self.max_value
|
|
1260
1247
|
return int(new_value)
|
|
1261
1248
|
|
|
1262
1249
|
def _validate_update(self) -> None:
|
|
1263
1250
|
"""
|
|
1264
1251
|
Validate complete parameter state after updates.
|
|
1265
1252
|
|
|
1266
|
-
Ensures min_value <= max_value, swapping if needed.
|
|
1267
|
-
Re-validates current value against potentially updated bounds.
|
|
1268
|
-
|
|
1269
1253
|
Raises:
|
|
1270
1254
|
ParameterUpdateError: If bounds are invalid (e.g. None when required)
|
|
1271
1255
|
"""
|
|
1272
|
-
if (
|
|
1273
|
-
self.min_value is not None
|
|
1274
|
-
and self.max_value is not None
|
|
1275
|
-
and self.min_value > self.max_value
|
|
1276
|
-
):
|
|
1277
|
-
warn(
|
|
1278
|
-
ParameterUpdateWarning(
|
|
1279
|
-
self.name,
|
|
1280
|
-
type(self).__name__,
|
|
1281
|
-
f"Min value greater than max value, swapping",
|
|
1282
|
-
)
|
|
1283
|
-
)
|
|
1284
|
-
self.min_value, self.max_value = self.max_value, self.min_value
|
|
1285
1256
|
self.value = self._validate(self.value)
|
|
1286
1257
|
|
|
1287
1258
|
|
|
@@ -1291,8 +1262,8 @@ class UnboundedFloatParameter(Parameter[float]):
|
|
|
1291
1262
|
Parameter for optionally bounded decimal numbers.
|
|
1292
1263
|
|
|
1293
1264
|
Creates a text input box in the GUI for entering numbers.
|
|
1294
|
-
See :meth:`~syd.
|
|
1295
|
-
:meth:`~syd.
|
|
1265
|
+
See :meth:`~syd.viewer.Viewer.add_unbounded_float` and
|
|
1266
|
+
:meth:`~syd.viewer.Viewer.update_unbounded_float` for usage.
|
|
1296
1267
|
|
|
1297
1268
|
Parameters
|
|
1298
1269
|
----------
|
|
@@ -1300,21 +1271,14 @@ class UnboundedFloatParameter(Parameter[float]):
|
|
|
1300
1271
|
The name of the parameter
|
|
1301
1272
|
value : float
|
|
1302
1273
|
Initial value
|
|
1303
|
-
min_value : float, optional
|
|
1304
|
-
Minimum allowed value (or None for no minimum)
|
|
1305
|
-
max_value : float, optional
|
|
1306
|
-
Maximum allowed value (or None for no maximum)
|
|
1307
1274
|
step : float, optional
|
|
1308
1275
|
Size of each increment (default is None, meaning no rounding)
|
|
1309
1276
|
|
|
1310
1277
|
Examples
|
|
1311
1278
|
--------
|
|
1312
|
-
>>> price = UnboundedFloatParameter("price", value=19.99
|
|
1279
|
+
>>> price = UnboundedFloatParameter("price", value=19.99)
|
|
1313
1280
|
>>> price.value
|
|
1314
1281
|
19.99
|
|
1315
|
-
>>> price.update({"value": -5.0}) # Will be clamped to min_value
|
|
1316
|
-
>>> price.value
|
|
1317
|
-
0.0
|
|
1318
1282
|
>>> price.update({"value": 19.987}) # Will be rounded to step
|
|
1319
1283
|
>>> price.value
|
|
1320
1284
|
19.99
|
|
@@ -1323,7 +1287,6 @@ class UnboundedFloatParameter(Parameter[float]):
|
|
|
1323
1287
|
-----
|
|
1324
1288
|
Use this instead of FloatParameter when you:
|
|
1325
1289
|
- Don't know a reasonable maximum value
|
|
1326
|
-
- Only want to enforce a minimum or maximum, but not both
|
|
1327
1290
|
- Need to allow very large or precise numbers that would be impractical with a slider
|
|
1328
1291
|
|
|
1329
1292
|
If step is provided, values will be rounded:
|
|
@@ -1332,42 +1295,25 @@ class UnboundedFloatParameter(Parameter[float]):
|
|
|
1332
1295
|
- step=5.0 rounds to 0.0, 5.0, 10.0, etc.
|
|
1333
1296
|
"""
|
|
1334
1297
|
|
|
1335
|
-
|
|
1336
|
-
max_value: Optional[float]
|
|
1337
|
-
step: float
|
|
1298
|
+
step: Optional[float]
|
|
1338
1299
|
|
|
1339
1300
|
def __init__(
|
|
1340
1301
|
self,
|
|
1341
1302
|
name: str,
|
|
1342
1303
|
value: float,
|
|
1343
|
-
min_value: Optional[float] = None,
|
|
1344
|
-
max_value: Optional[float] = None,
|
|
1345
1304
|
step: Optional[float] = None,
|
|
1346
1305
|
):
|
|
1347
1306
|
self.name = name
|
|
1348
1307
|
self.step = step
|
|
1349
|
-
self.min_value = (
|
|
1350
|
-
self._validate(min_value, compare_to_range=False)
|
|
1351
|
-
if min_value is not None
|
|
1352
|
-
else None
|
|
1353
|
-
)
|
|
1354
|
-
self.max_value = (
|
|
1355
|
-
self._validate(max_value, compare_to_range=False)
|
|
1356
|
-
if max_value is not None
|
|
1357
|
-
else None
|
|
1358
|
-
)
|
|
1359
1308
|
self._value = self._validate(value)
|
|
1360
1309
|
|
|
1361
|
-
def _validate(self, new_value: Any
|
|
1310
|
+
def _validate(self, new_value: Any) -> float:
|
|
1362
1311
|
"""
|
|
1363
|
-
Validate and convert value to float
|
|
1364
|
-
|
|
1365
|
-
Handles None min/max values by skipping those bound checks.
|
|
1312
|
+
Validate and convert value to float.
|
|
1366
1313
|
Only rounds to step if step is not None.
|
|
1367
1314
|
|
|
1368
1315
|
Args:
|
|
1369
1316
|
new_value: Value to validate
|
|
1370
|
-
compare_to_range: If True, clamps value to any defined min/max bounds
|
|
1371
1317
|
|
|
1372
1318
|
Returns:
|
|
1373
1319
|
Validated and potentially rounded float value
|
|
@@ -1384,26 +1330,6 @@ class UnboundedFloatParameter(Parameter[float]):
|
|
|
1384
1330
|
if self.step is not None:
|
|
1385
1331
|
new_value = round(new_value / self.step) * self.step
|
|
1386
1332
|
|
|
1387
|
-
if compare_to_range:
|
|
1388
|
-
if self.min_value is not None and new_value < self.min_value:
|
|
1389
|
-
warn(
|
|
1390
|
-
ParameterUpdateWarning(
|
|
1391
|
-
self.name,
|
|
1392
|
-
type(self).__name__,
|
|
1393
|
-
f"Value {new_value} below minimum {self.min_value}, clamping",
|
|
1394
|
-
)
|
|
1395
|
-
)
|
|
1396
|
-
new_value = self.min_value
|
|
1397
|
-
if self.max_value is not None and new_value > self.max_value:
|
|
1398
|
-
warn(
|
|
1399
|
-
ParameterUpdateWarning(
|
|
1400
|
-
self.name,
|
|
1401
|
-
type(self).__name__,
|
|
1402
|
-
f"Value {new_value} above maximum {self.max_value}, clamping",
|
|
1403
|
-
)
|
|
1404
|
-
)
|
|
1405
|
-
new_value = self.max_value
|
|
1406
|
-
|
|
1407
1333
|
return float(new_value)
|
|
1408
1334
|
|
|
1409
1335
|
def _validate_update(self) -> None:
|
|
@@ -1416,19 +1342,6 @@ class UnboundedFloatParameter(Parameter[float]):
|
|
|
1416
1342
|
Raises:
|
|
1417
1343
|
ParameterUpdateError: If bounds are invalid (e.g. None when required)
|
|
1418
1344
|
"""
|
|
1419
|
-
if (
|
|
1420
|
-
self.min_value is not None
|
|
1421
|
-
and self.max_value is not None
|
|
1422
|
-
and self.min_value > self.max_value
|
|
1423
|
-
):
|
|
1424
|
-
warn(
|
|
1425
|
-
ParameterUpdateWarning(
|
|
1426
|
-
self.name,
|
|
1427
|
-
type(self).__name__,
|
|
1428
|
-
f"Min value greater than max value, swapping",
|
|
1429
|
-
)
|
|
1430
|
-
)
|
|
1431
|
-
self.min_value, self.max_value = self.max_value, self.min_value
|
|
1432
1345
|
self.value = self._validate(self.value)
|
|
1433
1346
|
|
|
1434
1347
|
|
|
@@ -1438,8 +1351,8 @@ class ButtonAction(Parameter[None]):
|
|
|
1438
1351
|
Parameter for creating clickable buttons with callbacks.
|
|
1439
1352
|
|
|
1440
1353
|
Creates a button in the GUI that executes a callback function when clicked.
|
|
1441
|
-
See :meth:`~syd.
|
|
1442
|
-
:meth:`~syd.
|
|
1354
|
+
See :meth:`~syd.viewer.Viewer.add_button` and
|
|
1355
|
+
:meth:`~syd.viewer.Viewer.update_button` for usage.
|
|
1443
1356
|
|
|
1444
1357
|
Parameters
|
|
1445
1358
|
----------
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .deployer import PlotlyDeployer
|