From ffd883ea9e38012daf0da9a85d696d229334882e Mon Sep 17 00:00:00 2001 From: bjkim Date: Mon, 22 Sep 2025 16:17:37 +0900 Subject: [PATCH] =?UTF-8?q?[ADD]=20MLflow=20Experiment=20=EC=A1=B0?= =?UTF-8?q?=ED=9A=8C=20API=20=EA=B5=AC=ED=98=84=20(MlflowController)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controllers/MlflowController.java | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 src/main/java/kr/re/etri/autoflow/controllers/MlflowController.java diff --git a/src/main/java/kr/re/etri/autoflow/controllers/MlflowController.java b/src/main/java/kr/re/etri/autoflow/controllers/MlflowController.java new file mode 100644 index 0000000..0b3ba02 --- /dev/null +++ b/src/main/java/kr/re/etri/autoflow/controllers/MlflowController.java @@ -0,0 +1,47 @@ +package kr.re.etri.autoflow.controllers; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.reactive.function.client.WebClient; +import reactor.core.publisher.Mono; + +import java.util.Collections; +import java.util.Map; + +@Tag(name = "MLflow API", description = "MLflow Experiment 및 Run 조회 API") +@RestController +@RequestMapping("/api/mlflow") +public class MlflowController { + + private final WebClient webClient; + + public MlflowController() { + this.webClient = WebClient.builder() + .baseUrl("http://192.168.10.135:30128/api/2.0/mlflow") + .defaultHeaders(headers -> headers.setBasicAuth("user", "LImQa2Me37nu")) + .build(); + } + + @Operation(summary = "Experiment의 Run 목록 조회", description = "주어진 Experiment ID의 Run을 최대 1000개까지 조회합니다.") + @GetMapping(value = "/runs", produces = MediaType.APPLICATION_JSON_VALUE) + public Mono> getRuns(@RequestParam String experimentId) { + Map body = Map.of( + "experiment_ids", Collections.singletonList(experimentId), + "order_by", Collections.singletonList("attribute.start_time DESC"), + "max_results", 1000 + ); + + return webClient.post() + .uri("/runs/search") + .contentType(MediaType.APPLICATION_JSON) + .bodyValue(body) + .retrieve() + .bodyToMono(String.class) + .map(ResponseEntity::ok) + .onErrorResume(e -> Mono.just(ResponseEntity.internalServerError().body(e.getMessage()))); + } + +}