|
|
|
|
import { request } from "@/components/service/index";
|
|
|
|
|
import { saveBlob, filenameFromContentDisposition } from "@/utils/download";
|
|
|
|
|
|
|
|
|
|
export const MlflowService = {
|
|
|
|
|
getRuns: (experimentId: string) => {
|
|
|
|
|
return request.get("/api/mlflow/runs", {
|
|
|
|
|
experimentId,
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/** Kubeflow run id 태그로 MLflow run 검색 (전체 experiment 대상, experiment name 무관) */
|
|
|
|
|
getRunsByKubeflowRunId: (kubeflowRunId: string) => {
|
|
|
|
|
return request.get("/api/mlflow/runs/by-kubeflow-run-id", {
|
|
|
|
|
kubeflowRunId,
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/** 전체 Experiment 목록 조회 (이름 등록 없이 동적 검색용) */
|
|
|
|
|
getExperiments: () => {
|
|
|
|
|
return request.get("/api/mlflow/experiments");
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
getExperimentByName: (experimentName: string) => {
|
|
|
|
|
return request.get("/api/mlflow/experiment", {
|
|
|
|
|
experimentName,
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
getExperimentRun: (runId: string) => {
|
|
|
|
|
return request.get("/api/mlflow/run", {
|
|
|
|
|
runId,
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
artifact: (runId: string, path?: string) => {
|
|
|
|
|
const params: Record<string, any> = {
|
|
|
|
|
runId,
|
|
|
|
|
run_id: runId,
|
|
|
|
|
};
|
|
|
|
|
if (path !== undefined) params.path = path;
|
|
|
|
|
|
|
|
|
|
// 1차: /list 시도 → 404면 구(舊) 경로로 폴백
|
|
|
|
|
return request
|
|
|
|
|
.get("/api/mlflow/artifacts/list", params)
|
|
|
|
|
.catch((err: any) => {
|
|
|
|
|
if (err?.response?.status === 404) {
|
|
|
|
|
return request.get("/api/mlflow/artifacts", params);
|
|
|
|
|
}
|
|
|
|
|
throw err;
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* MLflow get-artifact API를 통해 artifact 파일 다운로드 (MinIO 직접 경로 대신 사용 시 NoSuchKey 방지).
|
|
|
|
|
*/
|
|
|
|
|
async downloadArtifact(runId: string, path: string): Promise<void> {
|
|
|
|
|
const res = await request.getFile("/api/mlflow/artifacts/download", {
|
|
|
|
|
run_id: runId,
|
|
|
|
|
path,
|
|
|
|
|
});
|
|
|
|
|
const blob: Blob = res.data;
|
|
|
|
|
const cd = res.headers?.["content-disposition"];
|
|
|
|
|
const fallback = path.split("/").pop() || "download.bin";
|
|
|
|
|
const filename = filenameFromContentDisposition(cd, fallback);
|
|
|
|
|
saveBlob(blob, filename);
|
|
|
|
|
},
|
|
|
|
|
};
|