mirror of
https://github.com/wassname/optuna-dashboard.git
synced 2026-09-23 13:30:25 +08:00
Implement register_user_attr_form_widgets
This commit is contained in:
@@ -7,6 +7,7 @@ from ._objective_form_widget import ObjectiveSliderWidget # noqa
|
||||
from ._objective_form_widget import ObjectiveTextInputWidget # noqa
|
||||
from ._objective_form_widget import ObjectiveUserAttrRef # noqa
|
||||
from ._objective_form_widget import register_objective_form_widgets # noqa
|
||||
from ._objective_form_widget import register_user_attr_form_widgets # noqa
|
||||
|
||||
|
||||
__version__ = "0.9.0b6"
|
||||
|
||||
@@ -34,6 +34,7 @@ from ._bottle_util import BottleViewReturn
|
||||
from ._bottle_util import json_api_view
|
||||
from ._cached_extra_study_property import get_cached_extra_study_property
|
||||
from ._importance import get_param_importance_from_trials_cache
|
||||
from ._objective_form_widget import SYSTEM_ATTR_OUTPUT_TYPE_KEY
|
||||
from ._pareto_front import get_pareto_front_trials
|
||||
from ._serializer import serialize_study_detail
|
||||
from ._serializer import serialize_study_summary
|
||||
@@ -357,6 +358,7 @@ def create_app(
|
||||
union_user_attrs,
|
||||
has_intermediate_values,
|
||||
) = get_cached_extra_study_property(study_id, trials)
|
||||
form_widgets_output_type = storage.get_study_system_attrs(study_id).get(SYSTEM_ATTR_OUTPUT_TYPE_KEY)
|
||||
return serialize_study_detail(
|
||||
summary,
|
||||
best_trials,
|
||||
@@ -365,6 +367,7 @@ def create_app(
|
||||
union,
|
||||
union_user_attrs,
|
||||
has_intermediate_values,
|
||||
form_widgets_output_type,
|
||||
)
|
||||
|
||||
@app.get("/api/studies/<study_id:int>/param_importances")
|
||||
|
||||
@@ -111,6 +111,7 @@ ObjectiveFormWidget = Union[
|
||||
ObjectiveChoiceWidget, ObjectiveSliderWidget, ObjectiveTextInputWidget, ObjectiveUserAttrRef
|
||||
]
|
||||
SYSTEM_ATTR_KEY = "dashboard:objective_form_widgets:v1"
|
||||
SYSTEM_ATTR_OUTPUT_TYPE_KEY = "dashboard:form_widgets_output_type:v1"
|
||||
|
||||
|
||||
def register_objective_form_widgets(
|
||||
@@ -120,6 +121,15 @@ def register_objective_form_widgets(
|
||||
raise ValueError("The length of actions must be the same with the number of objectives.")
|
||||
widget_dicts = [w.to_dict() for w in widgets]
|
||||
study._storage.set_study_system_attr(study._study_id, SYSTEM_ATTR_KEY, widget_dicts)
|
||||
study._storage.set_study_system_attr(study._study_id, SYSTEM_ATTR_OUTPUT_TYPE_KEY, "objective")
|
||||
|
||||
|
||||
def register_user_attr_form_widgets(
|
||||
study: optuna.Study, widgets: list[ObjectiveFormWidget]
|
||||
) -> None:
|
||||
widget_dicts = [w.to_dict() for w in widgets]
|
||||
study._storage.set_study_system_attr(study._study_id, SYSTEM_ATTR_KEY, widget_dicts)
|
||||
study._storage.set_study_system_attr(study._study_id, SYSTEM_ATTR_OUTPUT_TYPE_KEY, "user_attr")
|
||||
|
||||
|
||||
def get_objective_form_widgets_json(
|
||||
|
||||
@@ -2,6 +2,7 @@ from __future__ import annotations
|
||||
|
||||
import json
|
||||
from typing import Any
|
||||
from typing import Optional
|
||||
from typing import TYPE_CHECKING
|
||||
from typing import Union
|
||||
|
||||
@@ -121,6 +122,7 @@ def serialize_study_detail(
|
||||
union: list[tuple[str, BaseDistribution]],
|
||||
union_user_attrs: list[tuple[str, bool]],
|
||||
has_intermediate_values: bool,
|
||||
form_widgets_output_type: Optional[str],
|
||||
) -> dict[str, Any]:
|
||||
serialized: dict[str, Any] = {
|
||||
"name": summary.study_name,
|
||||
@@ -147,6 +149,7 @@ def serialize_study_detail(
|
||||
objective_form_widgets = get_objective_form_widgets_json(system_attrs)
|
||||
if objective_form_widgets:
|
||||
serialized["objective_form_widgets"] = objective_form_widgets
|
||||
serialized["form_widgets_output_type"] = form_widgets_output_type
|
||||
return serialized
|
||||
|
||||
|
||||
|
||||
@@ -68,6 +68,7 @@ interface StudyDetailResponse {
|
||||
note: Note
|
||||
objective_names?: string[]
|
||||
objective_form_widgets?: ObjectiveFormWidget[]
|
||||
form_widgets_output_type?: string
|
||||
}
|
||||
|
||||
export const getStudyDetailAPI = (
|
||||
@@ -101,6 +102,7 @@ export const getStudyDetailAPI = (
|
||||
note: res.data.note,
|
||||
objective_names: res.data.objective_names,
|
||||
objective_form_widgets: res.data.objective_form_widgets,
|
||||
form_widgets_output_type: res.data.form_widgets_output_type,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -21,7 +21,8 @@ export const ObjectiveForm: FC<{
|
||||
directions: StudyDirection[]
|
||||
names: string[]
|
||||
widgets: ObjectiveFormWidget[]
|
||||
}> = ({ trial, directions, names, widgets }) => {
|
||||
outputType: string
|
||||
}> = ({ trial, directions, names, widgets, outputType }) => {
|
||||
const theme = useTheme()
|
||||
const action = actionCreator()
|
||||
const [values, setValues] = useState<(number | null)[]>(
|
||||
@@ -64,8 +65,16 @@ export const ObjectiveForm: FC<{
|
||||
|
||||
const handleSubmit = (e: React.MouseEvent<HTMLButtonElement>): void => {
|
||||
e.preventDefault()
|
||||
const user_attrs = Object.fromEntries(widgets.map((widget, i) => [widget.description, values[i]]))
|
||||
action.saveTrialUserAttrs(trial.study_id, trial.trial_id, user_attrs)
|
||||
if (outputType == "objective") {
|
||||
const filtered = values.filter<number>((v): v is number => v !== null)
|
||||
if (filtered.length !== directions.length) {
|
||||
return
|
||||
}
|
||||
action.tellTrial(trial.study_id, trial.trial_id, "Complete", filtered)
|
||||
} else if (outputType == "user_attr") {
|
||||
const user_attrs = Object.fromEntries(widgets.map((widget, i) => [widget.description, values[i]]))
|
||||
action.saveTrialUserAttrs(trial.study_id, trial.trial_id, user_attrs)
|
||||
}
|
||||
}
|
||||
|
||||
const getObjectiveName = (i: number): string => {
|
||||
|
||||
@@ -144,12 +144,14 @@ const TrialListDetail: FC<{
|
||||
directions: StudyDirection[]
|
||||
objectiveNames: string[]
|
||||
objectiveFormWidgets: ObjectiveFormWidget[]
|
||||
formWigetsOutputType: string
|
||||
}> = ({
|
||||
trial,
|
||||
isBestTrial,
|
||||
directions,
|
||||
objectiveNames,
|
||||
objectiveFormWidgets,
|
||||
formWigetsOutputType
|
||||
}) => {
|
||||
const theme = useTheme()
|
||||
const artifactEnabled = useRecoilValue<boolean>(artifactIsAvailable)
|
||||
@@ -297,6 +299,7 @@ const TrialListDetail: FC<{
|
||||
directions={directions}
|
||||
names={objectiveNames}
|
||||
widgets={objectiveFormWidgets}
|
||||
outputType={formWigetsOutputType}
|
||||
/>
|
||||
)}
|
||||
{trial.state === "Complete" && directions.length > 0 && (
|
||||
@@ -816,6 +819,9 @@ export const TrialList: FC<{ studyDetail: StudyDetail | null }> = ({
|
||||
objectiveFormWidgets={
|
||||
studyDetail?.objective_form_widgets || []
|
||||
}
|
||||
formWigetsOutputType={
|
||||
studyDetail?.form_widgets_output_type || ""
|
||||
}
|
||||
/>
|
||||
))}
|
||||
</Box>
|
||||
|
||||
Vendored
+1
@@ -176,6 +176,7 @@ type StudyDetail = {
|
||||
note: Note
|
||||
objective_names?: string[]
|
||||
objective_form_widgets?: ObjectiveFormWidget[]
|
||||
form_widgets_output_type?: string
|
||||
}
|
||||
|
||||
type StudyDetails = {
|
||||
|
||||
Reference in New Issue
Block a user