syd 0.1.5__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 +7 -11
- syd/flask_deployment/__init__.py +1 -0
- syd/flask_deployment/components.py +510 -0
- syd/flask_deployment/deployer.py +302 -0
- syd/flask_deployment/static/css/viewer.css +82 -0
- syd/flask_deployment/static/js/viewer.js +174 -0
- syd/flask_deployment/templates/base.html +29 -0
- syd/flask_deployment/templates/viewer.html +51 -0
- syd/flask_deployment/testing_principles.md +300 -0
- syd/notebook_deployment/__init__.py +1 -0
- syd/{notebook_deploy/deployer.py → notebook_deployment/_ipympl_deployer.py} +57 -36
- syd/notebook_deployment/deployer.py +330 -0
- syd/{notebook_deploy → notebook_deployment}/widgets.py +192 -112
- syd/parameters.py +390 -194
- 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} +309 -176
- syd-0.1.7.dist-info/METADATA +120 -0
- syd-0.1.7.dist-info/RECORD +22 -0
- syd/notebook_deploy/__init__.py +0 -1
- syd-0.1.5.dist-info/METADATA +0 -41
- syd-0.1.5.dist-info/RECORD +0 -10
- {syd-0.1.5.dist-info → syd-0.1.7.dist-info}/WHEEL +0 -0
- {syd-0.1.5.dist-info → syd-0.1.7.dist-info}/licenses/LICENSE +0 -0
|
@@ -14,14 +14,14 @@ from ..parameters import (
|
|
|
14
14
|
FloatRangeParameter,
|
|
15
15
|
UnboundedIntegerParameter,
|
|
16
16
|
UnboundedFloatParameter,
|
|
17
|
-
|
|
17
|
+
ButtonAction,
|
|
18
18
|
)
|
|
19
19
|
|
|
20
20
|
T = TypeVar("T", bound=Parameter[Any])
|
|
21
21
|
W = TypeVar("W", bound=widgets.Widget)
|
|
22
22
|
|
|
23
23
|
|
|
24
|
-
class
|
|
24
|
+
class BaseWidget(Generic[T, W], ABC):
|
|
25
25
|
"""
|
|
26
26
|
Abstract base class for all parameter widgets.
|
|
27
27
|
|
|
@@ -31,15 +31,32 @@ class BaseParameterWidget(Generic[T, W], ABC):
|
|
|
31
31
|
|
|
32
32
|
_widget: W
|
|
33
33
|
_callbacks: List[Dict[str, Union[Callable, Union[str, List[str]]]]]
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
34
|
+
_is_action: bool = False
|
|
35
|
+
|
|
36
|
+
def __init__(
|
|
37
|
+
self,
|
|
38
|
+
parameter: T,
|
|
39
|
+
continuous: bool = False,
|
|
40
|
+
width: str = "auto",
|
|
41
|
+
margin: str = "3px 0px",
|
|
42
|
+
description_width: str = "initial",
|
|
43
|
+
):
|
|
44
|
+
self._widget = self._create_widget(
|
|
45
|
+
parameter, continuous, width, margin, description_width
|
|
46
|
+
)
|
|
37
47
|
self._updating = False # Flag to prevent circular updates
|
|
38
48
|
# List of callbacks to remember for quick disabling/enabling
|
|
39
49
|
self._callbacks = []
|
|
40
50
|
|
|
41
51
|
@abstractmethod
|
|
42
|
-
def _create_widget(
|
|
52
|
+
def _create_widget(
|
|
53
|
+
self,
|
|
54
|
+
parameter: T,
|
|
55
|
+
continuous: bool,
|
|
56
|
+
width: str = "auto",
|
|
57
|
+
margin: str = "3px 0px",
|
|
58
|
+
description_width: str = "initial",
|
|
59
|
+
) -> W:
|
|
43
60
|
"""Create and return the appropriate ipywidget."""
|
|
44
61
|
pass
|
|
45
62
|
|
|
@@ -100,42 +117,62 @@ class BaseParameterWidget(Generic[T, W], ABC):
|
|
|
100
117
|
self._widget.unobserve(**callback)
|
|
101
118
|
|
|
102
119
|
|
|
103
|
-
class
|
|
120
|
+
class TextWidget(BaseWidget[TextParameter, widgets.Text]):
|
|
104
121
|
"""Widget for text parameters."""
|
|
105
122
|
|
|
106
123
|
def _create_widget(
|
|
107
|
-
self,
|
|
124
|
+
self,
|
|
125
|
+
parameter: TextParameter,
|
|
126
|
+
continuous: bool,
|
|
127
|
+
width: str = "auto",
|
|
128
|
+
margin: str = "3px 0px",
|
|
129
|
+
description_width: str = "initial",
|
|
108
130
|
) -> widgets.Text:
|
|
109
131
|
return widgets.Text(
|
|
110
132
|
value=parameter.value,
|
|
111
133
|
description=parameter.name,
|
|
112
|
-
|
|
113
|
-
layout=widgets.Layout(width=
|
|
134
|
+
continuous=continuous,
|
|
135
|
+
layout=widgets.Layout(width=width, margin=margin),
|
|
136
|
+
style={"description_width": description_width},
|
|
114
137
|
)
|
|
115
138
|
|
|
116
139
|
|
|
117
|
-
class
|
|
140
|
+
class BooleanWidget(BaseWidget[BooleanParameter, widgets.ToggleButton]):
|
|
118
141
|
"""Widget for boolean parameters."""
|
|
119
142
|
|
|
120
143
|
def _create_widget(
|
|
121
|
-
self,
|
|
122
|
-
|
|
123
|
-
|
|
144
|
+
self,
|
|
145
|
+
parameter: BooleanParameter,
|
|
146
|
+
continuous: bool,
|
|
147
|
+
width: str = "auto",
|
|
148
|
+
margin: str = "3px 0px",
|
|
149
|
+
description_width: str = "initial",
|
|
150
|
+
) -> widgets.ToggleButton:
|
|
151
|
+
return widgets.ToggleButton(
|
|
152
|
+
value=parameter.value,
|
|
153
|
+
description=parameter.name,
|
|
154
|
+
layout=widgets.Layout(width=width, margin=margin),
|
|
155
|
+
style={"description_width": description_width},
|
|
156
|
+
)
|
|
124
157
|
|
|
125
158
|
|
|
126
|
-
class
|
|
127
|
-
BaseParameterWidget[SelectionParameter, widgets.Dropdown]
|
|
128
|
-
):
|
|
159
|
+
class SelectionWidget(BaseWidget[SelectionParameter, widgets.Dropdown]):
|
|
129
160
|
"""Widget for single selection parameters."""
|
|
130
161
|
|
|
131
162
|
def _create_widget(
|
|
132
|
-
self,
|
|
163
|
+
self,
|
|
164
|
+
parameter: SelectionParameter,
|
|
165
|
+
continuous: bool,
|
|
166
|
+
width: str = "auto",
|
|
167
|
+
margin: str = "3px 0px",
|
|
168
|
+
description_width: str = "initial",
|
|
133
169
|
) -> widgets.Dropdown:
|
|
134
170
|
return widgets.Dropdown(
|
|
135
171
|
value=parameter.value,
|
|
136
172
|
options=parameter.options,
|
|
137
173
|
description=parameter.name,
|
|
138
|
-
layout=widgets.Layout(width=
|
|
174
|
+
layout=widgets.Layout(width=width, margin=margin),
|
|
175
|
+
style={"description_width": description_width},
|
|
139
176
|
)
|
|
140
177
|
|
|
141
178
|
def matches_parameter(self, parameter: SelectionParameter) -> bool:
|
|
@@ -153,20 +190,26 @@ class SelectionParameterWidget(
|
|
|
153
190
|
self._widget.value = new_value
|
|
154
191
|
|
|
155
192
|
|
|
156
|
-
class
|
|
157
|
-
|
|
193
|
+
class MultipleSelectionWidget(
|
|
194
|
+
BaseWidget[MultipleSelectionParameter, widgets.SelectMultiple]
|
|
158
195
|
):
|
|
159
196
|
"""Widget for multiple selection parameters."""
|
|
160
197
|
|
|
161
198
|
def _create_widget(
|
|
162
|
-
self,
|
|
199
|
+
self,
|
|
200
|
+
parameter: MultipleSelectionParameter,
|
|
201
|
+
continuous: bool,
|
|
202
|
+
width: str = "auto",
|
|
203
|
+
margin: str = "3px 0px",
|
|
204
|
+
description_width: str = "initial",
|
|
163
205
|
) -> widgets.SelectMultiple:
|
|
164
206
|
return widgets.SelectMultiple(
|
|
165
207
|
value=parameter.value,
|
|
166
208
|
options=parameter.options,
|
|
167
209
|
description=parameter.name,
|
|
168
210
|
rows=min(len(parameter.options), 4),
|
|
169
|
-
layout=widgets.Layout(width=
|
|
211
|
+
layout=widgets.Layout(width=width, margin=margin),
|
|
212
|
+
style={"description_width": description_width},
|
|
170
213
|
)
|
|
171
214
|
|
|
172
215
|
def matches_parameter(self, parameter: MultipleSelectionParameter) -> bool:
|
|
@@ -186,20 +229,25 @@ class MultipleSelectionParameterWidget(
|
|
|
186
229
|
self._widget.value = new_values
|
|
187
230
|
|
|
188
231
|
|
|
189
|
-
class
|
|
232
|
+
class IntegerWidget(BaseWidget[IntegerParameter, widgets.IntSlider]):
|
|
190
233
|
"""Widget for integer parameters."""
|
|
191
234
|
|
|
192
235
|
def _create_widget(
|
|
193
|
-
self,
|
|
236
|
+
self,
|
|
237
|
+
parameter: IntegerParameter,
|
|
238
|
+
continuous: bool,
|
|
239
|
+
width: str = "auto",
|
|
240
|
+
margin: str = "3px 0px",
|
|
241
|
+
description_width: str = "initial",
|
|
194
242
|
) -> widgets.IntSlider:
|
|
195
243
|
return widgets.IntSlider(
|
|
196
244
|
value=parameter.value,
|
|
197
245
|
min=parameter.min_value,
|
|
198
246
|
max=parameter.max_value,
|
|
199
247
|
description=parameter.name,
|
|
200
|
-
|
|
201
|
-
layout=widgets.Layout(width=
|
|
202
|
-
style={"description_width":
|
|
248
|
+
continuous=continuous,
|
|
249
|
+
layout=widgets.Layout(width=width, margin=margin),
|
|
250
|
+
style={"description_width": description_width},
|
|
203
251
|
)
|
|
204
252
|
|
|
205
253
|
def matches_parameter(self, parameter: IntegerParameter) -> bool:
|
|
@@ -218,11 +266,16 @@ class IntegerParameterWidget(BaseParameterWidget[IntegerParameter, widgets.IntSl
|
|
|
218
266
|
self.value = max(parameter.min_value, min(parameter.max_value, current_value))
|
|
219
267
|
|
|
220
268
|
|
|
221
|
-
class
|
|
269
|
+
class FloatWidget(BaseWidget[FloatParameter, widgets.FloatSlider]):
|
|
222
270
|
"""Widget for float parameters."""
|
|
223
271
|
|
|
224
272
|
def _create_widget(
|
|
225
|
-
self,
|
|
273
|
+
self,
|
|
274
|
+
parameter: FloatParameter,
|
|
275
|
+
continuous: bool,
|
|
276
|
+
width: str = "auto",
|
|
277
|
+
margin: str = "3px 0px",
|
|
278
|
+
description_width: str = "initial",
|
|
226
279
|
) -> widgets.FloatSlider:
|
|
227
280
|
return widgets.FloatSlider(
|
|
228
281
|
value=parameter.value,
|
|
@@ -230,9 +283,9 @@ class FloatParameterWidget(BaseParameterWidget[FloatParameter, widgets.FloatSlid
|
|
|
230
283
|
max=parameter.max_value,
|
|
231
284
|
step=parameter.step,
|
|
232
285
|
description=parameter.name,
|
|
233
|
-
|
|
234
|
-
layout=widgets.Layout(width=
|
|
235
|
-
style={"description_width":
|
|
286
|
+
continuous=continuous,
|
|
287
|
+
layout=widgets.Layout(width=width, margin=margin),
|
|
288
|
+
style={"description_width": description_width},
|
|
236
289
|
)
|
|
237
290
|
|
|
238
291
|
def matches_parameter(self, parameter: FloatParameter) -> bool:
|
|
@@ -252,22 +305,25 @@ class FloatParameterWidget(BaseParameterWidget[FloatParameter, widgets.FloatSlid
|
|
|
252
305
|
self.value = max(parameter.min_value, min(parameter.max_value, current_value))
|
|
253
306
|
|
|
254
307
|
|
|
255
|
-
class
|
|
256
|
-
BaseParameterWidget[IntegerRangeParameter, widgets.IntRangeSlider]
|
|
257
|
-
):
|
|
308
|
+
class IntegerRangeWidget(BaseWidget[IntegerRangeParameter, widgets.IntRangeSlider]):
|
|
258
309
|
"""Widget for integer range parameters."""
|
|
259
310
|
|
|
260
311
|
def _create_widget(
|
|
261
|
-
self,
|
|
312
|
+
self,
|
|
313
|
+
parameter: IntegerRangeParameter,
|
|
314
|
+
continuous: bool,
|
|
315
|
+
width: str = "auto",
|
|
316
|
+
margin: str = "3px 0px",
|
|
317
|
+
description_width: str = "initial",
|
|
262
318
|
) -> widgets.IntRangeSlider:
|
|
263
319
|
return widgets.IntRangeSlider(
|
|
264
320
|
value=parameter.value,
|
|
265
321
|
min=parameter.min_value,
|
|
266
322
|
max=parameter.max_value,
|
|
267
323
|
description=parameter.name,
|
|
268
|
-
|
|
269
|
-
layout=widgets.Layout(width=
|
|
270
|
-
style={"description_width":
|
|
324
|
+
continuous=continuous,
|
|
325
|
+
layout=widgets.Layout(width=width, margin=margin),
|
|
326
|
+
style={"description_width": description_width},
|
|
271
327
|
)
|
|
272
328
|
|
|
273
329
|
def matches_parameter(self, parameter: IntegerRangeParameter) -> bool:
|
|
@@ -289,13 +345,16 @@ class IntegerRangeParameterWidget(
|
|
|
289
345
|
self.value = (low, high)
|
|
290
346
|
|
|
291
347
|
|
|
292
|
-
class
|
|
293
|
-
BaseParameterWidget[FloatRangeParameter, widgets.FloatRangeSlider]
|
|
294
|
-
):
|
|
348
|
+
class FloatRangeWidget(BaseWidget[FloatRangeParameter, widgets.FloatRangeSlider]):
|
|
295
349
|
"""Widget for float range parameters."""
|
|
296
350
|
|
|
297
351
|
def _create_widget(
|
|
298
|
-
self,
|
|
352
|
+
self,
|
|
353
|
+
parameter: FloatRangeParameter,
|
|
354
|
+
continuous: bool,
|
|
355
|
+
width: str = "auto",
|
|
356
|
+
margin: str = "3px 0px",
|
|
357
|
+
description_width: str = "initial",
|
|
299
358
|
) -> widgets.FloatRangeSlider:
|
|
300
359
|
return widgets.FloatRangeSlider(
|
|
301
360
|
value=parameter.value,
|
|
@@ -303,9 +362,9 @@ class FloatRangeParameterWidget(
|
|
|
303
362
|
max=parameter.max_value,
|
|
304
363
|
step=parameter.step,
|
|
305
364
|
description=parameter.name,
|
|
306
|
-
|
|
307
|
-
layout=widgets.Layout(width=
|
|
308
|
-
style={"description_width":
|
|
365
|
+
continuous=continuous,
|
|
366
|
+
layout=widgets.Layout(width=width, margin=margin),
|
|
367
|
+
style={"description_width": description_width},
|
|
309
368
|
)
|
|
310
369
|
|
|
311
370
|
def matches_parameter(self, parameter: FloatRangeParameter) -> bool:
|
|
@@ -328,21 +387,22 @@ class FloatRangeParameterWidget(
|
|
|
328
387
|
self.value = (low, high)
|
|
329
388
|
|
|
330
389
|
|
|
331
|
-
class
|
|
332
|
-
BaseParameterWidget[UnboundedIntegerParameter, widgets.BoundedIntText]
|
|
333
|
-
):
|
|
390
|
+
class UnboundedIntegerWidget(BaseWidget[UnboundedIntegerParameter, widgets.IntText]):
|
|
334
391
|
"""Widget for unbounded integer parameters."""
|
|
335
392
|
|
|
336
393
|
def _create_widget(
|
|
337
|
-
self,
|
|
338
|
-
|
|
339
|
-
|
|
394
|
+
self,
|
|
395
|
+
parameter: UnboundedIntegerParameter,
|
|
396
|
+
continuous: bool,
|
|
397
|
+
width: str = "auto",
|
|
398
|
+
margin: str = "3px 0px",
|
|
399
|
+
description_width: str = "initial",
|
|
400
|
+
) -> widgets.IntText:
|
|
401
|
+
return widgets.IntText(
|
|
340
402
|
value=parameter.value,
|
|
341
|
-
min=parameter.min_value,
|
|
342
|
-
max=parameter.max_value,
|
|
343
403
|
description=parameter.name,
|
|
344
|
-
layout=widgets.Layout(width=
|
|
345
|
-
style={"description_width":
|
|
404
|
+
layout=widgets.Layout(width=width, margin=margin),
|
|
405
|
+
style={"description_width": description_width},
|
|
346
406
|
)
|
|
347
407
|
|
|
348
408
|
def matches_parameter(self, parameter: UnboundedIntegerParameter) -> bool:
|
|
@@ -353,28 +413,26 @@ class UnboundedIntegerParameterWidget(
|
|
|
353
413
|
self, parameter: UnboundedIntegerParameter
|
|
354
414
|
) -> None:
|
|
355
415
|
"""Extra updates from the parameter."""
|
|
356
|
-
|
|
357
|
-
self._widget.min = parameter.min_value
|
|
358
|
-
if parameter.max_value is not None:
|
|
359
|
-
self._widget.max = parameter.max_value
|
|
416
|
+
pass
|
|
360
417
|
|
|
361
418
|
|
|
362
|
-
class
|
|
363
|
-
BaseParameterWidget[UnboundedFloatParameter, widgets.BoundedFloatText]
|
|
364
|
-
):
|
|
419
|
+
class UnboundedFloatWidget(BaseWidget[UnboundedFloatParameter, widgets.FloatText]):
|
|
365
420
|
"""Widget for unbounded float parameters."""
|
|
366
421
|
|
|
367
422
|
def _create_widget(
|
|
368
|
-
self,
|
|
369
|
-
|
|
370
|
-
|
|
423
|
+
self,
|
|
424
|
+
parameter: UnboundedFloatParameter,
|
|
425
|
+
continuous: bool,
|
|
426
|
+
width: str = "auto",
|
|
427
|
+
margin: str = "3px 0px",
|
|
428
|
+
description_width: str = "initial",
|
|
429
|
+
) -> widgets.FloatText:
|
|
430
|
+
return widgets.FloatText(
|
|
371
431
|
value=parameter.value,
|
|
372
|
-
min=parameter.min_value,
|
|
373
|
-
max=parameter.max_value,
|
|
374
432
|
step=parameter.step,
|
|
375
433
|
description=parameter.name,
|
|
376
|
-
layout=widgets.Layout(width=
|
|
377
|
-
style={"description_width":
|
|
434
|
+
layout=widgets.Layout(width=width, margin=margin),
|
|
435
|
+
style={"description_width": description_width},
|
|
378
436
|
)
|
|
379
437
|
|
|
380
438
|
def matches_parameter(self, parameter: UnboundedFloatParameter) -> bool:
|
|
@@ -383,89 +441,111 @@ class UnboundedFloatParameterWidget(
|
|
|
383
441
|
|
|
384
442
|
def extra_updates_from_parameter(self, parameter: UnboundedFloatParameter) -> None:
|
|
385
443
|
"""Extra updates from the parameter."""
|
|
386
|
-
if parameter.min_value is not None:
|
|
387
|
-
self._widget.min = parameter.min_value
|
|
388
|
-
if parameter.max_value is not None:
|
|
389
|
-
self._widget.max = parameter.max_value
|
|
390
444
|
self._widget.step = parameter.step
|
|
391
445
|
|
|
392
446
|
|
|
393
|
-
class
|
|
447
|
+
class ButtonWidget(BaseWidget[ButtonAction, widgets.Button]):
|
|
394
448
|
"""Widget for button parameters."""
|
|
395
449
|
|
|
396
|
-
|
|
450
|
+
_is_action: bool = True
|
|
397
451
|
|
|
398
452
|
def _create_widget(
|
|
399
|
-
self,
|
|
453
|
+
self,
|
|
454
|
+
parameter: ButtonAction,
|
|
455
|
+
continuous: bool,
|
|
456
|
+
width: str = "auto",
|
|
457
|
+
margin: str = "3px 0px",
|
|
458
|
+
description_width: str = "initial",
|
|
400
459
|
) -> widgets.Button:
|
|
401
460
|
button = widgets.Button(
|
|
402
461
|
description=parameter.label,
|
|
403
|
-
layout=widgets.Layout(width=
|
|
404
|
-
style={"description_width":
|
|
462
|
+
layout=widgets.Layout(width=width, margin=margin),
|
|
463
|
+
style={"description_width": description_width},
|
|
405
464
|
)
|
|
406
|
-
button.on_click(parameter.callback)
|
|
407
465
|
return button
|
|
408
466
|
|
|
409
|
-
def matches_parameter(self, parameter:
|
|
467
|
+
def matches_parameter(self, parameter: ButtonAction) -> bool:
|
|
410
468
|
"""Check if the widget matches the parameter."""
|
|
411
469
|
return self._widget.description == parameter.label
|
|
412
470
|
|
|
413
|
-
def extra_updates_from_parameter(self, parameter:
|
|
471
|
+
def extra_updates_from_parameter(self, parameter: ButtonAction) -> None:
|
|
414
472
|
"""Extra updates from the parameter."""
|
|
473
|
+
# Callbacks are handled in the deployer, so the only relevant update is the label
|
|
415
474
|
self._widget.description = parameter.label
|
|
416
|
-
# Update click handler
|
|
417
|
-
self._widget.on_click(parameter.callback, remove=True) # Remove old handler
|
|
418
|
-
self._widget.on_click(parameter.callback) # Add new handler
|
|
419
475
|
|
|
420
476
|
def observe(self, callback: Callable) -> None:
|
|
421
477
|
"""Observe the widget and call the callback when the value changes."""
|
|
478
|
+
if self._callbacks:
|
|
479
|
+
raise ValueError("ButtonWidget already has a callback!")
|
|
422
480
|
self._widget.on_click(callback)
|
|
423
|
-
self._callbacks
|
|
481
|
+
self._callbacks = callback
|
|
424
482
|
|
|
425
|
-
def unobserve(self, callback: Callable
|
|
483
|
+
def unobserve(self, callback: Callable) -> None:
|
|
426
484
|
"""Unobserve the widget and stop calling the callback when the value changes."""
|
|
427
|
-
self._widget.on_click(
|
|
428
|
-
self._callbacks
|
|
485
|
+
self._widget.on_click(callback, remove=True)
|
|
486
|
+
self._callbacks = []
|
|
429
487
|
|
|
430
488
|
def reenable_callbacks(self) -> None:
|
|
431
489
|
"""Reenable all callbacks from the widget."""
|
|
432
|
-
|
|
433
|
-
self._widget.on_click(callback)
|
|
490
|
+
self._widget.on_click(self._callbacks)
|
|
434
491
|
|
|
435
492
|
def disable_callbacks(self) -> None:
|
|
436
493
|
"""Disable all callbacks from the widget."""
|
|
437
|
-
|
|
438
|
-
self._widget.on_click(None)
|
|
494
|
+
self._widget.on_click(self._callbacks, remove=True)
|
|
439
495
|
|
|
440
496
|
|
|
441
|
-
def
|
|
442
|
-
parameter: Parameter[Any],
|
|
443
|
-
|
|
444
|
-
|
|
497
|
+
def create_widget(
|
|
498
|
+
parameter: Union[Parameter[Any], ButtonAction],
|
|
499
|
+
continuous: bool = False,
|
|
500
|
+
width: str = "auto",
|
|
501
|
+
margin: str = "3px 0px",
|
|
502
|
+
description_width: str = "initial",
|
|
503
|
+
) -> BaseWidget[Union[Parameter[Any], ButtonAction], widgets.Widget]:
|
|
445
504
|
"""Create and return the appropriate widget for the given parameter.
|
|
446
505
|
|
|
447
506
|
Args:
|
|
448
507
|
parameter: The parameter to create a widget for
|
|
449
|
-
|
|
508
|
+
continuous: Whether to update the widget value continuously during user interaction
|
|
509
|
+
width: Width of the widget
|
|
510
|
+
margin: Margin of the widget
|
|
511
|
+
description_width: Width of the description label
|
|
450
512
|
"""
|
|
451
513
|
widget_map = {
|
|
452
|
-
TextParameter:
|
|
453
|
-
SelectionParameter:
|
|
454
|
-
MultipleSelectionParameter:
|
|
455
|
-
BooleanParameter:
|
|
456
|
-
IntegerParameter:
|
|
457
|
-
FloatParameter:
|
|
458
|
-
IntegerRangeParameter:
|
|
459
|
-
FloatRangeParameter:
|
|
460
|
-
UnboundedIntegerParameter:
|
|
461
|
-
UnboundedFloatParameter:
|
|
462
|
-
|
|
514
|
+
TextParameter: TextWidget,
|
|
515
|
+
SelectionParameter: SelectionWidget,
|
|
516
|
+
MultipleSelectionParameter: MultipleSelectionWidget,
|
|
517
|
+
BooleanParameter: BooleanWidget,
|
|
518
|
+
IntegerParameter: IntegerWidget,
|
|
519
|
+
FloatParameter: FloatWidget,
|
|
520
|
+
IntegerRangeParameter: IntegerRangeWidget,
|
|
521
|
+
FloatRangeParameter: FloatRangeWidget,
|
|
522
|
+
UnboundedIntegerParameter: UnboundedIntegerWidget,
|
|
523
|
+
UnboundedFloatParameter: UnboundedFloatWidget,
|
|
524
|
+
ButtonAction: ButtonWidget,
|
|
463
525
|
}
|
|
464
526
|
|
|
527
|
+
# Try direct type lookup first
|
|
465
528
|
widget_class = widget_map.get(type(parameter))
|
|
529
|
+
|
|
530
|
+
# If that fails, try matching by class name
|
|
531
|
+
if widget_class is None:
|
|
532
|
+
param_type_name = type(parameter).__name__
|
|
533
|
+
for key_class, value_class in widget_map.items():
|
|
534
|
+
if key_class.__name__ == param_type_name:
|
|
535
|
+
widget_class = value_class
|
|
536
|
+
break
|
|
537
|
+
|
|
466
538
|
if widget_class is None:
|
|
467
539
|
raise ValueError(
|
|
468
|
-
f"No widget implementation for parameter type: {type(parameter)}"
|
|
540
|
+
f"No widget implementation for parameter type: {type(parameter)}\n"
|
|
541
|
+
f"Parameter type name: {type(parameter).__name__}\n"
|
|
542
|
+
f"Available types: {[k.__name__ for k in widget_map.keys()]}"
|
|
469
543
|
)
|
|
470
544
|
|
|
471
|
-
return widget_class(
|
|
545
|
+
return widget_class(
|
|
546
|
+
parameter,
|
|
547
|
+
continuous,
|
|
548
|
+
width=width,
|
|
549
|
+
margin=margin,
|
|
550
|
+
description_width=description_width,
|
|
551
|
+
)
|