Merge pull request #441 from knshnb/docstring-form-widget

Add docstring for FormWidgets
This commit is contained in:
Kenshin Abe
2023-05-09 17:22:02 +09:00
committed by GitHub
4 changed files with 198 additions and 0 deletions
+20
View File
@@ -0,0 +1,20 @@
{% extends "!autosummary/class.rst" %}
{#
Ref: https://github.com/optuna/optuna/blob/41045cef7a8f5d0e5e4026bf0c5c649b269fc312/docs/source/_templates/autosummary/class.rst
An autosummary template to exclude the class constructor (__init__)
which doesn't contain any docstring in Optuna Dashboard.
#}
{% block methods %}
{% set methods = methods | select("ne", "__init__") | list %}
{% if methods %}
.. rubric:: Methods
.. autosummary::
{% for item in methods %}
~{{ name }}.{{ item }}
{%- endfor %}
{% endif %}
{% endblock %}
+1
View File
@@ -23,6 +23,7 @@ Human-in-the-loop
:nosignatures:
optuna_dashboard.register_objective_form_widgets
optuna_dashboard.register_user_attr_form_widgets
optuna_dashboard.dict_to_form_widget
optuna_dashboard.ChoiceWidget
optuna_dashboard.SliderWidget
+1
View File
@@ -23,6 +23,7 @@ extensions = [
"sphinx.ext.autodoc",
"sphinx.ext.doctest",
"sphinx.ext.autosummary",
"sphinx.ext.napoleon",
]
templates_path = ["_templates"]
+176
View File
@@ -62,12 +62,37 @@ if TYPE_CHECKING:
@dataclass
class ChoiceWidget:
"""A widget representing a choice with associated values.
Args:
choices: A list of strings representing the available choices.
values: A list of float values associated with each choice.
description: A description of the widget. Defaults to None.
user_attr_key: The key used by `register_user_attr_form_widgets`.
Form output is saved as `trial.user_attrs[user_attr_key]`. Defaults to None.
Example:
.. code-block:: python
from optuna_dashboard import ChoiceWidget
choice_widget = ChoiceWidget(
choices=["A", "B", "C"], values=[1.0, 2.0, 3.0], description="Choose one"
)
"""
choices: list[str]
values: list[float]
description: Optional[str] = None
user_attr_key: Optional[str] = None
def to_dict(self) -> ChoiceWidgetJSON:
"""Convert the ChoiceWidget object to a dictionary.
Returns:
ChoiceWidgetJSON: A dictionary representing the ChoiceWidget object.
"""
return {
"type": "choice",
"description": self.description,
@@ -89,6 +114,26 @@ class ChoiceWidget:
@dataclass
class SliderWidget:
"""A widget representing a slider for selecting a value within a range.
Args:
min: The minimum value of the slider.
max: The maximum value of the slider.
step: The step size for the slider. Defaults to None.
labels: A list of tuples containing value and label for the slider. Defaults to None.
description: A description for the slider. Defaults to None.
user_attr_key: The key used by `register_user_attr_form_widgets`.
Form output is saved as `trial.user_attrs[user_attr_key]`. Defaults to None.
Example:
.. code-block:: python
from optuna_dashboard import SliderWidget
slide_widget = SliderWidget(min=0, max=10, step=1, description="Example slider")
"""
min: float
max: float
step: Optional[float] = None
@@ -97,6 +142,11 @@ class SliderWidget:
user_attr_key: Optional[str] = None
def to_dict(self) -> SliderWidgetJSON:
"""Convert the SliderWidget instance to a dictionary.
Returns:
SliderWidgetJSON: A dictionary representation of the SliderWidget instance.
"""
labels: Optional[list[SliderWidgetLabel]] = None
if self.labels is not None:
labels = [{"value": value, "label": label} for value, label in self.labels]
@@ -128,10 +178,33 @@ class SliderWidget:
@dataclass
class TextInputWidget:
"""
A text input widget class that defines a text input field.
Args:
description: A description of the text input field.
user_attr_key: The key used by `register_user_attr_form_widgets`.
Form output is saved as `trial.user_attrs[user_attr_key]`. Defaults to None.
Example:
.. code-block:: python
from optuna_dashboard import TextInputWidget
text_input = TextInputWidget(description="Text Input Example")
"""
description: Optional[str] = None
user_attr_key: Optional[str] = None
def to_dict(self) -> TextInputWidgetJSON:
"""
Converts the TextInputWidget instance to a dictionary representation.
Returns:
TextInputWidgetJSON: The dictionary representation of the TextInputWidget instance.
"""
return {
"type": "text",
"description": self.description,
@@ -149,9 +222,32 @@ class TextInputWidget:
@dataclass
class ObjectiveUserAttrRef:
"""
A class representing a reference to a value of `trial.user_attrs`.
When combined with `register_objective_form_widgets`, users can tell values that are
registered to `trial.user_attrs` during the human-in-the-loop optimization.
Args:
key: The key of `trial.user_attrs` being referenced.
Example:
.. code-block:: python
from optuna_dashboard import ObjectiveUserAttrRef
user_attr_ref = ObjectiveUserAttrRef(key="key")
"""
key: str
def to_dict(self) -> UserAttrRefJSON:
"""
Converts the ObjectiveUserAttrRef instance to a dictionary representation.
Returns:
UserAttrRefJSON: The dictionary representation of the ObjectiveUserAttrRef instance.
"""
return {
"type": "user_attr",
"key": self.key,
@@ -197,6 +293,45 @@ def dict_to_form_widget(d: dict[str, Any]) -> ObjectiveFormWidget:
def register_objective_form_widgets(
study: optuna.Study, widgets: list[ObjectiveFormWidget]
) -> None:
"""
Register a list of form widgets to an Optuna study.
Submitted values to the forms are told as each trial's objective values.
Args:
study: The Optuna study object to register the form widgets for.
widgets: A list of ObjectiveFormWidget objects to be registered in the study.
Raises:
ValueError: If the length of study directions is not equal to the length of widgets.
Warning: If any widget has `user_attr_key` specified, but it will not be used.
Examples:
.. code-block:: python
import optuna
from optuna_dashboard import ChoiceWidget, SliderWidget
from optuna_dashboard import register_objective_form_widgets
study = optuna.create_study()
register_objective_form_widgets(
study,
widgets=[
ObjectiveChoiceWidget(
choices=["Good 👍", "Bad 👎"],
values=[-1, 1],
description="Please input your score!",
),
ObjectiveSliderWidget(
min=1,
max=10,
step=1,
description="Higher is better.",
),
],
)
"""
if version.parse(optuna_ver) < version.Version("3.2") and isinstance(
study._storage, optuna.storages._CachedStorage
):
@@ -222,6 +357,47 @@ def register_objective_form_widgets(
def register_user_attr_form_widgets(
study: optuna.Study, widgets: list[ObjectiveFormWidget]
) -> None:
"""
Register a list of form widgets to an Optuna study.
Submitted values to the forms are registered as each trial's user_attrs.
Args:
study: The Optuna study object to register the form widgets for.
widgets: A list of ObjectiveFormWidget objects to be registered in the study.
Raises:
ValueError: If an ObjectiveUserAttrRef is specified or if `user_attr_key` is not specified.
ValueError: If `user_attr_key` is not unique for each widget.
Examples:
.. code-block:: python
import optuna
from optuna_dashboard import ChoiceWidget, SliderWidget
from optuna_dashboard import register_user_attr_form_widgets
study = optuna.create_study()
register_user_attr_form_widgets(
study,
widgets=[
ChoiceWidget(
choices=["Good 👍", "Bad 👎"],
values=[-1, 1],
description="Please input your score!",
user_attr_key="hitl/choice",
),
SliderWidget(
min=1,
max=10,
step=1,
description="Higher is better.",
user_attr_key="hitl/slider",
),
],
)
"""
if version.parse(optuna_ver) < version.Version("3.2") and isinstance(
study._storage, optuna.storages._CachedStorage
):