Add dict_to_form_widget

This commit is contained in:
c-bata
2023-04-13 18:52:35 +09:00
parent ea4b294289
commit 3c63388198
4 changed files with 104 additions and 0 deletions
+1
View File
@@ -23,6 +23,7 @@ Human-in-the-loop
:nosignatures:
optuna_dashboard.register_objective_form_widgets
optuna_dashboard.dict_to_form_widget
optuna_dashboard.ChoiceWidget
optuna_dashboard.SliderWidget
optuna_dashboard.TextInputWidget
+1
View File
@@ -1,6 +1,7 @@
from ._app import run_server # noqa
from ._app import wsgi # noqa
from ._form_widget import ChoiceWidget # noqa
from ._form_widget import dict_to_form_widget # noqa
from ._form_widget import ObjectiveChoiceWidget # noqa
from ._form_widget import ObjectiveSliderWidget # noqa
from ._form_widget import ObjectiveTextInputWidget # noqa
+62
View File
@@ -76,6 +76,16 @@ class ChoiceWidget:
"user_attr_key": self.user_attr_key,
}
@classmethod
def _from_dict(cls, d: dict[str, Any]) -> ChoiceWidget:
assert d.get("type") == "choice"
return cls(
description=d.get("description"),
choices=d["choices"],
values=d["values"],
user_attr_key=d.get("user_attr_key"),
)
@dataclass
class SliderWidget:
@@ -100,6 +110,21 @@ class SliderWidget:
"user_attr_key": self.user_attr_key,
}
@classmethod
def _from_dict(cls, d: dict[str, Any]) -> SliderWidget:
assert d.get("type") == "slider"
labels = d.get("labels")
if labels is not None:
labels = [(l["value"], l["label"]) for l in labels]
return cls(
description=d.get("description"),
min=d["min"],
max=d["max"],
step=d.get("step"),
labels=labels,
user_attr_key=d.get("user_attr_key"),
)
@dataclass
class TextInputWidget:
@@ -113,10 +138,19 @@ class TextInputWidget:
"user_attr_key": self.user_attr_key,
}
@classmethod
def _from_dict(cls, d: dict[str, Any]) -> TextInputWidget:
assert d.get("type") == "text"
return cls(
description=d.get("description"),
user_attr_key=d.get("user_attr_key"),
)
@dataclass
class ObjectiveUserAttrRef:
key: str
# TODO(c-bata): Remove this attribute
user_attr_key: Optional[str] = None
def to_dict(self) -> UserAttrRefJSON:
@@ -126,6 +160,13 @@ class ObjectiveUserAttrRef:
"user_attr_key": self.user_attr_key,
}
@classmethod
def _from_dict(cls, d: dict[str, Any]) -> ObjectiveUserAttrRef:
assert d.get("type") == "user_attr"
return cls(
key=d["key"],
)
ObjectiveFormWidget = Union[ChoiceWidget, SliderWidget, TextInputWidget, ObjectiveUserAttrRef]
# For backward compatibility.
@@ -135,6 +176,27 @@ ObjectiveTextInputWidget = TextInputWidget
FORM_WIDGETS_KEY = "dashboard:form_widgets:v2"
def dict_to_form_widget(d: dict[str, Any]) -> ObjectiveFormWidget:
"""Restore form widget objects from the dictionary.
Args:
d: A dictionary object.
Returns:
object: an instance of the restored form widget class.
"""
widget_type = d.get("type", None)
if widget_type == "choice":
return ChoiceWidget._from_dict(d)
elif widget_type == "slider":
return SliderWidget._from_dict(d)
elif widget_type == "text":
return TextInputWidget._from_dict(d)
elif widget_type == "user_attr":
return ObjectiveUserAttrRef._from_dict(d)
raise ValueError("Unexpected widget type")
def register_objective_form_widgets(
study: optuna.Study, widgets: list[ObjectiveFormWidget]
) -> None:
+40
View File
@@ -0,0 +1,40 @@
from __future__ import annotations
from unittest import TestCase
from optuna_dashboard import ChoiceWidget
from optuna_dashboard import dict_to_form_widget
from optuna_dashboard import ObjectiveUserAttrRef
from optuna_dashboard import SliderWidget
from optuna_dashboard import TextInputWidget
class FormWidgetsTestCase(TestCase):
def test_widget_to_dict_from_dict(self) -> None:
widgets = [
ChoiceWidget(choices=["Good", "Bad"], values=[1, -1]),
ChoiceWidget(
choices=["Good", "Bad"],
values=[1, -1],
description="description",
user_attr_key="key",
),
SliderWidget(min=1, max=5),
SliderWidget(
min=1,
max=5,
step=1,
labels=[(1, "Bad"), (5, "Good")],
description="description",
user_attr_key="key",
),
TextInputWidget(),
TextInputWidget(description="description", user_attr_key="key"),
ObjectiveUserAttrRef(key="key"),
]
for i, widget in enumerate(widgets):
with self.subTest(f"{widget.__class__}-{i}"):
d = widget.to_dict()
restored = dict_to_form_widget(d)
assert widget == restored