diff --git a/optuna_dashboard/ts/action.ts b/optuna_dashboard/ts/action.ts index e0819b37..091e7339 100644 --- a/optuna_dashboard/ts/action.ts +++ b/optuna_dashboard/ts/action.ts @@ -1,27 +1,7 @@ import * as Optuna from "@optuna/types" import { useSnackbar } from "notistack" import { useRecoilState, useSetRecoilState } from "recoil" -import { - createNewStudyAPI, - deleteStudyAPI, - deleteStudyArtifactAPI, - deleteTrialArtifactAPI, - getMetaInfoAPI, - getStudyDetailAPI, - getStudySummariesAPI, - removePreferentialHistoryAPI, - renameStudyAPI, - reportFeedbackComponentAPI, - reportPreferenceAPI, - restorePreferentialHistoryAPI, - saveStudyNoteAPI, - saveTrialNoteAPI, - saveTrialUserAttrsAPI, - skipPreferentialTrialAPI, - tellTrialAPI, - uploadStudyArtifactAPI, - uploadTrialArtifactAPI, -} from "./apiClient" +import { useAPIClient } from "./apiClientProvider" import { getDominatedTrials } from "./dominatedTrials" import { artifactIsAvailable, @@ -46,6 +26,7 @@ import { // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types export const actionCreator = () => { + const { apiClient } = useAPIClient() const { enqueueSnackbar } = useSnackbar() const [studySummaries, setStudySummaries] = useRecoilState(studySummariesState) @@ -218,7 +199,7 @@ export const actionCreator = () => { } const updateAPIMeta = () => { - getMetaInfoAPI().then((r) => { + apiClient.getMetaInfo().then((r) => { setArtifactIsAvailable(r.artifact_is_available) setPlotlypyIsAvailable(r.plotlypy_is_available) }) @@ -226,7 +207,8 @@ export const actionCreator = () => { const updateStudySummaries = (successMsg?: string) => { setStudySummariesLoading(true) - getStudySummariesAPI() + apiClient + .getStudySummaries() .then((studySummaries: StudySummary[]) => { setStudySummariesLoading(false) setStudySummaries(studySummaries) @@ -258,7 +240,8 @@ export const actionCreator = () => { nLocalFixedTrials = firstUpdatable === -1 ? currentTrials.length : firstUpdatable } - getStudyDetailAPI(studyId, nLocalFixedTrials) + apiClient + .getStudyDetail(studyId, nLocalFixedTrials) .then((study) => { setStudyDetailLoading({ ...studyDetailLoading, [studyId]: false }) const currentFixedTrials = @@ -284,7 +267,8 @@ export const actionCreator = () => { studyName: string, directions: Optuna.StudyDirection[] ) => { - createNewStudyAPI(studyName, directions) + apiClient + .createNewStudy(studyName, directions) .then((study_summary) => { const newVal = [...studySummaries, study_summary] setStudySummaries(newVal) @@ -301,7 +285,8 @@ export const actionCreator = () => { } const deleteStudy = (studyId: number) => { - deleteStudyAPI(studyId) + apiClient + .deleteStudy(studyId) .then(() => { setStudySummaries(studySummaries.filter((s) => s.study_id !== studyId)) enqueueSnackbar(`Success to delete a study (id=${studyId})`, { @@ -317,7 +302,8 @@ export const actionCreator = () => { } const renameStudy = (studyId: number, studyName: string) => { - renameStudyAPI(studyId, studyName) + apiClient + .renameStudy(studyId, studyName) .then((study) => { const newStudySummaries = [ ...studySummaries.filter((s) => s.study_id !== studyId), @@ -341,7 +327,8 @@ export const actionCreator = () => { } const saveStudyNote = (studyId: number, note: Note): Promise => { - return saveStudyNoteAPI(studyId, note) + return apiClient + .saveStudyNote(studyId, note) .then(() => { const newStudy = Object.assign({}, studyDetails[studyId]) newStudy.note = note @@ -371,7 +358,8 @@ export const actionCreator = () => { trialId: number, note: Note ): Promise => { - return saveTrialNoteAPI(studyId, trialId, note) + return apiClient + .saveTrialNote(studyId, trialId, note) .then(() => { const index = studyDetails[studyId].trials.findIndex( (t) => t.trial_id === trialId @@ -422,12 +410,13 @@ export const actionCreator = () => { setUploading(true) reader.readAsDataURL(file) reader.onload = (upload: ProgressEvent) => { - uploadTrialArtifactAPI( - studyId, - trialId, - file.name, - upload.target?.result as string - ) + apiClient + .uploadTrialArtifact( + studyId, + trialId, + file.name, + upload.target?.result as string + ) .then((res) => { setUploading(false) const index = studyDetails[studyId].trials.findIndex( @@ -455,11 +444,12 @@ export const actionCreator = () => { setUploading(true) reader.readAsDataURL(file) reader.onload = (upload: ProgressEvent) => { - uploadStudyArtifactAPI( - studyId, - file.name, - upload.target?.result as string - ) + apiClient + .uploadStudyArtifact( + studyId, + file.name, + upload.target?.result as string + ) .then((res) => { setUploading(false) setStudyArtifacts(studyId, res.artifacts) @@ -481,7 +471,8 @@ export const actionCreator = () => { trialId: number, artifactId: string ): void => { - deleteTrialArtifactAPI(studyId, trialId, artifactId) + apiClient + .deleteTrialArtifact(studyId, trialId, artifactId) .then(() => { deleteTrialArtifactState(studyId, trialId, artifactId) enqueueSnackbar(`Success to delete an artifact.`, { @@ -497,7 +488,8 @@ export const actionCreator = () => { } const deleteStudyArtifact = (studyId: number, artifactId: string): void => { - deleteStudyArtifactAPI(studyId, artifactId) + apiClient + .deleteStudyArtifact(studyId, artifactId) .then(() => { deleteStudyArtifactState(studyId, artifactId) enqueueSnackbar(`Success to delete an artifact.`, { @@ -515,7 +507,8 @@ export const actionCreator = () => { const makeTrialFail = (studyId: number, trialId: number): void => { const message = `id=${trialId}, state=Fail` setTrialUpdating(trialId, true) - tellTrialAPI(trialId, "Fail") + apiClient + .tellTrial(trialId, "Fail") .then(() => { const index = studyDetails[studyId].trials.findIndex( (t) => t.trial_id === trialId @@ -551,7 +544,8 @@ export const actionCreator = () => { ): void => { const message = `id=${trialId}, state=Complete, values=${values}` setTrialUpdating(trialId, true) - tellTrialAPI(trialId, "Complete", values) + apiClient + .tellTrial(trialId, "Complete", values) .then(() => { const index = studyDetails[studyId].trials.findIndex( (t) => t.trial_id === trialId @@ -584,7 +578,8 @@ export const actionCreator = () => { ): void => { const message = `id=${trialId}, user_attrs=${JSON.stringify(user_attrs)}` setTrialUpdating(trialId, true) - saveTrialUserAttrsAPI(trialId, user_attrs) + apiClient + .saveTrialUserAttrs(trialId, user_attrs) .then(() => { const index = studyDetails[studyId].trials.findIndex( (t) => t.trial_id === trialId @@ -618,7 +613,7 @@ export const actionCreator = () => { candidates: number[], clicked: number ) => { - reportPreferenceAPI(studyId, candidates, clicked).catch((err) => { + apiClient.reportPreference(studyId, candidates, clicked).catch((err) => { const reason = err.response?.data.reason enqueueSnackbar(`Failed to report preference. Reason: ${reason}`, { variant: "error", @@ -628,7 +623,7 @@ export const actionCreator = () => { } const skipPreferentialTrial = (studyId: number, trialId: number) => { - skipPreferentialTrialAPI(studyId, trialId).catch((err) => { + apiClient.skipPreferentialTrial(studyId, trialId).catch((err) => { const reason = err.response?.data.reason enqueueSnackbar(`Failed to skip trial. Reason: ${reason}`, { variant: "error", @@ -640,7 +635,8 @@ export const actionCreator = () => { studyId: number, compoennt_type: FeedbackComponentType ) => { - reportFeedbackComponentAPI(studyId, compoennt_type) + apiClient + .reportFeedbackComponent(studyId, compoennt_type) .then(() => { const newStudy = Object.assign({}, studyDetails[studyId]) newStudy.feedback_component_type = compoennt_type @@ -659,7 +655,8 @@ export const actionCreator = () => { } const removePreferentialHistory = (studyId: number, historyId: string) => { - removePreferentialHistoryAPI(studyId, historyId) + apiClient + .removePreferentialHistory(studyId, historyId) .then(() => { const newStudy = Object.assign({}, studyDetails[studyId]) newStudy.preference_history = newStudy.preference_history?.map((h) => @@ -683,7 +680,8 @@ export const actionCreator = () => { }) } const restorePreferentialHistory = (studyId: number, historyId: string) => { - restorePreferentialHistoryAPI(studyId, historyId) + apiClient + .restorePreferentialHistory(studyId, historyId) .then(() => { const newStudy = Object.assign({}, studyDetails[studyId]) newStudy.preference_history = newStudy.preference_history?.map((h) => diff --git a/optuna_dashboard/ts/components/GraphEdf.tsx b/optuna_dashboard/ts/components/GraphEdf.tsx index e3c17690..72b36b02 100644 --- a/optuna_dashboard/ts/components/GraphEdf.tsx +++ b/optuna_dashboard/ts/components/GraphEdf.tsx @@ -2,7 +2,8 @@ import { Box, Typography, useTheme } from "@mui/material" import * as plotly from "plotly.js-dist-min" import React, { FC, useEffect, useMemo } from "react" import { StudyDetail, Trial } from "ts/types/optuna" -import { CompareStudiesPlotType, getCompareStudiesPlotAPI } from "../apiClient" +import { CompareStudiesPlotType } from "../apiClient" +import { useAPIClient } from "../apiClientProvider" import { useGraphComponentState } from "../hooks/useGraphComponentState" import { useBackendRender, usePlotlyColorTheme } from "../state" import { Target, useFilteredTrialsFromStudies } from "../trialFilter" @@ -29,6 +30,7 @@ export const GraphEdf: FC<{ const GraphEdfBackend: FC<{ studies: StudyDetail[] }> = ({ studies }) => { + const { apiClient } = useAPIClient() const { graphComponentState, notifyGraphDidRender } = useGraphComponentState() const studyIds = studies.map((s) => s.id) @@ -43,7 +45,8 @@ const GraphEdfBackend: FC<{ return } if (graphComponentState !== "componentWillMount") { - getCompareStudiesPlotAPI(studyIds, CompareStudiesPlotType.EDF) + apiClient + .getCompareStudiesPlot(studyIds, CompareStudiesPlotType.EDF) .then(({ data, layout }) => { plotly.react(domId, data, layout).then(notifyGraphDidRender) }) diff --git a/optuna_dashboard/ts/hooks/useParamImportance.ts b/optuna_dashboard/ts/hooks/useParamImportance.ts index 50d37ac2..9cddaafa 100644 --- a/optuna_dashboard/ts/hooks/useParamImportance.ts +++ b/optuna_dashboard/ts/hooks/useParamImportance.ts @@ -3,12 +3,13 @@ import { AxiosError } from "axios" import { useSnackbar } from "notistack" import { useEffect } from "react" import { ParamImportance } from "ts/types/optuna" -import { getParamImportances } from "../apiClient" +import { useAPIClient } from "../apiClientProvider" export const useParamImportance = ({ numCompletedTrials, studyId, }: { numCompletedTrials: number; studyId: number }) => { + const { apiClient } = useAPIClient() const { enqueueSnackbar } = useSnackbar() const { data, isLoading, error } = useQuery< @@ -16,7 +17,7 @@ export const useParamImportance = ({ AxiosError<{ reason: string }> >({ queryKey: ["paramImportance", studyId, numCompletedTrials], - queryFn: () => getParamImportances(studyId), + queryFn: () => apiClient.getParamImportances(studyId), staleTime: Infinity, gcTime: 30 * 60 * 1000, // 30 minutes }) diff --git a/optuna_dashboard/ts/hooks/usePlot.ts b/optuna_dashboard/ts/hooks/usePlot.ts index 4b3588fa..e6ca5166 100644 --- a/optuna_dashboard/ts/hooks/usePlot.ts +++ b/optuna_dashboard/ts/hooks/usePlot.ts @@ -1,7 +1,8 @@ import { useQuery } from "@tanstack/react-query" import { AxiosError } from "axios" import * as plotly from "plotly.js-dist-min" -import { PlotType, getPlotAPI } from "../apiClient" +import { PlotType } from "../apiClient" +import { useAPIClient } from "../apiClientProvider" export const usePlot = ({ numCompletedTrials, @@ -12,6 +13,7 @@ export const usePlot = ({ studyId: number | undefined plotType: PlotType }) => { + const { apiClient } = useAPIClient() const { data, isLoading, error } = useQuery< { data: plotly.Data[]; layout: plotly.Layout }, AxiosError @@ -22,7 +24,7 @@ export const usePlot = ({ if (studyId === undefined) { return Promise.reject(new Error("Invalid studyId")) } - return getPlotAPI(studyId, plotType) + return apiClient.getPlot(studyId, plotType) }, staleTime: Infinity, gcTime: 30 * 60 * 1000, // 30 minutes