Implement human-in-the-loop via trial.user_attrs

This commit is contained in:
Kenshin Abe
2023-03-06 21:34:01 +09:00
parent 03baf45c7e
commit 8aadf8aab3
4 changed files with 60 additions and 5 deletions
+17
View File
@@ -447,6 +447,23 @@ def create_app(
response.status = 204
return {}
@app.post("/api/trials/<trial_id:int>/user-attrs")
@json_api_view
def save_trial_user_attrs(trial_id: int) -> dict[str, Any]:
if "user_attrs" not in request.json:
response.status = 400 # Bad request
return {"reason": "user_attrs must be specified."}
try: # TODO(knshnb): Proper error handling.
for key, val in request.json.get("user_attrs").items():
storage.set_trial_user_attr(trial_id, key, val)
except Exception as e:
response.status = 500
return {"reason": f"Internal server error: {e}"}
response.status = 204
return {}
@app.put("/api/studies/<study_id:int>/<trial_id:int>/note")
@json_api_view
def save_trial_note(study_id: int, trial_id: int) -> dict[str, Any]:
+28
View File
@@ -13,6 +13,7 @@ import {
uploadArtifactAPI,
getMetaInfoAPI,
deleteArtifactAPI,
saveTrialUserAttrsAPI,
} from "./apiClient"
import {
graphVisibilityState,
@@ -482,6 +483,32 @@ export const actionCreator = () => {
})
}
const saveTrialUserAttrs = (
studyId: number,
trialId: number,
user_attrs: {[key: string]: number},
): void => {
console.log("user_attrs", user_attrs)
// TODO(knshnb): Update rendering of `user_attrs`.
const message = `id=${trialId}, user_attrs=${user_attrs}`
saveTrialUserAttrsAPI(trialId, user_attrs)
.then(() => {
// TODO(knshnb): Update states.
enqueueSnackbar(`Successfully updated trial (${message})`, {
variant: "success",
})
})
.catch((err) => {
const reason = err.response?.data.reason
enqueueSnackbar(
`Failed to update trial (${message}). Reason: ${reason}`,
{
variant: "error",
}
)
console.log(err)
})
}
return {
updateAPIMeta,
updateStudyDetail,
@@ -499,6 +526,7 @@ export const actionCreator = () => {
uploadArtifact,
deleteArtifact,
tellTrial,
saveTrialUserAttrs,
}
}
+13
View File
@@ -281,6 +281,19 @@ export const tellTrialAPI = (
})
}
export const saveTrialUserAttrsAPI = (
trialId: number,
user_attrs: { [key: string]: number }
): Promise<void> => {
const req = { user_attrs: user_attrs }
return axiosInstance
.post<void>(`/api/trials/${trialId}/user-attrs`, req)
.then((res) => {
return
})
}
interface ParamImportancesResponse {
param_importances: ParamImportance[][]
}
@@ -65,11 +65,8 @@ export const ObjectiveForm: FC<{
const handleSubmit = (e: React.MouseEvent<HTMLButtonElement>): void => {
e.preventDefault()
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)
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 => {